The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
tab_container.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2024 - 2025
3 by Subhraman Sarkar (babaissarkar) <sbmskmm@protonmail.com>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#define GETTEXT_DOMAIN "wesnoth-lib"
17
19
20#include "gui/core/log.hpp"
21#include "gettext.hpp"
27#include "wml_exception.hpp"
28
29#include <functional>
30
31#define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
32#define LOG_HEADER LOG_SCOPE_HEADER + ':'
33
34namespace gui2
35{
36
37// ------------ WIDGET -----------{
38
39REGISTER_WIDGET(tab_container)
40
42{
43 template<typename W>
45 const std::string_view id,
46 const bool must_be_active)
47 {
48 for(unsigned i = 0; i < stack.get_tab_count(); ++i) {
49 auto* tab_grid = stack.get_tab_grid(i);
50 if(!tab_grid) {
51 continue;
52 }
53
54 if(W* res = tab_grid->find(id, must_be_active)) {
55 return res;
56 }
57 }
58
59 return stack.container_base::find(id, must_be_active);
60 }
61};
62
64 : container_base(builder, type())
65 , state_(ENABLED)
66 , tab_count_(0)
67 , generator_(nullptr)
68{
69 const auto conf = cast_config_to<tab_container_definition>();
70 assert(conf);
71
72 init_grid(*conf->grid);
73
75
76 generator_ = generator.get();
77 assert(generator_);
78
79 const widget_item empty_data;
80 for(const auto& builder_entry : builder.builders) {
81 generator->create_item(-1, *builder_entry, empty_data, nullptr);
82 }
83
84 grid* parent_grid = find_widget<grid>("_content_grid", false, true);
85 if(parent_grid) {
86 parent_grid->swap_child("_page", std::move(generator), false);
87 }
88
89 for (const widget_data& row : builder.list_items) {
90 add_tab_entry(row);
91 }
92
93 tab_count_ = builder.builders.size();
94
96}
97
98void tab_container::set_self_active(const bool active)
99{
100 state_ = active ? ENABLED : DISABLED;
101}
102
104{
105 return state_ != DISABLED;
106}
107
109{
110 return state_;
111}
112
114{
115 return true;
116}
117
119{
120 return get_grid().find_widget<listbox>("_tab_list", false);
121}
122
124{
125 listbox& list = get_internal_list();
126 list.add_row(row);
127}
128
129void tab_container::select_tab(unsigned index)
130{
131 if (index < get_tab_count()) {
133 generator_->select_item(index, true);
134 }
135}
136
144
145widget* tab_container::find(const std::string_view id, const bool must_be_active)
146{
147 return tab_container_implementation::find<widget>(*this, id, must_be_active);
148}
149
150const widget* tab_container::find(const std::string_view id, const bool must_be_active) const
151{
152 return tab_container_implementation::find<const widget>(*this, id, must_be_active);
153}
154
155// }---------- DEFINITION ---------{
156
159{
160 DBG_GUI_P << "Parsing tab_container " << id;
161
162 load_resolutions<resolution>(cfg);
163}
164
166 : resolution_definition(cfg), grid(nullptr)
167{
168 // Note the order should be the same as the enum state_t is tab_container.hpp.
169 state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_enabled", missing_mandatory_wml_tag("tab_container_definition][resolution", "state_enabled")));
170 state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_disabled", missing_mandatory_wml_tag("tab_container_definition][resolution", "state_disabled")));
171
172 auto child = VALIDATE_WML_CHILD(cfg, "grid", _("No grid defined for tab container control"));
173 grid = std::make_shared<builder_grid>(child);
174}
175
176// }---------- BUILDER -----------{
177
178namespace implementation
179{
180
181builder_tab_container::builder_tab_container(const config& cfg)
183{
184 if(cfg.has_child("tab")) {
185 for(const config& tab : cfg.child_range("tab")) {
186 list_items.emplace_back(widget_data{
187 { "image", {{"label", tab["image"].str()}} },
188 { "name", {{"label", tab["name"].t_str()}} }
189 });
190
191 if(tab.has_child("data")) {
192 auto builder = std::make_shared<builder_grid>(tab.mandatory_child("data"));
193 builders.push_back(builder);
194 }
195 }
196 }
197}
198
199std::unique_ptr<widget> builder_tab_container::build() const
200{
201 auto widget = std::make_unique<tab_container>(*this);
202 DBG_GUI_G << "Window builder: placed tab_container '" << id
203 << "' with definition '" << definition << "'.";
204 return widget;
205}
206
207} // namespace implementation
208
209// }------------ END --------------
210
211} //
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
child_itors child_range(std::string_view key)
Definition config.cpp:268
bool has_child(std::string_view key) const
Determine whether a config has a child or not.
Definition config.cpp:312
A generic container base class.
const grid & get_grid() const
virtual void place(const point &origin, const point &size) override
See widget::place.
void init_grid(const builder_grid &grid_builder)
Initializes and builds the grid.
void connect_signal(const F &func, const queue_position position=back_child)
Adds a callback to the appropriate queue based on event type.
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
virtual void select_item(const unsigned index, const bool select)=0
(De)selects an item.
static std::unique_ptr< generator_base > build(const bool has_minimum, const bool has_maximum, const placement placement, const bool select)
Create a new generator.
Basic template class to generate new items.
grid & create_item(const int index, const builder_grid &list_builder, const widget_item &item_data, const std::function< void(widget &)> &callback) override
Inherited from generator_base.
Base container class.
Definition grid.hpp:32
std::unique_ptr< widget > swap_child(const std::string &id, std::unique_ptr< widget > w, const bool recurse, widget *new_parent=nullptr)
Exchanges a child in the grid.
Definition grid.cpp:101
The listbox class.
Definition listbox.hpp:41
grid & add_row(const widget_item &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
Definition listbox.cpp:92
bool select_row(const unsigned row, const bool select=true)
Selects a row.
Definition listbox.cpp:267
state_t state_
Current state of the widget.
virtual unsigned get_state() const override
Returns the id of the state.
generator_base * generator_
Contains a pointer to the generator.
virtual bool get_active() const override
Gets the active state of the styled_widget.
virtual widget * find(const std::string_view id, const bool must_be_active) override
See widget::find.
void add_tab_entry(const widget_data &row)
unsigned get_tab_count() const
virtual void set_self_active(const bool active) override
Helper for set_active.
bool can_wrap() const override
See widget::can_wrap.
void select_tab(unsigned index)
listbox & get_internal_list()
Get the listbox inside which the tabs are shown.
tab_container(const implementation::builder_tab_container &builder)
unsigned get_active_tab_index()
Base class for all widgets.
Definition widget.hpp:55
T * find_widget(const std::string_view id, const bool must_be_active, const bool must_exist)
Gets a widget with the wanted id.
Definition widget.hpp:747
void queue_redraw()
Indicates that this widget should be redrawn.
Definition widget.cpp:464
point get_origin() const
Returns the screen origin of the widget.
Definition widget.cpp:311
point get_size() const
Returns the size of the widget.
Definition widget.cpp:316
const config * cfg
static std::string _(const char *str)
Definition gettext.hpp:100
Define the common log macros for the gui toolkit.
#define DBG_GUI_G
Definition log.hpp:41
#define DBG_GUI_P
Definition log.hpp:66
This file contains the window object, this object is a top level container which has the event manage...
Generic file dialog.
std::map< std::string, widget_item > widget_data
Definition widget.hpp:36
std::map< std::string, t_string > widget_item
Definition widget.hpp:33
Contains the implementation details for lexical_cast and shouldn't be used directly.
typename const_clone< D, S >::reference const_clone_ref
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
This file contains the settings handling of the widget library.
std::string definition
Parameters for the styled_widget.
virtual std::unique_ptr< widget > build() const override
std::vector< std::shared_ptr< builder_grid > > builders
std::vector< state_definition > state
tab_container_definition(const config &cfg)
static W * find(utils::const_clone_ref< tab_container, W > stack, const std::string_view id, const bool must_be_active)
std::string missing_mandatory_wml_tag(const std::string &section, const std::string &tag)
Returns a standard message for a missing wml child (tag).
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE_WML_CHILD(cfg, key, message)
#define i