The Battle for Wesnoth  1.19.7+dev
tab_container.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2024
3  by Subhraman Sarkar (babaissarkar) <suvrax@gmail.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"
24 #include "gui/widgets/listbox.hpp"
25 #include "gui/widgets/settings.hpp"
26 #include "gui/widgets/window.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 
34 namespace gui2
35 {
36 
37 // ------------ WIDGET -----------{
38 
39 REGISTER_WIDGET(tab_container)
40 
41 tab_container::tab_container(const implementation::builder_tab_container& builder)
42  : container_base(builder, type())
43  , state_(ENABLED)
44  , builders_(builder.builders)
45  , list_items_(builder.list_items)
46 {
47 }
48 
49 void tab_container::set_self_active(const bool active)
50 {
51  state_ = active ? ENABLED : DISABLED;
52 }
53 
55 {
56  return state_ != DISABLED;
57 }
58 
59 unsigned tab_container::get_state() const
60 {
61  return state_;
62 }
63 
65 {
66  return true;
67 }
68 
70 {
71  return get_grid().find_widget<listbox>("_tab_list", false);
72 }
73 
74 void tab_container::finalize(std::unique_ptr<generator_base> generator)
75 {
76  generator_ = generator.get();
77  assert(generator_);
78 
79  widget_item empty_data;
80  for(const auto& builder_entry : 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 
90 
91  select_tab(0);
92 }
93 
95  for (const widget_data& row : list_items_) {
96  add_tab_entry(row);
97  }
99 };
100 
102 {
103  listbox& list = get_internal_list();
104  list.add_row(row);
105 }
106 
108 {
109  if (index < get_tab_count()) {
111  generator_->select_item(index, true);
112  }
113 }
114 
117  place(get_origin(), get_size());
118  queue_redraw();
119 
120  fire(event::NOTIFY_MODIFIED, *this, nullptr);
121 }
122 
123 // }---------- DEFINITION ---------{
124 
127 {
128  DBG_GUI_P << "Parsing tab_container " << id;
129 
130  load_resolutions<resolution>(cfg);
131 }
132 
134  : resolution_definition(cfg), grid(nullptr)
135 {
136  // Note the order should be the same as the enum state_t is tab_container.hpp.
137  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_enabled", missing_mandatory_wml_tag("tab_container_definition][resolution", "state_enabled")));
138  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_disabled", missing_mandatory_wml_tag("tab_container_definition][resolution", "state_disabled")));
139 
140  auto child = VALIDATE_WML_CHILD(cfg, "grid", _("No grid defined for tab container control"));
141  grid = std::make_shared<builder_grid>(child);
142 }
143 
144 // }---------- BUILDER -----------{
145 
146 namespace implementation
147 {
148 
149 builder_tab_container::builder_tab_container(const config& cfg)
151 {
152  if (cfg.has_child("tab")) {
153  for(const auto & tab : cfg.child_range("tab"))
154  {
155  widget_data list_row;
156  widget_item item;
157 
158  item["label"] = tab["image"];
159  list_row.emplace("image", item);
160  item["label"] = tab["name"];
161  list_row.emplace("name", item);
162 
163  list_items.emplace_back(list_row);
164 
165  if (tab.has_child("data")) {
166  auto builder = std::make_shared<builder_grid>(tab.mandatory_child("data"));
167  builders.push_back(builder);
168  }
169  }
170  }
171 }
172 
173 std::unique_ptr<widget> builder_tab_container::build() const
174 {
175  auto widget = std::make_unique<tab_container>(*this);
176 
177  const auto conf = widget->cast_config_to<tab_container_definition>();
178  assert(conf);
179 
180  widget->init_grid(*conf->grid);
181 
183  widget->finalize(std::move(generator));
184 
185  DBG_GUI_G << "Window builder: placed tab_container '" << id
186  << "' with definition '" << definition << "'.";
187 
188  return widget;
189 }
190 
191 } // namespace implementation
192 
193 // }------------ END --------------
194 
195 } //
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
Definition: config.cpp:316
child_itors child_range(config_key_type key)
Definition: config.cpp:272
A generic container base class.
const grid & get_grid() const
virtual void place(const point &origin, const point &size) override
See widget::place.
void connect_signal(const F &func, const queue_position position=back_child)
Adds a callback to the appropriate queue based on event type.
Definition: dispatcher.hpp:351
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:74
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.
Definition: generator.cpp:1160
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:280
A container widget that shows one of its pages of widgets depending on which tab the user clicked.
state_t state_
Current state of the widget.
virtual unsigned get_state() const override
Returns the id of the state.
void finalize(std::unique_ptr< generator_base > generator)
Finishes the building initialization of the widget.
generator_base * generator_
Contains a pointer to the generator.
virtual bool get_active() const override
Gets the active state of the styled_widget.
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.
std::vector< std::shared_ptr< builder_grid > > builders_
void select_tab(unsigned index)
std::vector< widget_data > list_items_
listbox & get_internal_list()
Get the listbox inside which the tabs are shown.
unsigned get_active_tab_index()
Base class for all widgets.
Definition: widget.hpp:55
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
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:753
static std::string _(const char *str)
Definition: gettext.hpp:93
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...
@ NOTIFY_MODIFIED
Definition: handler.hpp:158
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.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
#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)
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)