event.h

Go to the documentation of this file.
00001 
00007 /*
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation; either
00011     version 2.1 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00021 */
00022 
00023 #ifndef OMGUI_EVENT_H
00024 #define OMGUI_EVENT_H
00025 
00026 #include <omgui/dllimpexp.h>
00027 #include <omgui/event-id.h>
00028 #include <omgui/types.h>
00029 
00030 #include <map>
00031 #include <list>
00032 #include <queue>
00033 
00034 namespace omgui {
00035 
00036 class Event;
00037 class ConnectionBody;
00038 class ConnectionImpl;
00039 
00040 const event_id EVENT_ID_ANY = 0;
00041 
00045 class OMGUI_API SlotBase : public RefCounted
00046 {
00047 public:
00051     virtual ~SlotBase() { }
00052 
00056     virtual bool operator() (const Event &e) = 0;
00057 };
00058 
00062 template<typename E> class PointerSlot : public SlotBase
00063 {
00064 public:
00065     typedef E event_type;
00066     typedef bool(*function_type)(const event_type&);
00067 
00068     PointerSlot(const function_type& f): func(f) { }
00069 
00070     bool operator() (const Event &e) {
00071         return func(dynamic_cast<const event_type&>(e));    
00072     }
00073 
00074 private:
00075     function_type func;
00076 };
00077 
00085 template<typename E, typename T> class MemberSlot : public SlotBase
00086 {
00087 public:
00088     typedef E event_type;
00089     typedef bool(T::*function_type)(const event_type &e);
00090 
00091     MemberSlot(const function_type &function, T &t): func(function), instance(t) { }
00092 
00093     bool operator() (const Event &e) {
00094         return (instance.*func)(dynamic_cast<const event_type&>(e));
00095     }
00096 
00097 private:
00098     function_type func;
00099     T &instance;
00100 };
00101 
00109 template<typename E, typename T> class ConstMemberSlot : public SlotBase
00110 {
00111 public:
00112     typedef E event_type;
00113     typedef bool(T::*function_type)(const event_type &e) const;
00114 
00115     ConstMemberSlot(const function_type &function, T &t): func(function), instance(t) { }
00116 
00117     bool operator() (const Event &e) {
00118         return (instance.*func)(dynamic_cast<const event_type&>(e));
00119     }
00120 
00121 private:
00122     function_type func;
00123     T &instance;
00124 };
00125 
00131 template<typename E, typename F> class FunctorSlot : public SlotBase
00132 {
00133 public:
00134     typedef E event_type;
00135     typedef F function_type;
00136 
00137     FunctorSlot(const function_type& f): func(f) { }
00138 
00139     bool operator() (const Event &e) {
00140         return func(dynamic_cast<const event_type&>(e));
00141     }
00142 
00143 private:
00144     function_type func;
00145 };
00146 
00152 class OMGUI_API Connection
00153 {
00154 public:
00155     Connection();
00156     ~Connection();
00157 
00161     void disconnect();
00162 
00166     bool connected() const;
00167 
00172     void block(bool b = true);
00173 
00177     void unblock() { block(false); }
00178 
00182     bool blocked() const;
00183 
00184 private:
00185     Connection(const Pointer<ConnectionBody> &body);
00186 
00187     Pointer<ConnectionBody> body;
00188 
00189     friend class Signal;
00190 };
00191 
00196 class ConnectionBody : public RefCounted
00197 {
00198 public:
00199     virtual ~ConnectionBody() { }
00200 
00204     virtual void disconnect() = 0;
00205 
00209     virtual bool connected() const = 0;
00210 
00215     virtual void block(bool) = 0;
00216 
00220     virtual bool blocked() const = 0;
00221 };
00222 
00229 class OMGUI_API Signal
00230 {
00231 public:
00232     typedef Pointer<SlotBase> slot_type;
00233 
00234     Signal();
00235 
00239     ~Signal();
00240 
00245     Connection connect(const slot_type &slot);
00246 
00252     bool operator() (const Event&);
00253 
00257     void disconnect_all();
00258 
00259 private:
00260     friend class ConnectionImpl;
00261     typedef std::list< Pointer<ConnectionImpl> > Slots;
00262     typedef std::queue<Slots::iterator> DisconnectedSlots;
00263 
00269     void disconnect(const Slots::iterator &it);
00270 
00271     Slots slots;
00272     DisconnectedSlots disconnected_slots;
00273     int signaling_;
00274 };
00275 
00281 class ConnectionImpl : public ConnectionBody
00282 {
00283 public:
00284     ConnectionImpl(Signal &signal, Signal::slot_type slot);
00285 
00286     void set_iterator(const Signal::Slots::iterator &it);
00287 
00288     void disconnect();
00289 
00290     bool connected() const;
00291 
00292     void block(bool b = true);
00293     bool blocked() const;
00294 
00295     SlotBase &get_slot() const;
00296 
00300     bool operator==(const ConnectionImpl &other) const;
00301 
00302 private:
00303     enum {
00304         CONNECTED = 1,
00305         BLOCKED = 2,
00306     };
00307 
00309     int state_;
00310     Signal::slot_type slot_;
00311     Signal &signal_;
00312     Signal::Slots::iterator it_;
00313 };
00314 
00323 const int SIGNAL_PRIORITY_RUN_FIRST = 1;
00324 const int SIGNAL_PRIORITY_HIGHER = 9;
00326 const int SIGNAL_PRIORITY_NORMAL = 10;
00327 const int SIGNAL_PRIORITY_LOWER = 11;
00328 const int SIGNAL_PRIORITY_RUN_LAST = 20;
00330 
00334 class OMGUI_API EventManager
00335 {
00336 public:
00351     static Connection connect(object_id object, event_id event, SlotBase* slot, int priority = SIGNAL_PRIORITY_NORMAL);
00352 
00357     static void disconnect_all(object_id object);
00358 
00362     static bool send_event(const Event &event);
00363 
00367     static void disconnect_all();
00368 
00369 private:
00370     typedef std::map<event_id, Signal> EventSignals;
00371     typedef std::map<object_id, EventSignals> ObjectEventSignals;
00372 
00373     struct SignalsGroup
00374     {
00375         // Signals raised on any event from any object
00376         //Signal signals;
00378         //EventSignals event_signals;
00380         ObjectEventSignals object_event_signals;
00381 
00382         void disconnect_all()
00383         {
00384             //signals.disconnect_all();
00385             //event_signals.clear();
00386             object_event_signals.clear();
00387         }
00388     };
00389 
00390     typedef std::map<int, SignalsGroup> Signals;
00391     static Signals signals;
00392     static int sending_event;
00393     struct ObjectEventEraseBufferData
00394     {
00395         ObjectEventEraseBufferData(ObjectEventSignals &container, ObjectEventSignals::iterator iterator): container(container), iterator(iterator) { }
00396         ObjectEventSignals &container;
00397         ObjectEventSignals::iterator iterator;
00398     };
00399     static std::deque<ObjectEventEraseBufferData> object_event_erase_buffer;
00400 
00407     static bool send_event(SignalsGroup &group, const Event &event, bool &processed);
00408 };
00409 
00415 template<typename E> 
00416 SlotBase *make_slot(typename PointerSlot<E>::function_type const &func)
00417 {
00418     return new PointerSlot<E>(func);
00419 }
00420 
00424 template<typename E, typename T>
00425 SlotBase *make_slot(typename MemberSlot<E,T>::function_type func, T &instance)
00426 {
00427     return new MemberSlot<E, T>(func, instance);
00428 }
00429 
00433 template<typename E, typename T>
00434 SlotBase *make_slot(typename ConstMemberSlot<E,T>::function_type func, T &instance)
00435 {
00436     return new ConstMemberSlot<E, T>(func, instance);
00437 }
00438 
00445 template<typename E, typename Functor> 
00446 SlotBase *make_slot(const Functor &func)
00447 {
00448     return new FunctorSlot<E, Functor>(func);
00449 }
00450 
00451 /*******************************************
00452  *       Event Object Declarations         *
00453  *******************************************/
00454 
00455 class OMGUI_API Event
00456 {
00457 public:
00465     Event(event_id id, object_id obj);
00466 
00467     Event(const Event &other);
00468 
00469     virtual ~Event();
00470 
00474     event_id get_id() const;
00475 
00479     object_id get_object_id() const;
00480 
00486     void veto(bool v = true) const;
00487 
00491     bool get_veto() const;
00492 
00496     virtual bool can_veto() const;
00497 
00498 private:
00499     const event_id m_id;
00500     const object_id m_obj_id;
00501     mutable bool m_veto;
00502 };
00503 
00520 class OMGUI_API MouseEvent : public Event
00521 {
00522 public:
00532     MouseEvent(event_id id, object_id obj, const omgui::Point &pos, int button_flags, int key_flags);
00533     MouseEvent(const MouseEvent &other);
00534 
00538     enum KEY_FLAGS {
00539         NONE =      0x0,
00540         SHIFT =     0x1,
00541         ALT =       0x2,
00542         CONTROL =   0x4,
00543     };
00544 
00548     enum BUTTON_FLAGS {
00549         LEFT =      0x1,
00550         RIGHT =     0x2,
00551         MIDDLE =    0x4
00552     };
00553 
00557     int get_button_flags() const;
00558 
00562     bool get_button_state(BUTTON_FLAGS button) const;
00563 
00567     int get_key_flags() const;
00568 
00572     bool get_key_state(KEY_FLAGS key) const;
00573 
00577     omgui::Point get_position() const;
00578 
00579 private:
00581     omgui::Point m_position;
00582 
00584     int m_button_flags;
00585 
00587     int m_key_flags;
00588 };
00589 
00594 class WindowCloseEvent : public Event
00595 {
00596 public:
00604     WindowCloseEvent(event_id id, object_id obj, bool vetoable = true);
00605     WindowCloseEvent(const WindowCloseEvent &other);
00606 
00612     bool can_veto() const;
00613 
00614 private:
00615     bool m_vetoable;
00616 };
00617 
00622 class NotebookEvent : public Event
00623 {
00624 public:
00632     NotebookEvent(event_id id, object_id obj, omgui::NotebookPage current_page);
00633     NotebookEvent(const NotebookEvent &other);
00634 
00638     omgui::NotebookPage get_current_page() const;
00639 
00643     bool can_veto() const;
00644 
00645 private:
00646     omgui::NotebookPage m_current_page;
00647 };
00648 
00653 class MenuEvent : public Event
00654 {
00655 public:
00663     MenuEvent(event_id e_id, object_id obj, menu_id m_id);
00664 
00665     menu_id get_menu_id() const;
00666 
00667 protected:
00668     menu_id m_menu_id;
00669 };
00670 
00671 } // omgui
00672 
00673 #endif // OMGUI_EVENT_H

doxygen SourceForge.net Logo