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