The Battle for Wesnoth  1.15.2+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
28 {
29 namespace dialogs
30 {
31 
32 void wml_message_base::set_input(const std::string& caption,
33  std::string* text,
34  const unsigned maximum_length)
35 {
36  assert(text);
37 
38  has_input_ = true;
39  input_caption_ = caption;
40  input_text_ = text;
41  input_maximum_length_ = maximum_length;
42 }
43 
44 void wml_message_base::set_option_list(const std::vector<wml_message_option>& option_list,
45  int* chosen_option)
46 {
47  assert(!option_list.empty());
48  assert(chosen_option);
49 
50  option_list_ = option_list;
51  chosen_option_ = chosen_option;
52 }
53 
54 /**
55  * @todo This function enables the wml markup for all items, but the interface
56  * is a bit hacky. Especially the fiddling in the internals of the listbox is
57  * ugly. There needs to be a clean interface to set whether a widget has a
58  * markup and what kind of markup. These fixes will be post 1.6.
59  */
61 {
62  set_restore(true);
63 
64  window.get_canvas(1).set_variable("portrait_image", wfl::variant(portrait_));
65  window.get_canvas(1).set_variable("portrait_mirror", wfl::variant(mirror_));
66 
67  // Set the markup
68  label& title = find_widget<label>(&window, "title", false);
69  title.set_label(title_);
70  title.set_use_markup(true);
71  title.set_can_wrap(true);
72 
73  styled_widget& message = find_widget<styled_widget>(&window, "message", false);
74  message.set_label(message_);
75  message.set_use_markup(true);
76  // The message label might not always be a scroll_label but the capturing
77  // shouldn't hurt.
78  window.keyboard_capture(&message);
79 
80  // Find the input box related fields.
81  label& caption = find_widget<label>(&window, "input_caption", false);
82  text_box& input = find_widget<text_box>(&window, "input", true);
83 
84  if(has_input_) {
85  caption.set_label(input_caption_);
86  caption.set_use_markup(true);
87  input.set_value(*input_text_);
88  input.set_maximum_length(input_maximum_length_);
89  window.keyboard_capture(&input);
90  window.set_click_dismiss(false);
91  window.set_escape_disabled(true);
92  } else {
94  input.set_visible(widget::visibility::invisible);
95  }
96 
97  // Find the option list related fields.
98  listbox& options = find_widget<listbox>(&window, "input_list", true);
99 
100  if(!option_list_.empty()) {
101  std::map<std::string, string_map> data;
102  for(const wml_message_option& item : option_list_) {
103  // Add the data.
104  data["icon"]["label"] = item.image();
105  data["label"]["label"] = item.label();
106  data["label"]["use_markup"] = "true";
107  data["description"]["label"] = item.description();
108  data["description"]["use_markup"] = "true";
109  options.add_row(data);
110  }
111 
112  // Avoid negative and 0 since item 0 is already selected.
113  if(*chosen_option_ > 0 && static_cast<std::size_t>(*chosen_option_)
114  < option_list_.size()) {
115 
116  options.select_row(*chosen_option_);
117  }
118 
119  if(!has_input_) {
120  window.keyboard_capture(&options);
121  window.set_click_dismiss(false);
122  window.set_escape_disabled(true);
123  } else {
124  window.add_to_keyboard_chain(&options);
125  // click_dismiss has been disabled due to the input.
126  }
127  } else {
129  }
130  window.set_click_dismiss(!has_input_ && option_list_.empty());
131 }
132 
134 {
135  if(has_input_) {
136  *input_text_
137  = find_widget<text_box>(&window, "input", true).get_value();
138  }
139 
140  if(!option_list_.empty()) {
141  *chosen_option_ = find_widget<listbox>(&window, "input_list", true)
142  .get_selected_row();
143  }
144 }
145 
147 {
149  window.get_canvas(1).set_variable("second_portrait_image", wfl::variant(second_portrait_));
150  window.get_canvas(1).set_variable("second_portrait_mirror", wfl::variant(second_mirror_));
151 }
152 
154 
156 
158 
159 int show_wml_message(const std::string& title,
160  const std::string& message,
161  const wml_message_portrait* left,
164  const wml_message_input& input)
165 {
166  std::shared_ptr<wml_message_base> dlg;
167  if(left && !right) {
168  dlg.reset(new wml_message_left(title, message, left->portrait, left->mirror));
169  } else if(!left && right) {
170  dlg.reset(new wml_message_right(title, message, right->portrait, right->mirror));
171  } else if(right && left) {
172  dlg.reset(new wml_message_double(title, message, left->portrait, left->mirror, right->portrait, right->mirror));
173  }
174  assert(dlg.get());
175 
176  if(input.text_input_was_specified) {
177  dlg->set_input(input.caption, &input.text, input.maximum_length);
178  }
179 
180  if(!options.option_list.empty()) {
181  dlg->set_option_list(options.option_list, &options.chosen_option);
182  }
183 
184  dlg->show();
185  return dlg->get_retval();
186 }
187 
188 } // namespace dialogs
189 } // namespace gui2
Parameter pack for message portrait.
std::string portrait_
Filename of the portrait.
void set_can_wrap(const bool wrap)
Definition: label.hpp:65
std::string title_
The title for the dialog.
Definition: wml_message.hpp:91
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:171
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.
Label showing a text.
Definition: label.hpp:32
bool select_row(const unsigned row, const bool select=true)
Selects a row.
Definition: listbox.cpp:250
Class for a single line text area.
Definition: text_box.hpp:121
Generic file dialog.
Definition: field-fwd.hpp:22
virtual void set_label(const t_string &label)
The listbox class.
Definition: listbox.hpp:40
Shows a dialog with the portrait on the left side.
const config & options()
Definition: game.cpp:579
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:473
void set_option_list(const std::vector< wml_message_option > &option_list, int *chosen_option)
Sets the option list.
Definition: wml_message.cpp:44
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:32
Various uncategorised dialogs.
lu_byte right
Definition: lparser.cpp:1027
virtual void post_show(window &window) override
Inherited from modal_dialog.
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
Inherited from modal_dialog.
Helper class for message options.
Definition: wml_message.hpp:27
virtual void pre_show(window &window) override
Inherited from modal_dialog.
Definition: wml_message.cpp:60
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:66
Shows a dialog with two portraits, one on each side.
Base class for all visible items.
lu_byte left
Definition: lparser.cpp:1026
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:63
void set_restore(const bool restore)
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:371
Parameter pack for message text input options.