Skip to content

Commit

Permalink
Issue #123: Allow binding to multiple events
Browse files Browse the repository at this point in the history
Making it possible to bind to multiple events.

Updated Docs.
  • Loading branch information
rmpowell77 committed Jul 3, 2023
1 parent 59e4da2 commit f139198
Show file tree
Hide file tree
Showing 24 changed files with 249 additions and 114 deletions.
6 changes: 3 additions & 3 deletions LATEST_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# wxUI release notes for v0.1.3
# wxUI release notes for v0.1.4

Bugs addressed in this release:

* [#118](../../issues/118) make_unique used without including <memory>

Other changes:

* [#123](../../issues/123) Allow binding to multiple events

46 changes: 27 additions & 19 deletions docs/ProgrammersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ Handlers are callable items that handle events. The handler can be declared wit
ExtendedExample dialog(this);
dialog.ShowModal();
} },
wxUI::Item { "&MultibindExample...", [this] {
MultibindExample dialog(this);
dialog.ShowModal();
} },
wxUI::Item { "&Example Item...", [] {
wxLogMessage("Hello World!");
} },
Expand Down Expand Up @@ -85,6 +89,10 @@ Items { "Name", "Help", Handler }
ExtendedExample dialog(this);
dialog.ShowModal();
} },
wxUI::Item { "&MultibindExample...", [this] {
MultibindExample dialog(this);
dialog.ShowModal();
} },
wxUI::Item { "&Example Item...", [] {
wxLogMessage("Hello World!");
} },
Expand Down Expand Up @@ -174,7 +182,7 @@ The list of Methods supported by all controllers:

#### Bind

Some *Controllers* support "binding" a function call to their event handlers. When the event for that controller is emitted, the function-like object supplied will be called.
*Controllers* support "binding" a function call to their event handlers. When the event for that *controller* is emitted, the function-like object supplied will be called. You can bind multiple events on a single *controller*. For convenience, some *controllers* have default events that will be used if none is supplied.

```cpp
Button { wxSizerFlags().Border(wxRIGHT), "Left" }
Expand Down Expand Up @@ -223,24 +231,24 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
The "Controllers" currently supported by `wxUI`:
| wxUI | wxWidget | Proxy | Proxy accessors value |
| :------------------- | :--------------------- | :------------------------ | :-------------- |
| `Bitmap` | `wxStaticBitmap` | `BitmapProxy` | n/a |
| `BitmapButton` | `wxBitmapButton` | `BitmapButtonProxy` | n/a |
| `BitmapComboBox` | `wxBitmapComboBox` | `BitmapComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `BitmapToggleButton` | `wxBitmapToggleButton` | `BitmapToggleButtonProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Button` | `wxButton` | `ButtonProxy` | n/a |
| `CheckBox` | `wxCheckBox` | `CheckBoxProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Choice` | `wxChoice` | `ChoiceProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `ComboBox` | `wxComboBox` | `ComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `Hypertext` | `wxHypertextCtrl` | `HypertextProxy` | n/a |
| `Line` | `wxStaticLine` | `LineProxy` | n/a |
| `ListBox` | `wxListBox` | `ListBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `RadioBox` | `wxRadioBox` | `RadioBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `Slider` | `wxSlider` | `SliderProxy` | `value` -> `int`<BR>*default*: `value` |
| `SpinCtrl` | `wxSpinCtrl` | `SpinCtrlProxy` | `value` -> `int`<BR>*default*: `value` |
| `Text` | `wxStaticText` | `TextProxy` | `label` -> `std::string`<BR>*default*: `label` |
| `TextCtrl` | `wxTextCtrl` | `TextCtrlProxy` | `label` -> `std::string`<BR>*default*: `label` |
| wxUI | wxWidget | Default Event | Proxy | Proxy accessors value |
| :------------------- | :--------------------- | :----------------- | :------------------------ | :-------------- |
| `Bitmap` | `wxStaticBitmap` | n/a | `BitmapProxy` | n/a |
| `BitmapButton` | `wxBitmapButton` | `EVT_BUTTON` | `BitmapButtonProxy` | n/a |
| `BitmapComboBox` | `wxBitmapComboBox` | `EVT_COMBOBOX` | `BitmapComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `BitmapToggleButton` | `wxBitmapToggleButton` | `EVT_TOGGLEBUTTON` | `BitmapToggleButtonProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Button` | `wxButton` | `EVT_BUTTON` | `ButtonProxy` | n/a |
| `CheckBox` | `wxCheckBox` | `EVT_CHECKBOX` | `CheckBoxProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Choice` | `wxChoice` | `EVT_CHOICE` | `ChoiceProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `ComboBox` | `wxComboBox` | `EVT_COMBOBOX` | `ComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `Hypertext` | `wxHypertextCtrl` | n/a | `HypertextProxy` | n/a |
| `Line` | `wxStaticLine` | n/a | `LineProxy` | n/a |
| `ListBox` | `wxListBox` | `EVT_LISTBOX` | `ListBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `RadioBox` | `wxRadioBox` | `EVT_RADIOBOX` | `RadioBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `Slider` | `wxSlider` | `EVT_SLIDER` | `SliderProxy` | `value` -> `int`<BR>*default*: `value` |
| `SpinCtrl` | `wxSpinCtrl` | `EVT_SPINCTRL` | `SpinCtrlProxy` | `value` -> `int`<BR>*default*: `value` |
| `Text` | `wxStaticText` | n/a | `TextProxy` | `label` -> `std::string`<BR>*default*: `label` |
| `TextCtrl` | `wxTextCtrl` | `EVT_TEXT` | `TextCtrlProxy` | `label` -> `std::string`<BR>*default*: `label` |
Additional "Contollers" should be easy to add in future updates.
Expand Down
38 changes: 19 additions & 19 deletions docs/src/docs/ProgrammersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ The list of Methods supported by all controllers:

#### Bind

Some *Controllers* support "binding" a function call to their event handlers. When the event for that controller is emitted, the function-like object supplied will be called.
*Controllers* support "binding" a function call to their event handlers. When the event for that *controller* is emitted, the function-like object supplied will be called. You can bind multiple events on a single *controller*. For convenience, some *controllers* have default events that will be used if none is supplied.

```cpp
{{{ examples/HelloWorld/HelloWorld.cpp wxUIBind " // ..." }}}
Expand Down Expand Up @@ -157,24 +157,24 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
The "Controllers" currently supported by `wxUI`:
| wxUI | wxWidget | Proxy | Proxy accessors value |
| :------------------- | :--------------------- | :------------------------ | :-------------- |
| `Bitmap` | `wxStaticBitmap` | `BitmapProxy` | n/a |
| `BitmapButton` | `wxBitmapButton` | `BitmapButtonProxy` | n/a |
| `BitmapComboBox` | `wxBitmapComboBox` | `BitmapComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `BitmapToggleButton` | `wxBitmapToggleButton` | `BitmapToggleButtonProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Button` | `wxButton` | `ButtonProxy` | n/a |
| `CheckBox` | `wxCheckBox` | `CheckBoxProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Choice` | `wxChoice` | `ChoiceProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `ComboBox` | `wxComboBox` | `ComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `Hypertext` | `wxHypertextCtrl` | `HypertextProxy` | n/a |
| `Line` | `wxStaticLine` | `LineProxy` | n/a |
| `ListBox` | `wxListBox` | `ListBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `RadioBox` | `wxRadioBox` | `RadioBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `Slider` | `wxSlider` | `SliderProxy` | `value` -> `int`<BR>*default*: `value` |
| `SpinCtrl` | `wxSpinCtrl` | `SpinCtrlProxy` | `value` -> `int`<BR>*default*: `value` |
| `Text` | `wxStaticText` | `TextProxy` | `label` -> `std::string`<BR>*default*: `label` |
| `TextCtrl` | `wxTextCtrl` | `TextCtrlProxy` | `label` -> `std::string`<BR>*default*: `label` |
| wxUI | wxWidget | Default Event | Proxy | Proxy accessors value |
| :------------------- | :--------------------- | :----------------- | :------------------------ | :-------------- |
| `Bitmap` | `wxStaticBitmap` | n/a | `BitmapProxy` | n/a |
| `BitmapButton` | `wxBitmapButton` | `EVT_BUTTON` | `BitmapButtonProxy` | n/a |
| `BitmapComboBox` | `wxBitmapComboBox` | `EVT_COMBOBOX` | `BitmapComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `BitmapToggleButton` | `wxBitmapToggleButton` | `EVT_TOGGLEBUTTON` | `BitmapToggleButtonProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Button` | `wxButton` | `EVT_BUTTON` | `ButtonProxy` | n/a |
| `CheckBox` | `wxCheckBox` | `EVT_CHECKBOX` | `CheckBoxProxy` | `value` -> `bool`<BR>*default*: `value` |
| `Choice` | `wxChoice` | `EVT_CHOICE` | `ChoiceProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `ComboBox` | `wxComboBox` | `EVT_COMBOBOX` | `ComboBoxProxy` | `selection` -> `int`<BR>`value` -> `std::string`<BR>*default*: `value` |
| `Hypertext` | `wxHypertextCtrl` | n/a | `HypertextProxy` | n/a |
| `Line` | `wxStaticLine` | n/a | `LineProxy` | n/a |
| `ListBox` | `wxListBox` | `EVT_LISTBOX` | `ListBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `RadioBox` | `wxRadioBox` | `EVT_RADIOBOX` | `RadioBoxProxy` | `selection` -> `int`<BR>*default*: `selection` |
| `Slider` | `wxSlider` | `EVT_SLIDER` | `SliderProxy` | `value` -> `int`<BR>*default*: `value` |
| `SpinCtrl` | `wxSpinCtrl` | `EVT_SPINCTRL` | `SpinCtrlProxy` | `value` -> `int`<BR>*default*: `value` |
| `Text` | `wxStaticText` | n/a | `TextProxy` | `label` -> `std::string`<BR>*default*: `label` |
| `TextCtrl` | `wxTextCtrl` | `EVT_TEXT` | `TextCtrlProxy` | `label` -> `std::string`<BR>*default*: `label` |
Additional "Contollers" should be easy to add in future updates.
Expand Down
32 changes: 28 additions & 4 deletions examples/HelloWorld/ExtendedExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ SOFTWARE.
#include "ExtendedExample.h"
#include <wxUI/wxUI.h>

wxUI::Text::Proxy textProxy;
wxUI::SpinCtrl::Proxy spinProxy;
ExtendedExample::ExtendedExample(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "ExtendedExample",
wxDefaultPosition, wxDefaultSize,
Expand All @@ -42,7 +40,7 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
},
HSizer {
Button { "Incr" }
.bind([]() {
.bind([this]() {
*spinProxy = 1 + *spinProxy;
}),
},
Expand All @@ -61,7 +59,7 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
},
HSizer {
Button { "ReduceText" }
.bind([]() {
.bind([this]() {
auto str = textProxy->get();
if (str.size()) {
str.pop_back();
Expand Down Expand Up @@ -123,3 +121,29 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
}
.attachTo(this);
}

MultibindExample::MultibindExample(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "MultibindExample", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
using namespace wxUI;
VSizer {
wxSizerFlags().Expand().Border(),
HSizer {
TextCtrl {}
.withSize({ 200, -1 })
.withStyle(wxTE_PROCESS_ENTER)
.bind([this]() {
*timesTyped = std::to_string(stoi(*timesTyped) + 1);
})
.bind(wxEVT_TEXT_ENTER, [this]() {
*timesEntered = std::to_string(stoi(*timesEntered) + 1);
}),
},
HSizer {
timesTyped = Text { "0" },
timesEntered = Text { "0" },
},
Generic { CreateStdDialogButtonSizer(wxOK) },
}
.attachTo(this);
}
14 changes: 14 additions & 0 deletions examples/HelloWorld/ExtendedExample.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,22 @@ SOFTWARE.
// wxUI Extended Dialog Example

#include <wx/wx.h>
#include <wxUI/wxUI.h>

class ExtendedExample : public wxDialog {
public:
explicit ExtendedExample(wxWindow* parent);

private:
wxUI::Text::Proxy textProxy;
wxUI::SpinCtrl::Proxy spinProxy;
};

class MultibindExample : public wxDialog {
public:
explicit MultibindExample(wxWindow* parent);

private:
wxUI::Text::Proxy timesTyped;
wxUI::Text::Proxy timesEntered;
};
4 changes: 4 additions & 0 deletions examples/HelloWorld/HelloWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ HelloWorldFrame::HelloWorldFrame()
ExtendedExample dialog(this);
dialog.ShowModal();
} },
wxUI::Item { "&MultibindExample...", [this] {
MultibindExample dialog(this);
dialog.ShowModal();
} },
wxUI::Item { "&Example Item...", [] {
wxLogMessage("Hello World!");
} },
Expand Down
3 changes: 2 additions & 1 deletion include/wxUI/Bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@ struct Bitmap : public details::WidgetDetails<Bitmap, wxStaticBitmap> {
wxBitmap bitmap;
};

static_assert(details::Widget<Bitmap>);
WIDGET_STATIC_ASSERT_BOILERPLATE(Bitmap);

}
5 changes: 3 additions & 2 deletions include/wxUI/BitmapButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ struct BitmapButton : public details::WidgetDetails<BitmapButton, wxBitmapButton
return *this;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_BUTTON, func };
return super::bind(wxEVT_BUTTON, func);
}

struct Proxy : super::WidgetProxy {
Expand All @@ -85,5 +86,5 @@ struct BitmapButton : public details::WidgetDetails<BitmapButton, wxBitmapButton
bool isDefault = false;
};

static_assert(details::Widget<BitmapButton>);
WIDGET_STATIC_ASSERT_BOILERPLATE(BitmapButton);
}
5 changes: 3 additions & 2 deletions include/wxUI/BitmapComboBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,11 @@ struct BitmapComboBox : public details::WidgetDetails<BitmapComboBox, wxBitmapCo
return *this;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_COMBOBOX, func };
return super::bind(wxEVT_COMBOBOX, func);
}

struct Proxy : super::WidgetProxy {
Expand Down Expand Up @@ -138,5 +139,5 @@ struct BitmapComboBox : public details::WidgetDetails<BitmapComboBox, wxBitmapCo
int selection = 0;
};

static_assert(details::Widget<BitmapComboBox>);
WIDGET_STATIC_ASSERT_BOILERPLATE(BitmapComboBox);
}
5 changes: 3 additions & 2 deletions include/wxUI/BitmapToggleButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ struct BitmapToggleButton : public details::WidgetDetails<BitmapToggleButton, wx
return widget;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_TOGGLEBUTTON, func };
return super::bind(wxEVT_TOGGLEBUTTON, func);
}

struct Proxy : super::WidgetProxy {
Expand All @@ -93,5 +94,5 @@ struct BitmapToggleButton : public details::WidgetDetails<BitmapToggleButton, wx
std::optional<wxBitmap> bitmapPressed;
};

static_assert(details::Widget<BitmapToggleButton>);
WIDGET_STATIC_ASSERT_BOILERPLATE(BitmapToggleButton);
}
5 changes: 3 additions & 2 deletions include/wxUI/Button.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ struct Button : public details::WidgetDetails<Button, wxButton> {
return *this;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_BUTTON, func };
return super::bind(wxEVT_BUTTON, func);
}

struct Proxy : super::WidgetProxy {
Expand All @@ -86,5 +87,5 @@ struct Button : public details::WidgetDetails<Button, wxButton> {
bool isDefault = false;
};

static_assert(details::Widget<Button>);
WIDGET_STATIC_ASSERT_BOILERPLATE(Button);
}
5 changes: 3 additions & 2 deletions include/wxUI/CheckBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ struct CheckBox : public details::WidgetDetails<CheckBox, wxCheckBox> {
return *this;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_CHECKBOX, func };
return super::bind(wxEVT_CHECKBOX, func);
}

struct Proxy : super::WidgetProxy {
Expand All @@ -95,5 +96,5 @@ struct CheckBox : public details::WidgetDetails<CheckBox, wxCheckBox> {
bool value = false;
};

static_assert(details::Widget<CheckBox>);
WIDGET_STATIC_ASSERT_BOILERPLATE(CheckBox);
}
5 changes: 3 additions & 2 deletions include/wxUI/Choice.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ struct Choice : public details::WidgetDetails<Choice, wxChoice> {
return widget;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_CHOICE, func };
return super::bind(wxEVT_CHOICE, func);
}

struct Proxy : super::WidgetProxy {
Expand All @@ -95,5 +96,5 @@ struct Choice : public details::WidgetDetails<Choice, wxChoice> {
int selection {};
};

static_assert(details::Widget<Choice>);
WIDGET_STATIC_ASSERT_BOILERPLATE(Choice);
}
5 changes: 3 additions & 2 deletions include/wxUI/ComboBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ struct ComboBox : public details::WidgetDetails<ComboBox, wxComboBox> {
return *this;
}

using super::bind;
template <typename Function>
auto bind(Function func)
{
return details::BindWidgetToEvent { *this, wxEVT_COMBOBOX, func };
return super::bind(wxEVT_COMBOBOX, func);
}

struct Proxy : super::WidgetProxy {
Expand Down Expand Up @@ -104,5 +105,5 @@ struct ComboBox : public details::WidgetDetails<ComboBox, wxComboBox> {
int selection = 0;
};

static_assert(details::Widget<ComboBox>);
WIDGET_STATIC_ASSERT_BOILERPLATE(ComboBox);
}
Loading

0 comments on commit f139198

Please sign in to comment.