mouse.C

00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
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       {{ // The extra scope is needed to work around gcc3.2 bug #8287
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 }

Generated on Sun Jul 30 22:55:44 2006 for Archon by  doxygen 1.4.4