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