The Battle for Wesnoth  1.17.0-dev
wml_message.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
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  set_restore(true);
62 
63  window.get_canvas(1).set_variable("portrait_image", wfl::variant(portrait_));
64  window.get_canvas(1).set_variable("portrait_mirror", wfl::variant(mirror_));
65 
66  // Set the markup
67  label& title = find_widget<label>(&window, "title", false);
68  title.set_label(title_);
69  title.set_use_markup(true);
70  title.set_can_wrap(true);
71 
72  styled_widget& message = find_widget<styled_widget>(&window, "message", false);
73  message.set_label(message_);
74  message.set_use_markup(true);
75  // The message label might not always be a scroll_label but the capturing
76  // shouldn't hurt.
77  window.keyboard_capture(&message);
78 
79  // Find the input box related fields.
80  label& caption = find_widget<label>(&window, "input_caption", false);
81  text_box& input = find_widget<text_box>(&window, "input", true);
82 
83  if(has_input_) {
84  caption.set_label(input_caption_);
85  caption.set_use_markup(true);
86  input.set_value(*input_text_);
87  input.set_maximum_length(input_maximum_length_);
88  window.keyboard_capture(&input);
89  window.set_click_dismiss(false);
90  window.set_escape_disabled(true);
91  } else {
93  input.set_visible(widget::visibility::invisible);
94  }
95 
96  // Find the option list related fields.
97  listbox& options = find_widget<listbox>(&window, "input_list", true);
98 
99  if(!option_list_.empty()) {
100  std::map<std::string, string_map> data;
101  for(const wml_message_option& item : option_list_) {
102  // Add the data.
103  data["icon"]["label"] = item.image();
104  data["label"]["label"] = item.label();
105  data["label"]["use_markup"] = "true";
106  data["description"]["label"] = item.description();
107  data["description"]["use_markup"] = "true";
108  options.add_row(data);
109  }
110 
111  // Avoid negative and 0 since item 0 is already selected.
112  if(*chosen_option_ > 0 && static_cast<std::size_t>(*chosen_option_)
113  < option_list_.size()) {
114 
115  options.select_row(*chosen_option_);
116  }
117 
118  if(!has_input_) {
119  window.keyboard_capture(&options);
120  window.set_click_dismiss(false);
121  window.set_escape_disabled(true);
122  } else {
123  window.add_to_keyboard_chain(&options);
124  // click_dismiss has been disabled due to the input.
125  }
126  } else {
128  }
129  window.set_click_dismiss(!has_input_ && option_list_.empty());
130 }
131 
133 {
134  if(has_input_) {
135  *input_text_
136  = find_widget<text_box>(&window, "input", true).get_value();
137  }
138 
139  if(!option_list_.empty()) {
140  *chosen_option_ = find_widget<listbox>(&window, "input_list", true)
141  .get_selected_row();
142  }
143 }
144 
146 {
148  window.get_canvas(1).set_variable("second_portrait_image", wfl::variant(second_portrait_));
149  window.get_canvas(1).set_variable("second_portrait_mirror", wfl::variant(second_mirror_));
150 }
151 
153 
155 
157 
158 int show_wml_message(const std::string& title,
159  const std::string& message,
160  const wml_message_portrait* left,
163  const wml_message_input& input)
164 {
165  std::shared_ptr<wml_message_base> dlg;
166  if(left && !right) {
167  dlg.reset(new wml_message_left(title, message, left->portrait, left->mirror));
168  } else if(!left && right) {
169  dlg.reset(new wml_message_right(title, message, right->portrait, right->mirror));
170  } else if(right && left) {
171  dlg.reset(new wml_message_double(title, message, left->portrait, left->mirror, right->portrait, right->mirror));
172  }
173  assert(dlg.get());
174 
175  if(input.text_input_was_specified) {
176  dlg->set_input(input.caption, &input.text, input.maximum_length);
177  }
178 
179  if(!options.option_list.empty()) {
180  dlg->set_option_list(options.option_list, &options.chosen_option);
181  }
182 
183  dlg->show();
184  return dlg->get_retval();
185 }
186 
187 } // namespace dialogs
Parameter pack for message portrait.
std::string portrait_
Filename of the portrait.
void set_can_wrap(const bool wrap)
Definition: label.hpp:120
std::string title_
The title for the dialog.
Definition: wml_message.hpp:90
void set_variable(const std::string &key, wfl::variant &&value)
Definition: canvas.hpp:168
std::vector< wml_message_option > option_list_
The list of options the user can choose.
Main class to show messages to the user.
Definition: message.hpp:35
std::string input_caption_
The caption to show for the input text.
This file contains the window object, this object is a top level container which has the event manage...
Parameter pack for message list input options.
STL namespace.
A label displays a text, the text can be wrapped but no scrollbars are provided.
Definition: label.hpp:57
bool select_row(const unsigned row, const bool select=true)
Selects a row.
Definition: listbox.cpp:252
Class for a single line text area.
Definition: text_box.hpp:141
virtual void set_label(const t_string &label)
The listbox class.
Definition: listbox.hpp:43
Shows a dialog with the portrait on the left side.
const config & options()
Definition: game.cpp:569
unsigned input_maximum_length_
The maximum length of the input text.
This file contains the settings handling of the widget library.
void set_visible(const visibility visible)
Definition: widget.cpp:476
void set_option_list(const std::vector< wml_message_option > &option_list, int *chosen_option)
Sets the option list.
Definition: wml_message.cpp:43
virtual void set_use_markup(bool use_markup)
void set_input(const std::string &caption, std::string *text, const unsigned maximum_length)
Sets the input text variables.
Definition: wml_message.cpp:31
lu_byte right
Definition: lparser.cpp:1227
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
bool has_input_
Do we need to show an input box?
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.
bool mirror_
Mirror the portrait?
The user set the widget invisible, that means:
virtual void pre_show(window &window) override
Helper class for message options.
Definition: wml_message.hpp:26
virtual void pre_show(window &window) override
Definition: wml_message.cpp:59
std::string message_
The message to show to the user.
grid & add_row(const string_map &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:68
Shows a dialog with two portraits, one on each side.
Base class for all visible items.
lu_byte left
Definition: lparser.cpp:1226
std::string * input_text_
The text input.
int * chosen_option_
The chosen option.
canvas & get_canvas(const unsigned index)
Shows a dialog with the portrait on the right side.
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
void set_restore(const bool restore)
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:410
Parameter pack for message text input options.