Patch up some missing bits in the GUI2 iterator system

This commit is contained in:
Celtic Minstrel 2022-06-06 00:21:34 -04:00
parent 0093d64296
commit 3bd8d82d4a
11 changed files with 394 additions and 5 deletions

View File

@ -824,6 +824,10 @@
91AF556D281101C4007A7652 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF556C281101C3007A7652 /* input.cpp */; };
91AF55B02827588B007A7652 /* texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF55AF2827588B007A7652 /* texture.cpp */; };
91AF55DF2848472F007A7652 /* draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF55DE2848472F007A7652 /* draw.cpp */; };
91AF564F284D8A8B007A7652 /* walker_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF5649284D88DA007A7652 /* walker_container.cpp */; };
91AF5654284D90ED007A7652 /* walker_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF5649284D88DA007A7652 /* walker_container.cpp */; };
91AF565B284D9251007A7652 /* walker_scrollbar_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF5659284D9251007A7652 /* walker_scrollbar_container.cpp */; };
91AF565C284D9251007A7652 /* walker_scrollbar_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91AF5659284D9251007A7652 /* walker_scrollbar_container.cpp */; };
91B621A21B76A3CC00B00E0F /* build_info.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B621A11B76A3CC00B00E0F /* build_info.cpp */; };
91B621BA1B76B2C900B00E0F /* version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B621B91B76B2C900B00E0F /* version.cpp */; };
91B6220A1B76C0A600B00E0F /* libcairo.2.dylib in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = B513B2270ED36BFB0006E551 /* libcairo.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
@ -2141,6 +2145,10 @@
91AF55AF2827588B007A7652 /* texture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = texture.cpp; sourceTree = "<group>"; };
91AF55DD2848472E007A7652 /* draw.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = draw.hpp; sourceTree = "<group>"; };
91AF55DE2848472F007A7652 /* draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = draw.cpp; sourceTree = "<group>"; };
91AF5649284D88DA007A7652 /* walker_container.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = walker_container.cpp; sourceTree = "<group>"; };
91AF564A284D88DA007A7652 /* walker_container.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = walker_container.hpp; sourceTree = "<group>"; };
91AF5659284D9251007A7652 /* walker_scrollbar_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = walker_scrollbar_container.cpp; sourceTree = "<group>"; };
91AF565A284D9251007A7652 /* walker_scrollbar_container.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = walker_scrollbar_container.hpp; sourceTree = "<group>"; };
91B621801B766ED500B00E0F /* buffered_istream.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = buffered_istream.hpp; sourceTree = "<group>"; };
91B621811B766F1900B00E0F /* carryover.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = carryover.hpp; sourceTree = "<group>"; };
91B621821B766FD200B00E0F /* display_context.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = display_context.hpp; sourceTree = "<group>"; };
@ -3773,8 +3781,12 @@
46F92D0A2174F6A300602C1C /* iterator.hpp */,
46F92D072174F6A300602C1C /* policy_order.hpp */,
46F92D032174F6A300602C1C /* policy_visit.hpp */,
91AF5649284D88DA007A7652 /* walker_container.cpp */,
91AF564A284D88DA007A7652 /* walker_container.hpp */,
46F92D052174F6A300602C1C /* walker_grid.cpp */,
46F92D0C2174F6A300602C1C /* walker_grid.hpp */,
91AF5659284D9251007A7652 /* walker_scrollbar_container.cpp */,
91AF565A284D9251007A7652 /* walker_scrollbar_container.hpp */,
46F92D012174F6A300602C1C /* walker_tree_node.cpp */,
46F92D082174F6A300602C1C /* walker_tree_node.hpp */,
46F92D092174F6A300602C1C /* walker_widget.cpp */,
@ -5347,6 +5359,7 @@
46F92EDC2174FD9900602C1C /* scrollarea.cpp in Sources */,
ECA1E0F21A1271AC00426E00 /* lua_gui2.cpp in Sources */,
46F92D872174F6A300602C1C /* horizontal_list.cpp in Sources */,
91AF564F284D8A8B007A7652 /* walker_container.cpp in Sources */,
EC5401851EBE0C4500AE66EE /* display.cpp in Sources */,
46F92C1E2174F5D700602C1C /* help.cpp in Sources */,
F4D5483E15198D060058C8A7 /* lua_jailbreak_exception.cpp in Sources */,
@ -5481,6 +5494,7 @@
B559986C0EC616B3008DD061 /* SDLMain.mm in Sources */,
EC64D7611A085CE60092EF75 /* seed_rng.cpp in Sources */,
B5599B030EC62181008DD061 /* map_settings.cpp in Sources */,
91AF565B284D9251007A7652 /* walker_scrollbar_container.cpp in Sources */,
46F92C1A2174F5D700602C1C /* help_text_area.cpp in Sources */,
46F92DC12174F6A300602C1C /* game_version_dialog.cpp in Sources */,
ECAB84551B0C1934001A3EB7 /* shroud_clearing_action.cpp in Sources */,
@ -5802,6 +5816,7 @@
46F92EE42174FDA600602C1C /* menu.cpp in Sources */,
91E356691CACC6E000774252 /* mouse_events.cpp in Sources */,
91E3566A1CACC6E000774252 /* mouse_handler_base.cpp in Sources */,
91AF565C284D9251007A7652 /* walker_scrollbar_container.cpp in Sources */,
46F92EEB2174FDAB00602C1C /* widget.cpp in Sources */,
91E3566B1CACC6E000774252 /* movetype.cpp in Sources */,
91E3566C1CACC6E000774252 /* mp_game_settings.cpp in Sources */,
@ -6084,6 +6099,7 @@
91A214FA1CAD66B900927AEA /* hotkey_manager.cpp in Sources */,
46F92D802174F6A300602C1C /* static_registry.cpp in Sources */,
91A214FB1CAD66CC00927AEA /* picture.cpp in Sources */,
91AF5654284D90ED007A7652 /* walker_container.cpp in Sources */,
91A214FC1CAD66CC00927AEA /* image_modifications.cpp in Sources */,
4649B88420288DFB00827CFB /* game.cpp in Sources */,
46F92E322174F6A400602C1C /* custom_tod.cpp in Sources */,

View File

@ -142,7 +142,9 @@ game_initialization/singleplayer.cpp
game_launcher.cpp
game_state.cpp
gui/auxiliary/iterator/iterator.cpp
gui/auxiliary/iterator/walker_container.cpp
gui/auxiliary/iterator/walker_grid.cpp
gui/auxiliary/iterator/walker_scrollbar_container.cpp
gui/auxiliary/iterator/walker_tree_node.cpp
gui/auxiliary/iterator/walker_widget.cpp
gui/auxiliary/tips.cpp

View File

@ -198,6 +198,7 @@ public:
bool at_end() const
{
if(!root_) return true;
return visit_widget::at_end(*root_) && visit_grid::at_end(*root_)
&& visit_child::at_end(*root_);
}
@ -266,8 +267,8 @@ public:
stack_.push_back(std::exchange(root_, visit_child::get(*root_)->create_walker()));
assert(root_);
assert(!at_end());
TST_GUI_I << " Down and visit '" << operator*().id() << "'.\n";
if(at_end()) up();
return true;
}

View File

@ -0,0 +1,101 @@
/*
Copyright (C) 2011 - 2022
by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/auxiliary/iterator/walker_container.hpp"
#include <cassert>
namespace gui2::iteration
{
container::container(gui2::container_base& container)
: container_(container), widget_(&container), itor_(container.begin())
{
}
walker_base::state_t container::next(const level level)
{
if(at_end(level)) {
return fail;
}
switch(level) {
case self:
if(widget_) {
widget_ = nullptr;
return invalid;
}
assert(false);
return fail;
case internal:
if(!entered_grid) {
entered_grid = true;
in_grid = true;
return valid;
}
if(in_grid) {
in_grid = false;
return invalid;
}
assert(false);
return fail;
case child:
if(itor_ != container_.end()) {
++itor_;
return itor_ == container_.end() ? invalid : valid;
}
}
assert(false);
return fail;
}
bool container::at_end(const level level) const
{
switch(level) {
case self:
return widget_ == nullptr;
case internal:
return entered_grid && !in_grid;
case child:
return (itor_ == container_.end());
}
assert(false);
return true;
}
gui2::widget* container::get(const level level)
{
switch(level) {
case self:
return widget_;
case internal:
return &container_.get_grid();
case child:
if(itor_ == container_.end()) {
return nullptr;
} else {
return *itor_;
}
}
assert(false);
return nullptr;
}
} // namespace gui2::iteration

View File

@ -0,0 +1,74 @@
/*
Copyright (C) 2011 - 2022
by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
#include "gui/auxiliary/iterator/walker.hpp"
#include "gui/widgets/container_base.hpp"
namespace gui2::iteration
{
/** A walker for a @ref gui2::container_base. */
class container : public walker_base
{
public:
/**
* Constructor.
*
* @param grid The grid which the walker is attached to.
*/
explicit container(gui2::container_base& container);
/** Inherited from @ref gui2::iteration::walker_base. */
virtual state_t next(const level level);
/** Inherited from @ref gui2::iteration::walker_base. */
virtual bool at_end(const level level) const;
/** Inherited from @ref gui2::iteration::walker_base. */
virtual gui2::widget* get(const level level);
private:
/** The container which the walker is attached to. */
gui2::container_base& container_;
/**
* The widget which the walker is attached to.
*
* This variable is used to track whether the
* gui2::iteration::walker_base::widget level has been visited.
*/
gui2::widget* widget_;
/**
* Whether the grid has been yielded
*
* This variable is used to track whether the
* gui2::iteration::walker_base::internal level has been visited.
*/
bool entered_grid = false, in_grid = false;
/**
* The iterator to the children of @ref container_.
*
* This variable is used to track where the
* gui2::iteration::walker_base::child level visiting is.
*/
gui2::grid::iterator itor_;
};
} // namespace gui2::iteration

View File

@ -0,0 +1,111 @@
/*
Copyright (C) 2011 - 2022
by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/auxiliary/iterator/walker_scrollbar_container.hpp"
#include <cassert>
namespace gui2::iteration
{
scrollbar_container::scrollbar_container(gui2::scrollbar_container& container)
: container_(container), widget_(&container), itor_(container.begin())
{
}
walker_base::state_t scrollbar_container::next(const level level)
{
if(at_end(level)) {
return fail;
}
switch(level) {
case self:
if(widget_) {
widget_ = nullptr;
return invalid;
}
assert(false);
return fail;
case internal:
if(!entered_grid) {
entered_grid = true;
in_grid = true;
return valid;
}
if(in_grid) {
++itor_;
if(itor_ == container_.end()) {
in_grid = false;
entered_children = true;
itor_ = container_.content_grid()->begin();
return invalid;
}
return valid;
}
assert(false);
return fail;
case child:
if(itor_ != container_.content_grid()->end()) {
++itor_;
return itor_ == container_.content_grid()->end() ? invalid : valid;
}
}
assert(false);
return fail;
}
bool scrollbar_container::at_end(const level level) const
{
switch(level) {
case self:
return widget_ == nullptr;
case internal:
return entered_grid && !in_grid;
case child:
return entered_children && (itor_ == container_.content_grid()->end());
}
assert(false);
return true;
}
gui2::widget* scrollbar_container::get(const level level)
{
switch(level) {
case self:
return widget_;
case internal:
if(!in_grid || itor_ == container_.end()) {
return nullptr;
} else {
return *itor_;
}
case child:
if(!entered_children || itor_ == container_.content_grid()->end()) {
return nullptr;
} else {
return *itor_;
}
}
assert(false);
return nullptr;
}
} // namespace gui2::iteration

View File

@ -0,0 +1,75 @@
/*
Copyright (C) 2011 - 2022
by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
#include "gui/auxiliary/iterator/walker.hpp"
#include "gui/widgets/scrollbar_container.hpp"
namespace gui2::iteration
{
/** A walker for a @ref gui2::container_base. */
class scrollbar_container : public walker_base
{
public:
/**
* Constructor.
*
* @param grid The grid which the walker is attached to.
*/
explicit scrollbar_container(gui2::scrollbar_container& container);
/** Inherited from @ref gui2::iteration::walker_base. */
virtual state_t next(const level level);
/** Inherited from @ref gui2::iteration::walker_base. */
virtual bool at_end(const level level) const;
/** Inherited from @ref gui2::iteration::walker_base. */
virtual gui2::widget* get(const level level);
private:
/** The container which the walker is attached to. */
gui2::scrollbar_container& container_;
/**
* The widget which the walker is attached to.
*
* This variable is used to track whether the
* gui2::iteration::walker_base::widget level has been visited.
*/
gui2::widget* widget_;
/**
* Whether the grid has been yielded
*
* This variable is used to track whether the
* gui2::iteration::walker_base::internal level has been visited.
*/
bool entered_grid = false, in_grid = false, entered_children = false;
/**
* The iterator to the children of @ref container_.
*
* This variable is used to track where the
* gui2::iteration::walker_base::child level and
* gui2::iteration::walker_base::internal level visiting is.
*/
gui2::grid::iterator itor_;
};
} // namespace gui2::iteration

View File

@ -17,7 +17,7 @@
#include "gui/widgets/container_base.hpp"
#include "gui/auxiliary/iterator/walker.hpp"
#include "gui/auxiliary/iterator/walker_container.hpp"
#include "gui/core/log.hpp"
#include "gui/widgets/window.hpp"
@ -264,7 +264,7 @@ bool container_base::disable_click_dismiss() const
iteration::walker_ptr container_base::create_walker()
{
return nullptr;
return std::make_unique<gui2::iteration::container>(*this);
}
void container_base::init_grid(const builder_grid& grid_builder)

View File

@ -143,8 +143,6 @@ public:
/**
* See @ref widget::create_walker.
*
* @todo Implement properly.
*/
virtual iteration::walker_ptr create_walker() override;

View File

@ -18,6 +18,7 @@
#include "gui/widgets/scrollbar_container_private.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/auxiliary/iterator/walker_scrollbar_container.hpp"
#include "gui/core/event/message.hpp"
#include "gui/core/layout_exception.hpp"
#include "gui/core/log.hpp"
@ -516,6 +517,11 @@ bool scrollbar_container::disable_click_dismiss() const
return container_base::disable_click_dismiss() || content_grid_->disable_click_dismiss();
}
iteration::walker_ptr scrollbar_container::create_walker()
{
return std::make_unique<gui2::iteration::scrollbar_container>(*this);
}
bool scrollbar_container::content_resize_request(const bool force_sizing)
{
/**

View File

@ -137,6 +137,11 @@ public:
/** See @ref widget::disable_click_dismiss. */
bool disable_click_dismiss() const override;
/**
* See @ref widget::create_walker.
*/
virtual iteration::walker_ptr create_walker() override;
/***** ***** ***** setters / getters for members ***** ****** *****/