The Battle for Wesnoth  1.17.17+dev
wml_message.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2023
3  by Mark de Wever <koraq@xs4all.nl>
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 
21 #include "gui/widgets/button.hpp"
22 #include "gui/widgets/label.hpp"
23 #include "gui/widgets/listbox.hpp"
24 #include "gui/widgets/settings.hpp"
25 #include "gui/widgets/text_box.hpp"
26 #include "gui/widgets/window.hpp"
27 
28 namespace gui2::dialogs
29 {
30 
31 void wml_message_base::set_input(const std::string& caption,
32  std::string* text,
33  const unsigned maximum_length)
34 {
35  assert(text);
36 
37  has_input_ = true;
38  input_caption_ = caption;
39  input_text_ = text;
40  input_maximum_length_ = maximum_length;
41 }
42 
43 void wml_message_base::set_option_list(const std::vector<wml_message_option>& option_list,
44  int* chosen_option)
45 {
46  assert(!option_list.empty());
47  assert(chosen_option);
48 
49  option_list_ = option_list;
50  chosen_option_ = chosen_option;
51 }
52 
53 /**
54  * @todo This function enables the wml markup for all items, but the interface
55  * is a bit hacky. Especially the fiddling in the internals of the listbox is
56  * ugly. There needs to be a clean interface to set whether a widget has a
57  * markup and what kind of markup. These fixes will be post 1.6.
58  */
60 {
61  window.get_canvas(1).set_variable("portrait_image", wfl::variant(portrait_));
62  window.get_canvas(1).set_variable("portrait_mirror", wfl::variant(mirror_));
63 
64  // Set the markup
65  label& title = find_widget<label>(&window, "title", false);
66  title.set_label(title_);
67  title.set_use_markup(true);
68  title.set_can_wrap(true);
69 
70  styled_widget& message = find_widget<styled_widget>(&window, "message", false);
72  message.set_use_markup(true);
73  // The message label might not always be a scroll_label but the capturing
74  // shouldn't hurt.
76 
77  // Find the input box related fields.
78  label& caption = find_widget<label>(&window, "input_caption", false);
79  text_box& input = find_widget<text_box>(&window, "input", true);
80 
81  if(has_input_) {
82  caption.set_label(input_caption_);
83  caption.set_use_markup(true);
84  input.set_value(*input_text_);
86  window.keyboard_capture(&input);
89  } else {
92  }
93 
94  // Find the option list related fields.
95  listbox& options = find_widget<listbox>(&window, "input_list", true);
96 
97  if(!option_list_.empty()) {
99  for(const wml_message_option& item : option_list_) {
100  // Add the data.
101  data["icon"]["label"] = item.image();
102  data["label"]["label"] = item.label();
103  data["label"]["use_markup"] = "true";
104  data["description"]["label"] = item.description();
105  data["description"]["use_markup"] = "true";
106  options.add_row(data);
107  }
108 
109  // Avoid negative and 0 since item 0 is already selected.
110  if(*chosen_option_ > 0 && static_cast<std::size_t>(*chosen_option_)
111  < option_list_.size()) {
112 
113  options.select_row(*chosen_option_);
114  }
115 
116  if(!has_input_) {
118  window.set_click_dismiss(false);
120  } else {
122  // click_dismiss has been disabled due to the input.
123  }
124  } else {
126  }
128 }
129 
131 {
132  if(has_input_) {
133  *input_text_
134  = find_widget<text_box>(&window, "input", true).get_value();
135  }
136 
137  if(!option_list_.empty()) {
138  *chosen_option_ = find_widget<listbox>(&window, "input_list", true)
139  .get_selected_row();
140  }
141 }
142 
144 {
146  window.get_canvas(1).set_variable("second_portrait_image", wfl::variant(second_portrait_));
147  window.get_canvas(1).set_variable("second_portrait_mirror", wfl::variant(second_mirror_));
148 }
149 
151 
153 
155 
156 int show_wml_message(const std::string& title,
157  const std::string& message,
158  const wml_message_portrait* left,
159  const wml_message_portrait* right,
161  const wml_message_input& input)
162 {
163  std::shared_ptr<wml_message_base> dlg;
164  if(left && !right) {
165  dlg.reset(new wml_message_left(title, message, left->portrait, left->mirror));
166  } else if(!left && right) {
167  dlg.reset(new wml_message_right(title, message, right->portrait, right->mirror));
168  } else if(right && left) {
169  dlg.reset(new wml_message_double(title, message, left->portrait, left->mirror, right->portrait, right->mirror));
170  }
171  assert(dlg.get());
172 
173  if(input.text_input_was_specified) {
174  dlg->set_input(input.caption, &input.text, input.maximum_length);
175  }
176 
177  if(!options.option_list.empty()) {
178  dlg->set_option_list(options.option_list, &options.chosen_option);
179  }
180 
181  dlg->show();
182  return dlg->get_retval();
183 }
184 
185 } // namespace dialogs
bool empty() const
Definition: config.cpp:856
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:137
Main class to show messages to the user.
Definition: message.hpp:36
std::string * input_text_
The text input.
std::string portrait_
Filename of the portrait.
std::string message_
The message to show to the user.
void set_input(const std::string &caption, std::string *text, const unsigned maximum_length)
Sets the input text variables.
Definition: wml_message.cpp:31
bool has_input_
Do we need to show an input box?
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
unsigned input_maximum_length_
The maximum length of the input text.
bool mirror_
Mirror the portrait?
int * chosen_option_
The chosen option.
std::string input_caption_
The caption to show for the input text.
void set_option_list(const std::vector< wml_message_option > &option_list, int *chosen_option)
Sets the option list.
Definition: wml_message.cpp:43
std::string title_
The title for the dialog.
Definition: wml_message.hpp:93
std::vector< wml_message_option > option_list_
The list of options the user can choose.
virtual void pre_show(window &window) override
Definition: wml_message.cpp:59
Shows a dialog with two portraits, one on each side.
virtual void pre_show(window &window) override
Shows a dialog with the portrait on the left side.
Helper class for message options.
Definition: wml_message.hpp:26
Shows a dialog with the portrait on the right side.
A label displays a text, the text can be wrapped but no scrollbars are provided.
Definition: label.hpp:58
void set_can_wrap(const bool wrap)
Definition: label.hpp:120
The listbox class.
Definition: listbox.hpp:46
Base class for all visible items.
virtual void set_label(const t_string &label)
canvas & get_canvas(const unsigned index)
virtual void set_use_markup(bool use_markup)
virtual void set_value(const std::string &text)
The set_value is virtual for the password_box class.
void set_maximum_length(const std::size_t maximum_length)
Class for a single line text area.
Definition: text_box.hpp:142
void set_visible(const visibility visible)
Definition: widget.cpp:456
@ invisible
The user set the widget invisible, that means:
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:67
void keyboard_capture(widget *widget)
Definition: window.cpp:1130
void add_to_keyboard_chain(widget *widget)
Adds the widget to the keyboard chain.
Definition: window.cpp:1136
void set_escape_disabled(const bool escape_disabled)
Disable the escape key.
Definition: window.hpp:299
void set_click_dismiss(const bool click_dismiss)
Definition: window.hpp:375
This file contains the window object, this object is a top level container which has the event manage...
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
int show_wml_message(const std::string &title, const std::string &message, const wml_message_portrait *left, const wml_message_portrait *right, const wml_message_options &options, const wml_message_input &input)
Helper function to show a portrait.
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:35
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:414
const config & options()
Definition: game.cpp:555
std::string_view data
Definition: picture.cpp:199
This file contains the settings handling of the widget library.
Parameter pack for message text input options.
Parameter pack for message list input options.
Parameter pack for message portrait.