GUI2/Stacked Widget: added ability for widgets to be found in all layers

This is controlled by a find_in_all_layers flag (false by default). The reason I added this was to
have a cleaner method for find_widget to locate widgets on layers other than the currently visible
one. Usually, they aren't found, which leads to a rather hacky workaround of showing all layers
(selecting layer -1) manually whenever this was needed. There are a few cases where this isn't doable,
though, such as in the Preferences dialog. Right now, if a setting isn't on the currently visible page
when you exit the dialog, your selections won't be saved. Since modal_dialog::finalize_fields is called
before post_show, I can't do the show-all-layers trick in post_show.

This will provide a cleaner method for dialogs to use the find-in-all-layers behavior, if desired, without
unexpectedly running into issues in the future if someone forgot to add the workaround code.

This also adds a const overload for get_layer_grid to facilitate the find() implementation. I also haven't
implemented a find_at overload since I don't think it's necessary yet. Probably should get to that at some
point, though.
This commit is contained in:
Charles Dang 2017-09-21 15:17:22 -04:00
parent 42f353dec3
commit d1bcb6fe72
2 changed files with 63 additions and 1 deletions

View file

@ -22,6 +22,7 @@
#include "gui/widgets/widget_helpers.hpp"
#include "gui/widgets/generator.hpp"
#include "gettext.hpp"
#include "utils/const_clone.hpp"
#include "utils/general.hpp"
#include "utils/functional.hpp"
@ -33,10 +34,33 @@ namespace gui2
REGISTER_WIDGET(stacked_widget)
struct stacked_widget_implementation
{
template<typename W>
static W* find(utils::const_clone_ref<stacked_widget, W> stack,
const std::string& id,
const bool must_be_active)
{
// Use base method if find-in-all-layer isn't set.
if(!stack.find_in_all_layers_) {
return stack.container_base::find(id, must_be_active);
}
for(unsigned i = 0; i < stack.get_layer_count(); ++i) {
if(W* res = stack.get_layer_grid(i)->find(id, must_be_active)) {
return res;
}
}
return stack.container_base::find(id, must_be_active);
}
};
stacked_widget::stacked_widget(const implementation::builder_stacked_widget& builder)
: container_base(builder, get_control_type())
, generator_(generator_base::build(false, false, generator_base::independent, false))
, selected_layer_(-1)
, find_in_all_layers_(false)
{
}
@ -160,6 +184,22 @@ grid* stacked_widget::get_layer_grid(unsigned int i)
return &generator_->item(i);
}
const grid* stacked_widget::get_layer_grid(unsigned int i) const
{
assert(generator_);
return &generator_->item(i);
}
widget* stacked_widget::find(const std::string& id, const bool must_be_active)
{
return stacked_widget_implementation::find<widget>(*this, id, must_be_active);
}
const widget* stacked_widget::find(const std::string& id, const bool must_be_active) const
{
return stacked_widget_implementation::find<const widget>(*this, id, must_be_active);
}
// }---------- DEFINITION ---------{
stacked_widget_definition::stacked_widget_definition(const config& cfg)

View file

@ -35,6 +35,7 @@ class generator_base;
class stacked_widget : public container_base
{
friend struct stacked_widget_implementation;
friend struct implementation::builder_stacked_widget;
friend class debug_layout_graph;
@ -107,6 +108,14 @@ public:
*/
grid* get_layer_grid(unsigned int i);
/** Const overload for @ref get_layer_grid. */
const grid* get_layer_grid(unsigned int i) const;
void set_find_in_all_layers(const bool do_find)
{
find_in_all_layers_ = do_find;
}
private:
/**
* Finishes the building initialization of the widget.
@ -120,7 +129,7 @@ private:
* Contains a pointer to the generator.
*
* The pointer is not owned by this class, it's stored in the content_grid_
* of the scrollbar_container super class and freed when it's grid is
* of the scrollbar_container super class and freed when its grid is
* freed.
*
* NOTE: the generator is initialized with has_minimum (first arg) as false,
@ -141,6 +150,12 @@ private:
*/
int selected_layer_;
/**
* If true, @ref find will search all layers for widgets regardless of which
* one is visible.
*/
bool find_in_all_layers_;
void update_selected_layer_index(const int i);
/** Internal implementation detail for selecting layers. */
@ -151,6 +166,13 @@ private:
/** See @ref container_base::set_self_active. */
virtual void set_self_active(const bool active) override;
public:
/** See @ref widget::find. */
virtual widget* find(const std::string& id, const bool must_be_active) override;
/** See @ref widget::find. */
virtual const widget* find(const std::string& id, const bool must_be_active) const override;
};
// }---------- DEFINITION ---------{