(svn r8931) [cpp_gui] -Add: first OO widget type (TextButton) added only with basic functionality
-Add: new gui events (C++)
-Add: dynamic event handlers introduced (see Widget::AddReflectHandlerT)
-Add: test window using the new features (intro_gui.cpp)
/* $Id$ */
#ifndef WINDOW_EVENT_BASE_H
#define WINDOW_EVENT_BASE_H
struct BaseWindow;
namespace gui {
enum EventCode {
EVT_CREATE,
EVT_DESTROY,
EVT_PAINT,
EVT_KEYPRESS,
EVT_CLICK,
EVT_RCLICK,
EVT_MOUSEOVER,
EVT_MOUSELOOP,
EVT_MOUSEWHEEL,
EVT_TICK,
EVT_4,
EVT_TIMEOUT,
EVT_PLACE_OBJ,
EVT_ABORT_PLACE_OBJ,
EVT_ON_EDIT_TEXT,
EVT_ON_EDIT_TEXT_CANCEL,
EVT_POPUPMENU_SELECT,
EVT_POPUPMENU_OVER,
EVT_DRAGDROP,
EVT_PLACE_DRAG,
EVT_PLACE_MOUSEUP,
EVT_PLACE_PRESIZE,
EVT_DROPDOWN_SELECT,
EVT_RESIZE,
EVT_MESSAGE,
EVT_SCROLL,
EVT_INVALIDATE_DATA,
};
template <EventCode Tcode> struct EventT;
typedef EventT<EVT_CREATE > EvtCreate;
typedef EventT<EVT_DESTROY > EvtDestroy;
typedef EventT<EVT_PAINT > EvtPaint;
typedef EventT<EVT_KEYPRESS > EvtKeyPress;
typedef EventT<EVT_CLICK > EvtClick;
typedef EventT<EVT_RCLICK > EvtRightClick;
typedef EventT<EVT_MOUSEOVER > EvtMouseOver;
typedef EventT<EVT_MOUSELOOP > EvtMouseLoop;
typedef EventT<EVT_MOUSEWHEEL > EvtMouseWheel;
typedef EventT<EVT_TICK > EvtTick;
typedef EventT<EVT_4 > Evt4;
typedef EventT<EVT_TIMEOUT > EvtTimeout;
typedef EventT<EVT_PLACE_OBJ > EvtPlaceObj;
typedef EventT<EVT_ABORT_PLACE_OBJ > EvtAbortPlaceObj;
typedef EventT<EVT_ON_EDIT_TEXT > EvtOnEditText;
typedef EventT<EVT_ON_EDIT_TEXT_CANCEL> EvtOnEditTextCancel;
typedef EventT<EVT_POPUPMENU_SELECT > EvtPopupMenuSelect;
typedef EventT<EVT_POPUPMENU_OVER > EvtPopupMenuOver;
typedef EventT<EVT_DRAGDROP > EvtDragDrop;
typedef EventT<EVT_PLACE_DRAG > EvtPlaceDrag;
typedef EventT<EVT_PLACE_MOUSEUP > EvtPlaceMouseUp;
typedef EventT<EVT_PLACE_PRESIZE > EvtPlacePresize;
typedef EventT<EVT_DROPDOWN_SELECT > EvtDropdownSelect;
typedef EventT<EVT_RESIZE > EvtResize;
typedef EventT<EVT_MESSAGE > EvtMessage;
typedef EventT<EVT_SCROLL > EvtScroll;
typedef EventT<EVT_INVALIDATE_DATA > EvtInvalidateData;
struct Widget;
typedef CCountedPtr<Widget> WidgetPtr;
/** Base of all gui events. Never constructed directly. Used as base class
* of event types */
struct EventBase {
protected:
EventCode m_code;
bool m_handled;
public:
WidgetPtr m_widget;
protected:
/** protected constructor (called from subclasses only) */
EventBase(EventCode code)
: m_code(code)
, m_handled(false)
{}
public:
virtual ~EventBase() {}
/** @return event code */
EventCode GetCode() const
{
return m_code;
}
/** @return true if event was already handled */
bool IsHandled() const
{
return m_handled;
}
void SetHandled(bool handled = true)
{
m_handled = handled;
}
/** type-safe conversion operator */
//template <EventCode Tcode> operator EventT<Tcode>& ()
//{
// assert(m_code == Tcode);
// return *(EventT<Tcode>*)this;
//}
virtual void Dispatch() = 0;
};
/** Intermediate event base that calls EventBase constructor with the proper event type as parameter.
* Used only by event subclasses */
template <EventCode Tcode, void (Widget::*Tevt_method)(EventT<Tcode> &)> struct EventBaseT : public EventBase {
static const EventCode ID = Tcode; ///< allow access to event codes by class name (i.e. EvtCreate::ID)
protected:
EventBaseT()
: EventBase(Tcode)
{}
/*virtual*/ void Dispatch()
{
assert(!m_widget.IsNull());
assert(m_code == Tcode);
(m_widget->*Tevt_method)(*(EventT<Tcode>*)this);
}
};
/**
* Base of all Event Handler Delegates - class that represents Event Handler object/method
* pair that can be called by widget when particular event is handled by a widget. Object
* of any type can register itself and its method as gui event callback handler by adding
* the appropriate delegate object into widget handler list.
*/
struct EventHandlerDelegate : public SimpleCountedObject {
EventCode m_code; ///< event code this handler is registered for
EventHandlerDelegate(EventCode code)
: m_code(code)
{}
/**
* The only method that delegate must provide. Called by widget if the appropriate event
* is reflected.
*/
virtual void HandleEvent(BaseWindow *w, EventBase &e) = 0;
};
/** Reference counting pointer to the event handler delegate. */
typedef CCountedPtr<EventHandlerDelegate> EventHandlerDelegatePtr;
/**
* Delegate for handlers of events reflected back from widget to window.
*/
template <class Twnd_cls, EventCode Tevt_code> struct ReflectHandlerDelegateT : public EventHandlerDelegate {
void (Twnd_cls::*m_handler)(EventT<Tevt_code>&);
ReflectHandlerDelegateT(void (Twnd_cls::*handler)(EventT<Tevt_code>&))
: EventHandlerDelegate(Tevt_code)
, m_handler(handler)
{}
virtual void HandleEvent(BaseWindow *w, EventBase &e)
{
assert(e.GetCode() == Tevt_code);
Twnd_cls &wnd = *(Twnd_cls*)w;
EventT<Tevt_code> &ev = *(EventT<Tevt_code>*)&e;
(wnd.*m_handler)(ev);
}
};
}; // namespace gui
#endif /* WINDOW_EVENT_BASE_H */