home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
-
- FILE: EVENT.H
-
- Defines base class for events and predefined event types.
-
- (Event)
- |
- ----------------------------------
- | | | |
- KbdEvent MouseEvent ScrlEvent PushEvent
-
- ********************************************************************/
-
- #if !defined( _EVENT_H_ )
-
- #define _EVENT_H_
-
- #include "misc.h"
-
- enum EventType { KBD_EVENT = 1,
- MOUSE_EVENT,
- SCRL_EVENT,
- PUSH_EVENT };
-
- /********************************************************************
-
- Event
-
- Defines a base class for all types of events.
-
- Public Interface:
-
- getType - returns type of event
-
- ********************************************************************/
-
- class Event
- {
- public:
- virtual EventType getType() const = 0;
- virtual ~Event() {}
- };
-
- /********************************************************************
-
- KbdEvent
-
- Defines events generated by the keyboard. Each event contains
- an ASCII character and a scancode, allowing cursor keys to be
- read.
-
- Public Interface:
-
- KbdEvent - constructor taking two characters, an ASCII value
- and a scan code (0 if none)
- val - returns value of key pressed. The value is returned as
- an integer with the scan code in the high word (0 if none)
- and the ASCII value in the low word. This allows the value
- to be compared directly with chars (through the built-in
- conversion).
-
- (inherited from Event)
-
- getType - redefined to return KBD_EVENT
-
- ********************************************************************/
-
-
- class KbdEvent : public Event
- {
- public:
- KbdEvent(char one, char two = 0);
- // use default copy-constructor (memberwise initialization)
- // use default operator= (memberwise assignment)
- EventType getType() const;
- unsigned int val() const;
- private:
- char ascii;
- char scancode;
- };
-
- inline KbdEvent::KbdEvent( char one, char two )
- {
- ascii = one;
- scancode = two;
- }
-
- inline EventType KbdEvent::getType() const
- {
- return KBD_EVENT;
- }
-
- inline unsigned int KbdEvent::val() const
- {
- return ((unsigned int) scancode << 8) |
- (unsigned char) ascii;
- }
-
- /********************************************************************
-
- MouseEvent
-
- Defines events generated by the mouse. Each event contains the
- position at which the event occurred and the status of the mouse
- buttons during the event.
-
- Public Interface:
-
- MouseEvent - constructor taking the position of the event and
- an integer representing the button status
-
- getPosition - returns position at which event occurred
-
- getButton - returns status of mouse buttons, encoded as
- an integer.
-
- (inherited from Event)
- getType - redefined to return MOUSE_EVENT
-
- ********************************************************************/
-
- class MouseEvent : public Event
- {
- public:
- MouseEvent( Point pos, int but );
- // use default copy-constructor (memberwise initialization)
- // use default operator= (memberwise assignment)
- EventType getType() const;
- Point getPosition() const;
- int getButton() const;
- private:
- MouseStatus status;
- };
-
- inline MouseEvent::MouseEvent( Point pos, int but )
- {
- status.position = pos;
- status.button = but;
- }
-
- inline EventType MouseEvent::getType() const
- {
- return MOUSE_EVENT;
- }
-
- inline Point MouseEvent::getPosition() const
- {
- return status.position;
- }
-
- inline int MouseEvent::getButton() const
- {
- return status.button;
- }
-
- /********************************************************************
-
- ScrollEvent
-
- Defines a request for scrolling. Each event contains the direction
- and distance of scrolling requested, and a pointer to the
- ScrollBar that generated the event.
-
- Public Interface:
-
- ScrollEvent - constructor taking flags indicating the direction
- and distance of scrolling, and the scroll bar that originated
- the event
-
- getDirection - returns direction
-
- getDistance - returns distances
-
- getSource - returns pointer to ScrollBar that generated the
- event
-
- (inherited from Event)
-
- getType - redefined to return SCRL_EVENT
-
- ********************************************************************/
-
- class ScrollBar;
-
- enum DirType { FORWARD = 1, BACKWARD };
-
- enum DistType{ LINE = 1, PAGE };
-
- class ScrollEvent : public Event
- {
- public:
- ScrollEvent( DirType dir, DistType dist, ScrollBar *src );
- // use default copy-constructor (memberwise initialization)
- // use default operator= (memberwise assignment)
- EventType getType() const;
- DirType getDirection() const;
- DistType getDistance() const;
- ScrollBar *getSource() const;
- private:
- DirType direction;
- DistType distance;
- ScrollBar *const source;
- };
-
- inline ScrollEvent::ScrollEvent( DirType dir, DistType dist, ScrollBar *src )
- : source( src )
- {
- direction = dir;
- distance = dist;
- }
-
- inline EventType ScrollEvent::getType() const
- {
- return SCRL_EVENT;
- }
-
- inline DirType ScrollEvent::getDirection() const
- {
- return direction;
- }
-
- inline DistType ScrollEvent::getDistance() const
- {
- return distance;
- }
-
- inline ScrollBar *ScrollEvent::getSource() const
- {
- return source;
- }
-
- /********************************************************************
-
- PushEvent
-
- Defines a button press event. Each event contains a pointer to
- the PushButton that generated it.
-
- Public Interface:
-
- PushEvent - constructor taking the push button that generated the
- event
-
- getSource - returns pointer to PushButton that generated
- the event
-
- (inherited from Event)
-
- getType - redefined to return PUSH_EVENT
-
- ********************************************************************/
-
- class PushButton;
-
- class PushEvent : public Event
- {
- public:
- PushEvent( PushButton *src ) : source( src ) {}
- // use default copy-constructor (memberwise initialization)
- // use default operator= (memberwise assignment)
- EventType getType() const;
- PushButton *getSource() const;
- private:
- PushButton *const source;
- };
-
- inline EventType PushEvent::getType() const
- {
- return PUSH_EVENT;
- }
-
- inline PushButton *PushEvent::getSource() const
- {
- return source;
- }
-
- /********************************************************************
-
- EventGenerator
-
- ********************************************************************/
-
- class EventGenerator
- {
- public:
- EventGenerator();
- Event *getNextEvent();
- ~EventGenerator();
- private:
- MouseEvent *getMouseEvent();
- MouseStatus lastStatus;
- };
-
- /********************************************************************
-
- NOTES ON ALTERNATE IMPLEMENTATIONS
-
- The getType() function of events returns an enumerated type.
- An enum is used for simplicity. Its drawback is that the enum
- must be kept synchronized with the types of events. When a new
- type of event is defined, the enum must be modified, causing
- all previously defined events to be recompiled.
-
- One alternative is to have each class define a static integer member,
- and use its address to identify the class (see Ellis & Stroustrup, p 213):
-
- class Event
- {
- public:
- virtual int *getType();
- };
-
- class KbdEvent : public Event
- {
- public:
- static int rep;
- int *getType() { return &rep; }
- };
-
- void TextWin::handleEvent( Event &action )
- {
- if( action.getType() == &KbdEvent::rep )
- {
- // ...
- }
- else if( action.getType() == &MouseEvent::rep )
- {
- // ...
- }
- else
- //..
- }
-
- This technique guarantees a unique value for each class, and
- lets a new type of event to be defined without having to update
- existing files.
-
- One way to avoid the use of a getType() function altogether,
- and thus avoid performing a switch on the type of event, is to
- use pointers to member functions. To use them, you define a
- separate function to handle each type of event, as follows:
-
- class Win
- {
- public:
- virtual void handleEvent( Event &action ) {}
- virtual void handleKbdEvent( KbdEvent &action ) {}
- virtual void handleMouseEvent( MouseEvent &action ) {}
- //...
- };
-
- With such a design, each type of window overrides the functions
- for the events it responds to. If a window ignores a certain
- type of event, it uses the default implementation, which is
- a null function.
-
- Each Event contains a pointer to the member function that
- receives it.
-
- // pointer to a member function of Win that
- // takes an Event argument and returns void
- typedef void (Win::*ptrWinFunc)( Event &action );
-
- class MouseEvent : public Event
- {
- public:
- ptrWinFunc getHandler() { return &Win::handleMouseEvent; }
- // ...
- };
-
- class KbdEvent : public Event
- {
- public:
- ptrWinFunc getHandler() { return &Win::handleKbdEvent; }
- // ...
- };
-
- The handleEvent function receives an Event, gets a pointer to
- a member function from it, and calls that function, passing
- the Event to it.
-
- void Win::handleEvent( Event &action )
- {
- // get handler function from Event
- ptrWinFunc eventHandler = action.getHandler();
- // pass Event to it
- (this->*eventHandler)( action );
- }
-
- This approach provides faster execution than a switch statement.
- The main drawback is that if you define a new type of event,
- you have to modify the interface to Win by adding a new function
- that handles the event.
-
- ********************************************************************/
-
-
- #endif // _EVENT_H_
-