Skip to content
This repository has been archived by the owner on Aug 29, 2024. It is now read-only.

Commit

Permalink
Start #318: foreach, traverse etc. sanitizations
Browse files Browse the repository at this point in the history
  • Loading branch information
xparq committed Aug 1, 2023
1 parent 0857739 commit 2d045ac
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 142 deletions.
7 changes: 0 additions & 7 deletions include/sfw/GUI-main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,6 @@ class GUI: public VBox
*/
void close();

/**
* Do things to widgets...
*/
void foreach(const std::function<void(Widget*)>& f) { return traverse(f); }
void const_foreach(const std::function<void(const Widget*)>& f) const { return const_traverse(f); }


/*************************************************************************
Name->widget registry
Expand Down
10 changes: 8 additions & 2 deletions include/sfw/InputWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ template <class W> class InputWidget : public Widget
return (W*)updated(); // Downcasting only for the proper return type.
}

// Trigger the onUpdated() callback, if the widget's content has been changed,
// and then set it to unchanged.
// Trigger the onUpdated() callback, if the widget's content has changed,
// and then reset it back to unchanged.
//!! -> "notify..." (and "onUpdted" -> "EventHandler::invoke_callback(Updated)"
//!! Note though, that this is not just a generic "notify on event" function,
//!! but one specific to botk InputWidget and changing the widget value (the "changed" logic)
//!! Could still be a virtual override of a generic EventHandler::notify, but I don't feel
//!! OK with that.
//!! -> also Widget::onUpdated() -- soon to become EventHandler::invoke_callback!...
W* updated()
{
if (!changed()) return (W*)this;
Expand Down
27 changes: 15 additions & 12 deletions include/sfw/Widget.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#ifndef GUI_WIDGET_HPP
#define GUI_WIDGET_HPP
#ifndef SFW_WIDGET_HPP
#define SFW_WIDGET_HPP

#include "sfw/Event.hpp"
#include "sfw/WidgetState.hpp"

//!!#include "sfw/Widgets/Tooltip.hpp" // See forw. decl. below instead...
//!!#include "sfw/WidgetContainer.hpp" // See forw. decl. below instead...
//!!#include "sfw/Layout.hpp" // See forw. decl. below instead...
//!!#include "sfw/GUI-main.hpp" // See forw. decl. below instead...
//!!#include "sfw/Layout.hpp" // See forw. decl. below instead...
//!!#include "sfw/GUI-main.hpp" // See forw. decl. below instead...

#include "sfw/Gfx/Render.hpp"

Expand All @@ -19,7 +19,7 @@

#ifdef DEBUG
#
# include <SFML/Graphics/Color.hpp>
# include <SFML/Graphics/Color.hpp> // for draw_outline()
#
#endif

Expand Down Expand Up @@ -165,14 +165,17 @@ friend class Tooltip; // just to access getMain() via Tooltip::m_owner->!

// Recursive traversal of all the widget's descendants (if any)
// (Does not include the target widget itself.)
// Note: this operation is independent from being a widget container,
// despite currently only WidgetContainer implementing it, indeed.
// Note: this operation is not strictly related to widget *containers*,
// despite only WidgetContainer implementing it currently.
// This uniform interface is provided here on the Widget level a) for
// the convenience of uniform access, and b) to support compound Widget
// types that don't want to become a container (i.e. have a hardcoded
// internal structure rather than using that of WidgetContainer).
// the convenience of uniform access, and b) to support compound widget
// types that don't want to become containers per se, but just have an
// easily manageable internal structure of sub-widgets.
//!! (Not sure this latter makes sense, though: maybe that's OK to just be a container then!
//!! Also: complex assemblies may have multiple widget trees, too, not just this -- also
//!! implicit... -- one.)
virtual void traverse(const std::function<void(Widget*)>&) {}
virtual void const_traverse(const std::function<void(const Widget*)>&) const {}
virtual void ctraverse(const std::function<void(const Widget*)>&) const {}

private:
virtual void recomputeGeometry() {} // Also called by some of the friend classes
Expand Down Expand Up @@ -276,4 +279,4 @@ template <class W = Widget> W* getWidget(const std::string& name) { return (W*)W

} // namespace

#endif // GUI_WIDGET_HPP
#endif // SFW_WIDGET_HPP
32 changes: 16 additions & 16 deletions include/sfw/WidgetContainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class WidgetContainer: public Widget
Widget* addAfter(Widget* anchor, Widget* widget, const std::string& name = "");
Widget* addAfter(const std::string& anchor_name, Widget* widget, const std::string& name = "");

// STL-like iteration helpers --------------------------------------------
// STL-like iteration helpers ----------------------------------------
bool empty() const { return !m_first; }
Widget* begin() const { return m_first; }
Widget* end() const { return nullptr; }
Expand All @@ -65,25 +65,25 @@ class WidgetContainer: public Widget
Widget* rbegin() const { return m_last; }
//!! Make the entire class STL-compatible, so the std:: algorithms can be used on it! (#162)

protected:
// Internal helpers ------------------------------------------------------
//!!Some of them might as well be made public!
Widget* insert_after(Widget* anchor, Widget* widget, const std::string& name);

// Check if widget is a (direct or top-level) child of the container
bool is_child(const Widget* widget);

// Enumerate (only) the direct (top-level) children of the container
//!!This may also need to be defined in Widget instead, because client
// Enumerate (only) the direct descendants children of the container
//!!This may (also) need to be defined in Widget instead, because client
//!!code shouldn't really care whether some widgets can or cannot have
//!!children! A pure tree structure in this regard too could be preferable.
void for_each_child(const std::function<void(Widget*)>& f);
void const_for_each_child(const std::function<void(const Widget*)>& f) const;
//!!children! A homogeneous tree view in this regard would be preferable.
// Note: `for (auto i : wcont)` also works, so this is just syntactic sugar!
void foreach(const std::function<void(Widget*)>& f);
void cforeach(const std::function<void(const Widget*)>& f) const;

// Recursive traversal of all the contained widgets
// (Does not include this container itself.)
// Does not include this container itself.
void traverse(const std::function<void(Widget*)>& f) override;
void const_traverse(const std::function<void(const Widget*)>&) const override;
void ctraverse(const std::function<void(const Widget*)>&) const override;

// ---- Internal helpers -----------------------------------------------------
protected:
Widget* insert_after(Widget* anchor, Widget* widget, const std::string& name);

// Check if `widget` is a direct child node
bool is_child(const Widget* widget);

protected:
Widget* m_first;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ GUI* GUI::DefaultInstance = nullptr;
GUI::GUI(sf::RenderWindow& window, const sfw::Theme::Cfg& themeCfg, bool own_the_window):
m_error(), // no error by default
m_window(window),
m_own_window(own_the_window),
m_own_window(own_the_window), //!!Rename to sg. like manage_host_window
m_themeCfg(themeCfg)
{
// "Officially" mark this object as the "Main" in the GUI Widget tree:
Expand Down Expand Up @@ -270,7 +270,7 @@ void GUI::draw(const gfx::RenderContext& ctx) const
//!!replicate that using that Transform() hack below... :-/ (See also: #315)
//!!
auto widget_ctx = ctx;
const_traverse([&widget_ctx](const Widget* w) {
ctraverse([&widget_ctx](const Widget* w) {
if (w->m_tooltip) {
auto widget_pos = w->getParent()->getAbsolutePosition();
//!!SFML-specific:
Expand Down
12 changes: 6 additions & 6 deletions src/lib/Layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void Layout::draw(const gfx::RenderContext& ctx) const
}
#endif

const_for_each_child([&](auto widget) {
cforeach([&](auto widget) {
if (m_hoveredWidget != widget) //! Defer the hovered one, for "cheating" the Z-order; see below...
widget->draw(lctx);
#ifdef DEBUG
Expand Down Expand Up @@ -81,7 +81,7 @@ void Layout::draw(const gfx::RenderContext& ctx) const
//!!If multiple tooltips are visible and are too close to each other, and the most recent is
//!!iterated earlier, it WILL NOT be the topmost! Proper stacking or explicit Z-ordering needed!
//!!But, honestly... tooltips! There shouldn't even be more than one. ;)
const_for_each_child([&lctx](auto widget) {
cforeach([&lctx](auto widget) {
if (widget->m_tooltip)
widget->m_tooltip->draw(lctx);
});
Expand Down Expand Up @@ -125,9 +125,9 @@ void Layout::onMouseMoved(float x, float y)
return;
}

for (Widget* widget = begin(); widget != end(); widget = next(widget)) //!! Not a nice fit for `for_each_child([&](auto* widget)`
//!! because it doesn't support breaking the loop (see that
//!! `continue` and early `return` below)!...
for (Widget* widget = begin(); widget != end(); widget = next(widget)) //!! Not a nice fit for `foreach(widget)`, because
//!! it doesn't support breaking the loop (see that
//!! early `return` below)...
{
if (!widget->enabled())
continue;
Expand Down Expand Up @@ -193,7 +193,7 @@ void Layout::onMousePressed(float x, float y)
//
if (!m_hoveredWidget)
{
for (Widget* widget = begin(); widget != end(); widget = next(widget)) //!! Not `for_each_child([&](auto* widget),
for (Widget* widget = begin(); widget != end(); widget = next(widget)) //!! Not `foreach(widget) yet (-> #318),
//!! because of an early break-out!
{
if (widget->enabled())
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Layouts/HBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace sfw
void HBox::recomputeGeometry()
{
sf::Vector2f pos{}, size{};
for_each_child([&](Widget* w) {
foreach([&](Widget* w) {
w->setPosition(pos);
pos.x += w->getSize().x + Theme::MARGIN;

Expand Down
2 changes: 1 addition & 1 deletion src/lib/Layouts/VBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace sfw
void VBox::recomputeGeometry()
{
sf::Vector2f pos{}, size{};
for_each_child([&](Widget* w) {
foreach([&](Widget* w) {
w->setPosition(pos);
pos.y += w->getSize().y + Theme::MARGIN;

Expand Down
Loading

0 comments on commit 2d045ac

Please sign in to comment.