]> git.saurik.com Git - wxWidgets.git/blob - samples/xrc/objrefdlg.cpp
Use Connect() of Bind() in the new part of xrc sample.
[wxWidgets.git] / samples / xrc / objrefdlg.cpp
1 //-----------------------------------------------------------------------------
2 // Name: objref.cpp
3 // Purpose: XML resources sample: Object references and ID ranges dialog
4 // Author: David Hart, Vaclav Slavik
5 // RCS-ID: $Id$
6 // Copyright: (c) Vaclav Slavik
7 // Licence: wxWindows licence
8 //-----------------------------------------------------------------------------
9
10 //-----------------------------------------------------------------------------
11 // Standard wxWidgets headers
12 //-----------------------------------------------------------------------------
13
14 // For compilers that support precompilation, includes "wx/wx.h".
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 // For all others, include the necessary headers (this file is usually all you
22 // need because it includes almost all "standard" wxWidgets headers)
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 //-----------------------------------------------------------------------------
28 // Header of this .cpp file
29 //-----------------------------------------------------------------------------
30
31 #include "objrefdlg.h"
32
33 //-----------------------------------------------------------------------------
34 // Remaining headers: Needed wx headers, then wx/contrib headers, then application headers
35 //-----------------------------------------------------------------------------
36
37 #include "wx/xrc/xmlres.h" // XRC XML resouces
38
39
40
41 //-----------------------------------------------------------------------------
42 // Public members
43 //-----------------------------------------------------------------------------
44 ObjrefDialog::ObjrefDialog(wxWindow* parent)
45 {
46 wxXmlResource::Get()->LoadDialog(this, parent, wxT("objref_dialog"));
47
48 nb = XRCCTRL(*this, "objref_notebook", wxNotebook);
49 wxCHECK_RET(nb, "failed to find objref_notebook");
50
51 // Connect different event handlers.
52 nb->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
53 wxNotebookEventHandler(ObjrefDialog::OnNotebookPageChanged),
54 NULL, this);
55
56 // We want to direct UpdateUI events for the ID range 'first_row' to
57 // OnUpdateUIFirst(). We could achieve this using first_row[0] and
58 // first_row[2], but what if a fourth column were added? It's safer to use
59 // the 'typedefs' for the two ends of the range:
60 wxNotebookPage *page = nb->GetPage(icons_page);
61 page->Connect(XRCID("first_row[start]"), XRCID("first_row[end]"),
62 wxEVT_UPDATE_UI,
63 wxUpdateUIEventHandler(ObjrefDialog::OnUpdateUIFirst),
64 NULL, this);
65 page->Connect(XRCID("second_row[start]"), XRCID("second_row[end]"),
66 wxEVT_UPDATE_UI,
67 wxUpdateUIEventHandler(ObjrefDialog::OnUpdateUISecond),
68 NULL, this);
69 page->Connect(XRCID("third_row[start]"), XRCID("third_row[end]"),
70 wxEVT_UPDATE_UI,
71 wxUpdateUIEventHandler(ObjrefDialog::OnUpdateUIThird),
72 NULL, this);
73
74 // Connect the id ranges, using the [start] and [end] 'typedefs'
75 page = nb->GetPage(calc_page);
76 page->Connect(XRCID("digits[start]"), XRCID("digits[end]"),
77 wxEVT_COMMAND_BUTTON_CLICKED,
78 wxCommandEventHandler(ObjrefDialog::OnNumeralClick),
79 NULL, this);
80 page->Connect(XRCID("operators[start]"), XRCID("operators[end]"),
81 wxEVT_COMMAND_BUTTON_CLICKED,
82 wxCommandEventHandler(ObjrefDialog::OnOperatorClick),
83 NULL, this);
84
85 }
86
87 ObjrefDialog::~ObjrefDialog()
88 {
89 // Select page 0. Otherwise if the Calc page were selected, when it's removed the Icons page is selected
90 // and sets the log target again in idle time, *after* myframe restores the old one!
91 nb->ChangeSelection(0);
92 }
93
94 //-----------------------------------------------------------------------------
95 // Private members (including the event handlers)
96 //-----------------------------------------------------------------------------
97 void ObjrefDialog::OnNotebookPageChanged( wxNotebookEvent &event )
98 {
99 switch(event.GetSelection())
100 {
101 case copy_page:
102 {
103 // This is a straight object reference to the first page
104 // so change the text programmatically
105 nb->SetPageText(copy_page, "Page 1 copy");
106
107 wxNotebookPage *page = nb->GetPage(copy_page);
108 wxTextCtrl *text = XRCCTRL(*page, "description_text", wxTextCtrl);
109 text->ChangeValue(
110 wxString("This is a duplicate of page 1, using an object reference. ")
111 + wxString("It was created by this very simple xml:\n\n")
112 + wxString("<object class=\"notebookpage\">\n\t<object_ref ref=\"page1\"/>\n")
113 + wxString("\t<label>Page 1 copy</label>\n</object>")
114 + wxString("\n\n(Then I'm cheating by inserting this text programmatically.)")
115 );
116 break;
117 }
118
119 case icons_page:
120 {
121 wxNotebookPage *page = nb->GetPage(icons_page);
122 text = XRCCTRL(*page, "log_text", wxTextCtrl);
123 if (text)
124 delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
125 break;
126 }
127
128 case calc_page:
129 {
130 wxNotebookPage *page = nb->GetPage(calc_page);
131 result_txt = XRCCTRL(*page, "result", wxTextCtrl);
132 text = XRCCTRL(*page, "log_text", wxTextCtrl);
133 if (text)
134 delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
135
136 ClearCalculator();
137 break;
138 }
139
140 default: return;
141 }
142 }
143
144 // There are undoubtedly simpler ways of doing all this, but we're demonstrating the use of ID ranges
145 void ObjrefDialog::OnUpdateUIFirst(wxUpdateUIEvent& event)
146 {
147 // The checkbox with the XRCID 'check[0]' controls this row of icons
148 wxCheckBox *chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[0]", wxCheckBox);
149 if (chk)
150 event.Enable(chk->IsChecked());
151
152 // Let's create a log-window entry
153 static bool checked = true;
154 if (chk->IsChecked() != checked)
155 {
156 checked = chk->IsChecked();
157 wxLogMessage("Row one has been %s by check[0], XRCID = %i", checked ? "enabled" : "disabled", XRCID("check[0]"));
158 wxLogMessage("XRCIDs: first_row[start] = %i, first_row[0] = %i, first_row[1] = %i, first_row[2] = %i, first_row[end] = %i",
159 XRCID("first_row[start]"), XRCID("first_row[0]"), XRCID("first_row[1]"), XRCID("first_row[2]"), XRCID("first_row[end]"));
160 }
161 }
162
163 void ObjrefDialog::OnUpdateUISecond(wxUpdateUIEvent& event)
164 {
165 // The checkbox with the XRCID 'check[1]' controls this row of icons
166 wxCheckBox *chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[1]", wxCheckBox);
167 if (chk)
168 event.Enable(chk->IsChecked());
169
170 // Let's create a log-window entry
171 static bool checked = true;
172 if (chk->IsChecked() != checked)
173 {
174 checked = chk->IsChecked();
175 wxLogMessage("Row two has been %s by check[1], XRCID = %i", checked ? "enabled" : "disabled", XRCID("check[1]"));
176 wxLogMessage("XRCIDs: second_row[start] = %i, second_row[0] = %i, second_row[1] = %i, second_row[2] = %i, second_row[end] = %i",
177 XRCID("second_row[start]"), XRCID("second_row[0]"), XRCID("second_row[1]"), XRCID("second_row[2]"), XRCID("second_row[end]"));
178 }
179 }
180
181 void ObjrefDialog::OnUpdateUIThird(wxUpdateUIEvent& event)
182 {
183 // The checkbox with the XRCID 'check[2]' controls this row of icons
184 wxCheckBox *chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[2]", wxCheckBox);
185 if (chk)
186 event.Enable(chk->IsChecked());
187
188 // Let's create a log-window entry
189 static bool checked = true;
190 if (chk->IsChecked() != checked)
191 {
192 checked = chk->IsChecked();
193 wxLogMessage("Row three has been %s by check[2], XRCID = %i", checked ? "enabled" : "disabled", XRCID("check[2]"));
194 wxLogMessage("XRCIDs: third_row[start] = %i, third_row[0] = %i, third_row[1] = %i, third_row[2] = %i, third_row[end] = %i",
195 XRCID("third_row[start]"), XRCID("third_row[0]"), XRCID("third_row[1]"), XRCID("third_row[2]"), XRCID("third_row[end]"));
196 }
197 }
198
199 void ObjrefDialog::OnNumeralClick(wxCommandEvent& event)
200 {
201 // See how the id range simplifies determining which numeral was clicked
202 int digit = event.GetId() - XRCID("digits[start]");
203
204 char c = '0' + digit;
205 if (current==0 && previous==0)
206 {
207 // We're just starting a calculation, so get rid of the placeholder '0'
208 result_txt->Clear();
209 }
210 else if (operator_expected == true)
211 {
212 // If we've just finished one calculation, and now a digit is entered, clear
213 ClearCalculator();
214 result_txt->Clear();
215 }
216 (*result_txt) << c;
217
218
219 current = current*10 + digit;
220
221 wxLogMessage("You clicked digits[%c], XRCID %i", c, event.GetId());
222 }
223
224 void ObjrefDialog::OnOperatorClick(wxCommandEvent& event)
225 {
226 static const char symbols[] = "+-*/=";
227
228 operator_expected = false;
229 int ID = event.GetId() - XRCID("operators[start]");
230
231 // We carefully used "operators[end]" as the name of the Clear button
232 if (event.GetId() == XRCID("operators[end]"))
233 {
234 wxLogMessage("You clicked operators[%i], XRCID %i, 'Clear'", ID, event.GetId());
235 return ClearCalculator();
236 }
237
238 switch(ID)
239 {
240 case operator_plus:
241 case operator_minus:
242 case operator_multiply:
243 case operator_divide:
244 if (current!=0 || previous!=0)
245 {
246 // We're in the middle of a complex calculation, so do the first bit
247 Calculate();
248 }
249 curr_operator = (CalcOperator)ID;
250 break;
251
252 case operator_equals:
253 Calculate();
254 wxLogMessage("You clicked operators[%i], XRCID %i, giving a '%c'", ID, event.GetId(), symbols[ID]);
255 curr_operator = operator_equals;
256 // Flag that the next entry should be an operator, not a digit
257 operator_expected = true;
258 return;
259 }
260
261 (*result_txt) << ' ' << symbols[ID] << ' ';
262
263 wxLogMessage("You clicked operators[%i], XRCID %i, giving a '%c'", ID, event.GetId(), symbols[ID]);
264 }
265
266 void ObjrefDialog::Calculate()
267 {
268 switch(curr_operator)
269 {
270 case operator_plus:
271 previous += current; break;
272 case operator_minus:
273 previous -= current; break;
274 case operator_multiply:
275 previous *= current; break;
276 case operator_divide:
277 if (current!=0)
278 previous /= current;
279 break;
280 default: return;
281 }
282
283 curr_operator = operator_plus;
284 current = 0;
285 result_txt->Clear();
286
287 (*result_txt) << previous;
288 }
289
290 void ObjrefDialog::ClearCalculator()
291 {
292 current = previous = 0;
293 curr_operator = operator_plus;
294 operator_expected = false;
295 result_txt->ChangeValue("0");
296 }