| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- //-----------------------------------------------------------------------------
- // Name: objref.cpp
- // Purpose: XML resources sample: Object references and ID ranges dialog
- // Author: David Hart, Vaclav Slavik
- // Copyright: (c) Vaclav Slavik
- // Licence: wxWindows licence
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // Standard wxWidgets headers
- //-----------------------------------------------------------------------------
- // For compilers that support precompilation, includes "wx/wx.h".
- #include "wx/wxprec.h"
- #ifdef __BORLANDC__
- #pragma hdrstop
- #endif
- // For all others, include the necessary headers (this file is usually all you
- // need because it includes almost all "standard" wxWidgets headers)
- #ifndef WX_PRECOMP
- #include "wx/wx.h"
- #endif
- //-----------------------------------------------------------------------------
- // Header of this .cpp file
- //-----------------------------------------------------------------------------
- #include "objrefdlg.h"
- //-----------------------------------------------------------------------------
- // Needed wx headers,
- //-----------------------------------------------------------------------------
- #include "wx/xrc/xmlres.h" // XRC XML resouces
- //-----------------------------------------------------------------------------
- // Public members
- //-----------------------------------------------------------------------------
- ObjrefDialog::ObjrefDialog(wxWindow* parent)
- {
- wxXmlResource::Get()->LoadDialog(this, parent, wxT("objref_dialog"));
- nb = XRCCTRL(*this, "objref_notebook", wxNotebook);
- wxCHECK_RET(nb, "failed to find objref_notebook");
- // Connect different event handlers.
- nb->Connect(wxEVT_NOTEBOOK_PAGE_CHANGED,
- wxNotebookEventHandler(ObjrefDialog::OnNotebookPageChanged),
- NULL, this);
- // We want to direct UpdateUI events for the ID range 'first_row' to
- // OnUpdateUIFirst(). We could achieve this using first_row[0] and
- // first_row[2], but what if a fourth column were added? It's safer to use
- // the 'typedefs' for the two ends of the range:
- wxNotebookPage *page = nb->GetPage(icons_page);
- page->Connect(XRCID("first_row[start]"), XRCID("first_row[end]"),
- wxEVT_UPDATE_UI,
- wxUpdateUIEventHandler(ObjrefDialog::OnUpdateUIFirst),
- NULL, this);
- page->Connect(XRCID("second_row[start]"), XRCID("second_row[end]"),
- wxEVT_UPDATE_UI,
- wxUpdateUIEventHandler(ObjrefDialog::OnUpdateUISecond),
- NULL, this);
- page->Connect(XRCID("third_row[start]"), XRCID("third_row[end]"),
- wxEVT_UPDATE_UI,
- wxUpdateUIEventHandler(ObjrefDialog::OnUpdateUIThird),
- NULL, this);
- // Connect the id ranges, using the [start] and [end] 'typedefs'
- page = nb->GetPage(calc_page);
- page->Connect(XRCID("digits[start]"), XRCID("digits[end]"),
- wxEVT_BUTTON,
- wxCommandEventHandler(ObjrefDialog::OnNumeralClick),
- NULL, this);
- page->Connect(XRCID("operators[start]"), XRCID("operators[end]"),
- wxEVT_BUTTON,
- wxCommandEventHandler(ObjrefDialog::OnOperatorClick),
- NULL, this);
- }
- ObjrefDialog::~ObjrefDialog()
- {
- // Select page 0. Otherwise if the Calc page were selected, when it's
- // removed the Icons page is selected and sets the log target again in idle
- // time, *after* myframe restores the old one!
- nb->ChangeSelection(0);
- }
- //-----------------------------------------------------------------------------
- // Private members (including the event handlers)
- //-----------------------------------------------------------------------------
- void ObjrefDialog::OnNotebookPageChanged( wxNotebookEvent &event )
- {
- switch(event.GetSelection())
- {
- case copy_page:
- {
- // This is a straight object reference to the first page
- // so change the text programmatically
- nb->SetPageText(copy_page, "Page 1 copy");
- wxNotebookPage *page = nb->GetPage(copy_page);
- wxTextCtrl *
- text = XRCCTRL(*page, "description_text", wxTextCtrl);
- text->ChangeValue(
- "This is a duplicate of page 1, using an object reference. "
- "It was created by this very simple xml:\n\n"
- "<object class=\"notebookpage\">\n\t<object_ref ref=\"page1\"/>\n"
- "\t<label>Page 1 copy</label>\n</object>"
- "\n\n(Then I'm cheating by inserting this text programmatically.)"
- );
- break;
- }
- case icons_page:
- {
- wxNotebookPage *page = nb->GetPage(icons_page);
- text = XRCCTRL(*page, "log_text", wxTextCtrl);
- if (text)
- delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
- break;
- }
- case calc_page:
- {
- wxNotebookPage *page = nb->GetPage(calc_page);
- result_txt = XRCCTRL(*page, "result", wxTextCtrl);
- text = XRCCTRL(*page, "log_text", wxTextCtrl);
- if (text)
- delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
- ClearCalculator();
- break;
- }
- }
- }
- // There are undoubtedly simpler ways of doing all this, but we're
- // demonstrating the use of ID ranges
- void ObjrefDialog::OnUpdateUIFirst(wxUpdateUIEvent& event)
- {
- // The checkbox with the XRCID 'check[0]' controls this row of icons
- wxCheckBox *
- chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[0]", wxCheckBox);
- if (chk)
- event.Enable(chk->IsChecked());
- // Let's create a log-window entry
- static bool checked = true;
- if (chk->IsChecked() != checked)
- {
- checked = chk->IsChecked();
- wxLogMessage("Row one has been %s by check[0], XRCID = %i",
- checked ? "enabled" : "disabled", XRCID("check[0]"));
- wxLogMessage("XRCIDs: first_row[start] = %i, first_row[0] = %i, "
- "first_row[1] = %i, first_row[2] = %i, "
- "first_row[end] = %i",
- XRCID("first_row[start]"), XRCID("first_row[0]"),
- XRCID("first_row[1]"), XRCID("first_row[2]"),
- XRCID("first_row[end]"));
- }
- }
- void ObjrefDialog::OnUpdateUISecond(wxUpdateUIEvent& event)
- {
- // The checkbox with the XRCID 'check[1]' controls this row of icons
- wxCheckBox *
- chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[1]", wxCheckBox);
- if (chk)
- event.Enable(chk->IsChecked());
- // Let's create a log-window entry
- static bool checked = true;
- if (chk->IsChecked() != checked)
- {
- checked = chk->IsChecked();
- wxLogMessage("Row two has been %s by check[1], XRCID = %i",
- checked ? "enabled" : "disabled", XRCID("check[1]"));
- wxLogMessage("XRCIDs: second_row[start] = %i, second_row[0] = %i, "
- "second_row[1] = %i, second_row[2] = %i, "
- "second_row[end] = %i",
- XRCID("second_row[start]"), XRCID("second_row[0]"),
- XRCID("second_row[1]"), XRCID("second_row[2]"),
- XRCID("second_row[end]"));
- }
- }
- void ObjrefDialog::OnUpdateUIThird(wxUpdateUIEvent& event)
- {
- // The checkbox with the XRCID 'check[2]' controls this row of icons
- wxCheckBox *
- chk = XRCCTRL(*(nb->GetPage(icons_page)), "check[2]", wxCheckBox);
- if (chk)
- event.Enable(chk->IsChecked());
- // Let's create a log-window entry
- static bool checked = true;
- if (chk->IsChecked() != checked)
- {
- checked = chk->IsChecked();
- wxLogMessage("Row three has been %s by check[2], XRCID = %i",
- checked ? "enabled" : "disabled", XRCID("check[2]"));
- wxLogMessage("XRCIDs: third_row[start] = %i, third_row[0] = %i, "
- "third_row[1] = %i, third_row[2] = %i, "
- "third_row[end] = %i",
- XRCID("third_row[start]"), XRCID("third_row[0]"),
- XRCID("third_row[1]"), XRCID("third_row[2]"),
- XRCID("third_row[end]"));
- }
- }
- void ObjrefDialog::OnNumeralClick(wxCommandEvent& event)
- {
- // See how the id range simplifies determining which numeral was clicked
- int digit = event.GetId() - XRCID("digits[start]");
- char c = '0' + digit;
- if (current==0 && previous==0)
- {
- // We're just starting a calculation, so get rid of the placeholder '0'
- result_txt->Clear();
- }
- else if (operator_expected == true)
- {
- // If we've just finished one calculation, and now a digit is entered,
- // clear
- ClearCalculator();
- result_txt->Clear();
- }
- (*result_txt) << c;
- current = current*10 + digit;
- wxLogMessage("You clicked digits[%c], XRCID %i", c, event.GetId());
- }
- void ObjrefDialog::OnOperatorClick(wxCommandEvent& event)
- {
- static const char symbols[] = "+-*/=";
- operator_expected = false;
- int ID = event.GetId() - XRCID("operators[start]");
- // We carefully used "operators[end]" as the name of the Clear button
- if (event.GetId() == XRCID("operators[end]"))
- {
- wxLogMessage("You clicked operators[%i], XRCID %d, 'Clear'",
- ID, event.GetId());
- ClearCalculator();
- return;
- }
- switch(ID)
- {
- case operator_plus:
- case operator_minus:
- case operator_multiply:
- case operator_divide:
- if (current!=0 || previous!=0)
- {
- // We're in the middle of a complex calculation, so do the
- // first bit
- Calculate();
- }
- curr_operator = (CalcOperator)ID;
- break;
- case operator_equals:
- Calculate();
- wxLogMessage("You clicked operators[%i], XRCID %i, giving a '%c'",
- ID, event.GetId(), symbols[ID]);
- curr_operator = operator_equals;
- // Flag that the next entry should be an operator, not a digit
- operator_expected = true;
- return;
- }
- (*result_txt) << ' ' << symbols[ID] << ' ';
- wxLogMessage("You clicked operators[%i], XRCID %i, giving a '%c'",
- ID, event.GetId(), symbols[ID]);
- }
- void ObjrefDialog::Calculate()
- {
- switch(curr_operator)
- {
- case operator_plus:
- previous += current; break;
- case operator_minus:
- previous -= current; break;
- case operator_multiply:
- previous *= current; break;
- case operator_divide:
- if (current!=0)
- previous /= current;
- break;
- default: return;
- }
- curr_operator = operator_plus;
- current = 0;
- result_txt->Clear();
- (*result_txt) << previous;
- }
- void ObjrefDialog::ClearCalculator()
- {
- current = previous = 0;
- curr_operator = operator_plus;
- operator_expected = false;
- result_txt->ChangeValue("0");
- }
|