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 #pragma once
16 
17 #include "gui/dialogs/modal_dialog.hpp"
18 
19 namespace gui2
20 {
21 namespace dialogs
22 {
23 
24 /**
25  *  Helper class for message options
26  */
27 class wml_message_option {
28 public:
wml_message_option(std::string label,std::string description="",std::string image="")29 	explicit wml_message_option(std::string label, std::string description = "", std::string image = "")
30 		: label_(label)
31 		, description_(description)
32 		, image_(image)
33 	{}
label() const34 	std::string label() const {return label_;}
description() const35 	std::string description() const {return description_;}
image() const36 	std::string image() const {return image_;}
37 private:
38 	std::string label_, description_, image_;
39 };
40 
41 /**
42  * Base class for the wml generated messages.
43  *
44  * We have a separate sub class for left and right images.
45  */
46 class wml_message_base : public modal_dialog
47 {
48 public:
wml_message_base(const std::string & title,const std::string & message,const std::string & portrait,const bool mirror)49 	wml_message_base(const std::string& title,
50 				  const std::string& message,
51 				  const std::string& portrait,
52 				  const bool mirror)
53 		: title_(title)
54 		, image_("")
55 		, message_(message)
56 		, portrait_(portrait)
57 		, mirror_(mirror)
58 		, has_input_(false)
59 		, input_caption_("")
60 		, input_text_(nullptr)
61 		, input_maximum_length_(0)
62 		, option_list_()
63 		, chosen_option_(nullptr)
64 	{
65 	}
66 
67 	/**
68 	 * Sets the input text variables.
69 	 *
70 	 * @param caption             The caption for the label.
71 	 * @param [in,out] text       The initial text, after showing the final
72 	 *                            text.
73 	 * @param maximum_length      The maximum length of the text.
74 	 */
75 	void set_input(const std::string& caption,
76 				   std::string* text,
77 				   const unsigned maximum_length);
78 	/**
79 	 * Sets the option list
80 	 *
81 	 * @param option_list            The list of options to display.
82 	 * @param [in,out] chosen_option Pointer to the index of the initially
83 	 *                               selected option; after showing, the
84 	 *                               chosen option.
85 	 */
86 	void set_option_list(const std::vector<wml_message_option>& option_list,
87 						 int* chosen_option);
88 
89 private:
90 	/** The title for the dialog. */
91 	std::string title_;
92 
93 	/**
94 	 * The image which is shown in the dialog.
95 	 *
96 	 * This image can be an icon or portrait or any other image.
97 	 */
98 	std::string image_;
99 
100 	/** The message to show to the user. */
101 	std::string message_;
102 	/** Filename of the portrait. */
103 	std::string portrait_;
104 
105 	/** Mirror the portrait? */
106 	bool mirror_;
107 
108 	/** Do we need to show an input box? */
109 	bool has_input_;
110 
111 	/** The caption to show for the input text. */
112 	std::string input_caption_;
113 
114 	/** The text input. */
115 	std::string* input_text_;
116 
117 	/** The maximum length of the input text. */
118 	unsigned input_maximum_length_;
119 
120 	/** The list of options the user can choose. */
121 	std::vector<wml_message_option> option_list_;
122 
123 	/** The chosen option. */
124 	int* chosen_option_;
125 
126 protected:
127 	/** Inherited from modal_dialog. */
128 	virtual void pre_show(window& window) override;
129 
130 private:
131 	/** Inherited from modal_dialog. */
132 	virtual void post_show(window& window) override;
133 };
134 
135 /** Shows a dialog with the portrait on the left side. */
136 class wml_message_left : public wml_message_base
137 {
138 public:
wml_message_left(const std::string & title,const std::string & message,const std::string & portrait,const bool mirror)139 	wml_message_left(const std::string& title,
140 					  const std::string& message,
141 					  const std::string& portrait,
142 					  const bool mirror)
143 		: wml_message_base(title, message, portrait, mirror)
144 	{
145 	}
146 
147 private:
148 	/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
149 	virtual const std::string& window_id() const override;
150 };
151 
152 /** Shows a dialog with the portrait on the right side. */
153 class wml_message_right : public wml_message_base
154 {
155 public:
wml_message_right(const std::string & title,const std::string & message,const std::string & portrait,const bool mirror)156 	wml_message_right(const std::string& title,
157 					   const std::string& message,
158 					   const std::string& portrait,
159 					   const bool mirror)
160 		: wml_message_base(title, message, portrait, mirror)
161 	{
162 	}
163 
164 private:
165 	/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
166 	virtual const std::string& window_id() const override;
167 };
168 
169 /** Shows a dialog with two portraits, one on each side. */
170 class wml_message_double : public wml_message_left
171 {
172 public:
wml_message_double(const std::string & title,const std::string & message,const std::string & portrait,const bool mirror,const std::string & second_portrait,const bool second_mirror)173 	wml_message_double(const std::string& title,
174 					   const std::string& message,
175 					   const std::string& portrait,
176 					   const bool mirror,
177 					   const std::string& second_portrait,
178 					   const bool second_mirror)
179 		: wml_message_left(title, message, portrait, mirror)
180 		, second_portrait_(second_portrait)
181 		, second_mirror_(second_mirror)
182 	{
183 	}
184 
185 private:
186 	/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
187 	virtual const std::string& window_id() const override;
188 
189 	/** Inherited from modal_dialog. */
190 	virtual void pre_show(window& window) override;
191 
192 	std::string second_portrait_;
193 
194 	bool second_mirror_;
195 };
196 
197 /**
198  * Parameter pack for message list input options
199  */
200 struct wml_message_options
201 {
202 	/// A list of options to select in the dialog.
203 	std::vector<wml_message_option> option_list;
204 	/// The initially chosen option.
205 	/// Will be set to the chosen option when the dialog closes.
206 	mutable int chosen_option;
207 };
208 
209 /**
210  * Parameter pack for message text input options
211  */
212 struct wml_message_input
213 {
214 	/// The caption for the optional input text box.
215 	/// If empty, there is no input box.
216 	std::string caption;
217 	/// The initial text value.
218 	/// Will be set to the result.
219 	mutable std::string text;
220 	/// The maximum length of the text.
221 	unsigned maximum_length;
222 	/// True when [text_input] appeared in [message]
223 	bool text_input_was_specified;
224 };
225 
226 /**
227  * Parameter pack for message portrait
228  */
229 struct wml_message_portrait
230 {
231 	/// Filename of the portrait.
232 	std::string portrait;
233 	/// Does the portrait need to be mirrored?
234 	bool mirror;
235 };
236 
237 /**
238  *  Helper function to show a portrait.
239  *
240  *  @param title                  The title of the dialog.
241  *  @param message                The message to show.
242  *  @param left                   Portrait to show on the left.
243  *  @param right                  Portrait to show on the right.
244  *  @param options                Options to offer.
245  *  @param input                  Info on text input.
246  */
247 int show_wml_message(const std::string& title,
248 					 const std::string& message,
249 					 const wml_message_portrait* left,
250 					 const wml_message_portrait* right,
251 					 const wml_message_options& options,
252 					 const wml_message_input& input);
253 
254 } // namespace dialogs
255 } // namespace gui2
256