Files
wxWidgets/samples/xrc/objrefdlg.cpp
Vadim Zeitlin 14f0c8b716 Use Connect() of Bind() in the new part of xrc sample.
Use Connect() for compatibility (notably with VC6 which doesn't support
Bind()). Also connect the event handlers on loading the dialog instead of
waiting until the relevant page is selected, this makes the code slightly
simpler as we don't need to remember whether we connected them or not any
longer.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66062 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2010-11-07 19:33:30 +00:00

297 lines
11 KiB
C++

//-----------------------------------------------------------------------------
// Name: objref.cpp
// Purpose: XML resources sample: Object references and ID ranges dialog
// Author: David Hart, Vaclav Slavik
// RCS-ID: $Id$
// 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"
//-----------------------------------------------------------------------------
// Remaining headers: Needed wx headers, then wx/contrib headers, then application 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_COMMAND_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_COMMAND_BUTTON_CLICKED,
wxCommandEventHandler(ObjrefDialog::OnNumeralClick),
NULL, this);
page->Connect(XRCID("operators[start]"), XRCID("operators[end]"),
wxEVT_COMMAND_BUTTON_CLICKED,
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(
wxString("This is a duplicate of page 1, using an object reference. ")
+ wxString("It was created by this very simple xml:\n\n")
+ wxString("<object class=\"notebookpage\">\n\t<object_ref ref=\"page1\"/>\n")
+ wxString("\t<label>Page 1 copy</label>\n</object>")
+ wxString("\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;
}
default: return;
}
}
// 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 %i, 'Clear'", ID, event.GetId());
return ClearCalculator();
}
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");
}