00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <iostream>
00021
00022 #include <archon/util/mouse.H>
00023
00024 namespace Archon
00025 {
00026 namespace Utilities
00027 {
00028 namespace MouseEvents
00029 {
00030 Dispatcher::Dispatcher(unsigned numberOfButtons,
00031 unsigned numberOfModes,
00032 unsigned maxMulticlickLimit,
00033 unsigned long multiclickMaxDelay):
00034 numberOfButtons(numberOfButtons),
00035 numberOfModes(numberOfModes),
00036 maxMulticlickLimit(maxMulticlickLimit),
00037 multiclickMaxDelay(multiclickMaxDelay),
00038 currentMode(0)
00039 {
00040 if(maxMulticlickLimit < 1)
00041 ARCHON_THROW1(ArgumentException, "Invalid multiclick limit");
00042
00043 buttonAccounts = new ButtonAccount[numberOfButtons];
00044
00045 buttonHandlers =
00046 new ButtonHandler *[numberOfButtons *
00047 numberOfModes *
00048 maxMulticlickLimit];
00049
00050 motionHandlers = new MotionHandler *[numberOfModes];
00051
00052 for(unsigned i=0; i<numberOfButtons * numberOfModes *
00053 maxMulticlickLimit; ++i)
00054 buttonHandlers[i] = 0;
00055
00056 for(unsigned i=0; i<numberOfModes; ++i)
00057 motionHandlers[i] = 0;
00058 }
00059
00060 Dispatcher::~Dispatcher()
00061 {{
00062 delete[] motionHandlers;
00063 delete[] buttonHandlers;
00064 delete[] buttonAccounts;
00065 }}
00066
00067 void Dispatcher::setMulticlickLimit(unsigned button, unsigned limit)
00068 {
00069 if(button < 0 || button >= numberOfButtons)
00070 ARCHON_THROW1(ArgumentException, "Invalid button");
00071 if(limit < 1 || limit > maxMulticlickLimit)
00072 ARCHON_THROW1(ArgumentException, "Invalid multiclick limit");
00073
00074 buttonAccounts[button].multiclickLimit = limit;
00075 }
00076
00077 void Dispatcher::setMode(unsigned mode)
00078 {
00079 if(mode < 0 || mode >= numberOfModes)
00080 ARCHON_THROW1(ArgumentException, "Invalid mode");
00081 currentMode = mode;
00082 }
00083
00084 void Dispatcher::setButtonHandler(unsigned button, ButtonHandler *h,
00085 unsigned mode,
00086 unsigned multiclickCardinality)
00087 {
00088 if(button < 0 || button >= numberOfButtons)
00089 ARCHON_THROW1(ArgumentException, "Invalid button");
00090 if(mode < 0 || mode >= numberOfModes)
00091 ARCHON_THROW1(ArgumentException, "Invalid mode");
00092 if(multiclickCardinality < 1 ||
00093 multiclickCardinality > maxMulticlickLimit)
00094 ARCHON_THROW1(ArgumentException, "Invalid multiclick cardinality");
00095
00096 buttonHandlers[(button*numberOfModes + mode)*maxMulticlickLimit
00097 + multiclickCardinality - 1] = h;
00098 }
00099
00100 void Dispatcher::setMotionHandler(MotionHandler *h, unsigned mode)
00101 {
00102 if(mode < 0 || mode >= numberOfModes)
00103 ARCHON_THROW1(ArgumentException, "Invalid mode");
00104
00105 motionHandlers[mode] = h;
00106 }
00107
00108 void Dispatcher::press(unsigned button, unsigned x, unsigned y,
00109 unsigned long millisecondTime)
00110 {
00111 if(button >= numberOfButtons) return;
00112 ButtonAccount &a = buttonAccounts[button];
00113
00114 if(millisecondTime - a.lastClick < multiclickMaxDelay)
00115 {
00116 if(a.multiclickCounter < a.multiclickLimit) ++a.multiclickCounter;
00117 }
00118 else a.multiclickCounter = 1;
00119 a.lastClick = millisecondTime;
00120 a.clickMode = currentMode;
00121 ButtonHandler *h =
00122 buttonHandlers[(button*numberOfModes + currentMode)*
00123 maxMulticlickLimit + a.multiclickCounter - 1];
00124 if(h) h->press(x, y);
00125 }
00126
00127 void Dispatcher::release(unsigned button, unsigned x, unsigned y)
00128 {
00129 if(button >= numberOfButtons) return;
00130 ButtonAccount &a = buttonAccounts[button];
00131 ButtonHandler *h =
00132 buttonHandlers[(button*numberOfModes + a.clickMode)*
00133 maxMulticlickLimit + a.multiclickCounter - 1];
00134 if(h) h->release(x, y);
00135 }
00136
00137 void Dispatcher::motion(unsigned xAbs, unsigned yAbs,
00138 int xRel, int yRel)
00139 {
00140 MotionHandler *h = motionHandlers[currentMode];
00141 if(h) h->move(xAbs, yAbs, xRel, yRel);
00142 }
00143 }
00144 }
00145 }