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 #define GETTEXT_DOMAIN "wesnoth-editor"
15
16 #include "gui/dialogs/editor/resize_map.hpp"
17
18 #include "gui/auxiliary/field.hpp"
19 #include "gui/widgets/toggle_button.hpp"
20 #include "gui/widgets/settings.hpp"
21 #include "gui/widgets/slider.hpp"
22
23 #include "utils/functional.hpp"
24
25 namespace gui2
26 {
27 namespace dialogs
28 {
29
30 /*WIKI
31 * @page = GUIWindowDefinitionWML
32 * @order = 2_editor_resize_map
33 *
34 * == Editor resize map ==
35 *
36 * This shows the dialog to resize the current map.
37 *
38 * @begin{table}{dialog_widgets}
39 *
40 * old_width & & label & o &
41 * Shows the old width of the map. $
42 *
43 * old_height & & label & o &
44 * Shows the old height of the map. $
45 *
46 * width & & slider & m &
47 * Determines the new width of the map. $
48 *
49 * height & & slider & m &
50 * Determines the new height of the map. $
51 *
52 * copy_edge_terrain & & boolean_selector & m &
53 * Determines whether the border terrains should be used to expand or
54 * not. $
55 *
56 * expand0 & & toggle_button & m &
57 * Determines in which direction to expand, shows the north east
58 * marker. $
59 *
60 * expand1 & & toggle_button & m &
61 * Determines in which direction to expand, shows the north marker. $
62 *
63 * expand2 & & toggle_button & m &
64 * Determines in which direction to expand, shows the north west
65 * marker. $
66 *
67 * expand3 & & toggle_button & m &
68 * Determines in which direction to expand, shows the east marker. $
69 *
70 * expand4 & & toggle_button & m &
71 * Determines in which direction to expand, shows the center marker. $
72 *
73 * expand5 & & toggle_button & m &
74 * Determines in which direction to expand, shows the west marker. $
75 *
76 * expand6 & & toggle_button & m &
77 * Determines in which direction to expand, shows the south east
78 * marker. $
79 *
80 * expand7 & & toggle_button & m &
81 * Determines in which direction to expand, shows the south marker. $
82 *
83 * expand8 & & toggle_button & m &
84 * Determines in which direction to expand, shows the south west
85 * marker. $
86 *
87 * @end{table}
88 */
89
REGISTER_DIALOG(editor_resize_map)90 REGISTER_DIALOG(editor_resize_map)
91
92 editor_resize_map::editor_resize_map(int& width,
93 int& height,
94 EXPAND_DIRECTION& expand_direction,
95 bool& copy_edge_terrain)
96 : width_(register_integer("width", true, width))
97 , height_(register_integer("height", true, height))
98 , old_width_(width)
99 , old_height_(height)
100 , expand_direction_(expand_direction)
101 , direction_buttons_{}
102 {
103 register_bool("copy_edge_terrain", false, copy_edge_terrain);
104
105 register_label("old_width", false, std::to_string(width));
106 register_label("old_height", false, std::to_string(height));
107 }
108
pre_show(window & window)109 void editor_resize_map::pre_show(window& window)
110 {
111 slider& height = find_widget<slider>(&window, "height", false);
112 connect_signal_notify_modified(
113 height,
114 std::bind(&editor_resize_map::update_expand_direction,
115 this,
116 std::ref(window)));
117
118 slider& width = find_widget<slider>(&window, "width", false);
119 connect_signal_notify_modified(
120 width,
121 std::bind(&editor_resize_map::update_expand_direction,
122 this,
123 std::ref(window)));
124
125 std::string name_prefix = "expand";
126 for(int i = 0; i < 9; ++i) {
127 std::string name = name_prefix + std::to_string(i);
128 direction_buttons_[i]
129 = find_widget<toggle_button>(&window, name, false, true);
130
131 connect_signal_notify_modified(*direction_buttons_[i],
132 std::bind(&editor_resize_map::update_expand_direction, this, std::ref(window)));
133 }
134 direction_buttons_[0]->set_value(true);
135 update_expand_direction(window);
136 }
137
138 /**
139 * Convert a coordinate on a 3 by 3 grid to an index, return 9 for out of
140 * bounds
141 */
resize_grid_xy_to_idx(const int x,const int y)142 static int resize_grid_xy_to_idx(const int x, const int y)
143 {
144 if(x < 0 || x > 2 || y < 0 || y > 2) {
145 return 9;
146 } else {
147 return y * 3 + x;
148 }
149 }
150
set_direction_icon(int index,std::string icon)151 void editor_resize_map::set_direction_icon(int index, std::string icon)
152 {
153 if(index < 9) {
154 direction_buttons_[index]->set_icon_name("icons/arrows/arrows_blank_"
155 + icon + "_30.png");
156 }
157 }
158
update_expand_direction(window & window)159 void editor_resize_map::update_expand_direction(window& window)
160 {
161 for(int i = 0; i < 9; ++i) {
162 if(direction_buttons_[i]->get_value()
163 && static_cast<int>(expand_direction_) != i) {
164
165 expand_direction_ = static_cast<EXPAND_DIRECTION>(i);
166 break;
167 }
168 }
169 for(int i = 0; i < static_cast<int>(expand_direction_); ++i) {
170 direction_buttons_[i]->set_value(false);
171 set_direction_icon(i, "none");
172 }
173 direction_buttons_[expand_direction_]->set_value(true);
174 for(int i = expand_direction_ + 1; i < 9; ++i) {
175 direction_buttons_[i]->set_value(false);
176 set_direction_icon(i, "none");
177 }
178
179 int xdiff = width_->get_widget_value(window) - old_width_;
180 int ydiff = height_->get_widget_value(window) - old_height_;
181 int x = static_cast<int>(expand_direction_) % 3;
182 int y = static_cast<int>(expand_direction_) / 3;
183 set_direction_icon(expand_direction_, "center");
184 if(xdiff != 0) {
185 int left = resize_grid_xy_to_idx(x - 1, y);
186 int right = resize_grid_xy_to_idx(x + 1, y);
187 if(xdiff < 0)
188 std::swap(left, right);
189 set_direction_icon(left, "left");
190 set_direction_icon(right, "right");
191 }
192 if(ydiff != 0) {
193 int top = resize_grid_xy_to_idx(x, y - 1);
194 int bottom = resize_grid_xy_to_idx(x, y + 1);
195 if(ydiff < 0)
196 std::swap(top, bottom);
197 set_direction_icon(top, "up");
198 set_direction_icon(bottom, "down");
199 }
200 if(xdiff < 0 || ydiff < 0 || (xdiff > 0 && ydiff > 0)) {
201 int nw = resize_grid_xy_to_idx(x - 1, y - 1);
202 int ne = resize_grid_xy_to_idx(x + 1, y - 1);
203 int sw = resize_grid_xy_to_idx(x - 1, y + 1);
204 int se = resize_grid_xy_to_idx(x + 1, y + 1);
205 if(xdiff < 0 || ydiff < 0) {
206 std::swap(nw, se);
207 std::swap(ne, sw);
208 }
209 set_direction_icon(nw, "topleft");
210 set_direction_icon(ne, "topright");
211 set_direction_icon(sw, "bottomleft");
212 set_direction_icon(se, "bottomright");
213 }
214 }
215
216 } // namespace dialogs
217 } // namespace gui2
218