]> git.saurik.com Git - wxWidgets.git/blob - samples/xrc/objrefdlg.cpp
8fbb22acd3513b6ede1d347b9f2c32ae95235431
[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 nb->Bind(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, &ObjrefDialog::OnNotebookPageChanged, this);
51 iconspage_bound = false;
52 calcpage_bound = false;
53 }
54
55 ObjrefDialog::~ObjrefDialog()
56 {
57 // Select page 0. Otherwise if the Calc page were selected, when it's removed the Icons page is selected
58 // and sets the log target again in idle time, *after* myframe restores the old one!
59 nb->ChangeSelection(0);
60 }
61
62 //-----------------------------------------------------------------------------
63 // Private members (including the event handlers)
64 //-----------------------------------------------------------------------------
65 void ObjrefDialog::OnNotebookPageChanged( wxNotebookEvent &event )
66 {
67 switch(event.GetSelection())
68 {
69 case copy_page:
70 {
71 // This is a straight object reference to the first page
72 // so change the text programmatically
73 nb->SetPageText(copy_page, "Page 1 copy");
74
75 wxNotebookPage *page = nb->GetPage(copy_page);
76 wxTextCtrl *text = XRCCTRL(*page, "description_text", wxTextCtrl);
77 text->ChangeValue(
78 wxString("This is a duplicate of page 1, using an object reference. ")
79 + wxString("It was created by this very simple xml:\n\n")
80 + wxString("<object class=\"notebookpage\">\n\t<object_ref ref=\"page1\"/>\n")
81 + wxString("\t<label>Page 1 copy</label>\n</object>")
82 + wxString("\n\n(Then I'm cheating by inserting this text programmatically.)")
83 );
84 break;
85 }
86
87 case icons_page:
88 {
89 wxNotebookPage *page = nb->GetPage(icons_page);
90 if (!iconspage_bound)
91 {
92 iconspage_bound = true;
93 // We want to direct UpdateUI events for the ID range 'first_row' to OnUpdateUIFirst().
94 // We could achieve this using first_row[0] and first_row[2], but what if a fourth
95 // column were added? It's safer to use the 'typedefs' for the two ends of the range:
96 page->Bind(wxEVT_UPDATE_UI, &ObjrefDialog::OnUpdateUIFirst,
97 this, XRCID("first_row[start]"), XRCID("first_row[end]"));
98 // Similarly for the other two rows
99 page->Bind(wxEVT_UPDATE_UI, &ObjrefDialog::OnUpdateUISecond,
100 this, XRCID("second_row[start]"), XRCID("second_row[end]"));
101 page->Bind(wxEVT_UPDATE_UI, &ObjrefDialog::OnUpdateUIThird,
102 this, XRCID("third_row[start]"), XRCID("third_row[end]"));
103
104 }
105
106 text = XRCCTRL(*page, "log_text", wxTextCtrl);
107 if (text)
108 delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
109 break;
110 }
111
112 case calc_page:
113 {
114 wxNotebookPage *page = nb->GetPage(calc_page);
115 if (!calcpage_bound)
116 {
117 calcpage_bound = true;
118 // Bind the id ranges, using the [start] and [end] 'typedefs'
119 page->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ObjrefDialog::OnNumeralClick,
120 this, XRCID("digits[start]"), XRCID("digits[end]"));
121 page->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ObjrefDialog::OnOperatorClick,
122 this, XRCID("operators[start]"), XRCID("operators[end]"));
123 }
124
125 result_txt = XRCCTRL(*page, "result", wxTextCtrl);
126 text = XRCCTRL(*page, "log_text", wxTextCtrl);
127 if (text)
128 delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
129
130 ClearCalculator();
131 break;
132 }
133
134 default: return;
135 }
136 }
137
138 // There are undoubtedly simpler ways of doing all this, but we're demonstrating the use of ID ranges
139 void ObjrefDialog::OnUpdateUIFirst(wxUpdateUIEvent& event)
140 {
141 // The checkbox with the XRCID 'check[0]' controls this row of icons
142 wxCheckBox *chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[0]", wxCheckBox);
143 if (chk)
144 event.Enable(chk->IsChecked());
145
146 // Let's create a log-window entry
147 static bool checked = true;
148 if (chk->IsChecked() != checked)
149 {
150 checked = chk->IsChecked();
151 wxLogMessage("Row one has been %s by check[0], XRCID = %i", checked ? "enabled" : "disabled", XRCID("check[0]"));
152 wxLogMessage("XRCIDs: first_row[start] = %i, first_row[0] = %i, first_row[1] = %i, first_row[2] = %i, first_row[end] = %i",
153 XRCID("first_row[start]"), XRCID("first_row[0]"), XRCID("first_row[1]"), XRCID("first_row[2]"), XRCID("first_row[end]"));
154 }
155 }
156
157 void ObjrefDialog::OnUpdateUISecond(wxUpdateUIEvent& event)
158 {
159 // The checkbox with the XRCID 'check[1]' controls this row of icons
160 wxCheckBox *chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[1]", wxCheckBox);
161 if (chk)
162 event.Enable(chk->IsChecked());
163
164 // Let's create a log-window entry
165 static bool checked = true;
166 if (chk->IsChecked() != checked)
167 {
168 checked = chk->IsChecked();
169 wxLogMessage("Row two has been %s by check[1], XRCID = %i", checked ? "enabled" : "disabled", XRCID("check[1]"));
170 wxLogMessage("XRCIDs: second_row[start] = %i, second_row[0] = %i, second_row[1] = %i, second_row[2] = %i, second_row[end] = %i",
171 XRCID("second_row[start]"), XRCID("second_row[0]"), XRCID("second_row[1]"), XRCID("second_row[2]"), XRCID("second_row[end]"));
172 }
173 }
174
175 void ObjrefDialog::OnUpdateUIThird(wxUpdateUIEvent& event)
176 {
177 // The checkbox with the XRCID 'check[2]' controls this row of icons
178 wxCheckBox *chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[2]", wxCheckBox);
179 if (chk)
180 event.Enable(chk->IsChecked());
181
182 // Let's create a log-window entry
183 static bool checked = true;
184 if (chk->IsChecked() != checked)
185 {
186 checked = chk->IsChecked();
187 wxLogMessage("Row three has been %s by check[2], XRCID = %i", checked ? "enabled" : "disabled", XRCID("check[2]"));
188 wxLogMessage("XRCIDs: third_row[start] = %i, third_row[0] = %i, third_row[1] = %i, third_row[2] = %i, third_row[end] = %i",
189 XRCID("third_row[start]"), XRCID("third_row[0]"), XRCID("third_row[1]"), XRCID("third_row[2]"), XRCID("third_row[end]"));
190 }
191 }
192
193 void ObjrefDialog::OnNumeralClick(wxCommandEvent& event)
194 {
195 // See how the id range simplifies determining which numeral was clicked
196 int digit = event.GetId() - XRCID("digits[start]");
197
198 char c = '0' + digit;
199 if (current==0 && previous==0)
200 {
201 // We're just starting a calculation, so get rid of the placeholder '0'
202 result_txt->Clear();
203 }
204 else if (operator_expected == true)
205 {
206 // If we've just finished one calculation, and now a digit is entered, clear
207 ClearCalculator();
208 result_txt->Clear();
209 }
210 (*result_txt) << c;
211
212
213 current = current*10 + digit;
214
215 wxLogMessage("You clicked digits[%c], XRCID %i", c, event.GetId());
216 }
217
218 void ObjrefDialog::OnOperatorClick(wxCommandEvent& event)
219 {
220 static const char symbols[] = "+-*/=";
221
222 operator_expected = false;
223 int ID = event.GetId() - XRCID("operators[start]");
224
225 // We carefully used "operators[end]" as the name of the Clear button
226 if (event.GetId() == XRCID("operators[end]"))
227 {
228 wxLogMessage("You clicked operators[%i], XRCID %i, 'Clear'", ID, event.GetId());
229 return ClearCalculator();
230 }
231
232 switch(ID)
233 {
234 case operator_plus:
235 case operator_minus:
236 case operator_multiply:
237 case operator_divide:
238 if (current!=0 || previous!=0)
239 {
240 // We're in the middle of a complex calculation, so do the first bit
241 Calculate();
242 }
243 curr_operator = (CalcOperator)ID;
244 break;
245
246 case operator_equals:
247 Calculate();
248 wxLogMessage("You clicked operators[%i], XRCID %i, giving a '%c'", ID, event.GetId(), symbols[ID]);
249 curr_operator = operator_equals;
250 // Flag that the next entry should be an operator, not a digit
251 operator_expected = true;
252 return;
253 }
254
255 (*result_txt) << ' ' << symbols[ID] << ' ';
256
257 wxLogMessage("You clicked operators[%i], XRCID %i, giving a '%c'", ID, event.GetId(), symbols[ID]);
258 }
259
260 void ObjrefDialog::Calculate()
261 {
262 switch(curr_operator)
263 {
264 case operator_plus:
265 previous += current; break;
266 case operator_minus:
267 previous -= current; break;
268 case operator_multiply:
269 previous *= current; break;
270 case operator_divide:
271 if (current!=0)
272 previous /= current;
273 break;
274 default: return;
275 }
276
277 curr_operator = operator_plus;
278 current = 0;
279 result_txt->Clear();
280
281 (*result_txt) << previous;
282 }
283
284 void ObjrefDialog::ClearCalculator()
285 {
286 current = previous = 0;
287 curr_operator = operator_plus;
288 operator_expected = false;
289 result_txt->ChangeValue("0");
290 }