The Battle for Wesnoth  1.15.12+dev
wml_message.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
20 #include "gui/widgets/button.hpp"
21 #include "gui/widgets/label.hpp"
22 #include "gui/widgets/listbox.hpp"
23 #include "gui/widgets/settings.hpp"
24 #include "gui/widgets/text_box.hpp"
25 #include "gui/widgets/window.hpp"
26 
27 namespace gui2::dialogs
28 {
29 
30 void wml_message_base::set_input(const std::string& caption,
31  std::string* text,
32  const unsigned maximum_length)
33 {
34  assert(text);
35 
36  has_input_ = true;
37  input_caption_ = caption;
38  input_text_ = text;
39  input_maximum_length_ = maximum_length;
40 }
41 
42 void wml_message_base::set_option_list(const std::vector<wml_message_option>& option_list,
43  int* chosen_option)
44 {
45  assert(!option_list.empty());
46  assert(chosen_option);
47 
48  option_list_ = option_list;
49  chosen_option_ = chosen_option;
50 }
51 
52 /**
53  * @todo This function enables the wml markup for all items, but the interface
54  * is a bit hacky. Especially the fiddling in the internals of the listbox is
55  * ugly. There needs to be a clean interface to set whether a widget has a
56  * markup and what kind of markup. These fixes will be post 1.6.
57  */
59 {
60  set_restore(true);
61 
62  window.get_canvas(1).set_variable("portrait_image", wfl::variant(portrait_));
63  window.get_canvas(1).set_variable("portrait_mirror", wfl::variant(mirror_));
64 
65  // Set the markup
66  label& title = find_widget<label>(&window, "title", false);
67  title.set_label(title_);
68  title.set_use_markup(true);
69  title.set_can_wrap(true);
70 
71  styled_widget& message = find_widget<styled_widget>(&window, "message", false);
72  message.set_label(message_);
73  message.set_use_markup(true);
74  // The message label might not always be a scroll_label but the capturing
75  // shouldn't hurt.
76  window.keyboard_capture(&message);
77 
78  // Find the input box related fields.
79  label& caption = find_widget<label>(&window, "input_caption", false);
80  text_box& input = find_widget<text_box>(&window, "input", true);
81 
82  if(has_input_) {
83  caption.set_label(input_caption_);
84  caption.set_use_markup(true);
85  input.set_value(*input_text_);
86  input.set_maximum_length(input_maximum_length_);
87  window.keyboard_capture(&input);
88  window.set_click_dismiss(false);
89  window.set_escape_disabled(true);
90  } else {
92  input.set_visible(widget::visibility::invisible);
93  }
94 
95  // Find the option list related fields.
96  listbox& options = find_widget<listbox>(&window, "input_list", true);
97 
98  if(!option_list_.empty()) {
99  std::map<std::string, string_map> data;
100  for(const wml_message_option& item : option_list_) {
101  // Add the data.
102  data["icon"]["label"] = item.image();
103  data["label"]["label"] = item.label();
104  data["label"]["use_markup"] = "true";
105  data["description"]["label"] = item.description();
106  data["description"]["use_markup"] = "true";
107  options.add_row(data);
108  }
109 
110  // Avoid negative and 0 since item 0 is already selected.
111  if(*chosen_option_ > 0 && static_cast<std::size_t>(*chosen_option_)
112  < option_list_.size()) {
113 
114  options.select_row(*chosen_option_);
115  }
116 
117  if(!has_input_) {
118  window.keyboard_capture(&options);
119  window.set_click_dismiss(false);
120  window.set_escape_disabled(true);
121  } else {
122  window.add_to_keyboard_chain(&options);
123  // click_dismiss has been disabled due to the input.
124  }
125  } else {
127  }
128  window.set_click_dismiss(!has_input_ && option_list_.empty());
129 }
130 
132 {
133  if(has_input_) {
134  *input_text_
135  = find_widget<text_box>(&window, "input", true).get_value();
136  }
137 
138  if(!option_list_.empty()) {
139  *chosen_option_ = find_widget<listbox>(&window, "input_list", true)
140  .get_selected_row();
141  }
142 }
143 
145 {
147  window.get_canvas(1).set_variable("second_portrait_image", wfl::variant(second_portrait_));
148  window.get_canvas(1).set_variable("second_portrait_mirror", wfl::variant(second_mirror_));
149 }
150 
152 
154 
156 
157 int show_wml_message(const std::string& title,
158  const std::string& message,
159  const wml_message_portrait* left,
162  const wml_message_input& input)
163 {
164  std::shared_ptr<wml_message_base> dlg;
165  if(left && !right) {
166  dlg.reset(new wml_message_left(title, message, left->portrait, left->mirror));
167  } else if(!left && right) {
168  dlg.reset(new wml_message_right(title, message, right->portrait, right->mirror));
169  } else if(right && left) {
170  dlg.reset(new wml_message_double(title, message, left->portrait, left->mirror, right->portrait, right->mirror));
171  }
172  assert(dlg.get());
173 
174  if(input.text_input_was_specified) {
175  dlg->set_input(input.caption, &input.text, input.maximum_length);
176  }
177 
178  if(!options.option_list.empty()) {
179  dlg->set_option_list(options.option_list, &options.chosen_option);
180  }
181 
182  dlg->show();
183  return dlg->get_retval();
184 }
185 
186 } // namespace dialogs
Parameter pack for message portrait.
std::string portrait_
Filename of the portrait.
void set_can_wrap(const bool wrap)
Definition: label.hpp:119
std::string title_
The title for the dialog.
Definition: wml_message.hpp:89
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:34
std::string input_caption_
The caption to show for the input text.
void set_variable(const std::string &key, const wfl::variant &value)
Definition: canvas.hpp:167
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:56
bool select_row(const unsigned row, const bool select=true)
Selects a row.
Definition: listbox.cpp:251
Class for a single line text area.
Definition: text_box.hpp:140
virtual void set_label(const t_string &label)
The listbox class.
Definition: listbox.hpp:42
Shows a dialog with the portrait on the left side.
const config & options()
Definition: game.cpp:563
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:475
void set_option_list(const std::vector< wml_message_option > &option_list, int *chosen_option)
Sets the option list.
Definition: wml_message.cpp:42
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:30
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:25
virtual void pre_show(window &window) override
Definition: wml_message.cpp:58
std::string message_
The message to show to the user.
Definition: wml_message.hpp:99
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:67
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:64
void set_restore(const bool restore)
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:409
Parameter pack for message text input options.