Merge lp:~widelands-dev/widelands/options_window into lp:widelands
- options_window
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | kaputtnik | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 7685 | ||||
Proposed branch: | lp:~widelands-dev/widelands/options_window | ||||
Merge into: | lp:widelands | ||||
Diff against target: |
1821 lines (+767/-632) 5 files modified
src/ui_basic/tabpanel.cc (+232/-147) src/ui_basic/tabpanel.h (+51/-15) src/ui_fsmenu/base.h (+1/-1) src/ui_fsmenu/options.cc (+388/-383) src/ui_fsmenu/options.h (+95/-86) |
||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/options_window | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tino | Approve | ||
kaputtnik (community) | Approve | ||
Review via email: mp+280355@code.launchpad.net |
Commit message
Description of the change
The Options window now has a tabbed layout. I added textual tabs to TabPanel and did a couple of fixes there as well - the tab brightening on mouseover was never executed, and tabs now also play click on mouseclick.
Exposed rolling autosave option to the UI.
We are discussing some changes to the options themselves in the forum, e.g. some rephrasing and tooltips, but those can always be added later.
options.h/cc is probably best viewed with an offline diff tool.
TiborB (tiborb95) wrote : | # |
I went through code. LGTM though this is another huge and hard-to-read change...
Should I merge this as well?
bunnybot (widelandsofficial) wrote : | # |
Hi, I am bunnybot (https:/
I am keeping the source branch lp:~widelands-dev/widelands/options_window mirrored to
https:/
The latest continuous integration build can always be found here:
https:/
Please do not merge without making sure that it passes.
You can give me commands by starting a line with @bunnybot <command>. I understand:
merge: Merges the source branch into the target branch, closing the pull request.
Tino (tino79) wrote : | # |
Looks good to me and bunnybot ;).
@bunnybot merge
bunnybot (widelandsofficial) wrote : | # |
Travis build 130 has changed state to: passed. Details: https:/
Preview Diff
1 | === removed file 'pics/optionsmenu.jpg' | |||
2 | 0 | Binary files pics/optionsmenu.jpg 2008-07-23 15:48:24 +0000 and pics/optionsmenu.jpg 1970-01-01 00:00:00 +0000 differ | 0 | Binary files pics/optionsmenu.jpg 2008-07-23 15:48:24 +0000 and pics/optionsmenu.jpg 1970-01-01 00:00:00 +0000 differ |
3 | === modified file 'src/ui_basic/tabpanel.cc' | |||
4 | --- src/ui_basic/tabpanel.cc 2014-12-04 09:00:20 +0000 | |||
5 | +++ src/ui_basic/tabpanel.cc 2016-01-01 19:10:55 +0000 | |||
6 | @@ -19,41 +19,51 @@ | |||
7 | 19 | 19 | ||
8 | 20 | #include "ui_basic/tabpanel.h" | 20 | #include "ui_basic/tabpanel.h" |
9 | 21 | 21 | ||
10 | 22 | #include "graphic/font_handler1.h" | ||
11 | 22 | #include "graphic/rendertarget.h" | 23 | #include "graphic/rendertarget.h" |
12 | 24 | #include "graphic/text_layout.h" | ||
13 | 23 | #include "ui_basic/mouse_constants.h" | 25 | #include "ui_basic/mouse_constants.h" |
14 | 24 | 26 | ||
15 | 25 | namespace UI { | 27 | namespace UI { |
16 | 26 | 28 | ||
19 | 27 | // Button size of tab buttons in pixels. | 29 | // Button height of tab buttons in pixels. Is also used for width with pictorial buttons. |
20 | 28 | constexpr int kTabPanelButtonSize = 34; | 30 | constexpr int kTabPanelButtonHeight = 34; |
21 | 29 | 31 | ||
22 | 30 | // Margin around image. The image will be scaled down to fit into this rectangle with preserving size. | 32 | // Margin around image. The image will be scaled down to fit into this rectangle with preserving size. |
23 | 31 | constexpr int kTabPanelImageMargin = 2; | 33 | constexpr int kTabPanelImageMargin = 2; |
24 | 32 | 34 | ||
25 | 35 | // Left and right margin around text. | ||
26 | 36 | constexpr int kTabPanelTextMargin = 4; | ||
27 | 37 | |||
28 | 33 | // height of the bar separating buttons and tab contents | 38 | // height of the bar separating buttons and tab contents |
29 | 34 | constexpr int kTabPanelSeparatorHeight = 4; | 39 | constexpr int kTabPanelSeparatorHeight = 4; |
30 | 35 | 40 | ||
31 | 41 | // Constant to flag up when we're not at a tab. | ||
32 | 42 | constexpr uint32_t kNotFound = std::numeric_limits<uint32_t>::max(); | ||
33 | 43 | |||
34 | 36 | /* | 44 | /* |
35 | 37 | * ================= | 45 | * ================= |
36 | 38 | * class Tab | 46 | * class Tab |
37 | 39 | * ================= | 47 | * ================= |
38 | 40 | */ | 48 | */ |
39 | 41 | Tab::Tab | 49 | Tab::Tab |
46 | 42 | (TabPanel * const parent, | 50 | (TabPanel* const tab_parent, |
47 | 43 | uint32_t const id, | 51 | size_t const tab_id, |
48 | 44 | const std::string & name, | 52 | int32_t x, |
49 | 45 | const Image* gpic, | 53 | int32_t w, |
50 | 46 | const std::string & gtooltip, | 54 | const std::string& name, |
51 | 47 | Panel * const gpanel) | 55 | const std::string& _title, |
52 | 56 | const Image* _pic, | ||
53 | 57 | const std::string& tooltip_text, | ||
54 | 58 | Panel* const contents) | ||
55 | 48 | : | 59 | : |
64 | 49 | NamedPanel | 60 | NamedPanel(tab_parent, name, x, 0, w, kTabPanelButtonHeight, tooltip_text), |
65 | 50 | (parent, name, id * kTabPanelButtonSize, 0, kTabPanelButtonSize, | 61 | parent(tab_parent), |
66 | 51 | kTabPanelButtonSize, gtooltip), | 62 | id(tab_id), |
67 | 52 | m_parent(parent), | 63 | pic(_pic), |
68 | 53 | m_id(id), | 64 | title(_title), |
69 | 54 | pic(gpic), | 65 | tooltip(tooltip_text), |
70 | 55 | tooltip(gtooltip), | 66 | panel(contents) |
63 | 56 | panel(gpanel) | ||
71 | 57 | { | 67 | { |
72 | 58 | } | 68 | } |
73 | 59 | 69 | ||
74 | @@ -61,10 +71,15 @@ | |||
75 | 61 | * Currently active tab | 71 | * Currently active tab |
76 | 62 | */ | 72 | */ |
77 | 63 | bool Tab::active() { | 73 | bool Tab::active() { |
79 | 64 | return m_parent->m_active == m_id; | 74 | return parent->active_ == id; |
80 | 65 | } | 75 | } |
81 | 66 | void Tab::activate() { | 76 | void Tab::activate() { |
83 | 67 | return m_parent->activate(m_id); | 77 | return parent->activate(id); |
84 | 78 | } | ||
85 | 79 | |||
86 | 80 | bool Tab::handle_mousepress(uint8_t, int32_t, int32_t) { | ||
87 | 81 | play_click(); | ||
88 | 82 | return false; | ||
89 | 68 | } | 83 | } |
90 | 69 | 84 | ||
91 | 70 | /* | 85 | /* |
92 | @@ -78,22 +93,26 @@ | |||
93 | 78 | TabPanel::TabPanel | 93 | TabPanel::TabPanel |
94 | 79 | (Panel * const parent, | 94 | (Panel * const parent, |
95 | 80 | int32_t const x, int32_t const y, | 95 | int32_t const x, int32_t const y, |
97 | 81 | const Image* background) | 96 | const Image* background, |
98 | 97 | TabPanel::Type border_type) | ||
99 | 82 | : | 98 | : |
104 | 83 | Panel (parent, x, y, 0, 0), | 99 | Panel (parent, x, y, 0, 0), |
105 | 84 | m_active (0), | 100 | active_ (0), |
106 | 85 | m_highlight (-1), | 101 | highlight_ (kNotFound), |
107 | 86 | m_pic_background (background) | 102 | pic_background_ (background), |
108 | 103 | border_type_ (border_type) | ||
109 | 87 | {} | 104 | {} |
110 | 88 | TabPanel::TabPanel | 105 | TabPanel::TabPanel |
111 | 89 | (Panel * const parent, | 106 | (Panel * const parent, |
112 | 90 | int32_t const x, int32_t const y, int32_t const w, int32_t const h, | 107 | int32_t const x, int32_t const y, int32_t const w, int32_t const h, |
114 | 91 | const Image* background) | 108 | const Image* background, |
115 | 109 | TabPanel::Type border_type) | ||
116 | 92 | : | 110 | : |
121 | 93 | Panel (parent, x, y, w, h), | 111 | Panel (parent, x, y, w, h), |
122 | 94 | m_active (0), | 112 | active_ (0), |
123 | 95 | m_highlight (-1), | 113 | highlight_ (kNotFound), |
124 | 96 | m_pic_background (background) | 114 | pic_background_ (background), |
125 | 115 | border_type_ (border_type) | ||
126 | 97 | {} | 116 | {} |
127 | 98 | 117 | ||
128 | 99 | /** | 118 | /** |
129 | @@ -101,12 +120,16 @@ | |||
130 | 101 | */ | 120 | */ |
131 | 102 | void TabPanel::layout() | 121 | void TabPanel::layout() |
132 | 103 | { | 122 | { |
135 | 104 | if (m_active < m_tabs.size()) { | 123 | if (active_ < tabs_.size()) { |
136 | 105 | Panel * const panel = m_tabs[m_active]->panel; | 124 | Panel * const panel = tabs_[active_]->panel; |
137 | 106 | uint32_t h = get_h(); | 125 | uint32_t h = get_h(); |
138 | 107 | 126 | ||
139 | 108 | // avoid excessive craziness in case there is a wraparound | 127 | // avoid excessive craziness in case there is a wraparound |
141 | 109 | h = std::min(h, h - (kTabPanelButtonSize + kTabPanelSeparatorHeight)); | 128 | h = std::min(h, h - (kTabPanelButtonHeight + kTabPanelSeparatorHeight)); |
142 | 129 | // If we have a border, we will also want some margin to the bottom | ||
143 | 130 | if (border_type_ == TabPanel::Type::kBorder) { | ||
144 | 131 | h = h - kTabPanelSeparatorHeight; | ||
145 | 132 | } | ||
146 | 110 | panel->set_size(get_w(), h); | 133 | panel->set_size(get_w(), h); |
147 | 111 | } | 134 | } |
148 | 112 | } | 135 | } |
149 | @@ -120,12 +143,12 @@ | |||
150 | 120 | uint32_t h; | 143 | uint32_t h; |
151 | 121 | 144 | ||
152 | 122 | // size of button row | 145 | // size of button row |
155 | 123 | w = kTabPanelButtonSize * m_tabs.size(); | 146 | w = kTabPanelButtonHeight * tabs_.size(); |
156 | 124 | h = kTabPanelButtonSize + kTabPanelSeparatorHeight; | 147 | h = kTabPanelButtonHeight + kTabPanelSeparatorHeight; |
157 | 125 | 148 | ||
158 | 126 | // size of contents | 149 | // size of contents |
161 | 127 | if (m_active < m_tabs.size()) { | 150 | if (active_ < tabs_.size()) { |
162 | 128 | Panel * const panel = m_tabs[m_active]->panel; | 151 | Panel * const panel = tabs_[active_]->panel; |
163 | 129 | uint32_t panelw, panelh; | 152 | uint32_t panelw, panelh; |
164 | 130 | 153 | ||
165 | 131 | panel->get_desired_size(panelw, panelh); | 154 | panel->get_desired_size(panelw, panelh); |
166 | @@ -146,7 +169,25 @@ | |||
167 | 146 | } | 169 | } |
168 | 147 | 170 | ||
169 | 148 | /** | 171 | /** |
171 | 149 | * Add a new tab | 172 | * Add a new textual tab |
172 | 173 | */ | ||
173 | 174 | uint32_t TabPanel::add | ||
174 | 175 | (const std::string & name, | ||
175 | 176 | const std::string & title, | ||
176 | 177 | Panel * const panel, | ||
177 | 178 | const std::string & tooltip_text) | ||
178 | 179 | { | ||
179 | 180 | const Image* pic = UI::g_fh1->render(as_uifont(title)); | ||
180 | 181 | return add_tab(std::max(kTabPanelButtonHeight, pic->width() + 2 * kTabPanelTextMargin), | ||
181 | 182 | name, | ||
182 | 183 | title, | ||
183 | 184 | pic, | ||
184 | 185 | tooltip_text, | ||
185 | 186 | panel); | ||
186 | 187 | } | ||
187 | 188 | |||
188 | 189 | /** | ||
189 | 190 | * Add a new pictorial tab | ||
190 | 150 | */ | 191 | */ |
191 | 151 | uint32_t TabPanel::add | 192 | uint32_t TabPanel::add |
192 | 152 | (const std::string & name, | 193 | (const std::string & name, |
193 | @@ -154,14 +195,38 @@ | |||
194 | 154 | Panel * const panel, | 195 | Panel * const panel, |
195 | 155 | const std::string & tooltip_text) | 196 | const std::string & tooltip_text) |
196 | 156 | { | 197 | { |
197 | 198 | return add_tab(kTabPanelButtonHeight, | ||
198 | 199 | name, | ||
199 | 200 | "", | ||
200 | 201 | pic, | ||
201 | 202 | tooltip_text, | ||
202 | 203 | panel); | ||
203 | 204 | } | ||
204 | 205 | |||
205 | 206 | /** Common adding function for textual and pictorial tabs. */ | ||
206 | 207 | uint32_t TabPanel::add_tab(int32_t width, | ||
207 | 208 | const std::string& name, | ||
208 | 209 | const std::string& title, | ||
209 | 210 | const Image* pic, | ||
210 | 211 | const std::string& tooltip_text, | ||
211 | 212 | Panel* panel) { | ||
212 | 157 | assert(panel); | 213 | assert(panel); |
213 | 158 | assert(panel->get_parent() == this); | 214 | assert(panel->get_parent() == this); |
214 | 159 | 215 | ||
220 | 160 | uint32_t id = m_tabs.size(); | 216 | size_t id = tabs_.size(); |
221 | 161 | m_tabs.push_back(new Tab(this, id, name, pic, tooltip_text, panel)); | 217 | int32_t x = id > 0 ? tabs_[id - 1]->get_x() + tabs_[id - 1]->get_w() : 0; |
222 | 162 | 218 | tabs_.push_back(new Tab(this, id, x, width, name, title, pic, tooltip_text, panel)); | |
223 | 163 | panel->set_pos(Point(0, kTabPanelButtonSize + kTabPanelSeparatorHeight)); | 219 | |
224 | 164 | panel->set_visible(id == m_active); | 220 | // Add a margin if there is a border |
225 | 221 | if (border_type_ == TabPanel::Type::kBorder) { | ||
226 | 222 | panel->set_border(kTabPanelSeparatorHeight + 1, kTabPanelSeparatorHeight + 1, | ||
227 | 223 | kTabPanelSeparatorHeight, kTabPanelSeparatorHeight); | ||
228 | 224 | panel->set_pos(Point(0, kTabPanelButtonHeight)); | ||
229 | 225 | } else { | ||
230 | 226 | panel->set_pos(Point(0, kTabPanelButtonHeight + kTabPanelSeparatorHeight)); | ||
231 | 227 | } | ||
232 | 228 | |||
233 | 229 | panel->set_visible(id == active_); | ||
234 | 165 | update_desired_size(); | 230 | update_desired_size(); |
235 | 166 | 231 | ||
236 | 167 | return id; | 232 | return id; |
237 | @@ -173,20 +238,20 @@ | |||
238 | 173 | */ | 238 | */ |
239 | 174 | void TabPanel::activate(uint32_t idx) | 239 | void TabPanel::activate(uint32_t idx) |
240 | 175 | { | 240 | { |
245 | 176 | if (m_active < m_tabs.size()) | 241 | if (active_ < tabs_.size()) |
246 | 177 | m_tabs[m_active]->panel->set_visible(false); | 242 | tabs_[active_]->panel->set_visible(false); |
247 | 178 | if (idx < m_tabs.size()) | 243 | if (idx < tabs_.size()) |
248 | 179 | m_tabs[idx]->panel->set_visible(true); | 244 | tabs_[idx]->panel->set_visible(true); |
249 | 180 | 245 | ||
251 | 181 | m_active = idx; | 246 | active_ = idx; |
252 | 182 | 247 | ||
253 | 183 | update_desired_size(); | 248 | update_desired_size(); |
254 | 184 | } | 249 | } |
255 | 185 | 250 | ||
256 | 186 | void TabPanel::activate(const std::string & name) | 251 | void TabPanel::activate(const std::string & name) |
257 | 187 | { | 252 | { |
260 | 188 | for (uint32_t t = 0; t < m_tabs.size(); ++t) | 253 | for (uint32_t t = 0; t < tabs_.size(); ++t) |
261 | 189 | if (m_tabs[t]->get_name() == name) | 254 | if (tabs_[t]->get_name() == name) |
262 | 190 | activate(t); | 255 | activate(t); |
263 | 191 | } | 256 | } |
264 | 192 | 257 | ||
265 | @@ -194,7 +259,7 @@ | |||
266 | 194 | * Return the tab names in order | 259 | * Return the tab names in order |
267 | 195 | */ | 260 | */ |
268 | 196 | const TabPanel::TabList & TabPanel::tabs() { | 261 | const TabPanel::TabList & TabPanel::tabs() { |
270 | 197 | return m_tabs; | 262 | return tabs_; |
271 | 198 | } | 263 | } |
272 | 199 | 264 | ||
273 | 200 | /** | 265 | /** |
274 | @@ -202,96 +267,118 @@ | |||
275 | 202 | */ | 267 | */ |
276 | 203 | void TabPanel::draw(RenderTarget & dst) | 268 | void TabPanel::draw(RenderTarget & dst) |
277 | 204 | { | 269 | { |
278 | 205 | uint32_t idx; | ||
279 | 206 | uint32_t x; | ||
280 | 207 | |||
281 | 208 | // draw the background | 270 | // draw the background |
284 | 209 | static_assert(2 < kTabPanelButtonSize, "assert(2 < kTabPanelButtonSize) failed."); | 271 | static_assert(2 < kTabPanelButtonHeight, "assert(2 < kTabPanelButtonSize) failed."); |
285 | 210 | static_assert(4 < kTabPanelButtonSize, "assert(4 < kTabPanelButtonSize) failed."); | 272 | static_assert(4 < kTabPanelButtonHeight, "assert(4 < kTabPanelButtonSize) failed."); |
286 | 211 | 273 | ||
298 | 212 | if (m_pic_background) { | 274 | if (pic_background_) { |
299 | 213 | dst.tile | 275 | if (!tabs_.empty()) { |
300 | 214 | (Rect(Point(0, 0), m_tabs.size() * kTabPanelButtonSize, kTabPanelButtonSize - 2), | 276 | dst.tile |
301 | 215 | m_pic_background, Point(get_x(), get_y())); | 277 | (Rect(Point(0, 0), tabs_.back()->get_x() + tabs_.back()->get_w(), kTabPanelButtonHeight - 2), |
302 | 216 | assert(kTabPanelButtonSize - 2 <= get_h()); | 278 | pic_background_, |
303 | 217 | dst.tile | 279 | Point(get_x(), get_y())); |
304 | 218 | (Rect | 280 | } |
305 | 219 | (Point(0, kTabPanelButtonSize - 2), | 281 | assert(kTabPanelButtonHeight - 2 <= get_h()); |
306 | 220 | get_w(), get_h() - kTabPanelButtonSize + 2), | 282 | dst.tile |
307 | 221 | m_pic_background, | 283 | (Rect(Point(0, kTabPanelButtonHeight - 2), get_w(), get_h() - kTabPanelButtonHeight + 2), |
308 | 222 | Point(get_x(), get_y() + kTabPanelButtonSize - 2)); | 284 | pic_background_, |
309 | 285 | Point(get_x(), get_y() + kTabPanelButtonHeight - 2)); | ||
310 | 223 | } | 286 | } |
311 | 224 | 287 | ||
312 | 288 | RGBColor black(0, 0, 0); | ||
313 | 289 | |||
314 | 225 | // draw the buttons | 290 | // draw the buttons |
341 | 226 | for (idx = 0, x = 0; idx < m_tabs.size(); idx++, x += kTabPanelButtonSize) { | 291 | int32_t x = 0; |
342 | 227 | if (m_highlight == static_cast<int32_t>(idx)) | 292 | int tab_width = 0; |
343 | 228 | dst.brighten_rect | 293 | for (size_t idx = 0; idx < tabs_.size(); ++idx) { |
344 | 229 | (Rect(Point(x, 0), kTabPanelButtonSize, kTabPanelButtonSize), | 294 | x = tabs_[idx]->get_x(); |
345 | 230 | MOUSE_OVER_BRIGHT_FACTOR); | 295 | tab_width = tabs_[idx]->get_w(); |
346 | 231 | 296 | ||
347 | 232 | // Draw the icon | 297 | if (highlight_ == idx) { |
348 | 233 | assert(m_tabs[idx]->pic); | 298 | dst.brighten_rect(Rect(Point(x, 0), tab_width, kTabPanelButtonHeight), MOUSE_OVER_BRIGHT_FACTOR); |
349 | 234 | 299 | } | |
350 | 235 | // Scale the image down if needed, but keep the ratio. | 300 | |
351 | 236 | constexpr int kMaxImageSize = kTabPanelButtonSize - 2 * kTabPanelImageMargin; | 301 | assert(tabs_[idx]->pic); |
352 | 237 | double image_scale = | 302 | |
353 | 238 | std::min(1., | 303 | // If the title is empty, we will assume a pictorial tab |
354 | 239 | std::min(static_cast<double>(kMaxImageSize) / m_tabs[idx]->pic->width(), | 304 | if (tabs_[idx]->title.empty()) { |
355 | 240 | static_cast<double>(kMaxImageSize) / m_tabs[idx]->pic->height())); | 305 | // Scale the image down if needed, but keep the ratio. |
356 | 241 | 306 | constexpr int kMaxImageSize = kTabPanelButtonHeight - 2 * kTabPanelImageMargin; | |
357 | 242 | uint16_t picture_width = image_scale * m_tabs[idx]->pic->width(); | 307 | double image_scale = |
358 | 243 | uint16_t picture_height = image_scale * m_tabs[idx]->pic->height(); | 308 | std::min(1., |
359 | 244 | dst.blitrect_scale(Rect(x + (kTabPanelButtonSize - picture_width) / 2, | 309 | std::min(static_cast<double>(kMaxImageSize) / tabs_[idx]->pic->width(), |
360 | 245 | (kTabPanelButtonSize - picture_height) / 2, | 310 | static_cast<double>(kMaxImageSize) / tabs_[idx]->pic->height())); |
361 | 246 | picture_width, | 311 | |
362 | 247 | picture_height), | 312 | uint16_t picture_width = image_scale * tabs_[idx]->pic->width(); |
363 | 248 | m_tabs[idx]->pic, | 313 | uint16_t picture_height = image_scale * tabs_[idx]->pic->height(); |
364 | 249 | Rect(0, 0, m_tabs[idx]->pic->width(), m_tabs[idx]->pic->height()), | 314 | dst.blitrect_scale(Rect(x + (kTabPanelButtonHeight - picture_width) / 2, |
365 | 250 | 1., | 315 | (kTabPanelButtonHeight - picture_height) / 2, |
366 | 251 | BlendMode::UseAlpha); | 316 | picture_width, |
367 | 317 | picture_height), | ||
368 | 318 | tabs_[idx]->pic, | ||
369 | 319 | Rect(0, 0, tabs_[idx]->pic->width(), tabs_[idx]->pic->height()), | ||
370 | 320 | 1., | ||
371 | 321 | BlendMode::UseAlpha); | ||
372 | 322 | } else { | ||
373 | 323 | dst.blit(Point(x + kTabPanelTextMargin, (kTabPanelButtonHeight - tabs_[idx]->pic->height()) / 2), | ||
374 | 324 | tabs_[idx]->pic, | ||
375 | 325 | BlendMode::UseAlpha, | ||
376 | 326 | UI::Align_Left); | ||
377 | 327 | } | ||
378 | 252 | 328 | ||
379 | 253 | // Draw top part of border | 329 | // Draw top part of border |
386 | 254 | RGBColor black(0, 0, 0); | 330 | dst.brighten_rect |
387 | 255 | 331 | (Rect(Point(x, 0), tab_width, 2), BUTTON_EDGE_BRIGHT_FACTOR); | |
388 | 256 | dst.brighten_rect | 332 | dst.brighten_rect |
389 | 257 | (Rect(Point(x, 0), kTabPanelButtonSize, 2), BUTTON_EDGE_BRIGHT_FACTOR); | 333 | (Rect(Point(x, 2), 2, kTabPanelButtonHeight - 4), |
384 | 258 | dst.brighten_rect | ||
385 | 259 | (Rect(Point(x, 2), 2, kTabPanelButtonSize - 4), | ||
390 | 260 | BUTTON_EDGE_BRIGHT_FACTOR); | 334 | BUTTON_EDGE_BRIGHT_FACTOR); |
391 | 261 | dst.fill_rect | 335 | dst.fill_rect |
393 | 262 | (Rect(Point(x + kTabPanelButtonSize - 2, 2), 1, kTabPanelButtonSize - 4), | 336 | (Rect(Point(x + tab_width - 2, 2), 1, kTabPanelButtonHeight - 4), |
394 | 263 | black); | 337 | black); |
395 | 264 | dst.fill_rect | 338 | dst.fill_rect |
397 | 265 | (Rect(Point(x + kTabPanelButtonSize - 1, 1), 1, kTabPanelButtonSize - 3), | 339 | (Rect(Point(x + tab_width - 1, 1), 1, kTabPanelButtonHeight - 3), |
398 | 266 | black); | 340 | black); |
399 | 267 | 341 | ||
400 | 268 | // Draw bottom part | 342 | // Draw bottom part |
402 | 269 | if (m_active != idx) | 343 | if (active_ != idx) |
403 | 270 | dst.brighten_rect | 344 | dst.brighten_rect |
405 | 271 | (Rect(Point(x, kTabPanelButtonSize - 2), kTabPanelButtonSize, 2), | 345 | (Rect(Point(x, kTabPanelButtonHeight - 2), tab_width, 2), |
406 | 272 | 2 * BUTTON_EDGE_BRIGHT_FACTOR); | 346 | 2 * BUTTON_EDGE_BRIGHT_FACTOR); |
407 | 273 | else { | 347 | else { |
408 | 274 | dst.brighten_rect | 348 | dst.brighten_rect |
410 | 275 | (Rect(Point(x, kTabPanelButtonSize - 2), 2, 2), | 349 | (Rect(Point(x, kTabPanelButtonHeight - 2), 2, 2), |
411 | 276 | BUTTON_EDGE_BRIGHT_FACTOR); | 350 | BUTTON_EDGE_BRIGHT_FACTOR); |
412 | 277 | 351 | ||
413 | 278 | dst.brighten_rect | 352 | dst.brighten_rect |
415 | 279 | (Rect(Point(x + kTabPanelButtonSize - 2, kTabPanelButtonSize - 2), 2, 2), | 353 | (Rect(Point(x + tab_width - 2, kTabPanelButtonHeight - 2), 2, 2), |
416 | 280 | 2 * BUTTON_EDGE_BRIGHT_FACTOR); | 354 | 2 * BUTTON_EDGE_BRIGHT_FACTOR); |
417 | 281 | dst.fill_rect | 355 | dst.fill_rect |
419 | 282 | (Rect(Point(x + kTabPanelButtonSize - 2, kTabPanelButtonSize - 1), 1, 1), | 356 | (Rect(Point(x + tab_width - 2, kTabPanelButtonHeight - 1), 1, 1), |
420 | 283 | black); | 357 | black); |
421 | 284 | dst.fill_rect | 358 | dst.fill_rect |
423 | 285 | (Rect(Point(x + kTabPanelButtonSize - 2, kTabPanelButtonSize - 2), 2, 1), | 359 | (Rect(Point(x + tab_width - 2, kTabPanelButtonHeight - 2), 2, 1), |
424 | 286 | black); | 360 | black); |
425 | 287 | } | 361 | } |
426 | 288 | } | 362 | } |
427 | 289 | 363 | ||
428 | 290 | // draw the remaining separator | 364 | // draw the remaining separator |
430 | 291 | assert(x <= static_cast<uint32_t>(get_w())); | 365 | assert(x <= get_w()); |
431 | 292 | dst.brighten_rect | 366 | dst.brighten_rect |
433 | 293 | (Rect(Point(x, kTabPanelButtonSize - 2), get_w() - x, 2), | 367 | (Rect(Point(x + tab_width, kTabPanelButtonHeight - 2), get_w() - x, 2), |
434 | 294 | 2 * BUTTON_EDGE_BRIGHT_FACTOR); | 368 | 2 * BUTTON_EDGE_BRIGHT_FACTOR); |
435 | 369 | |||
436 | 370 | // Draw border around the main panel | ||
437 | 371 | if (border_type_ == TabPanel::Type::kBorder) { | ||
438 | 372 | // left edge | ||
439 | 373 | dst.brighten_rect | ||
440 | 374 | (Rect(Point(0, kTabPanelButtonHeight), 2, get_h() - 2), BUTTON_EDGE_BRIGHT_FACTOR); | ||
441 | 375 | // bottom edge | ||
442 | 376 | dst.fill_rect(Rect(Point(2, get_h() - 2), get_w() - 2, 1), black); | ||
443 | 377 | dst.fill_rect(Rect(Point(1, get_h() - 1), get_w() - 1, 1), black); | ||
444 | 378 | // right edge | ||
445 | 379 | dst.fill_rect(Rect(Point(get_w() - 2, kTabPanelButtonHeight - 1), 1, get_h() - 2), black); | ||
446 | 380 | dst.fill_rect(Rect(Point(get_w() - 1, kTabPanelButtonHeight - 2), 1, get_h() - 1), black); | ||
447 | 381 | } | ||
448 | 295 | } | 382 | } |
449 | 296 | 383 | ||
450 | 297 | 384 | ||
451 | @@ -300,11 +387,9 @@ | |||
452 | 300 | */ | 387 | */ |
453 | 301 | void TabPanel::handle_mousein(bool inside) | 388 | void TabPanel::handle_mousein(bool inside) |
454 | 302 | { | 389 | { |
460 | 303 | if (!inside && m_highlight >= 0) { | 390 | if (!inside && highlight_ != kNotFound) { |
461 | 304 | update | 391 | update(tabs_[highlight_]->get_x(), 0, tabs_[highlight_]->get_w(), kTabPanelButtonHeight); |
462 | 305 | (m_highlight * kTabPanelButtonSize, 0, kTabPanelButtonSize, kTabPanelButtonSize); | 392 | highlight_ = kNotFound; |
458 | 306 | |||
459 | 307 | m_highlight = -1; | ||
463 | 308 | } | 393 | } |
464 | 309 | } | 394 | } |
465 | 310 | 395 | ||
466 | @@ -315,31 +400,17 @@ | |||
467 | 315 | bool TabPanel::handle_mousemove | 400 | bool TabPanel::handle_mousemove |
468 | 316 | (uint8_t, int32_t const x, int32_t const y, int32_t, int32_t) | 401 | (uint8_t, int32_t const x, int32_t const y, int32_t, int32_t) |
469 | 317 | { | 402 | { |
495 | 318 | int32_t hl; | 403 | size_t hl = find_tab(x, y); |
496 | 319 | 404 | ||
497 | 320 | if (y < 0 || y >= kTabPanelButtonSize) | 405 | if (hl != highlight_) { |
498 | 321 | hl = -1; | 406 | if (hl != kNotFound) { |
499 | 322 | else { | 407 | update(tabs_[hl]->get_x(), 0, tabs_[hl]->get_w(), kTabPanelButtonHeight); |
500 | 323 | hl = x / kTabPanelButtonSize; | 408 | } |
501 | 324 | 409 | if (highlight_ != kNotFound) { | |
502 | 325 | if (m_tabs.size() <= static_cast<size_t>(hl)) | 410 | update(tabs_[highlight_]->get_x(), 0, tabs_[highlight_]->get_w(), kTabPanelButtonHeight); |
503 | 326 | hl = -1; | 411 | } |
504 | 327 | } | 412 | highlight_ = hl; |
505 | 328 | 413 | set_tooltip(highlight_ != kNotFound ? tabs_[highlight_]->tooltip : ""); | |
481 | 329 | if (hl != m_highlight) { | ||
482 | 330 | { | ||
483 | 331 | if (hl >= 0) | ||
484 | 332 | set_tooltip(m_tabs[hl]->tooltip); | ||
485 | 333 | } | ||
486 | 334 | if (m_highlight >= 0) | ||
487 | 335 | update | ||
488 | 336 | (m_highlight * kTabPanelButtonSize, 0, | ||
489 | 337 | kTabPanelButtonSize, kTabPanelButtonSize); | ||
490 | 338 | if (hl >= 0) | ||
491 | 339 | update | ||
492 | 340 | (hl * kTabPanelButtonSize, 0, kTabPanelButtonSize, kTabPanelButtonSize); | ||
493 | 341 | |||
494 | 342 | m_highlight = hl; | ||
506 | 343 | } | 414 | } |
507 | 344 | return true; | 415 | return true; |
508 | 345 | } | 416 | } |
509 | @@ -350,25 +421,39 @@ | |||
510 | 350 | */ | 421 | */ |
511 | 351 | bool TabPanel::handle_mousepress(const uint8_t btn, int32_t x, int32_t y) { | 422 | bool TabPanel::handle_mousepress(const uint8_t btn, int32_t x, int32_t y) { |
512 | 352 | if (btn == SDL_BUTTON_LEFT) { | 423 | if (btn == SDL_BUTTON_LEFT) { |
521 | 353 | int32_t id; | 424 | size_t id = find_tab(x, y); |
522 | 354 | 425 | if (id != kNotFound) { | |
515 | 355 | if (y >= kTabPanelButtonSize) | ||
516 | 356 | return false; | ||
517 | 357 | |||
518 | 358 | id = x / kTabPanelButtonSize; | ||
519 | 359 | |||
520 | 360 | if (static_cast<size_t>(id) < m_tabs.size()) { | ||
523 | 361 | activate(id); | 426 | activate(id); |
524 | 362 | |||
525 | 363 | return true; | 427 | return true; |
526 | 364 | } | 428 | } |
527 | 365 | } | 429 | } |
528 | 366 | |||
529 | 367 | return false; | 430 | return false; |
530 | 368 | } | 431 | } |
531 | 432 | |||
532 | 369 | bool TabPanel::handle_mouserelease(uint8_t, int32_t, int32_t) | 433 | bool TabPanel::handle_mouserelease(uint8_t, int32_t, int32_t) |
533 | 370 | { | 434 | { |
534 | 371 | return false; | 435 | return false; |
535 | 372 | } | 436 | } |
536 | 373 | 437 | ||
537 | 438 | |||
538 | 439 | /** | ||
539 | 440 | * Find the tab at the coordinates x, y | ||
540 | 441 | * Returns kNotFound if no tab was found | ||
541 | 442 | */ | ||
542 | 443 | size_t TabPanel::find_tab(int32_t x, int32_t y) const { | ||
543 | 444 | if (y < 0 || y >= kTabPanelButtonHeight) { | ||
544 | 445 | return kNotFound; | ||
545 | 446 | } | ||
546 | 447 | |||
547 | 448 | int32_t width = 0; | ||
548 | 449 | for (size_t id = 0; id < tabs_.size(); ++id) { | ||
549 | 450 | width += tabs_[id]->get_w(); | ||
550 | 451 | if (width > x) { | ||
551 | 452 | return id; | ||
552 | 453 | } | ||
553 | 454 | } | ||
554 | 455 | return kNotFound; | ||
555 | 456 | } | ||
556 | 457 | |||
557 | 458 | |||
558 | 374 | } | 459 | } |
559 | 375 | 460 | ||
560 | === modified file 'src/ui_basic/tabpanel.h' | |||
561 | --- src/ui_basic/tabpanel.h 2014-09-14 11:31:58 +0000 | |||
562 | +++ src/ui_basic/tabpanel.h 2016-01-01 19:10:55 +0000 | |||
563 | @@ -35,11 +35,16 @@ | |||
564 | 35 | struct Tab : public NamedPanel { | 35 | struct Tab : public NamedPanel { |
565 | 36 | friend struct TabPanel; | 36 | friend struct TabPanel; |
566 | 37 | 37 | ||
567 | 38 | /** If title is not empty, this will be a textual tab. | ||
568 | 39 | * In that case, pic will need to be the rendered title */ | ||
569 | 38 | Tab | 40 | Tab |
570 | 39 | (TabPanel * parent, | 41 | (TabPanel * parent, |
572 | 40 | uint32_t, | 42 | size_t id, |
573 | 43 | int32_t x, | ||
574 | 44 | int32_t w, | ||
575 | 41 | const std::string & name, | 45 | const std::string & name, |
577 | 42 | const Image*, | 46 | const std::string & title, |
578 | 47 | const Image* pic, | ||
579 | 43 | const std::string & gtooltip, | 48 | const std::string & gtooltip, |
580 | 44 | Panel * gpanel); | 49 | Panel * gpanel); |
581 | 45 | 50 | ||
582 | @@ -47,12 +52,18 @@ | |||
583 | 47 | void activate(); | 52 | void activate(); |
584 | 48 | 53 | ||
585 | 49 | private: | 54 | private: |
588 | 50 | TabPanel * m_parent; | 55 | // Leave handling the mouse move to the TabPanel. |
589 | 51 | uint32_t m_id; | 56 | bool handle_mousemove(uint8_t, int32_t, int32_t, int32_t, int32_t) override {return false;} |
590 | 57 | // Play click | ||
591 | 58 | bool handle_mousepress(uint8_t, int32_t, int32_t) override; | ||
592 | 59 | |||
593 | 60 | TabPanel* parent; | ||
594 | 61 | uint32_t id; | ||
595 | 52 | 62 | ||
596 | 53 | const Image* pic; | 63 | const Image* pic; |
597 | 64 | std::string title; | ||
598 | 54 | std::string tooltip; | 65 | std::string tooltip; |
600 | 55 | Panel * panel; | 66 | Panel* panel; |
601 | 56 | }; | 67 | }; |
602 | 57 | 68 | ||
603 | 58 | /** | 69 | /** |
604 | @@ -66,15 +77,30 @@ | |||
605 | 66 | * | 77 | * |
606 | 67 | */ | 78 | */ |
607 | 68 | struct TabPanel : public Panel { | 79 | struct TabPanel : public Panel { |
608 | 80 | enum class Type { | ||
609 | 81 | kNoBorder, | ||
610 | 82 | kBorder | ||
611 | 83 | }; | ||
612 | 84 | |||
613 | 69 | friend struct Tab; | 85 | friend struct Tab; |
614 | 70 | 86 | ||
616 | 71 | TabPanel(Panel * parent, int32_t x, int32_t y, const Image* background); | 87 | TabPanel(Panel * parent, int32_t x, int32_t y, const Image* background, |
617 | 88 | TabPanel::Type border_type = TabPanel::Type::kNoBorder); | ||
618 | 72 | // For Fullscreen menus | 89 | // For Fullscreen menus |
619 | 73 | TabPanel | 90 | TabPanel |
620 | 74 | (Panel * parent, | 91 | (Panel * parent, |
621 | 75 | int32_t x, int32_t y, int32_t w, int32_t h, | 92 | int32_t x, int32_t y, int32_t w, int32_t h, |
624 | 76 | const Image* background); | 93 | const Image* background, |
625 | 77 | 94 | TabPanel::Type border_type = TabPanel::Type::kNoBorder); | |
626 | 95 | |||
627 | 96 | /** Add textual tab */ | ||
628 | 97 | uint32_t add | ||
629 | 98 | (const std::string & name, | ||
630 | 99 | const std::string & title, | ||
631 | 100 | Panel * panel, | ||
632 | 101 | const std::string & tooltip = std::string()); | ||
633 | 102 | |||
634 | 103 | /** Add pictorial tab */ | ||
635 | 78 | uint32_t add | 104 | uint32_t add |
636 | 79 | (const std::string & name, | 105 | (const std::string & name, |
637 | 80 | const Image* pic, | 106 | const Image* pic, |
638 | @@ -86,13 +112,21 @@ | |||
639 | 86 | const TabList & tabs(); | 112 | const TabList & tabs(); |
640 | 87 | void activate(uint32_t idx); | 113 | void activate(uint32_t idx); |
641 | 88 | void activate(const std::string &); | 114 | void activate(const std::string &); |
643 | 89 | uint32_t active() {return m_active;} | 115 | uint32_t active() {return active_;} |
644 | 90 | 116 | ||
645 | 91 | protected: | 117 | protected: |
646 | 92 | void layout() override; | 118 | void layout() override; |
647 | 93 | void update_desired_size() override; | 119 | void update_desired_size() override; |
648 | 94 | 120 | ||
649 | 95 | private: | 121 | private: |
650 | 122 | // Common adding function for textual and pictorial tabs | ||
651 | 123 | uint32_t add_tab(int32_t width, | ||
652 | 124 | const std::string& name, | ||
653 | 125 | const std::string& title, | ||
654 | 126 | const Image* pic, | ||
655 | 127 | const std::string& tooltip, | ||
656 | 128 | Panel* contents); | ||
657 | 129 | |||
658 | 96 | // Drawing and event handlers | 130 | // Drawing and event handlers |
659 | 97 | void draw(RenderTarget &) override; | 131 | void draw(RenderTarget &) override; |
660 | 98 | 132 | ||
661 | @@ -102,12 +136,14 @@ | |||
662 | 102 | (uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff) override; | 136 | (uint8_t state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff) override; |
663 | 103 | void handle_mousein(bool inside) override; | 137 | void handle_mousein(bool inside) override; |
664 | 104 | 138 | ||
671 | 105 | 139 | size_t find_tab(int32_t x, int32_t y) const; | |
672 | 106 | TabList m_tabs; | 140 | |
673 | 107 | uint32_t m_active; ///< index of the currently active tab | 141 | TabList tabs_; |
674 | 108 | int32_t m_highlight; ///< index of the highlighted button | 142 | size_t active_; ///< index of the currently active tab |
675 | 109 | 143 | size_t highlight_; ///< index of the highlighted button | |
676 | 110 | const Image* m_pic_background; ///< picture used to draw background | 144 | |
677 | 145 | const Image* pic_background_; ///< picture used to draw background | ||
678 | 146 | TabPanel::Type border_type_; ///< whether there will be a border around the panels. | ||
679 | 111 | }; | 147 | }; |
680 | 112 | } | 148 | } |
681 | 113 | 149 | ||
682 | 114 | 150 | ||
683 | === modified file 'src/ui_fsmenu/base.h' | |||
684 | --- src/ui_fsmenu/base.h 2015-08-10 19:55:41 +0000 | |||
685 | +++ src/ui_fsmenu/base.h 2016-01-01 19:10:55 +0000 | |||
686 | @@ -45,7 +45,7 @@ | |||
687 | 45 | kOk = static_cast<int>(UI::Panel::Returncodes::kOk), | 45 | kOk = static_cast<int>(UI::Panel::Returncodes::kOk), |
688 | 46 | 46 | ||
689 | 47 | // Options | 47 | // Options |
691 | 48 | kRestart, | 48 | kApplyOptions, |
692 | 49 | 49 | ||
693 | 50 | // Main menu | 50 | // Main menu |
694 | 51 | kTutorial, | 51 | kTutorial, |
695 | 52 | 52 | ||
696 | === modified file 'src/ui_fsmenu/options.cc' | |||
697 | --- src/ui_fsmenu/options.cc 2015-12-01 21:52:24 +0000 | |||
698 | +++ src/ui_fsmenu/options.cc 2016-01-01 19:10:55 +0000 | |||
699 | @@ -96,184 +96,241 @@ | |||
700 | 96 | FullscreenMenuOptions::FullscreenMenuOptions | 96 | FullscreenMenuOptions::FullscreenMenuOptions |
701 | 97 | (OptionsCtrl::OptionsStruct opt) | 97 | (OptionsCtrl::OptionsStruct opt) |
702 | 98 | : | 98 | : |
704 | 99 | FullscreenMenuBase("optionsmenu.jpg"), | 99 | FullscreenMenuBase("ui_fsmenu.jpg"), |
705 | 100 | 100 | ||
706 | 101 | // Values for alignment and size | 101 | // Values for alignment and size |
732 | 102 | m_vbutw (get_h() * 333 / 10000), | 102 | butw_ (get_w() / 5), |
733 | 103 | m_butw (get_w() / 4), | 103 | buth_ (get_h() * 9 / 200), |
734 | 104 | m_buth (get_h() * 9 / 200), | 104 | hmargin_ (get_w() * 19 / 200), |
735 | 105 | m_hmargin (get_w() * 19 / 200), | 105 | padding_ (10), |
736 | 106 | m_padding (10), | 106 | space_ (25), |
737 | 107 | m_space (25), | 107 | tab_panel_width_(get_inner_w() - 2 * hmargin_), |
738 | 108 | m_offset_first_group (get_h() * 1417 / 10000), | 108 | column_width_(tab_panel_width_ - padding_), |
739 | 109 | m_offset_second_group(get_h() * 5833 / 10000), | 109 | tab_panel_y_(get_h() * 14 / 100), |
715 | 110 | |||
716 | 111 | // Buttons | ||
717 | 112 | m_advanced_options | ||
718 | 113 | (this, "advanced_options", | ||
719 | 114 | get_w() * 9 / 80, get_h() * 19 / 20, m_butw, m_buth, | ||
720 | 115 | g_gr->images().get("pics/but2.png"), | ||
721 | 116 | _("Advanced Options"), std::string(), true, false), | ||
722 | 117 | m_cancel | ||
723 | 118 | (this, "cancel", | ||
724 | 119 | get_w() * 51 / 80, get_h() * 19 / 20, m_butw, m_buth, | ||
725 | 120 | g_gr->images().get("pics/but0.png"), | ||
726 | 121 | _("Cancel"), std::string(), true, false), | ||
727 | 122 | m_apply | ||
728 | 123 | (this, "apply", | ||
729 | 124 | get_w() * 3 / 8, get_h() * 19 / 20, m_butw, m_buth, | ||
730 | 125 | g_gr->images().get("pics/but2.png"), | ||
731 | 126 | _("Apply"), std::string(), true, false), | ||
740 | 127 | 110 | ||
741 | 128 | // Title | 111 | // Title |
834 | 129 | m_title | 112 | title_ |
835 | 130 | (this, | 113 | (this, |
836 | 131 | get_w() / 2, get_h() / 40, | 114 | get_w() / 2, buth_, |
837 | 132 | _("General Options"), UI::Align_HCenter), | 115 | _("Options"), UI::Align_HCenter), |
838 | 133 | 116 | ||
839 | 134 | // First options block 'general options', first column | 117 | // Buttons |
840 | 135 | m_label_resolution | 118 | cancel_ |
841 | 136 | (this, | 119 | (this, "cancel", |
842 | 137 | m_hmargin, m_offset_first_group, | 120 | get_w() * 1 / 4 - butw_ / 2, |
843 | 138 | _("In-game resolution"), UI::Align_VCenter), | 121 | get_inner_h() - hmargin_, |
844 | 139 | m_reslist | 122 | butw_, buth_, |
845 | 140 | (this, | 123 | g_gr->images().get("pics/but0.png"), |
846 | 141 | m_hmargin, m_label_resolution.get_y() + m_label_resolution.get_h(), | 124 | _("Cancel"), std::string(), true, false), |
847 | 142 | (get_w() - 2 * m_hmargin - m_space) / 2, 95, | 125 | apply_ |
848 | 143 | UI::Align_Left, true), | 126 | (this, "apply", |
849 | 144 | 127 | get_w() * 2 / 4 - butw_ / 2, | |
850 | 145 | m_fullscreen (this, Point(m_hmargin, | 128 | get_inner_h() - hmargin_, |
851 | 146 | m_reslist.get_y() + | 129 | butw_, buth_, |
852 | 147 | m_reslist.get_h() + m_padding), | 130 | g_gr->images().get("pics/but0.png"), |
853 | 148 | _("Fullscreen")), | 131 | _("Apply"), std::string(), true, false), |
854 | 149 | m_inputgrab (this, Point(m_hmargin, | 132 | ok_ |
855 | 150 | m_fullscreen.get_y() + | 133 | (this, "ok", |
856 | 151 | m_fullscreen.get_h() + m_padding), | 134 | get_w() * 3 / 4 - butw_ / 2, |
857 | 152 | _("Grab Input")), | 135 | get_inner_h() - hmargin_, |
858 | 153 | m_sb_maxfps | 136 | butw_, buth_, |
859 | 154 | (this, | 137 | g_gr->images().get("pics/but2.png"), |
860 | 155 | m_hmargin, | 138 | _("OK"), std::string(), true, false), |
861 | 156 | m_inputgrab.get_y() + m_inputgrab.get_h() + m_padding, | 139 | |
862 | 157 | m_reslist.get_w(), 105, | 140 | tabs_(this, hmargin_, 0, |
863 | 158 | opt.maxfps, 0, 99, _("Maximum FPS:"), ""), | 141 | tab_panel_width_, get_inner_h() - tab_panel_y_ - buth_ - hmargin_, |
864 | 159 | 142 | g_gr->images().get("pics/but1.png"), | |
865 | 160 | 143 | UI::TabPanel::Type::kBorder), | |
866 | 161 | // First options block 'general options', second column | 144 | |
867 | 162 | m_label_language | 145 | box_interface_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_), |
868 | 163 | (this, | 146 | box_windows_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_), |
869 | 164 | get_w() - m_hmargin - (get_w() - 2 * m_hmargin - m_space) / 2, m_offset_first_group, | 147 | box_sound_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_), |
870 | 165 | _("Language"), UI::Align_VCenter), | 148 | box_saving_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_), |
871 | 166 | // same height as m_reslist | 149 | box_game_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_), |
872 | 167 | m_language_list | 150 | box_language_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_), |
873 | 168 | (this, | 151 | |
874 | 169 | m_label_language.get_x(), m_label_language.get_y() + m_label_language.get_h(), | 152 | // Interface options |
875 | 170 | (get_w() - 2 * m_hmargin - m_space) / 2, m_reslist.get_h(), | 153 | label_resolution_(&box_interface_, _("In-game resolution"), UI::Align_Left), |
876 | 171 | UI::Align_Left, true), | 154 | resolution_list_(&box_interface_, 0, 0, column_width_ / 2, 80, UI::Align_Left, true), |
877 | 172 | 155 | ||
878 | 173 | m_music (this, Point(m_label_language.get_x(), | 156 | fullscreen_ (&box_interface_, Point(0, 0), _("Fullscreen"), "", column_width_), |
879 | 174 | m_language_list.get_y() + | 157 | inputgrab_ (&box_interface_, Point(0, 0), _("Grab Input"), "", column_width_), |
880 | 175 | m_language_list.get_h() + m_padding), | 158 | |
881 | 176 | _("Enable Music")), | 159 | sb_maxfps_(&box_interface_, 0, 0, column_width_ / 2, column_width_ / 4, |
882 | 177 | m_fx (this, Point(m_label_language.get_x(), | 160 | opt.maxfps, 0, 99, |
883 | 178 | m_music.get_y() + | 161 | _("Maximum FPS:"), ""), |
884 | 179 | m_music.get_h() + m_padding), | 162 | |
885 | 180 | _("Enable Sound Effects")), | 163 | |
886 | 181 | 164 | // Windows options | |
887 | 182 | // Second options block 'In-game options' | 165 | snap_win_overlap_only_(&box_windows_, Point(0, 0), _("Snap windows only when overlapping"), |
888 | 183 | // Title 2 | 166 | "", column_width_), |
889 | 184 | m_label_game_options | 167 | dock_windows_to_edges_(&box_windows_, Point(0, 0), _("Dock windows to edges"), |
890 | 185 | (this, | 168 | "", column_width_), |
891 | 186 | get_w() / 2, get_h() / 2, | 169 | |
892 | 187 | _("In-game Options"), UI::Align_HCenter), | 170 | sb_dis_panel_ |
893 | 188 | 171 | (&box_windows_, 0, 0, column_width_, 200, | |
894 | 189 | /** TRANSLATORS: A watchwindow is a window where you keep watching an object or a map region,*/ | 172 | opt.panel_snap_distance, 0, 99, _("Distance for windows to snap to other panels:"), |
895 | 190 | /** TRANSLATORS: and it also lets you jump to it on the map. */ | 173 | /** TRANSLATORS: Options: Distance for windows to snap to other panels: */ |
896 | 191 | m_single_watchwin (this, Point(m_hmargin, m_offset_second_group), _("Use single watchwindow mode")), | 174 | /** TRANSLATORS: This will have a number added in front of it */ |
897 | 192 | 175 | ngettext("pixel", "pixels", opt.panel_snap_distance)), | |
898 | 193 | m_auto_roadbuild_mode (this, Point(m_single_watchwin.get_x(), | 176 | |
899 | 194 | m_single_watchwin.get_y() + | 177 | sb_dis_border_ |
900 | 195 | m_single_watchwin.get_h() + m_padding), | 178 | (&box_windows_, 0, 0, column_width_, 200, |
901 | 196 | _("Start building road after placing a flag")), | 179 | opt.border_snap_distance, 0, 99, |
902 | 197 | m_show_workarea_preview | 180 | _("Distance for windows to snap to borders:"), |
903 | 198 | (this, Point(m_auto_roadbuild_mode.get_x(), | 181 | /** TRANSLATORS: Options: Distance for windows to snap to borders: */ |
904 | 199 | m_auto_roadbuild_mode.get_y() + | 182 | /** TRANSLATORS: This will have a number added in front of it */ |
905 | 200 | m_auto_roadbuild_mode.get_h() + m_padding), | 183 | ngettext("pixel", "pixels", opt.border_snap_distance)), |
906 | 201 | _("Show buildings area preview")), | 184 | |
907 | 202 | 185 | // Sound options | |
908 | 203 | m_snap_win_overlap_only | 186 | music_ (&box_sound_, Point(0, 0), _("Enable Music"), "", column_width_), |
909 | 204 | (this, Point(m_show_workarea_preview.get_x(), | 187 | fx_ (&box_sound_, Point(0, 0), _("Enable Sound Effects"), "", column_width_), |
910 | 205 | m_show_workarea_preview.get_y() + | 188 | message_sound_(&box_sound_, Point(0, 0), _("Play a sound at message arrival"), |
911 | 206 | m_show_workarea_preview.get_h() + m_padding), | 189 | "", column_width_), |
912 | 207 | _("Snap windows only when overlapping")), | 190 | |
913 | 208 | 191 | // Saving options | |
914 | 209 | m_dock_windows_to_edges (this, Point(m_snap_win_overlap_only.get_x(), | 192 | sb_autosave_ |
915 | 210 | m_snap_win_overlap_only.get_y() + | 193 | (&box_saving_, 0, 0, column_width_, 240, |
916 | 211 | m_snap_win_overlap_only.get_h() + m_padding), | 194 | opt.autosave / 60, 0, 100, _("Save game automatically every"), |
825 | 212 | _("Dock windows to edges")), | ||
826 | 213 | m_sb_autosave | ||
827 | 214 | (this, | ||
828 | 215 | m_hmargin, | ||
829 | 216 | m_dock_windows_to_edges.get_y() + m_dock_windows_to_edges.get_h() + m_padding, | ||
830 | 217 | get_w() - 2 * m_hmargin, | ||
831 | 218 | 240, | ||
832 | 219 | opt.autosave / 60, 0, 100, | ||
833 | 220 | _("Save game automatically every"), | ||
917 | 221 | /** TRANSLATORS: Options: Save game automatically every: */ | 195 | /** TRANSLATORS: Options: Save game automatically every: */ |
918 | 222 | /** TRANSLATORS: This will have a number added in front of it */ | 196 | /** TRANSLATORS: This will have a number added in front of it */ |
919 | 223 | ngettext("minute", "minutes", opt.autosave / 60), | 197 | ngettext("minute", "minutes", opt.autosave / 60), |
920 | 224 | g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig), | 198 | g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig), |
921 | 225 | 199 | ||
930 | 226 | m_sb_remove_replays | 200 | sb_rolling_autosave_ |
931 | 227 | (this, | 201 | (&box_saving_, 0, 0, column_width_, 240, |
932 | 228 | m_hmargin, | 202 | opt.rolling_autosave, 1, 20, _("Maximum number of autosave files"), |
933 | 229 | m_sb_autosave.get_y() + m_sb_autosave.get_h() + m_padding, | 203 | "", |
934 | 230 | get_w() - 2 * m_hmargin, | 204 | g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig), |
935 | 231 | 240, | 205 | |
936 | 232 | opt.remove_replays, 0, 365, | 206 | sb_remove_replays_ |
937 | 233 | _("Remove replays older than:"), | 207 | (&box_saving_, 0, 0, column_width_, 240, |
938 | 208 | opt.remove_replays, 0, 365, _("Remove replays older than:"), | ||
939 | 234 | /** TRANSLATORS: Options: Remove Replays older than: */ | 209 | /** TRANSLATORS: Options: Remove Replays older than: */ |
940 | 235 | /** TRANSLATORS: This will have a number added in front of it */ | 210 | /** TRANSLATORS: This will have a number added in front of it */ |
941 | 236 | ngettext("day", "days", opt.remove_replays), | 211 | ngettext("day", "days", opt.remove_replays), |
942 | 237 | g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig), | 212 | g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig), |
944 | 238 | os(opt) | 213 | |
945 | 214 | nozip_(&box_saving_, Point(0, 0), _("Do not zip widelands data files (maps, replays and savegames)"), | ||
946 | 215 | "", column_width_), | ||
947 | 216 | remove_syncstreams_(&box_saving_, Point(0, 0), _("Remove Syncstream dumps on startup"), | ||
948 | 217 | "", column_width_), | ||
949 | 218 | |||
950 | 219 | // Game options | ||
951 | 220 | auto_roadbuild_mode_(&box_game_, Point(0, 0), _("Start building road after placing a flag")), | ||
952 | 221 | show_workarea_preview_(&box_game_, Point(0, 0), _("Show buildings area preview")), | ||
953 | 222 | transparent_chat_(&box_game_, Point(0, 0), _("Show in-game chat with transparent background"), | ||
954 | 223 | "", column_width_), | ||
955 | 224 | |||
956 | 225 | /** TRANSLATORS: A watchwindow is a window where you keep watching an object or a map region,*/ | ||
957 | 226 | /** TRANSLATORS: and it also lets you jump to it on the map. */ | ||
958 | 227 | single_watchwin_(&box_game_, Point(0, 0), _("Use single watchwindow mode")), | ||
959 | 228 | |||
960 | 229 | // Language options | ||
961 | 230 | label_language_(&box_language_, _("Language"), UI::Align_Left), | ||
962 | 231 | language_list_(&box_language_, 0, 0, column_width_ / 2, | ||
963 | 232 | get_inner_h() - tab_panel_y_ - buth_ - hmargin_ - 5 * padding_, | ||
964 | 233 | UI::Align_Left, true), | ||
965 | 234 | |||
966 | 235 | os_(opt) | ||
967 | 239 | { | 236 | { |
972 | 240 | m_advanced_options.sigclicked.connect | 237 | // Set up UI Elements |
973 | 241 | (boost::bind(&FullscreenMenuOptions::advanced_options, boost::ref(*this))); | 238 | title_ .set_textstyle(UI::TextStyle::ui_big()); |
974 | 242 | m_cancel.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_back, this)); | 239 | |
975 | 243 | m_apply.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_ok, this)); | 240 | tabs_.add("options_interface", _("Interface"), &box_interface_, ""); |
976 | 241 | tabs_.add("options_windows", _("Windows"), &box_windows_, ""); | ||
977 | 242 | tabs_.add("options_sound", _("Sound"), &box_sound_, ""); | ||
978 | 243 | tabs_.add("options_saving", _("Saving"), &box_saving_, ""); | ||
979 | 244 | tabs_.add("options_game", _("Game"), &box_game_, ""); | ||
980 | 245 | tabs_.add("options_language", _("Language"), &box_language_, ""); | ||
981 | 246 | |||
982 | 247 | // We want the last active tab when "Apply" was clicked. | ||
983 | 248 | if (os_.active_tab < tabs_.tabs().size()) { | ||
984 | 249 | tabs_.activate(os_.active_tab); | ||
985 | 250 | } | ||
986 | 251 | |||
987 | 252 | tabs_.set_pos(Point(hmargin_, tab_panel_y_)); | ||
988 | 253 | |||
989 | 254 | box_interface_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h()); | ||
990 | 255 | box_windows_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h()); | ||
991 | 256 | box_sound_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h()); | ||
992 | 257 | box_saving_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h()); | ||
993 | 258 | box_game_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h()); | ||
994 | 259 | box_language_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h()); | ||
995 | 260 | |||
996 | 261 | // Interface | ||
997 | 262 | box_interface_.add(&label_resolution_, UI::Align_Left); | ||
998 | 263 | box_interface_.add(&resolution_list_, UI::Align_Left); | ||
999 | 264 | box_interface_.add(&fullscreen_, UI::Align_Left); | ||
1000 | 265 | box_interface_.add(&inputgrab_, UI::Align_Left); | ||
1001 | 266 | box_interface_.add(&sb_maxfps_, UI::Align_Left); | ||
1002 | 267 | |||
1003 | 268 | // Windows | ||
1004 | 269 | box_windows_.add(&snap_win_overlap_only_, UI::Align_Left); | ||
1005 | 270 | box_windows_.add(&dock_windows_to_edges_, UI::Align_Left); | ||
1006 | 271 | box_windows_.add(&sb_dis_panel_, UI::Align_Left); | ||
1007 | 272 | box_windows_.add(&sb_dis_border_, UI::Align_Left); | ||
1008 | 273 | |||
1009 | 274 | // Sound | ||
1010 | 275 | box_sound_.add(&music_, UI::Align_Left); | ||
1011 | 276 | box_sound_.add(&fx_, UI::Align_Left); | ||
1012 | 277 | box_sound_.add(&message_sound_, UI::Align_Left); | ||
1013 | 278 | |||
1014 | 279 | // Saving | ||
1015 | 280 | box_saving_.add(&sb_autosave_, UI::Align_Left); | ||
1016 | 281 | box_saving_.add(&sb_rolling_autosave_, UI::Align_Left); | ||
1017 | 282 | box_saving_.add(&sb_remove_replays_, UI::Align_Left); | ||
1018 | 283 | box_saving_.add(&nozip_, UI::Align_Left); | ||
1019 | 284 | box_saving_.add(&remove_syncstreams_, UI::Align_Left); | ||
1020 | 285 | |||
1021 | 286 | // Game | ||
1022 | 287 | box_game_.add(&auto_roadbuild_mode_, UI::Align_Left); | ||
1023 | 288 | box_game_.add(&show_workarea_preview_, UI::Align_Left); | ||
1024 | 289 | box_game_.add(&transparent_chat_, UI::Align_Left); | ||
1025 | 290 | box_game_.add(&single_watchwin_, UI::Align_Left); | ||
1026 | 291 | |||
1027 | 292 | // Language | ||
1028 | 293 | box_language_.add(&label_language_, UI::Align_Left); | ||
1029 | 294 | box_language_.add(&language_list_, UI::Align_Left); | ||
1030 | 295 | |||
1031 | 296 | |||
1032 | 297 | // Bind actions | ||
1033 | 298 | cancel_.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_back, this)); | ||
1034 | 299 | apply_.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_apply, this)); | ||
1035 | 300 | ok_.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_ok, this)); | ||
1036 | 244 | 301 | ||
1037 | 245 | /** TRANSLATORS Options: Save game automatically every: */ | 302 | /** TRANSLATORS Options: Save game automatically every: */ |
1040 | 246 | m_sb_autosave .add_replacement(0, _("Off")); | 303 | sb_autosave_ .add_replacement(0, _("Off")); |
1041 | 247 | for (UI::Button* temp_button : m_sb_autosave.get_buttons()) { | 304 | for (UI::Button* temp_button : sb_autosave_.get_buttons()) { |
1042 | 248 | temp_button->sigclicked.connect | 305 | temp_button->sigclicked.connect |
1043 | 249 | (boost::bind | 306 | (boost::bind |
1044 | 250 | (&FullscreenMenuOptions::update_sb_autosave_unit, | 307 | (&FullscreenMenuOptions::update_sb_autosave_unit, |
1045 | 251 | boost::ref(*this))); | 308 | boost::ref(*this))); |
1046 | 252 | } | 309 | } |
1047 | 253 | /** TRANSLATORS Options: Remove Replays older than: */ | 310 | /** TRANSLATORS Options: Remove Replays older than: */ |
1050 | 254 | m_sb_remove_replays.add_replacement(0, _("Never")); | 311 | sb_remove_replays_.add_replacement(0, _("Never")); |
1051 | 255 | for (UI::Button* temp_button : m_sb_remove_replays.get_buttons()) { | 312 | for (UI::Button* temp_button : sb_remove_replays_.get_buttons()) { |
1052 | 256 | temp_button->sigclicked.connect | 313 | temp_button->sigclicked.connect |
1053 | 257 | (boost::bind | 314 | (boost::bind |
1054 | 258 | (&FullscreenMenuOptions::update_sb_remove_replays_unit, | 315 | (&FullscreenMenuOptions::update_sb_remove_replays_unit, |
1055 | 259 | boost::ref(*this))); | 316 | boost::ref(*this))); |
1056 | 260 | } | 317 | } |
1073 | 261 | 318 | for (UI::Button* temp_button : sb_dis_panel_.get_buttons()) { | |
1074 | 262 | m_title .set_textstyle(UI::TextStyle::ui_big()); | 319 | temp_button->sigclicked.connect |
1075 | 263 | m_fullscreen .set_state(opt.fullscreen); | 320 | (boost::bind |
1076 | 264 | m_inputgrab .set_state(opt.inputgrab); | 321 | (&FullscreenMenuOptions::update_sb_dis_panel_unit, |
1077 | 265 | m_music .set_state(opt.music); | 322 | boost::ref(*this))); |
1078 | 266 | m_music .set_enabled(!g_sound_handler.lock_audio_disabling_); | 323 | } |
1079 | 267 | m_fx .set_state(opt.fx); | 324 | |
1080 | 268 | m_fx .set_enabled(!g_sound_handler.lock_audio_disabling_); | 325 | for (UI::Button* temp_button : sb_dis_border_.get_buttons()) { |
1081 | 269 | 326 | temp_button->sigclicked.connect | |
1082 | 270 | m_label_game_options .set_textstyle(UI::TextStyle::ui_big()); | 327 | (boost::bind |
1083 | 271 | m_single_watchwin .set_state(opt.single_watchwin); | 328 | (&FullscreenMenuOptions::update_sb_dis_border_unit, |
1084 | 272 | m_auto_roadbuild_mode .set_state(opt.auto_roadbuild_mode); | 329 | boost::ref(*this))); |
1085 | 273 | m_show_workarea_preview .set_state(opt.show_warea); | 330 | } |
1086 | 274 | m_snap_win_overlap_only .set_state(opt.snap_win_overlap_only); | 331 | |
1087 | 275 | m_dock_windows_to_edges .set_state(opt.dock_windows_to_edges); | 332 | // Fill in data |
1088 | 276 | 333 | // Interface options | |
1089 | 277 | for (int modes = 0; modes < SDL_GetNumDisplayModes(0); ++modes) { | 334 | for (int modes = 0; modes < SDL_GetNumDisplayModes(0); ++modes) { |
1090 | 278 | SDL_DisplayMode mode; | 335 | SDL_DisplayMode mode; |
1091 | 279 | SDL_GetDisplayMode(0, modes, & mode); | 336 | SDL_GetDisplayMode(0, modes, & mode); |
1092 | @@ -281,64 +338,89 @@ | |||
1093 | 281 | (SDL_BITSPERPIXEL(mode.format) == 32 || | 338 | (SDL_BITSPERPIXEL(mode.format) == 32 || |
1094 | 282 | SDL_BITSPERPIXEL(mode.format) == 24)) { | 339 | SDL_BITSPERPIXEL(mode.format) == 24)) { |
1095 | 283 | ScreenResolution this_res = { | 340 | ScreenResolution this_res = { |
1097 | 284 | mode.w, mode.h, static_cast<int32_t>(SDL_BITSPERPIXEL(mode.format))}; | 341 | mode.w, mode.h, static_cast<int32_t>(SDL_BITSPERPIXEL(mode.format))}; |
1098 | 285 | if (this_res.depth == 24) this_res.depth = 32; | 342 | if (this_res.depth == 24) this_res.depth = 32; |
1103 | 286 | if (m_resolutions.empty() | 343 | if (resolutions_.empty() |
1104 | 287 | || this_res.xres != m_resolutions.rbegin()->xres | 344 | || this_res.xres != resolutions_.rbegin()->xres |
1105 | 288 | || this_res.yres != m_resolutions.rbegin()->yres) { | 345 | || this_res.yres != resolutions_.rbegin()->yres) { |
1106 | 289 | m_resolutions.push_back(this_res); | 346 | resolutions_.push_back(this_res); |
1107 | 290 | } | 347 | } |
1108 | 291 | } | 348 | } |
1109 | 292 | } | 349 | } |
1110 | 293 | 350 | ||
1111 | 294 | bool did_select_a_res = false; | 351 | bool did_select_a_res = false; |
1113 | 295 | for (uint32_t i = 0; i < m_resolutions.size(); ++i) { | 352 | for (uint32_t i = 0; i < resolutions_.size(); ++i) { |
1114 | 296 | const bool selected = | 353 | const bool selected = |
1117 | 297 | m_resolutions[i].xres == opt.xres && | 354 | resolutions_[i].xres == opt.xres && |
1118 | 298 | m_resolutions[i].yres == opt.yres; | 355 | resolutions_[i].yres == opt.yres; |
1119 | 299 | did_select_a_res |= selected; | 356 | did_select_a_res |= selected; |
1120 | 300 | /** TRANSLATORS: Screen resolution, e.g. 800 x 600*/ | 357 | /** TRANSLATORS: Screen resolution, e.g. 800 x 600*/ |
1124 | 301 | m_reslist.add((boost::format(_("%1% x %2%")) | 358 | resolution_list_.add((boost::format(_("%1% x %2%")) |
1125 | 302 | % m_resolutions[i].xres | 359 | % resolutions_[i].xres |
1126 | 303 | % m_resolutions[i].yres).str(), | 360 | % resolutions_[i].yres).str(), |
1127 | 304 | nullptr, nullptr, selected); | 361 | nullptr, nullptr, selected); |
1128 | 305 | } | 362 | } |
1129 | 306 | if (!did_select_a_res) { | 363 | if (!did_select_a_res) { |
1131 | 307 | m_reslist.add((boost::format(_("%1% x %2%")) | 364 | resolution_list_.add((boost::format(_("%1% x %2%")) |
1132 | 308 | % opt.xres | 365 | % opt.xres |
1133 | 309 | % opt.yres).str(), | 366 | % opt.yres).str(), |
1134 | 310 | nullptr, nullptr, true); | 367 | nullptr, nullptr, true); |
1139 | 311 | uint32_t entry = m_resolutions.size(); | 368 | uint32_t entry = resolutions_.size(); |
1140 | 312 | m_resolutions.resize(entry + 1); | 369 | resolutions_.resize(entry + 1); |
1141 | 313 | m_resolutions[entry].xres = opt.xres; | 370 | resolutions_[entry].xres = opt.xres; |
1142 | 314 | m_resolutions[entry].yres = opt.yres; | 371 | resolutions_[entry].yres = opt.yres; |
1143 | 315 | } | 372 | } |
1144 | 316 | 373 | ||
1145 | 374 | fullscreen_ .set_state(opt.fullscreen); | ||
1146 | 375 | inputgrab_ .set_state(opt.inputgrab); | ||
1147 | 376 | |||
1148 | 377 | // Windows options | ||
1149 | 378 | snap_win_overlap_only_.set_state(opt.snap_win_overlap_only); | ||
1150 | 379 | dock_windows_to_edges_.set_state(opt.dock_windows_to_edges); | ||
1151 | 380 | |||
1152 | 381 | // Sound options | ||
1153 | 382 | music_ .set_state(opt.music); | ||
1154 | 383 | music_ .set_enabled(!g_sound_handler.lock_audio_disabling_); | ||
1155 | 384 | fx_ .set_state(opt.fx); | ||
1156 | 385 | fx_ .set_enabled(!g_sound_handler.lock_audio_disabling_); | ||
1157 | 386 | message_sound_ .set_state(opt.message_sound); | ||
1158 | 387 | |||
1159 | 388 | // Saving options | ||
1160 | 389 | nozip_ .set_state(opt.nozip); | ||
1161 | 390 | remove_syncstreams_ .set_state(opt.remove_syncstreams); | ||
1162 | 391 | |||
1163 | 392 | // Game options | ||
1164 | 393 | auto_roadbuild_mode_ .set_state(opt.auto_roadbuild_mode); | ||
1165 | 394 | show_workarea_preview_.set_state(opt.show_warea); | ||
1166 | 395 | transparent_chat_ .set_state(opt.transparent_chat); | ||
1167 | 396 | single_watchwin_ .set_state(opt.single_watchwin); | ||
1168 | 397 | |||
1169 | 398 | // Language options | ||
1170 | 317 | add_languages_to_list(opt.language); | 399 | add_languages_to_list(opt.language); |
1172 | 318 | m_language_list.focus(); | 400 | language_list_.focus(); |
1173 | 319 | } | 401 | } |
1174 | 320 | 402 | ||
1175 | 321 | void FullscreenMenuOptions::update_sb_autosave_unit() { | 403 | void FullscreenMenuOptions::update_sb_autosave_unit() { |
1177 | 322 | m_sb_autosave.set_unit(ngettext("minute", "minutes", m_sb_autosave.get_value())); | 404 | sb_autosave_.set_unit(ngettext("minute", "minutes", sb_autosave_.get_value())); |
1178 | 323 | } | 405 | } |
1179 | 324 | 406 | ||
1180 | 325 | void FullscreenMenuOptions::update_sb_remove_replays_unit() { | 407 | void FullscreenMenuOptions::update_sb_remove_replays_unit() { |
1190 | 326 | m_sb_remove_replays.set_unit(ngettext("day", "days", m_sb_remove_replays.get_value())); | 408 | sb_remove_replays_.set_unit(ngettext("day", "days", sb_remove_replays_.get_value())); |
1191 | 327 | } | 409 | } |
1192 | 328 | 410 | ||
1193 | 329 | void FullscreenMenuOptions::advanced_options() { | 411 | void FullscreenMenuOptions::update_sb_dis_panel_unit() { |
1194 | 330 | FullscreenMenuAdvancedOptions aom(os); | 412 | sb_dis_panel_.set_unit(ngettext("pixel", "pixels", sb_dis_panel_.get_value())); |
1195 | 331 | if (aom.run<FullscreenMenuBase::MenuTarget>() == FullscreenMenuBase::MenuTarget::kOk) { | 413 | } |
1196 | 332 | os = aom.get_values(); | 414 | |
1197 | 333 | end_modal<FullscreenMenuBase::MenuTarget>(FullscreenMenuBase::MenuTarget::kRestart); | 415 | void FullscreenMenuOptions::update_sb_dis_border_unit() { |
1198 | 334 | } | 416 | sb_dis_border_.set_unit(ngettext("pixel", "pixels", sb_dis_border_.get_value())); |
1199 | 335 | } | 417 | } |
1200 | 336 | 418 | ||
1201 | 337 | void FullscreenMenuOptions::add_languages_to_list(const std::string& current_locale) { | 419 | void FullscreenMenuOptions::add_languages_to_list(const std::string& current_locale) { |
1202 | 338 | 420 | ||
1203 | 339 | // We want these two entries on top - the most likely user's choice and the default. | 421 | // We want these two entries on top - the most likely user's choice and the default. |
1206 | 340 | m_language_list.add(_("Try system language"), "", nullptr, current_locale == ""); | 422 | language_list_.add(_("Try system language"), "", nullptr, current_locale == ""); |
1207 | 341 | m_language_list.add("English", "en", nullptr, current_locale == "en"); | 423 | language_list_.add("English", "en", nullptr, current_locale == "en"); |
1208 | 342 | 424 | ||
1209 | 343 | // We start with the locale directory so we can pick up locales | 425 | // We start with the locale directory so we can pick up locales |
1210 | 344 | // that don't have a configuration file yet. | 426 | // that don't have a configuration file yet. |
1211 | @@ -391,241 +473,164 @@ | |||
1212 | 391 | 473 | ||
1213 | 392 | std::sort(entries.begin(), entries.end()); | 474 | std::sort(entries.begin(), entries.end()); |
1214 | 393 | for (const LanguageEntry& entry : entries) { | 475 | for (const LanguageEntry& entry : entries) { |
1216 | 394 | m_language_list.add(entry.descname.c_str(), entry.localename, nullptr, | 476 | language_list_.add(entry.descname.c_str(), entry.localename, nullptr, |
1217 | 395 | entry.localename == selected_locale, "", entry.fontname); | 477 | entry.localename == selected_locale, "", entry.fontname); |
1218 | 396 | } | 478 | } |
1219 | 397 | } | 479 | } |
1220 | 398 | 480 | ||
1221 | 399 | 481 | ||
1222 | 482 | void FullscreenMenuOptions::clicked_apply() { | ||
1223 | 483 | end_modal<FullscreenMenuBase::MenuTarget>(FullscreenMenuBase::MenuTarget::kApplyOptions); | ||
1224 | 484 | } | ||
1225 | 485 | |||
1226 | 486 | |||
1227 | 400 | OptionsCtrl::OptionsStruct FullscreenMenuOptions::get_values() { | 487 | OptionsCtrl::OptionsStruct FullscreenMenuOptions::get_values() { |
1228 | 401 | const uint32_t res_index = m_reslist.selection_index(); | ||
1229 | 402 | |||
1230 | 403 | // Write all data from UI elements | 488 | // Write all data from UI elements |
1373 | 404 | os.xres = m_resolutions[res_index].xres; | 489 | // Interface options |
1374 | 405 | os.yres = m_resolutions[res_index].yres; | 490 | const uint32_t res_index = resolution_list_.selection_index(); |
1375 | 406 | os.inputgrab = m_inputgrab.get_state(); | 491 | os_.xres = resolutions_[res_index].xres; |
1376 | 407 | os.fullscreen = m_fullscreen.get_state(); | 492 | os_.yres = resolutions_[res_index].yres; |
1377 | 408 | os.single_watchwin = m_single_watchwin.get_state(); | 493 | os_.fullscreen = fullscreen_.get_state(); |
1378 | 409 | os.auto_roadbuild_mode = m_auto_roadbuild_mode.get_state(); | 494 | os_.inputgrab = inputgrab_.get_state(); |
1379 | 410 | os.show_warea = m_show_workarea_preview.get_state(); | 495 | os_.maxfps = sb_maxfps_.get_value(); |
1380 | 411 | os.snap_win_overlap_only = m_snap_win_overlap_only.get_state(); | 496 | |
1381 | 412 | os.dock_windows_to_edges = m_dock_windows_to_edges.get_state(); | 497 | // Windows options |
1382 | 413 | os.music = m_music.get_state(); | 498 | os_.snap_win_overlap_only = snap_win_overlap_only_.get_state(); |
1383 | 414 | os.fx = m_fx.get_state(); | 499 | os_.dock_windows_to_edges = dock_windows_to_edges_.get_state(); |
1384 | 415 | if (m_language_list.has_selection()) | 500 | os_.panel_snap_distance = sb_dis_panel_.get_value(); |
1385 | 416 | os.language = m_language_list.get_selected(); | 501 | os_.border_snap_distance = sb_dis_border_.get_value(); |
1386 | 417 | os.autosave = m_sb_autosave.get_value(); | 502 | |
1387 | 418 | os.maxfps = m_sb_maxfps.get_value(); | 503 | // Sound options |
1388 | 419 | os.remove_replays = m_sb_remove_replays.get_value(); | 504 | os_.music = music_.get_state(); |
1389 | 420 | 505 | os_.fx = fx_.get_state(); | |
1390 | 421 | return os; | 506 | os_.message_sound = message_sound_.get_state(); |
1391 | 422 | } | 507 | |
1392 | 423 | 508 | // Saving options | |
1393 | 424 | 509 | os_.autosave = sb_autosave_.get_value(); | |
1394 | 425 | /** | 510 | os_.rolling_autosave = sb_rolling_autosave_.get_value(); |
1395 | 426 | * The advanced option menu | 511 | os_.remove_replays = sb_remove_replays_.get_value(); |
1396 | 427 | */ | 512 | os_.nozip = nozip_.get_state(); |
1397 | 428 | FullscreenMenuAdvancedOptions::FullscreenMenuAdvancedOptions | 513 | os_.remove_syncstreams = remove_syncstreams_.get_state(); |
1398 | 429 | (OptionsCtrl::OptionsStruct const opt) | 514 | |
1399 | 430 | : | 515 | // Game options |
1400 | 431 | FullscreenMenuBase("ui_fsmenu.jpg"), | 516 | os_.auto_roadbuild_mode = auto_roadbuild_mode_.get_state(); |
1401 | 432 | 517 | os_.show_warea = show_workarea_preview_.get_state(); | |
1402 | 433 | // Values for alignment and size | 518 | os_.transparent_chat = transparent_chat_.get_state(); |
1403 | 434 | m_vbutw (get_h() * 333 / 10000), | 519 | os_.single_watchwin = single_watchwin_.get_state(); |
1404 | 435 | m_butw (get_w() / 4), | 520 | |
1405 | 436 | m_buth (get_h() * 9 / 200), | 521 | // Language options |
1406 | 437 | m_hmargin (get_w() * 19 / 200), | 522 | if (language_list_.has_selection()) { |
1407 | 438 | m_padding (10), | 523 | os_.language = language_list_.get_selected(); |
1408 | 439 | m_space (25), | 524 | } |
1409 | 440 | 525 | ||
1410 | 441 | // Buttons | 526 | // Last tab for reloading the options menu |
1411 | 442 | m_cancel | 527 | os_.active_tab = tabs_.active(); |
1412 | 443 | (this, "cancel", | 528 | return os_; |
1413 | 444 | get_w() * 41 / 80, get_h() * 19 / 20, m_butw, m_buth, | 529 | } |
1272 | 445 | g_gr->images().get("pics/but0.png"), | ||
1273 | 446 | _("Cancel"), std::string(), true, false), | ||
1274 | 447 | m_apply | ||
1275 | 448 | (this, "apply", | ||
1276 | 449 | get_w() / 4, get_h() * 19 / 20, m_butw, m_buth, | ||
1277 | 450 | g_gr->images().get("pics/but2.png"), | ||
1278 | 451 | _("Apply"), std::string(), true, false), | ||
1279 | 452 | |||
1280 | 453 | // Title | ||
1281 | 454 | m_title | ||
1282 | 455 | (this, | ||
1283 | 456 | get_w() / 2, get_h() * 17 / 150, | ||
1284 | 457 | _("Advanced Options"), UI::Align_HCenter), | ||
1285 | 458 | |||
1286 | 459 | // Spinboxes | ||
1287 | 460 | m_sb_dis_panel | ||
1288 | 461 | (this, | ||
1289 | 462 | m_hmargin, get_h() * 9 / 30, | ||
1290 | 463 | get_w() - 2 * m_hmargin, get_w() / 5, | ||
1291 | 464 | opt.panel_snap_distance, 0, 99, | ||
1292 | 465 | _("Distance for windows to snap to other panels:"), | ||
1293 | 466 | ngettext("pixel", "pixels", opt.panel_snap_distance)), | ||
1294 | 467 | |||
1295 | 468 | m_sb_dis_border | ||
1296 | 469 | (this, | ||
1297 | 470 | m_hmargin, m_sb_dis_panel.get_y() + m_sb_dis_panel.get_h() + 2 * m_padding, | ||
1298 | 471 | get_w() - 2 * m_hmargin, get_w() / 5, | ||
1299 | 472 | opt.border_snap_distance, 0, 99, | ||
1300 | 473 | _("Distance for windows to snap to borders:"), | ||
1301 | 474 | ngettext("pixel", "pixels", opt.border_snap_distance)), | ||
1302 | 475 | |||
1303 | 476 | m_transparent_chat (this, Point(m_hmargin, | ||
1304 | 477 | m_sb_dis_border.get_y() + | ||
1305 | 478 | m_sb_dis_border.get_h() + m_space), | ||
1306 | 479 | _("Show in-game chat with transparent background"), | ||
1307 | 480 | "", get_w() - 2 * m_hmargin), | ||
1308 | 481 | |||
1309 | 482 | m_message_sound | ||
1310 | 483 | (this, Point(m_hmargin, | ||
1311 | 484 | m_transparent_chat.get_y() + | ||
1312 | 485 | m_transparent_chat.get_h() + m_padding), | ||
1313 | 486 | _("Play a sound at message arrival"), | ||
1314 | 487 | "", get_w() - 2 * m_hmargin), | ||
1315 | 488 | |||
1316 | 489 | m_nozip (this, Point(m_hmargin, | ||
1317 | 490 | m_message_sound.get_y() + | ||
1318 | 491 | m_message_sound.get_h() + m_padding), | ||
1319 | 492 | _("Do not zip widelands data files (maps, replays and savegames)"), | ||
1320 | 493 | "", get_w() - 2 * m_hmargin), | ||
1321 | 494 | |||
1322 | 495 | m_remove_syncstreams (this, Point(m_hmargin, | ||
1323 | 496 | m_nozip.get_y() + | ||
1324 | 497 | m_nozip.get_h() + m_padding), | ||
1325 | 498 | _("Remove Syncstream dumps on startup"), | ||
1326 | 499 | "", get_w() - 2 * m_hmargin), | ||
1327 | 500 | |||
1328 | 501 | os(opt) | ||
1329 | 502 | { | ||
1330 | 503 | for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) { | ||
1331 | 504 | temp_button->sigclicked.connect | ||
1332 | 505 | (boost::bind | ||
1333 | 506 | (&FullscreenMenuAdvancedOptions::update_sb_dis_panel_unit, | ||
1334 | 507 | boost::ref(*this))); | ||
1335 | 508 | } | ||
1336 | 509 | |||
1337 | 510 | for (UI::Button* temp_button : m_sb_dis_border.get_buttons()) { | ||
1338 | 511 | temp_button->sigclicked.connect | ||
1339 | 512 | (boost::bind | ||
1340 | 513 | (&FullscreenMenuAdvancedOptions::update_sb_dis_border_unit, | ||
1341 | 514 | boost::ref(*this))); | ||
1342 | 515 | } | ||
1343 | 516 | |||
1344 | 517 | m_cancel.sigclicked.connect(boost::bind(&FullscreenMenuAdvancedOptions::clicked_back, boost::ref(*this))); | ||
1345 | 518 | m_apply.sigclicked.connect(boost::bind(&FullscreenMenuAdvancedOptions::clicked_ok, boost::ref(*this))); | ||
1346 | 519 | |||
1347 | 520 | m_title .set_textstyle(UI::TextStyle::ui_big()); | ||
1348 | 521 | m_message_sound .set_state(opt.message_sound); | ||
1349 | 522 | m_nozip .set_state(opt.nozip); | ||
1350 | 523 | m_remove_syncstreams .set_state(opt.remove_syncstreams); | ||
1351 | 524 | m_transparent_chat .set_state(opt.transparent_chat); | ||
1352 | 525 | } | ||
1353 | 526 | |||
1354 | 527 | void FullscreenMenuAdvancedOptions::update_sb_dis_panel_unit() { | ||
1355 | 528 | m_sb_dis_panel.set_unit(ngettext("pixel", "pixels", m_sb_dis_panel.get_value())); | ||
1356 | 529 | } | ||
1357 | 530 | |||
1358 | 531 | void FullscreenMenuAdvancedOptions::update_sb_dis_border_unit() { | ||
1359 | 532 | m_sb_dis_border.set_unit(ngettext("pixel", "pixels", m_sb_dis_border.get_value())); | ||
1360 | 533 | } | ||
1361 | 534 | |||
1362 | 535 | OptionsCtrl::OptionsStruct FullscreenMenuAdvancedOptions::get_values() { | ||
1363 | 536 | // Write all remaining data from UI elements | ||
1364 | 537 | os.message_sound = m_message_sound.get_state(); | ||
1365 | 538 | os.nozip = m_nozip.get_state(); | ||
1366 | 539 | os.panel_snap_distance = m_sb_dis_panel.get_value(); | ||
1367 | 540 | os.border_snap_distance = m_sb_dis_border.get_value(); | ||
1368 | 541 | os.remove_syncstreams = m_remove_syncstreams.get_state(); | ||
1369 | 542 | os.transparent_chat = m_transparent_chat.get_state(); | ||
1370 | 543 | return os; | ||
1371 | 544 | } | ||
1372 | 545 | |||
1414 | 546 | 530 | ||
1415 | 547 | /** | 531 | /** |
1416 | 548 | * Handles communication between window class and options | 532 | * Handles communication between window class and options |
1417 | 549 | */ | 533 | */ |
1418 | 550 | OptionsCtrl::OptionsCtrl(Section & s) | 534 | OptionsCtrl::OptionsCtrl(Section & s) |
1420 | 551 | : m_opt_section(s), m_opt_dialog(new FullscreenMenuOptions(options_struct())) | 535 | : opt_section_(s), opt_dialog_(std::unique_ptr<FullscreenMenuOptions>(new FullscreenMenuOptions(options_struct(0)))) |
1421 | 552 | { | 536 | { |
1422 | 553 | handle_menu(); | 537 | handle_menu(); |
1423 | 554 | } | 538 | } |
1424 | 555 | 539 | ||
1425 | 556 | OptionsCtrl::~OptionsCtrl() { | ||
1426 | 557 | delete m_opt_dialog; | ||
1427 | 558 | } | ||
1428 | 559 | |||
1429 | 560 | void OptionsCtrl::handle_menu() | 540 | void OptionsCtrl::handle_menu() |
1430 | 561 | { | 541 | { |
1432 | 562 | FullscreenMenuBase::MenuTarget i = m_opt_dialog->run<FullscreenMenuBase::MenuTarget>(); | 542 | FullscreenMenuBase::MenuTarget i = opt_dialog_->run<FullscreenMenuBase::MenuTarget>(); |
1433 | 563 | if (i != FullscreenMenuBase::MenuTarget::kBack) | 543 | if (i != FullscreenMenuBase::MenuTarget::kBack) |
1434 | 564 | save_options(); | 544 | save_options(); |
1438 | 565 | if (i == FullscreenMenuBase::MenuTarget::kRestart) { | 545 | if (i == FullscreenMenuBase::MenuTarget::kApplyOptions) { |
1439 | 566 | delete m_opt_dialog; | 546 | uint32_t active_tab = opt_dialog_->get_values().active_tab; |
1440 | 567 | m_opt_dialog = new FullscreenMenuOptions(options_struct()); | 547 | g_gr->change_resolution(opt_dialog_->get_values().xres, opt_dialog_->get_values().yres); |
1441 | 548 | g_gr->set_fullscreen(opt_dialog_->get_values().fullscreen); | ||
1442 | 549 | opt_dialog_.reset(new FullscreenMenuOptions(options_struct(active_tab))); | ||
1443 | 568 | handle_menu(); // Restart general options menu | 550 | handle_menu(); // Restart general options menu |
1444 | 569 | } | 551 | } |
1445 | 570 | } | 552 | } |
1446 | 571 | 553 | ||
1448 | 572 | OptionsCtrl::OptionsStruct OptionsCtrl::options_struct() { | 554 | OptionsCtrl::OptionsStruct OptionsCtrl::options_struct(uint32_t active_tab) { |
1449 | 573 | OptionsStruct opt; | 555 | OptionsStruct opt; |
1457 | 574 | opt.xres = m_opt_section.get_int("xres", DEFAULT_RESOLUTION_W); | 556 | // Interface options |
1458 | 575 | opt.yres = m_opt_section.get_int("yres", DEFAULT_RESOLUTION_H); | 557 | opt.xres = opt_section_.get_int("xres", DEFAULT_RESOLUTION_W); |
1459 | 576 | opt.inputgrab = m_opt_section.get_bool("inputgrab", false); | 558 | opt.yres = opt_section_.get_int("yres", DEFAULT_RESOLUTION_H); |
1460 | 577 | opt.fullscreen = m_opt_section.get_bool("fullscreen", false); | 559 | opt.fullscreen = opt_section_.get_bool("fullscreen", false); |
1461 | 578 | opt.single_watchwin = m_opt_section.get_bool("single_watchwin", false); | 560 | opt.inputgrab = opt_section_.get_bool("inputgrab", false); |
1462 | 579 | opt.auto_roadbuild_mode = m_opt_section.get_bool("auto_roadbuild_mode", true); | 561 | opt.maxfps = opt_section_.get_int("maxfps", 25); |
1463 | 580 | opt.show_warea = m_opt_section.get_bool("workareapreview", true); | 562 | |
1464 | 563 | // Windows options | ||
1465 | 581 | opt.snap_win_overlap_only = | 564 | opt.snap_win_overlap_only = |
1482 | 582 | m_opt_section.get_bool("snap_windows_only_when_overlapping", false); | 565 | opt_section_.get_bool("snap_windows_only_when_overlapping", false); |
1483 | 583 | opt.dock_windows_to_edges = m_opt_section.get_bool("dock_windows_to_edges", false); | 566 | opt.dock_windows_to_edges = opt_section_.get_bool("dock_windows_to_edges", false); |
1484 | 584 | opt.language = m_opt_section.get_string("language", ""); | 567 | opt.panel_snap_distance = opt_section_.get_int("panel_snap_distance", 0); |
1485 | 585 | opt.music = !m_opt_section.get_bool("disable_music", false); | 568 | opt.border_snap_distance = opt_section_.get_int("border_snap_distance", 0); |
1486 | 586 | opt.fx = !m_opt_section.get_bool("disable_fx", false); | 569 | |
1487 | 587 | opt.autosave = m_opt_section.get_int("autosave", DEFAULT_AUTOSAVE_INTERVAL * 60); | 570 | // Sound options |
1488 | 588 | opt.rolling_autosave = m_opt_section.get_int("rolling_autosave", 5); | 571 | opt.music = !opt_section_.get_bool("disable_music", false); |
1489 | 589 | opt.maxfps = m_opt_section.get_int("maxfps", 25); | 572 | opt.fx = !opt_section_.get_bool("disable_fx", false); |
1490 | 590 | 573 | opt.message_sound = opt_section_.get_bool("sound_at_message", true); | |
1491 | 591 | opt.message_sound = m_opt_section.get_bool("sound_at_message", true); | 574 | |
1492 | 592 | opt.nozip = m_opt_section.get_bool("nozip", false); | 575 | // Saving options |
1493 | 593 | opt.border_snap_distance = m_opt_section.get_int("border_snap_distance", 0); | 576 | opt.autosave = opt_section_.get_int("autosave", DEFAULT_AUTOSAVE_INTERVAL * 60); |
1494 | 594 | opt.panel_snap_distance = m_opt_section.get_int("panel_snap_distance", 0); | 577 | opt.rolling_autosave = opt_section_.get_int("rolling_autosave", 5); |
1495 | 595 | opt.remove_replays = m_opt_section.get_int("remove_replays", 0); | 578 | opt.remove_replays = opt_section_.get_int("remove_replays", 0); |
1496 | 596 | opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true); | 579 | opt.nozip = opt_section_.get_bool("nozip", false); |
1497 | 597 | opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true); | 580 | opt.remove_syncstreams = opt_section_.get_bool("remove_syncstreams", true); |
1498 | 581 | |||
1499 | 582 | // Game options | ||
1500 | 583 | opt.auto_roadbuild_mode = opt_section_.get_bool("auto_roadbuild_mode", true); | ||
1501 | 584 | opt.show_warea = opt_section_.get_bool("workareapreview", true); | ||
1502 | 585 | opt.transparent_chat = opt_section_.get_bool("transparent_chat", true); | ||
1503 | 586 | opt.single_watchwin = opt_section_.get_bool("single_watchwin", false); | ||
1504 | 587 | |||
1505 | 588 | // Language options | ||
1506 | 589 | opt.language = opt_section_.get_string("language", ""); | ||
1507 | 590 | |||
1508 | 591 | // Last tab for reloading the options menu | ||
1509 | 592 | opt.active_tab = active_tab; | ||
1510 | 598 | return opt; | 593 | return opt; |
1511 | 599 | } | 594 | } |
1512 | 600 | 595 | ||
1513 | 601 | void OptionsCtrl::save_options() { | 596 | void OptionsCtrl::save_options() { |
1523 | 602 | OptionsCtrl::OptionsStruct opt = m_opt_dialog->get_values(); | 597 | OptionsCtrl::OptionsStruct opt = opt_dialog_->get_values(); |
1524 | 603 | m_opt_section.set_int ("xres", opt.xres); | 598 | |
1525 | 604 | m_opt_section.set_int ("yres", opt.yres); | 599 | // Interface options |
1526 | 605 | m_opt_section.set_bool("fullscreen", opt.fullscreen); | 600 | opt_section_.set_int ("xres", opt.xres); |
1527 | 606 | m_opt_section.set_bool("inputgrab", opt.inputgrab); | 601 | opt_section_.set_int ("yres", opt.yres); |
1528 | 607 | m_opt_section.set_bool("single_watchwin", opt.single_watchwin); | 602 | opt_section_.set_bool("fullscreen", opt.fullscreen); |
1529 | 608 | m_opt_section.set_bool("auto_roadbuild_mode", opt.auto_roadbuild_mode); | 603 | opt_section_.set_bool("inputgrab", opt.inputgrab); |
1530 | 609 | m_opt_section.set_bool("workareapreview", opt.show_warea); | 604 | opt_section_.set_int("maxfps", opt.maxfps); |
1531 | 610 | m_opt_section.set_bool | 605 | |
1532 | 606 | // Windows options | ||
1533 | 607 | opt_section_.set_bool | ||
1534 | 611 | ("snap_windows_only_when_overlapping", | 608 | ("snap_windows_only_when_overlapping", |
1535 | 612 | opt.snap_win_overlap_only); | 609 | opt.snap_win_overlap_only); |
1552 | 613 | m_opt_section.set_bool("dock_windows_to_edges", opt.dock_windows_to_edges); | 610 | opt_section_.set_bool("dock_windows_to_edges", opt.dock_windows_to_edges); |
1553 | 614 | m_opt_section.set_bool("disable_music", !opt.music); | 611 | opt_section_.set_int("panel_snap_distance", opt.panel_snap_distance); |
1554 | 615 | m_opt_section.set_bool("disable_fx", !opt.fx); | 612 | opt_section_.set_int("border_snap_distance", opt.border_snap_distance); |
1555 | 616 | m_opt_section.set_string("language", opt.language); | 613 | |
1556 | 617 | m_opt_section.set_int("autosave", opt.autosave * 60); | 614 | // Sound options |
1557 | 618 | m_opt_section.set_int("rolling_autosave", opt.rolling_autosave); | 615 | opt_section_.set_bool("disable_music", !opt.music); |
1558 | 619 | m_opt_section.set_int("maxfps", opt.maxfps); | 616 | opt_section_.set_bool("disable_fx", !opt.fx); |
1559 | 620 | 617 | opt_section_.set_bool("sound_at_message", opt.message_sound); | |
1560 | 621 | m_opt_section.set_bool("sound_at_message", opt.message_sound); | 618 | |
1561 | 622 | m_opt_section.set_bool("nozip", opt.nozip); | 619 | // Saving options |
1562 | 623 | m_opt_section.set_int("border_snap_distance", opt.border_snap_distance); | 620 | opt_section_.set_int("autosave", opt.autosave * 60); |
1563 | 624 | m_opt_section.set_int("panel_snap_distance", opt.panel_snap_distance); | 621 | opt_section_.set_int("rolling_autosave", opt.rolling_autosave); |
1564 | 625 | 622 | opt_section_.set_int("remove_replays", opt.remove_replays); | |
1565 | 626 | m_opt_section.set_int("remove_replays", opt.remove_replays); | 623 | opt_section_.set_bool("nozip", opt.nozip); |
1566 | 627 | m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams); | 624 | opt_section_.set_bool("remove_syncstreams", opt.remove_syncstreams); |
1567 | 628 | m_opt_section.set_bool("transparent_chat", opt.transparent_chat); | 625 | |
1568 | 626 | // Game options | ||
1569 | 627 | opt_section_.set_bool("auto_roadbuild_mode", opt.auto_roadbuild_mode); | ||
1570 | 628 | opt_section_.set_bool("workareapreview", opt.show_warea); | ||
1571 | 629 | opt_section_.set_bool("transparent_chat", opt.transparent_chat); | ||
1572 | 630 | opt_section_.set_bool("single_watchwin", opt.single_watchwin); | ||
1573 | 631 | |||
1574 | 632 | // Language options | ||
1575 | 633 | opt_section_.set_string("language", opt.language); | ||
1576 | 629 | 634 | ||
1577 | 630 | WLApplication::get()->set_input_grab(opt.inputgrab); | 635 | WLApplication::get()->set_input_grab(opt.inputgrab); |
1578 | 631 | i18n::set_locale(opt.language); | 636 | i18n::set_locale(opt.language); |
1579 | 632 | 637 | ||
1580 | === modified file 'src/ui_fsmenu/options.h' | |||
1581 | --- src/ui_fsmenu/options.h 2015-12-01 16:58:54 +0000 | |||
1582 | +++ src/ui_fsmenu/options.h 2016-01-01 19:10:55 +0000 | |||
1583 | @@ -21,6 +21,7 @@ | |||
1584 | 21 | #define WL_UI_FSMENU_OPTIONS_H | 21 | #define WL_UI_FSMENU_OPTIONS_H |
1585 | 22 | 22 | ||
1586 | 23 | #include <cstring> | 23 | #include <cstring> |
1587 | 24 | #include <memory> | ||
1588 | 24 | #include <string> | 25 | #include <string> |
1589 | 25 | #include <vector> | 26 | #include <vector> |
1590 | 26 | 27 | ||
1591 | @@ -31,6 +32,7 @@ | |||
1592 | 31 | #include "ui_basic/multilinetextarea.h" | 32 | #include "ui_basic/multilinetextarea.h" |
1593 | 32 | #include "ui_basic/spinbox.h" | 33 | #include "ui_basic/spinbox.h" |
1594 | 33 | #include "ui_basic/textarea.h" | 34 | #include "ui_basic/textarea.h" |
1595 | 35 | #include "ui_basic/tabpanel.h" | ||
1596 | 34 | 36 | ||
1597 | 35 | class FullscreenMenuOptions; | 37 | class FullscreenMenuOptions; |
1598 | 36 | class Section; | 38 | class Section; |
1599 | @@ -39,41 +41,52 @@ | |||
1600 | 39 | class OptionsCtrl { | 41 | class OptionsCtrl { |
1601 | 40 | public: | 42 | public: |
1602 | 41 | struct OptionsStruct { | 43 | struct OptionsStruct { |
1603 | 44 | |||
1604 | 45 | // Interface options | ||
1605 | 42 | int32_t xres; | 46 | int32_t xres; |
1606 | 43 | int32_t yres; | 47 | int32_t yres; |
1607 | 48 | bool fullscreen; | ||
1608 | 44 | bool inputgrab; | 49 | bool inputgrab; |
1613 | 45 | bool fullscreen; | 50 | uint32_t maxfps; |
1614 | 46 | bool single_watchwin; | 51 | |
1615 | 47 | bool auto_roadbuild_mode; | 52 | // Windows options |
1612 | 48 | bool show_warea; | ||
1616 | 49 | bool snap_win_overlap_only; | 53 | bool snap_win_overlap_only; |
1617 | 50 | bool dock_windows_to_edges; | 54 | bool dock_windows_to_edges; |
1618 | 55 | int32_t panel_snap_distance; | ||
1619 | 56 | int32_t border_snap_distance; | ||
1620 | 57 | |||
1621 | 58 | // Sound options | ||
1622 | 51 | bool music; | 59 | bool music; |
1623 | 52 | bool fx; | 60 | bool fx; |
1625 | 53 | std::string language; | 61 | bool message_sound; |
1626 | 62 | |||
1627 | 63 | // Saving options | ||
1628 | 54 | int32_t autosave; // autosave interval in minutes | 64 | int32_t autosave; // autosave interval in minutes |
1631 | 55 | int32_t rolling_autosave; //number of file to use for rolling autosave | 65 | int32_t rolling_autosave; // number of file to use for rolling autosave |
1630 | 56 | uint32_t maxfps; | ||
1632 | 57 | uint32_t remove_replays; | 66 | uint32_t remove_replays; |
1633 | 67 | bool nozip; | ||
1634 | 58 | bool remove_syncstreams; | 68 | bool remove_syncstreams; |
1635 | 69 | |||
1636 | 70 | // Game options | ||
1637 | 71 | bool auto_roadbuild_mode; | ||
1638 | 72 | bool show_warea; | ||
1639 | 59 | bool transparent_chat; | 73 | bool transparent_chat; |
1647 | 60 | 74 | bool single_watchwin; | |
1648 | 61 | // advanced options | 75 | |
1649 | 62 | bool message_sound; | 76 | // Language options |
1650 | 63 | bool nozip; | 77 | std::string language; |
1651 | 64 | std::string ui_font; | 78 | |
1652 | 65 | int32_t border_snap_distance; | 79 | // Last tab for reloading the options menu |
1653 | 66 | int32_t panel_snap_distance; | 80 | uint32_t active_tab; |
1654 | 67 | }; | 81 | }; |
1655 | 68 | 82 | ||
1656 | 69 | OptionsCtrl(Section &); | 83 | OptionsCtrl(Section &); |
1657 | 70 | ~OptionsCtrl(); | ||
1658 | 71 | void handle_menu(); | 84 | void handle_menu(); |
1660 | 72 | OptionsCtrl::OptionsStruct options_struct(); | 85 | OptionsCtrl::OptionsStruct options_struct(uint32_t active_tab); |
1661 | 73 | void save_options(); | 86 | void save_options(); |
1662 | 74 | private: | 87 | private: |
1665 | 75 | Section & m_opt_section; | 88 | Section & opt_section_; |
1666 | 76 | FullscreenMenuOptions * m_opt_dialog; | 89 | std::unique_ptr<FullscreenMenuOptions> opt_dialog_; |
1667 | 77 | }; | 90 | }; |
1668 | 78 | 91 | ||
1669 | 79 | /** | 92 | /** |
1670 | @@ -86,47 +99,75 @@ | |||
1671 | 86 | OptionsCtrl::OptionsStruct get_values(); | 99 | OptionsCtrl::OptionsStruct get_values(); |
1672 | 87 | 100 | ||
1673 | 88 | private: | 101 | private: |
1674 | 89 | uint32_t const m_vbutw; | ||
1675 | 90 | uint32_t const m_butw; | ||
1676 | 91 | uint32_t const m_buth; | ||
1677 | 92 | uint32_t const m_hmargin; | ||
1678 | 93 | uint32_t const m_padding; | ||
1679 | 94 | uint32_t const m_space; | ||
1680 | 95 | uint32_t const m_offset_first_group; | ||
1681 | 96 | uint32_t const m_offset_second_group; | ||
1682 | 97 | |||
1683 | 98 | UI::Button m_advanced_options, m_cancel, m_apply; | ||
1684 | 99 | |||
1685 | 100 | UI::Textarea m_title; | ||
1686 | 101 | UI::Textarea m_label_resolution; | ||
1687 | 102 | UI::Listselect<void *> m_reslist; | ||
1688 | 103 | UI::Checkbox m_fullscreen; | ||
1689 | 104 | UI::Checkbox m_inputgrab; | ||
1690 | 105 | UI::SpinBox m_sb_maxfps; | ||
1691 | 106 | |||
1692 | 107 | UI::Textarea m_label_language; | ||
1693 | 108 | UI::Listselect<std::string> m_language_list; | ||
1694 | 109 | UI::Checkbox m_music; | ||
1695 | 110 | UI::Checkbox m_fx; | ||
1696 | 111 | |||
1697 | 112 | UI::Textarea m_label_game_options; | ||
1698 | 113 | UI::Checkbox m_single_watchwin; | ||
1699 | 114 | UI::Checkbox m_auto_roadbuild_mode; | ||
1700 | 115 | UI::Checkbox m_show_workarea_preview; | ||
1701 | 116 | UI::Checkbox m_snap_win_overlap_only; | ||
1702 | 117 | UI::Checkbox m_dock_windows_to_edges; | ||
1703 | 118 | UI::SpinBox m_sb_autosave; | ||
1704 | 119 | UI::SpinBox m_sb_remove_replays; | ||
1705 | 120 | |||
1706 | 121 | OptionsCtrl::OptionsStruct os; | ||
1707 | 122 | |||
1708 | 123 | void update_sb_autosave_unit(); | 102 | void update_sb_autosave_unit(); |
1709 | 124 | void update_sb_remove_replays_unit(); | 103 | void update_sb_remove_replays_unit(); |
1711 | 125 | void advanced_options(); | 104 | void update_sb_dis_panel_unit(); |
1712 | 105 | void update_sb_dis_border_unit(); | ||
1713 | 126 | 106 | ||
1714 | 127 | // Fills the language selection list | 107 | // Fills the language selection list |
1715 | 128 | void add_languages_to_list(const std::string& current_locale); | 108 | void add_languages_to_list(const std::string& current_locale); |
1716 | 129 | 109 | ||
1717 | 110 | // Saves the options and reloads the active tab | ||
1718 | 111 | void clicked_apply(); | ||
1719 | 112 | |||
1720 | 113 | uint32_t const butw_; | ||
1721 | 114 | uint32_t const buth_; | ||
1722 | 115 | uint32_t const hmargin_; | ||
1723 | 116 | uint32_t const padding_; | ||
1724 | 117 | uint32_t const space_; | ||
1725 | 118 | uint32_t const tab_panel_width_; | ||
1726 | 119 | uint32_t const column_width_; | ||
1727 | 120 | uint32_t const tab_panel_y_; | ||
1728 | 121 | |||
1729 | 122 | UI::Textarea title_; | ||
1730 | 123 | UI::Button cancel_, apply_, ok_; | ||
1731 | 124 | |||
1732 | 125 | // UI elements | ||
1733 | 126 | UI::TabPanel tabs_; | ||
1734 | 127 | UI::Box box_interface_; | ||
1735 | 128 | UI::Box box_windows_; | ||
1736 | 129 | UI::Box box_sound_; | ||
1737 | 130 | UI::Box box_saving_; | ||
1738 | 131 | UI::Box box_game_; | ||
1739 | 132 | UI::Box box_language_; | ||
1740 | 133 | |||
1741 | 134 | // Interface options | ||
1742 | 135 | UI::Textarea label_resolution_; | ||
1743 | 136 | UI::Listselect<void *> resolution_list_; | ||
1744 | 137 | UI::Checkbox fullscreen_; | ||
1745 | 138 | UI::Checkbox inputgrab_; | ||
1746 | 139 | UI::SpinBox sb_maxfps_; | ||
1747 | 140 | |||
1748 | 141 | // Windows options | ||
1749 | 142 | UI::Checkbox snap_win_overlap_only_; | ||
1750 | 143 | UI::Checkbox dock_windows_to_edges_; | ||
1751 | 144 | UI::SpinBox sb_dis_panel_; | ||
1752 | 145 | UI::SpinBox sb_dis_border_; | ||
1753 | 146 | |||
1754 | 147 | // Sound options | ||
1755 | 148 | UI::Checkbox music_; | ||
1756 | 149 | UI::Checkbox fx_; | ||
1757 | 150 | UI::Checkbox message_sound_; | ||
1758 | 151 | |||
1759 | 152 | // Saving options | ||
1760 | 153 | UI::SpinBox sb_autosave_; | ||
1761 | 154 | UI::SpinBox sb_rolling_autosave_; | ||
1762 | 155 | UI::SpinBox sb_remove_replays_; | ||
1763 | 156 | UI::Checkbox nozip_; | ||
1764 | 157 | UI::Checkbox remove_syncstreams_; | ||
1765 | 158 | |||
1766 | 159 | // Game options | ||
1767 | 160 | UI::Checkbox auto_roadbuild_mode_; | ||
1768 | 161 | UI::Checkbox show_workarea_preview_; | ||
1769 | 162 | UI::Checkbox transparent_chat_; | ||
1770 | 163 | UI::Checkbox single_watchwin_; | ||
1771 | 164 | |||
1772 | 165 | // Language options | ||
1773 | 166 | UI::Textarea label_language_; | ||
1774 | 167 | UI::Listselect<std::string> language_list_; | ||
1775 | 168 | |||
1776 | 169 | OptionsCtrl::OptionsStruct os_; | ||
1777 | 170 | |||
1778 | 130 | class ScreenResolution { | 171 | class ScreenResolution { |
1779 | 131 | public: | 172 | public: |
1780 | 132 | int32_t xres; | 173 | int32_t xres; |
1781 | @@ -135,39 +176,7 @@ | |||
1782 | 135 | }; | 176 | }; |
1783 | 136 | 177 | ||
1784 | 137 | /// All supported screen resolutions. | 178 | /// All supported screen resolutions. |
1818 | 138 | std::vector<ScreenResolution> m_resolutions; | 179 | std::vector<ScreenResolution> resolutions_; |
1786 | 139 | }; | ||
1787 | 140 | |||
1788 | 141 | /** | ||
1789 | 142 | * Fullscreen Optionsmenu. A modal optionsmenu | ||
1790 | 143 | */ | ||
1791 | 144 | |||
1792 | 145 | class FullscreenMenuAdvancedOptions : public FullscreenMenuBase { | ||
1793 | 146 | public: | ||
1794 | 147 | FullscreenMenuAdvancedOptions(OptionsCtrl::OptionsStruct opt); | ||
1795 | 148 | OptionsCtrl::OptionsStruct get_values(); | ||
1796 | 149 | |||
1797 | 150 | private: | ||
1798 | 151 | void update_sb_dis_panel_unit(); | ||
1799 | 152 | void update_sb_dis_border_unit(); | ||
1800 | 153 | |||
1801 | 154 | uint32_t const m_vbutw; | ||
1802 | 155 | uint32_t const m_butw; | ||
1803 | 156 | uint32_t const m_buth; | ||
1804 | 157 | uint32_t const m_hmargin; | ||
1805 | 158 | uint32_t const m_padding; | ||
1806 | 159 | uint32_t const m_space; | ||
1807 | 160 | |||
1808 | 161 | UI::Button m_cancel, m_apply; | ||
1809 | 162 | UI::Textarea m_title; | ||
1810 | 163 | |||
1811 | 164 | UI::SpinBox m_sb_dis_panel, m_sb_dis_border; | ||
1812 | 165 | UI::Checkbox m_transparent_chat; | ||
1813 | 166 | UI::Checkbox m_message_sound; | ||
1814 | 167 | UI::Checkbox m_nozip; | ||
1815 | 168 | UI::Checkbox m_remove_syncstreams; | ||
1816 | 169 | |||
1817 | 170 | OptionsCtrl::OptionsStruct os; | ||
1819 | 171 | }; | 180 | }; |
1820 | 172 | 181 | ||
1821 | 173 | #endif // end of include guard: WL_UI_FSMENU_OPTIONS_H | 182 | #endif // end of include guard: WL_UI_FSMENU_OPTIONS_H |
As i can see all works as expected. Not tested are some time related things (like autosave)
Maybe we should reorder some things, but this could be done later.