The Battle for Wesnoth  1.19.0-dev
spinner.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2023 - 2024
3  by babaissarkar(Subhraman Sarkar) <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 
18 #include "gui/widgets/spinner.hpp"
19 
22 #include "gui/widgets/text_box.hpp"
23 #include "gui/core/log.hpp"
25 #include "gui/widgets/window.hpp"
26 #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 
34 namespace gui2
35 {
36 
37 // ------------ WIDGET -----------{
38 
39 REGISTER_WIDGET(spinner)
40 
41 spinner::spinner(const implementation::builder_spinner& builder)
42  : container_base(builder, type())
43  , state_(ENABLED)
44  , step_size_(1)
45  , invalid_(false)
46 {
47  connect_signal<event::LEFT_BUTTON_DOWN>(
48  std::bind(&spinner::signal_handler_left_button_down, this, std::placeholders::_2),
50 }
51 
53 {
54  return find_widget<text_box>(this, "_text", false, true);
55 }
56 
57 void spinner::set_value(const int val)
58 {
59  text_box* edit_area = get_internal_text_box();
60  if (edit_area != nullptr) {
61  edit_area->set_value(std::to_string(val));
62  }
63 }
64 
66 {
67  /* Return 0 if invalid.
68  * TODO: give visual indication of wrong value
69  */
70  int val;
71  try {
72  text_box* edit_area = get_internal_text_box();
73  if (edit_area != nullptr) {
74  val = stoi(edit_area->get_value());
75  invalid_ = false;
76  } else {
77  val = 0;
78  invalid_ = true;
79  }
80  } catch(std::invalid_argument const& /*ex*/) {
81  val = 0;
82  invalid_ = true;
83  } catch(std::out_of_range const& /*ex*/) {
84  val = 0;
85  invalid_ = true;
86  }
87 
88  return val;
89 }
90 
92 {
93  repeating_button* btn_prev = find_widget<repeating_button>(this, "_prev", false, true);
94  repeating_button* btn_next = find_widget<repeating_button>(this, "_next", false, true);
95  btn_prev->connect_signal_mouse_left_down(std::bind(&spinner::prev, this));
96  btn_next->connect_signal_mouse_left_down(std::bind(&spinner::next, this));
97 
98 }
99 
100 void spinner::set_self_active(const bool active)
101 {
102  state_ = active ? ENABLED : DISABLED;
103 }
104 
106 {
107  return state_ != DISABLED;
108 }
109 
110 unsigned spinner::get_state() const
111 {
112  return state_;
113 }
114 
115 bool spinner::can_wrap() const
116 {
117  return true;
118 }
119 
121 {
122  DBG_GUI_E << LOG_HEADER << ' ' << event << ".";
123 
124  get_window()->keyboard_capture(this);
125 }
126 
127 // }---------- DEFINITION ---------{
128 
131 {
132  DBG_GUI_P << "Parsing spinner " << id;
133 
134  load_resolutions<resolution>(cfg);
135 }
136 
138  : resolution_definition(cfg), grid(nullptr)
139 {
140  // Note the order should be the same as the enum state_t is spinner.hpp.
141  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_enabled", missing_mandatory_wml_tag("spinner", "state_enabled")));
142  state.emplace_back(VALIDATE_WML_CHILD(cfg, "state_disabled", missing_mandatory_wml_tag("spinner", "state_disabled")));
143 
144  auto child = VALIDATE_WML_CHILD(cfg, "grid", missing_mandatory_wml_tag("spinner", "grid"));
145  grid = std::make_shared<builder_grid>(child);
146 }
147 
148 // }---------- BUILDER -----------{
149 
150 namespace implementation
151 {
152 
153 builder_spinner::builder_spinner(const config& cfg)
155 {
156 }
157 
158 std::unique_ptr<widget> builder_spinner::build() const
159 {
160  auto widget = std::make_unique<spinner>(*this);
161 
162  const auto conf = widget->cast_config_to<spinner_definition>();
163  assert(conf);
164 
165  widget->init_grid(*conf->grid);
166  widget->finalize_setup();
167 
168  DBG_GUI_G << "Window builder: placed spinner '" << id
169  << "' with definition '" << definition << "'.";
170 
171  return widget;
172 }
173 
174 } // namespace implementation
175 
176 // }------------ END --------------
177 
178 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
A generic container base class.
Base container class.
Definition: grid.hpp:32
A repeating_button is a control that can be pushed down and repeat a certain action.
void connect_signal_mouse_left_down(const event::signal &signal)
Connects a signal handler for a left mouse button down.
Spinner widget.
Definition: spinner.hpp:67
void prev()
Definition: spinner.hpp:90
bool invalid_
If the entered data is invalid.
Definition: spinner.hpp:141
void next()
Definition: spinner.hpp:102
int get_value()
Definition: spinner.cpp:65
state_t state_
Current state of the widget.
Definition: spinner.hpp:133
void finalize_setup()
Definition: spinner.cpp:91
void set_value(const int val)
Definition: spinner.cpp:57
void signal_handler_left_button_down(const event::ui_event event)
Definition: spinner.cpp:120
virtual bool get_active() const override
See styled_widget::get_active.
Definition: spinner.cpp:105
text_box * get_internal_text_box()
Definition: spinner.cpp:52
bool can_wrap() const override
See widget::can_wrap.
Definition: spinner.cpp:115
virtual void set_self_active(const bool active) override
See container_base::set_self_active.
Definition: spinner.cpp:100
virtual unsigned get_state() const override
See styled_widget::get_state.
Definition: spinner.cpp:110
std::string get_value() const
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
Class for a single line text area.
Definition: text_box.hpp:142
Base class for all widgets.
Definition: widget.hpp:53
window * get_window()
Get the parent window.
Definition: widget.cpp:117
void keyboard_capture(widget *widget)
Definition: window.cpp:1221
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
#define DBG_GUI_E
Definition: log.hpp:35
This file contains the window object, this object is a top level container which has the event manage...
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
Generic file dialog.
Contains the implementation details for lexical_cast and shouldn't be used directly.
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
#define LOG_HEADER
Definition: spinner.cpp:32
virtual std::unique_ptr< widget > build() const override
Definition: spinner.cpp:158
std::string definition
Parameters for the styled_widget.
Base class of a resolution, contains the common keys for a resolution.
std::vector< state_definition > state
spinner_definition(const config &cfg)
Definition: spinner.cpp:129
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)