1 //-------------------------------------------------------------------------- 2 // Name: pyevent.h 3 // Purpose: A set of event classes that can be derived from in Python 4 // and that preserve their attributes when cloned. 5 // 6 // Author: Robin Dunn 7 // 8 // Created: 18-Dec-2010 9 // Copyright: (c) 2010-2018 by Total Control Software 10 // Licence: wxWindows license 11 //-------------------------------------------------------------------------- 12 13 #ifndef PYEVENT_H 14 #define PYEVENT_H 15 16 // The wxPyEvent and wxPyCommandEvent classes can be derived from in Python 17 // and passed through the event system without losing anything. 18 19 // This wxPyEvtDict class holds a Python dictionary object and is used to 20 // store any attributes that are set from Python code for the wx.PyEvent and 21 // wx.PyCommandEvent classes. This dictionary is used to make it easy to 22 // transport those attributes over to the clone when wx needs to make a copy 23 // of the event instance. 24 25 // NOTE: This class is intentionally not exposed to SIP as there is no 26 // need for it in Python code. Instead we just tell SIP that the __*attr__ 27 // methods are in the event classes. (See wxPyEvent and wxPyCommandEvent 28 // below and in etg/pyevent.py.) 29 30 class wxPyEvtDict 31 { 32 public: wxPyEvtDict()33 wxPyEvtDict() 34 { 35 wxPyThreadBlocker blocker; 36 m_dict = PyDict_New(); 37 } 38 wxPyEvtDict(const wxPyEvtDict & other)39 wxPyEvtDict(const wxPyEvtDict& other) 40 { 41 wxPyThreadBlocker blocker; 42 m_dict = PyDict_Copy(other.m_dict); 43 } 44 ~wxPyEvtDict()45 ~wxPyEvtDict() 46 { 47 wxPyThreadBlocker blocker; 48 Py_DECREF(m_dict); 49 m_dict = NULL; 50 } 51 _getAttrDict()52 PyObject* _getAttrDict() 53 { 54 wxPyThreadBlocker blocker; 55 Py_INCREF(m_dict); 56 return m_dict; 57 } 58 __getattr__(PyObject * name)59 PyObject* __getattr__(PyObject* name) 60 { 61 PyObject* value = NULL; 62 wxPyThreadBlocker blocker; 63 if (PyDict_Contains(m_dict, name)) { 64 value = PyDict_GetItem(m_dict, name); 65 Py_INCREF(value); 66 } 67 else { 68 PyErr_SetObject(PyExc_AttributeError, name); 69 } 70 return value; 71 } 72 __setattr__(PyObject * name,PyObject * value)73 void __setattr__(PyObject* name, PyObject* value) 74 { 75 wxPyThreadBlocker blocker; 76 PyDict_SetItem(m_dict, name, value); 77 } 78 __delattr__(PyObject * name)79 void __delattr__(PyObject* name) 80 { 81 wxPyThreadBlocker blocker; 82 if (PyDict_Contains(m_dict, name)) 83 PyDict_DelItem(m_dict, name); 84 else 85 PyErr_SetObject(PyExc_AttributeError, name); 86 } 87 88 protected: 89 PyObject* m_dict; 90 }; 91 92 93 //-------------------------------------------------------------------------- 94 95 96 class wxPyEvent : public wxEvent, public wxPyEvtDict 97 { DECLARE_DYNAMIC_CLASS(wxPyEvent)98 DECLARE_DYNAMIC_CLASS(wxPyEvent) 99 public: 100 wxPyEvent(int id=0, wxEventType eventType = wxEVT_NULL) 101 : wxEvent(id, eventType) {} 102 103 // NOTE: The default copy ctor is used here Clone()104 virtual wxEvent* Clone() const { return new wxPyEvent(*this); } 105 }; 106 107 108 //-------------------------------------------------------------------------- 109 110 111 class wxPyCommandEvent : public wxCommandEvent, public wxPyEvtDict 112 { DECLARE_DYNAMIC_CLASS(wxPyCommandEvent)113 DECLARE_DYNAMIC_CLASS(wxPyCommandEvent) 114 public: 115 wxPyCommandEvent(wxEventType eventType = wxEVT_NULL, int id=0) 116 : wxCommandEvent(eventType, id) {} 117 118 // NOTE: The default copy ctor is used here Clone()119 virtual wxEvent* Clone() const { return new wxPyCommandEvent(*this); } 120 }; 121 122 123 124 //-------------------------------------------------------------------------- 125 #endif 126