Skip to content

Commit

Permalink
Issue #148: Make sure operator-> returns controller on proxies.
Browse files Browse the repository at this point in the history
  • Loading branch information
rmpowell77 committed Nov 20, 2023
1 parent 73d55f1 commit a94ff69
Show file tree
Hide file tree
Showing 18 changed files with 35 additions and 41 deletions.
5 changes: 2 additions & 3 deletions LATEST_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# wxUI release notes for v0.1.6
# wxUI release notes for v0.1.7

Bugs addressed in this release:

Other changes:

* [#140](../../issues/140) Generic should take functions that convert to wxWindow
* [#142](../../issues/142) Generic needs a proxy
* [#148](../../issues/148) Make sure operator-> returns controller on proxies

17 changes: 9 additions & 8 deletions docs/ProgrammersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,34 +249,35 @@ For convenience the event parameter of the function can be omitted in cases wher

Often the value of a *Controller* in a layout needs to be referenced, or sometimes the backing `wxWindow` itself needs to be used directly. This could be for reading a currently typed in value in a `TextCtrl`, or to change the selection of a `Choice`. *Controllers* support `Proxy` objects, a way to get the handle to the underlying `wxWindow` that is created for the *Controller*.

Some *Controllers* do not support values that are intended to change, such as a `Line`, and others can have several values of interest, such as a `ComboBox`. `Proxy` objects can have several accessors that allow access to these, most commonly called `value()` and `selection()` (see Supported Controllers for details of each supported *Controller*). These accessors are proxy objects support `get()` and `set()` functions, as well as a set of appropriate overloads for the underlying type, allowing more ergonomic interaction with the code. `Proxy` also supplies `operator*` and `operator->` which reference the most common accessor.
Some *Controllers* do not support values that are intended to change, such as a `Line`, and others can have several values of interest, such as a `ComboBox`. `Proxy` objects can have several accessors that allow access to these, most commonly called `value()` and `selection()` (see Supported Controllers for details of each supported *Controller*). These accessors are proxy objects support `get()` and `set()` functions, as well as a set of appropriate overloads for the underlying type, allowing more ergonomic interaction with the code. `Proxy` also supplies `operator*` which reference the most common accessor.

`Proxy` supply `control()`, which is intended to allow access to the underlying controller.
`Proxy` supply `control()`, which is intended to allow access to the underlying controller. `Proxy` overloads `operator->` to allow a "natural" syntax for calling functions on the underlying *Controller*.

As `Proxy` objects need to be a named variable that exist outside of a *Controller*, and require being "attached". This is done with the `operator=`, allowing for an ergonomic way to attach `Proxy` objects to controls. Accessing a proxy object that has not been attached to a controller will cause an exception to be raised.


```cpp
auto getHandle(UnderlyingType** handlePtr);
```
```cpp
class ExtendedExample : public wxDialog {
public:
explicit ExtendedExample(wxWindow* parent);
void Reset();
private:
wxTextCtrl* mText;
wxUI::TextCtrl::Proxy mText;
};

ExtendedExample::ExtendedExample(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "ExtendedExample")
{
using namespace wxUI;
VSizer {
proxy = TextCtrl { "Hello" }
mText = TextCtrl { "Hello" }
}
.attachTo(this);
}

ExtendedExample::Reset() {
mText->DiscardEdits();
}
```
#### Supported Controllers
Expand Down
17 changes: 9 additions & 8 deletions docs/src/docs/ProgrammersGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,34 +136,35 @@ For convenience the event parameter of the function can be omitted in cases wher

Often the value of a *Controller* in a layout needs to be referenced, or sometimes the backing `wxWindow` itself needs to be used directly. This could be for reading a currently typed in value in a `TextCtrl`, or to change the selection of a `Choice`. *Controllers* support `Proxy` objects, a way to get the handle to the underlying `wxWindow` that is created for the *Controller*.

Some *Controllers* do not support values that are intended to change, such as a `Line`, and others can have several values of interest, such as a `ComboBox`. `Proxy` objects can have several accessors that allow access to these, most commonly called `value()` and `selection()` (see Supported Controllers for details of each supported *Controller*). These accessors are proxy objects support `get()` and `set()` functions, as well as a set of appropriate overloads for the underlying type, allowing more ergonomic interaction with the code. `Proxy` also supplies `operator*` and `operator->` which reference the most common accessor.
Some *Controllers* do not support values that are intended to change, such as a `Line`, and others can have several values of interest, such as a `ComboBox`. `Proxy` objects can have several accessors that allow access to these, most commonly called `value()` and `selection()` (see Supported Controllers for details of each supported *Controller*). These accessors are proxy objects support `get()` and `set()` functions, as well as a set of appropriate overloads for the underlying type, allowing more ergonomic interaction with the code. `Proxy` also supplies `operator*` which reference the most common accessor.

`Proxy` supply `control()`, which is intended to allow access to the underlying controller.
`Proxy` supply `control()`, which is intended to allow access to the underlying controller. `Proxy` overloads `operator->` to allow a "natural" syntax for calling functions on the underlying *Controller*.

As `Proxy` objects need to be a named variable that exist outside of a *Controller*, and require being "attached". This is done with the `operator=`, allowing for an ergonomic way to attach `Proxy` objects to controls. Accessing a proxy object that has not been attached to a controller will cause an exception to be raised.


```cpp
auto getHandle(UnderlyingType** handlePtr);
```
```cpp
class ExtendedExample : public wxDialog {
public:
explicit ExtendedExample(wxWindow* parent);
void Reset();
private:
wxTextCtrl* mText;
wxUI::TextCtrl::Proxy mText;
};

ExtendedExample::ExtendedExample(wxWindow* parent)
: wxDialog(parent, wxID_ANY, "ExtendedExample")
{
using namespace wxUI;
VSizer {
proxy = TextCtrl { "Hello" }
mText = TextCtrl { "Hello" }
}
.attachTo(this);
}

ExtendedExample::Reset() {
mText->DiscardEdits();
}
```
#### Supported Controllers
Expand Down
8 changes: 5 additions & 3 deletions examples/HelloWorld/ExtendedExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
using namespace wxUI;
ComboBox::Proxy proxy2;
VSizer {
wxSizerFlags().Expand().Border(),
// incr example
Expand Down Expand Up @@ -60,11 +61,11 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
HSizer {
Button { "ReduceText" }
.bind([this]() {
auto str = textProxy->get();
auto str = static_cast<std::string>(*textProxy);
if (str.size()) {
str.pop_back();
}
textProxy->set(str);
*textProxy = str;
}),
},
HSizer {
Expand All @@ -74,7 +75,7 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
CheckBox {},
},
HSizer {
ComboBox { { "hello" } },
proxy2 = ComboBox { { "hello" } },
},
HSizer {
Line {},
Expand Down Expand Up @@ -120,6 +121,7 @@ ExtendedExample::ExtendedExample(wxWindow* parent)
// endsnippet CustomExample
}
.attachTo(this);
proxy2->SetFocus();
}

MultibindExample::MultibindExample(wxWindow* parent)
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/BitmapComboBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ struct BitmapComboBox : public details::WidgetDetails<BitmapComboBox, wxBitmapCo
};
}

auto operator->() const { return value(); }
auto operator*() const { return value(); }
};
RULE_OF_SIX_BOILERPLATE(BitmapComboBox);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/BitmapToggleButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ struct BitmapToggleButton : public details::WidgetDetails<BitmapToggleButton, wx
};
}

auto operator->() const { return value(); }
auto operator*() const { return value(); }
};
RULE_OF_SIX_BOILERPLATE(BitmapToggleButton);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/CheckBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ struct CheckBox : public details::WidgetDetails<CheckBox, wxCheckBox> {
};
}

auto operator->() const { return value(); }
auto operator*() const { return value(); }
};
RULE_OF_SIX_BOILERPLATE(CheckBox);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/Choice.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ struct Choice : public details::WidgetDetails<Choice, wxChoice> {
};
}

auto operator->() const { return selection(); }
auto operator*() const { return selection(); }
};
RULE_OF_SIX_BOILERPLATE(Choice);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/ComboBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ struct ComboBox : public details::WidgetDetails<ComboBox, wxComboBox> {
};
}

auto operator->() const { return value(); }
auto operator*() const { return value(); }
};
RULE_OF_SIX_BOILERPLATE(ComboBox);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/ListBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ struct ListBox : public details::WidgetDetails<ListBox, wxListBox> {
};
}

auto operator->() const { return selection(); }
auto operator*() const { return selection(); }
};
RULE_OF_SIX_BOILERPLATE(ListBox);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/RadioBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ struct RadioBox : details::WidgetDetails<RadioBox, wxRadioBox> {
};
}

auto operator->() const { return selection(); }
auto operator*() const { return selection(); }
};
RULE_OF_SIX_BOILERPLATE(RadioBox);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/Slider.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ struct Slider : public details::WidgetDetails<Slider, wxSlider> {
};
}

auto operator->() const { return value(); }
auto operator*() const { return value(); }
};
RULE_OF_SIX_BOILERPLATE(Slider);
Expand Down
1 change: 0 additions & 1 deletion include/wxUI/SpinCtrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ struct SpinCtrl : public details::WidgetDetails<SpinCtrl, wxSpinCtrl> {
};
}

auto operator->() const { return value(); }
auto operator*() const { return value(); }
};

Expand Down
1 change: 0 additions & 1 deletion include/wxUI/Text.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ struct Text : public details::WidgetDetails<Text, wxStaticText> {
};
}

auto operator->() const { return label(); }
auto operator*() const { return label(); }
};

Expand Down
1 change: 0 additions & 1 deletion include/wxUI/TextCtrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ struct TextCtrl : public details::WidgetDetails<TextCtrl, wxTextCtrl> {
};
}

auto operator->() const { return label(); }
auto operator*() const { return label(); }
};

Expand Down
2 changes: 2 additions & 0 deletions include/wxUI/Widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ struct WidgetDetails {
controller = control;
}

auto operator->() const { return control(); }

private:
Underlying* controller {};
};
Expand Down
8 changes: 4 additions & 4 deletions tests/wxUI_SpinCtrlTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,11 @@ TEST_CASE("SpinCtrl")
auto uut = proxy = createUUT().withSize({ 1, 2 });
uut.create(&frame);

CHECK(proxy->get() == 0);
proxy->set(1);
CHECK(proxy->get() == 1);
CHECK(*proxy == 0);
*proxy = 1;
CHECK(*proxy == 1);
*proxy = 2;
CHECK(proxy->get() == 2);
CHECK(*proxy == 2);
int result2 = *proxy;
CHECK(result2 == 2);
}
Expand Down
8 changes: 4 additions & 4 deletions tests/wxUI_TextTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ TEST_CASE("Text")
auto proxy = TypeUnderTest::Proxy {};
auto uut = proxy.bind(TypeUnderTest { "label1" }.withSize({ 1, 2 }));
uut.create(&frame);
CHECK(proxy->get() == "label1");
CHECK(static_cast<std::string>(*proxy) == std::string("label1"));
// CHECK(static_cast<std::string>(proxy) == "label1");
// CHECK("label1" == static_cast<std::string>(proxy));
// CHECK(static_cast<std::string>(proxy) == "label1");
proxy->set("label2");
CHECK(proxy->get() == "label2");
*proxy = "label2";
CHECK(static_cast<std::string>(*proxy) == "label2");
*proxy = "label3";
CHECK(proxy->get() == "label3");
CHECK(static_cast<std::string>(*proxy) == "label3");
std::string result2 = *proxy;
CHECK(result2 == "label3");
}
Expand Down

0 comments on commit a94ff69

Please sign in to comment.