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/auxiliary/typed_formula.hpp"
18 #include "gui/core/linked_group_definition.hpp"
19 #include "gui/widgets/grid.hpp"
20 #include "color.hpp"
21
22 #include "utils/functional.hpp"
23
24 class config;
25
26 namespace gui2
27 {
28
29 class window;
30
31 /**
32 * Builds a window.
33 *
34 * @param type The type id string of the window, this window
35 * must be registered at startup.
36 */
37 window* build(const std::string& type);
38
39 /** Contains the info needed to instantiate a widget. */
40 struct builder_widget
41 {
42 public:
43 /**
44 * The replacements type is used to define replacement types.
45 *
46 * Certain widgets need to build a part of themselves upon instantiation
47 * but at the time of the definition it's not yet known what exactly. By
48 * using and `[instance]' widget this decision can be postponed until
49 * instantiation.
50 */
51 typedef std::map<std::string, std::shared_ptr<builder_widget>> replacements_map;
52
53 explicit builder_widget(const config& cfg);
54
~builder_widgetgui2::builder_widget55 virtual ~builder_widget()
56 {
57 }
58
59 virtual widget* build() const = 0;
60
61 virtual widget* build(const replacements_map& replacements) const = 0;
62
63 /** Parameters for the widget. */
64 std::string id;
65 std::string linked_group;
66
67 int debug_border_mode;
68 color_t debug_border_color;
69 };
70
71 typedef std::shared_ptr<builder_widget> builder_widget_ptr;
72 typedef std::shared_ptr<const builder_widget> builder_widget_const_ptr;
73
74 /**
75 * Create a widget builder.
76 *
77 * This object holds the instance builder for a single widget.
78 *
79 * @param cfg The config object holding the information
80 * regarding the widget instance.
81 *
82 * @returns The builder for the widget instance.
83 */
84 builder_widget_ptr create_widget_builder(const config& cfg);
85
86 /**
87 * Helper function to implement @ref build_single_widget_instance. This keeps the main
88 * logic in the implementation despite said function being a template and therefor
89 * needing to be fully implemented in the declaration.
90 */
91 widget* build_single_widget_instance_helper(const std::string& type, const config& cfg);
92
93 /**
94 * Builds a single widget instance of the given type with the specified attributes.
95 *
96 * This should be used in place of creating a widget object directly, as it
97 * allows the widget-specific builder code to be executed.
98 *
99 * @tparam T The final widget type. The widget pointer will be
100 * cast to this.
101 *
102 * @param type String ID of the widget type.
103 * @param cfg Data config to pass to the widget's builder.
104 */
105 template<typename T>
build_single_widget_instance(const std::string & type,const config & cfg=config ())106 T* build_single_widget_instance(const std::string& type, const config& cfg = config())
107 {
108 return dynamic_cast<T*>(build_single_widget_instance_helper(type, cfg));
109 }
110
111 struct builder_grid : public builder_widget
112 {
113 public:
114 explicit builder_grid(const config& cfg);
115
116 unsigned rows;
117 unsigned cols;
118
119 /** The grow factor for the rows / columns. */
120 std::vector<unsigned> row_grow_factor;
121 std::vector<unsigned> col_grow_factor;
122
123 /** The flags per grid cell. */
124 std::vector<unsigned> flags;
125
126 /** The border size per grid cell. */
127 std::vector<unsigned> border_size;
128
129 /** The widgets per grid cell. */
130 std::vector<builder_widget_ptr> widgets;
131
132 grid* build() const;
133 widget* build(const replacements_map& replacements) const;
134
135 grid* build(grid* grid) const;
136 void build(grid& grid, const replacements_map& replacements) const;
137 };
138
139 typedef std::shared_ptr<builder_grid> builder_grid_ptr;
140 typedef std::shared_ptr<const builder_grid> builder_grid_const_ptr;
141
142 class builder_window
143 {
144 public:
builder_window(const config & cfg)145 explicit builder_window(const config& cfg)
146 : resolutions()
147 , id_(cfg["id"])
148 , description_(cfg["description"])
149 {
150 read(cfg);
151 }
152
153 struct window_resolution
154 {
155 public:
156 explicit window_resolution(const config& cfg);
157
158 unsigned window_width;
159 unsigned window_height;
160
161 bool automatic_placement;
162
163 typed_formula<unsigned> x;
164 typed_formula<unsigned> y;
165 typed_formula<unsigned> width;
166 typed_formula<unsigned> height;
167 typed_formula<bool> reevaluate_best_size;
168
169 wfl::function_symbol_table functions;
170
171 unsigned vertical_placement;
172 unsigned horizontal_placement;
173
174 unsigned maximum_width;
175 unsigned maximum_height;
176
177 bool click_dismiss;
178
179 std::string definition;
180
181 std::vector<linked_group_definition> linked_groups;
182
183 /** Helper struct to store information about the tips. */
184 struct tooltip_info
185 {
186 tooltip_info(const config& cfg, const std::string& tagname);
187
188 std::string id;
189 };
190
191 tooltip_info tooltip;
192 tooltip_info helptip;
193
194 builder_grid_ptr grid;
195 };
196
197 /**
198 * Resolution options for this window instance.
199 *
200 * The window widget handles resolution options differently from other widgets.
201 * Most specify their resolution options in their definitions. However, windows
202 * define different resolution options for each window *instance*. That enables
203 * each dialog to have its own set of options.
204 */
205 std::vector<window_resolution> resolutions;
206
207 private:
208 void read(const config& cfg);
209
210 std::string id_;
211 std::string description_;
212 };
213
214 /**
215 * Builds a window.
216 */
217 window* build(const builder_window::window_resolution* res);
218
219 } // namespace gui2
220