Merge lp:~widelands-dev/widelands/options_window into lp:widelands

Proposed by GunChleoc
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
Reviewer Review Type Date Requested Status
Tino Approve
kaputtnik (community) Approve
Review via email: mp+280355@code.launchpad.net

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.

To post a comment you must log in.
Revision history for this message
kaputtnik (franku) wrote :

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.

review: Approve
Revision history for this message
TiborB (tiborb95) wrote :

I went through code. LGTM though this is another huge and hard-to-read change...

Should I merge this as well?

Revision history for this message
bunnybot (widelandsofficial) wrote :

Hi, I am bunnybot (https://github.com/widelands/bunnybot).

I am keeping the source branch lp:~widelands-dev/widelands/options_window mirrored to
  https://github.com/widelands/widelands/tree/_widelands_dev_widelands_options_window

The latest continuous integration build can always be found here:
  https://travis-ci.org/widelands/widelands/branches
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.

Revision history for this message
Tino (tino79) wrote :

Looks good to me and bunnybot ;).

@bunnybot merge

review: Approve
Revision history for this message
bunnybot (widelandsofficial) wrote :

Travis build 130 has changed state to: passed. Details: https://travis-ci.org/widelands/widelands/builds/99817066.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file 'pics/optionsmenu.jpg'
0Binary files pics/optionsmenu.jpg 2008-07-23 15:48:24 +0000 and pics/optionsmenu.jpg 1970-01-01 00:00:00 +0000 differ0Binary files pics/optionsmenu.jpg 2008-07-23 15:48:24 +0000 and pics/optionsmenu.jpg 1970-01-01 00:00:00 +0000 differ
=== modified file 'src/ui_basic/tabpanel.cc'
--- src/ui_basic/tabpanel.cc 2014-12-04 09:00:20 +0000
+++ src/ui_basic/tabpanel.cc 2016-01-01 19:10:55 +0000
@@ -19,41 +19,51 @@
1919
20#include "ui_basic/tabpanel.h"20#include "ui_basic/tabpanel.h"
2121
22#include "graphic/font_handler1.h"
22#include "graphic/rendertarget.h"23#include "graphic/rendertarget.h"
24#include "graphic/text_layout.h"
23#include "ui_basic/mouse_constants.h"25#include "ui_basic/mouse_constants.h"
2426
25namespace UI {27namespace UI {
2628
27// Button size of tab buttons in pixels.29// Button height of tab buttons in pixels. Is also used for width with pictorial buttons.
28constexpr int kTabPanelButtonSize = 34;30constexpr int kTabPanelButtonHeight = 34;
2931
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.
31constexpr int kTabPanelImageMargin = 2;33constexpr int kTabPanelImageMargin = 2;
3234
35// Left and right margin around text.
36constexpr int kTabPanelTextMargin = 4;
37
33// height of the bar separating buttons and tab contents38// height of the bar separating buttons and tab contents
34constexpr int kTabPanelSeparatorHeight = 4;39constexpr int kTabPanelSeparatorHeight = 4;
3540
41// Constant to flag up when we're not at a tab.
42constexpr uint32_t kNotFound = std::numeric_limits<uint32_t>::max();
43
36/*44/*
37 * =================45 * =================
38 * class Tab46 * class Tab
39 * =================47 * =================
40 */48 */
41Tab::Tab49Tab::Tab
42 (TabPanel * const parent,50 (TabPanel* const tab_parent,
43 uint32_t const id,51 size_t const tab_id,
44 const std::string & name,52 int32_t x,
45 const Image* gpic,53 int32_t w,
46 const std::string & gtooltip,54 const std::string& name,
47 Panel * const gpanel)55 const std::string& _title,
56 const Image* _pic,
57 const std::string& tooltip_text,
58 Panel* const contents)
48 :59 :
49 NamedPanel60 NamedPanel(tab_parent, name, x, 0, w, kTabPanelButtonHeight, tooltip_text),
50 (parent, name, id * kTabPanelButtonSize, 0, kTabPanelButtonSize,61 parent(tab_parent),
51 kTabPanelButtonSize, gtooltip),62 id(tab_id),
52 m_parent(parent),63 pic(_pic),
53 m_id(id),64 title(_title),
54 pic(gpic),65 tooltip(tooltip_text),
55 tooltip(gtooltip),66 panel(contents)
56 panel(gpanel)
57{67{
58}68}
5969
@@ -61,10 +71,15 @@
61 * Currently active tab71 * Currently active tab
62 */72 */
63bool Tab::active() {73bool Tab::active() {
64 return m_parent->m_active == m_id;74 return parent->active_ == id;
65}75}
66void Tab::activate() {76void Tab::activate() {
67 return m_parent->activate(m_id);77 return parent->activate(id);
78}
79
80bool Tab::handle_mousepress(uint8_t, int32_t, int32_t) {
81 play_click();
82 return false;
68}83}
6984
70/*85/*
@@ -78,22 +93,26 @@
78TabPanel::TabPanel93TabPanel::TabPanel
79 (Panel * const parent,94 (Panel * const parent,
80 int32_t const x, int32_t const y,95 int32_t const x, int32_t const y,
81 const Image* background)96 const Image* background,
97 TabPanel::Type border_type)
82 :98 :
83 Panel (parent, x, y, 0, 0),99 Panel (parent, x, y, 0, 0),
84 m_active (0),100 active_ (0),
85 m_highlight (-1),101 highlight_ (kNotFound),
86 m_pic_background (background)102 pic_background_ (background),
103 border_type_ (border_type)
87{}104{}
88TabPanel::TabPanel105TabPanel::TabPanel
89 (Panel * const parent,106 (Panel * const parent,
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,
91 const Image* background)108 const Image* background,
109 TabPanel::Type border_type)
92 :110 :
93 Panel (parent, x, y, w, h),111 Panel (parent, x, y, w, h),
94 m_active (0),112 active_ (0),
95 m_highlight (-1),113 highlight_ (kNotFound),
96 m_pic_background (background)114 pic_background_ (background),
115 border_type_ (border_type)
97{}116{}
98117
99/**118/**
@@ -101,12 +120,16 @@
101 */120 */
102void TabPanel::layout()121void TabPanel::layout()
103{122{
104 if (m_active < m_tabs.size()) {123 if (active_ < tabs_.size()) {
105 Panel * const panel = m_tabs[m_active]->panel;124 Panel * const panel = tabs_[active_]->panel;
106 uint32_t h = get_h();125 uint32_t h = get_h();
107126
108 // avoid excessive craziness in case there is a wraparound127 // avoid excessive craziness in case there is a wraparound
109 h = std::min(h, h - (kTabPanelButtonSize + kTabPanelSeparatorHeight));128 h = std::min(h, h - (kTabPanelButtonHeight + kTabPanelSeparatorHeight));
129 // If we have a border, we will also want some margin to the bottom
130 if (border_type_ == TabPanel::Type::kBorder) {
131 h = h - kTabPanelSeparatorHeight;
132 }
110 panel->set_size(get_w(), h);133 panel->set_size(get_w(), h);
111 }134 }
112}135}
@@ -120,12 +143,12 @@
120 uint32_t h;143 uint32_t h;
121144
122 // size of button row145 // size of button row
123 w = kTabPanelButtonSize * m_tabs.size();146 w = kTabPanelButtonHeight * tabs_.size();
124 h = kTabPanelButtonSize + kTabPanelSeparatorHeight;147 h = kTabPanelButtonHeight + kTabPanelSeparatorHeight;
125148
126 // size of contents149 // size of contents
127 if (m_active < m_tabs.size()) {150 if (active_ < tabs_.size()) {
128 Panel * const panel = m_tabs[m_active]->panel;151 Panel * const panel = tabs_[active_]->panel;
129 uint32_t panelw, panelh;152 uint32_t panelw, panelh;
130153
131 panel->get_desired_size(panelw, panelh);154 panel->get_desired_size(panelw, panelh);
@@ -146,7 +169,25 @@
146}169}
147170
148/**171/**
149 * Add a new tab172 * Add a new textual tab
173*/
174uint32_t TabPanel::add
175 (const std::string & name,
176 const std::string & title,
177 Panel * const panel,
178 const std::string & tooltip_text)
179{
180 const Image* pic = UI::g_fh1->render(as_uifont(title));
181 return add_tab(std::max(kTabPanelButtonHeight, pic->width() + 2 * kTabPanelTextMargin),
182 name,
183 title,
184 pic,
185 tooltip_text,
186 panel);
187}
188
189/**
190 * Add a new pictorial tab
150*/191*/
151uint32_t TabPanel::add192uint32_t TabPanel::add
152 (const std::string & name,193 (const std::string & name,
@@ -154,14 +195,38 @@
154 Panel * const panel,195 Panel * const panel,
155 const std::string & tooltip_text)196 const std::string & tooltip_text)
156{197{
198 return add_tab(kTabPanelButtonHeight,
199 name,
200 "",
201 pic,
202 tooltip_text,
203 panel);
204}
205
206/** Common adding function for textual and pictorial tabs. */
207uint32_t TabPanel::add_tab(int32_t width,
208 const std::string& name,
209 const std::string& title,
210 const Image* pic,
211 const std::string& tooltip_text,
212 Panel* panel) {
157 assert(panel);213 assert(panel);
158 assert(panel->get_parent() == this);214 assert(panel->get_parent() == this);
159215
160 uint32_t id = m_tabs.size();216 size_t id = tabs_.size();
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;
162218 tabs_.push_back(new Tab(this, id, x, width, name, title, pic, tooltip_text, panel));
163 panel->set_pos(Point(0, kTabPanelButtonSize + kTabPanelSeparatorHeight));219
164 panel->set_visible(id == m_active);220 // Add a margin if there is a border
221 if (border_type_ == TabPanel::Type::kBorder) {
222 panel->set_border(kTabPanelSeparatorHeight + 1, kTabPanelSeparatorHeight + 1,
223 kTabPanelSeparatorHeight, kTabPanelSeparatorHeight);
224 panel->set_pos(Point(0, kTabPanelButtonHeight));
225 } else {
226 panel->set_pos(Point(0, kTabPanelButtonHeight + kTabPanelSeparatorHeight));
227 }
228
229 panel->set_visible(id == active_);
165 update_desired_size();230 update_desired_size();
166231
167 return id;232 return id;
@@ -173,20 +238,20 @@
173*/238*/
174void TabPanel::activate(uint32_t idx)239void TabPanel::activate(uint32_t idx)
175{240{
176 if (m_active < m_tabs.size())241 if (active_ < tabs_.size())
177 m_tabs[m_active]->panel->set_visible(false);242 tabs_[active_]->panel->set_visible(false);
178 if (idx < m_tabs.size())243 if (idx < tabs_.size())
179 m_tabs[idx]->panel->set_visible(true);244 tabs_[idx]->panel->set_visible(true);
180245
181 m_active = idx;246 active_ = idx;
182247
183 update_desired_size();248 update_desired_size();
184}249}
185250
186void TabPanel::activate(const std::string & name)251void TabPanel::activate(const std::string & name)
187{252{
188 for (uint32_t t = 0; t < m_tabs.size(); ++t)253 for (uint32_t t = 0; t < tabs_.size(); ++t)
189 if (m_tabs[t]->get_name() == name)254 if (tabs_[t]->get_name() == name)
190 activate(t);255 activate(t);
191}256}
192257
@@ -194,7 +259,7 @@
194 * Return the tab names in order259 * Return the tab names in order
195 */260 */
196const TabPanel::TabList & TabPanel::tabs() {261const TabPanel::TabList & TabPanel::tabs() {
197 return m_tabs;262 return tabs_;
198}263}
199264
200/**265/**
@@ -202,96 +267,118 @@
202*/267*/
203void TabPanel::draw(RenderTarget & dst)268void TabPanel::draw(RenderTarget & dst)
204{269{
205 uint32_t idx;
206 uint32_t x;
207
208 // draw the background270 // draw the background
209 static_assert(2 < kTabPanelButtonSize, "assert(2 < kTabPanelButtonSize) failed.");271 static_assert(2 < kTabPanelButtonHeight, "assert(2 < kTabPanelButtonSize) failed.");
210 static_assert(4 < kTabPanelButtonSize, "assert(4 < kTabPanelButtonSize) failed.");272 static_assert(4 < kTabPanelButtonHeight, "assert(4 < kTabPanelButtonSize) failed.");
211273
212 if (m_pic_background) {274 if (pic_background_) {
213 dst.tile275 if (!tabs_.empty()) {
214 (Rect(Point(0, 0), m_tabs.size() * kTabPanelButtonSize, kTabPanelButtonSize - 2),276 dst.tile
215 m_pic_background, Point(get_x(), get_y()));277 (Rect(Point(0, 0), tabs_.back()->get_x() + tabs_.back()->get_w(), kTabPanelButtonHeight - 2),
216 assert(kTabPanelButtonSize - 2 <= get_h());278 pic_background_,
217 dst.tile279 Point(get_x(), get_y()));
218 (Rect280 }
219 (Point(0, kTabPanelButtonSize - 2),281 assert(kTabPanelButtonHeight - 2 <= get_h());
220 get_w(), get_h() - kTabPanelButtonSize + 2),282 dst.tile
221 m_pic_background,283 (Rect(Point(0, kTabPanelButtonHeight - 2), get_w(), get_h() - kTabPanelButtonHeight + 2),
222 Point(get_x(), get_y() + kTabPanelButtonSize - 2));284 pic_background_,
285 Point(get_x(), get_y() + kTabPanelButtonHeight - 2));
223 }286 }
224287
288 RGBColor black(0, 0, 0);
289
225 // draw the buttons290 // draw the buttons
226 for (idx = 0, x = 0; idx < m_tabs.size(); idx++, x += kTabPanelButtonSize) {291 int32_t x = 0;
227 if (m_highlight == static_cast<int32_t>(idx))292 int tab_width = 0;
228 dst.brighten_rect293 for (size_t idx = 0; idx < tabs_.size(); ++idx) {
229 (Rect(Point(x, 0), kTabPanelButtonSize, kTabPanelButtonSize),294 x = tabs_[idx]->get_x();
230 MOUSE_OVER_BRIGHT_FACTOR);295 tab_width = tabs_[idx]->get_w();
231296
232 // Draw the icon297 if (highlight_ == idx) {
233 assert(m_tabs[idx]->pic);298 dst.brighten_rect(Rect(Point(x, 0), tab_width, kTabPanelButtonHeight), MOUSE_OVER_BRIGHT_FACTOR);
234299 }
235 // Scale the image down if needed, but keep the ratio.300
236 constexpr int kMaxImageSize = kTabPanelButtonSize - 2 * kTabPanelImageMargin;301 assert(tabs_[idx]->pic);
237 double image_scale =302
238 std::min(1.,303 // If the title is empty, we will assume a pictorial tab
239 std::min(static_cast<double>(kMaxImageSize) / m_tabs[idx]->pic->width(),304 if (tabs_[idx]->title.empty()) {
240 static_cast<double>(kMaxImageSize) / m_tabs[idx]->pic->height()));305 // Scale the image down if needed, but keep the ratio.
241306 constexpr int kMaxImageSize = kTabPanelButtonHeight - 2 * kTabPanelImageMargin;
242 uint16_t picture_width = image_scale * m_tabs[idx]->pic->width();307 double image_scale =
243 uint16_t picture_height = image_scale * m_tabs[idx]->pic->height();308 std::min(1.,
244 dst.blitrect_scale(Rect(x + (kTabPanelButtonSize - picture_width) / 2,309 std::min(static_cast<double>(kMaxImageSize) / tabs_[idx]->pic->width(),
245 (kTabPanelButtonSize - picture_height) / 2,310 static_cast<double>(kMaxImageSize) / tabs_[idx]->pic->height()));
246 picture_width,311
247 picture_height),312 uint16_t picture_width = image_scale * tabs_[idx]->pic->width();
248 m_tabs[idx]->pic,313 uint16_t picture_height = image_scale * tabs_[idx]->pic->height();
249 Rect(0, 0, m_tabs[idx]->pic->width(), m_tabs[idx]->pic->height()),314 dst.blitrect_scale(Rect(x + (kTabPanelButtonHeight - picture_width) / 2,
250 1.,315 (kTabPanelButtonHeight - picture_height) / 2,
251 BlendMode::UseAlpha);316 picture_width,
317 picture_height),
318 tabs_[idx]->pic,
319 Rect(0, 0, tabs_[idx]->pic->width(), tabs_[idx]->pic->height()),
320 1.,
321 BlendMode::UseAlpha);
322 } else {
323 dst.blit(Point(x + kTabPanelTextMargin, (kTabPanelButtonHeight - tabs_[idx]->pic->height()) / 2),
324 tabs_[idx]->pic,
325 BlendMode::UseAlpha,
326 UI::Align_Left);
327 }
252328
253 // Draw top part of border329 // Draw top part of border
254 RGBColor black(0, 0, 0);330 dst.brighten_rect
255331 (Rect(Point(x, 0), tab_width, 2), BUTTON_EDGE_BRIGHT_FACTOR);
256 dst.brighten_rect332 dst.brighten_rect
257 (Rect(Point(x, 0), kTabPanelButtonSize, 2), BUTTON_EDGE_BRIGHT_FACTOR);333 (Rect(Point(x, 2), 2, kTabPanelButtonHeight - 4),
258 dst.brighten_rect
259 (Rect(Point(x, 2), 2, kTabPanelButtonSize - 4),
260 BUTTON_EDGE_BRIGHT_FACTOR);334 BUTTON_EDGE_BRIGHT_FACTOR);
261 dst.fill_rect335 dst.fill_rect
262 (Rect(Point(x + kTabPanelButtonSize - 2, 2), 1, kTabPanelButtonSize - 4),336 (Rect(Point(x + tab_width - 2, 2), 1, kTabPanelButtonHeight - 4),
263 black);337 black);
264 dst.fill_rect338 dst.fill_rect
265 (Rect(Point(x + kTabPanelButtonSize - 1, 1), 1, kTabPanelButtonSize - 3),339 (Rect(Point(x + tab_width - 1, 1), 1, kTabPanelButtonHeight - 3),
266 black);340 black);
267341
268 // Draw bottom part342 // Draw bottom part
269 if (m_active != idx)343 if (active_ != idx)
270 dst.brighten_rect344 dst.brighten_rect
271 (Rect(Point(x, kTabPanelButtonSize - 2), kTabPanelButtonSize, 2),345 (Rect(Point(x, kTabPanelButtonHeight - 2), tab_width, 2),
272 2 * BUTTON_EDGE_BRIGHT_FACTOR);346 2 * BUTTON_EDGE_BRIGHT_FACTOR);
273 else {347 else {
274 dst.brighten_rect348 dst.brighten_rect
275 (Rect(Point(x, kTabPanelButtonSize - 2), 2, 2),349 (Rect(Point(x, kTabPanelButtonHeight - 2), 2, 2),
276 BUTTON_EDGE_BRIGHT_FACTOR);350 BUTTON_EDGE_BRIGHT_FACTOR);
277351
278 dst.brighten_rect352 dst.brighten_rect
279 (Rect(Point(x + kTabPanelButtonSize - 2, kTabPanelButtonSize - 2), 2, 2),353 (Rect(Point(x + tab_width - 2, kTabPanelButtonHeight - 2), 2, 2),
280 2 * BUTTON_EDGE_BRIGHT_FACTOR);354 2 * BUTTON_EDGE_BRIGHT_FACTOR);
281 dst.fill_rect355 dst.fill_rect
282 (Rect(Point(x + kTabPanelButtonSize - 2, kTabPanelButtonSize - 1), 1, 1),356 (Rect(Point(x + tab_width - 2, kTabPanelButtonHeight - 1), 1, 1),
283 black);357 black);
284 dst.fill_rect358 dst.fill_rect
285 (Rect(Point(x + kTabPanelButtonSize - 2, kTabPanelButtonSize - 2), 2, 1),359 (Rect(Point(x + tab_width - 2, kTabPanelButtonHeight - 2), 2, 1),
286 black);360 black);
287 }361 }
288 }362 }
289363
290 // draw the remaining separator364 // draw the remaining separator
291 assert(x <= static_cast<uint32_t>(get_w()));365 assert(x <= get_w());
292 dst.brighten_rect366 dst.brighten_rect
293 (Rect(Point(x, kTabPanelButtonSize - 2), get_w() - x, 2),367 (Rect(Point(x + tab_width, kTabPanelButtonHeight - 2), get_w() - x, 2),
294 2 * BUTTON_EDGE_BRIGHT_FACTOR);368 2 * BUTTON_EDGE_BRIGHT_FACTOR);
369
370 // Draw border around the main panel
371 if (border_type_ == TabPanel::Type::kBorder) {
372 // left edge
373 dst.brighten_rect
374 (Rect(Point(0, kTabPanelButtonHeight), 2, get_h() - 2), BUTTON_EDGE_BRIGHT_FACTOR);
375 // bottom edge
376 dst.fill_rect(Rect(Point(2, get_h() - 2), get_w() - 2, 1), black);
377 dst.fill_rect(Rect(Point(1, get_h() - 1), get_w() - 1, 1), black);
378 // right edge
379 dst.fill_rect(Rect(Point(get_w() - 2, kTabPanelButtonHeight - 1), 1, get_h() - 2), black);
380 dst.fill_rect(Rect(Point(get_w() - 1, kTabPanelButtonHeight - 2), 1, get_h() - 1), black);
381 }
295}382}
296383
297384
@@ -300,11 +387,9 @@
300*/387*/
301void TabPanel::handle_mousein(bool inside)388void TabPanel::handle_mousein(bool inside)
302{389{
303 if (!inside && m_highlight >= 0) {390 if (!inside && highlight_ != kNotFound) {
304 update391 update(tabs_[highlight_]->get_x(), 0, tabs_[highlight_]->get_w(), kTabPanelButtonHeight);
305 (m_highlight * kTabPanelButtonSize, 0, kTabPanelButtonSize, kTabPanelButtonSize);392 highlight_ = kNotFound;
306
307 m_highlight = -1;
308 }393 }
309}394}
310395
@@ -315,31 +400,17 @@
315bool TabPanel::handle_mousemove400bool TabPanel::handle_mousemove
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)
317{402{
318 int32_t hl;403 size_t hl = find_tab(x, y);
319404
320 if (y < 0 || y >= kTabPanelButtonSize)405 if (hl != highlight_) {
321 hl = -1;406 if (hl != kNotFound) {
322 else {407 update(tabs_[hl]->get_x(), 0, tabs_[hl]->get_w(), kTabPanelButtonHeight);
323 hl = x / kTabPanelButtonSize;408 }
324409 if (highlight_ != kNotFound) {
325 if (m_tabs.size() <= static_cast<size_t>(hl))410 update(tabs_[highlight_]->get_x(), 0, tabs_[highlight_]->get_w(), kTabPanelButtonHeight);
326 hl = -1;411 }
327 }412 highlight_ = hl;
328413 set_tooltip(highlight_ != kNotFound ? tabs_[highlight_]->tooltip : "");
329 if (hl != m_highlight) {
330 {
331 if (hl >= 0)
332 set_tooltip(m_tabs[hl]->tooltip);
333 }
334 if (m_highlight >= 0)
335 update
336 (m_highlight * kTabPanelButtonSize, 0,
337 kTabPanelButtonSize, kTabPanelButtonSize);
338 if (hl >= 0)
339 update
340 (hl * kTabPanelButtonSize, 0, kTabPanelButtonSize, kTabPanelButtonSize);
341
342 m_highlight = hl;
343 }414 }
344 return true;415 return true;
345}416}
@@ -350,25 +421,39 @@
350*/421*/
351bool TabPanel::handle_mousepress(const uint8_t btn, int32_t x, int32_t y) {422bool TabPanel::handle_mousepress(const uint8_t btn, int32_t x, int32_t y) {
352 if (btn == SDL_BUTTON_LEFT) {423 if (btn == SDL_BUTTON_LEFT) {
353 int32_t id;424 size_t id = find_tab(x, y);
354425 if (id != kNotFound) {
355 if (y >= kTabPanelButtonSize)
356 return false;
357
358 id = x / kTabPanelButtonSize;
359
360 if (static_cast<size_t>(id) < m_tabs.size()) {
361 activate(id);426 activate(id);
362
363 return true;427 return true;
364 }428 }
365 }429 }
366
367 return false;430 return false;
368}431}
432
369bool TabPanel::handle_mouserelease(uint8_t, int32_t, int32_t)433bool TabPanel::handle_mouserelease(uint8_t, int32_t, int32_t)
370{434{
371 return false;435 return false;
372}436}
373437
438
439/**
440 * Find the tab at the coordinates x, y
441 * Returns kNotFound if no tab was found
442 */
443size_t TabPanel::find_tab(int32_t x, int32_t y) const {
444 if (y < 0 || y >= kTabPanelButtonHeight) {
445 return kNotFound;
446 }
447
448 int32_t width = 0;
449 for (size_t id = 0; id < tabs_.size(); ++id) {
450 width += tabs_[id]->get_w();
451 if (width > x) {
452 return id;
453 }
454 }
455 return kNotFound;
456}
457
458
374}459}
375460
=== modified file 'src/ui_basic/tabpanel.h'
--- src/ui_basic/tabpanel.h 2014-09-14 11:31:58 +0000
+++ src/ui_basic/tabpanel.h 2016-01-01 19:10:55 +0000
@@ -35,11 +35,16 @@
35struct Tab : public NamedPanel {35struct Tab : public NamedPanel {
36 friend struct TabPanel;36 friend struct TabPanel;
3737
38 /** If title is not empty, this will be a textual tab.
39 * In that case, pic will need to be the rendered title */
38 Tab40 Tab
39 (TabPanel * parent,41 (TabPanel * parent,
40 uint32_t,42 size_t id,
43 int32_t x,
44 int32_t w,
41 const std::string & name,45 const std::string & name,
42 const Image*,46 const std::string & title,
47 const Image* pic,
43 const std::string & gtooltip,48 const std::string & gtooltip,
44 Panel * gpanel);49 Panel * gpanel);
4550
@@ -47,12 +52,18 @@
47 void activate();52 void activate();
4853
49private:54private:
50 TabPanel * m_parent;55 // Leave handling the mouse move to the TabPanel.
51 uint32_t m_id;56 bool handle_mousemove(uint8_t, int32_t, int32_t, int32_t, int32_t) override {return false;}
57 // Play click
58 bool handle_mousepress(uint8_t, int32_t, int32_t) override;
59
60 TabPanel* parent;
61 uint32_t id;
5262
53 const Image* pic;63 const Image* pic;
64 std::string title;
54 std::string tooltip;65 std::string tooltip;
55 Panel * panel;66 Panel* panel;
56};67};
5768
58/**69/**
@@ -66,15 +77,30 @@
66 *77 *
67 */78 */
68struct TabPanel : public Panel {79struct TabPanel : public Panel {
80 enum class Type {
81 kNoBorder,
82 kBorder
83 };
84
69 friend struct Tab;85 friend struct Tab;
7086
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,
88 TabPanel::Type border_type = TabPanel::Type::kNoBorder);
72 // For Fullscreen menus89 // For Fullscreen menus
73 TabPanel90 TabPanel
74 (Panel * parent,91 (Panel * parent,
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,
76 const Image* background);93 const Image* background,
7794 TabPanel::Type border_type = TabPanel::Type::kNoBorder);
95
96 /** Add textual tab */
97 uint32_t add
98 (const std::string & name,
99 const std::string & title,
100 Panel * panel,
101 const std::string & tooltip = std::string());
102
103 /** Add pictorial tab */
78 uint32_t add104 uint32_t add
79 (const std::string & name,105 (const std::string & name,
80 const Image* pic,106 const Image* pic,
@@ -86,13 +112,21 @@
86 const TabList & tabs();112 const TabList & tabs();
87 void activate(uint32_t idx);113 void activate(uint32_t idx);
88 void activate(const std::string &);114 void activate(const std::string &);
89 uint32_t active() {return m_active;}115 uint32_t active() {return active_;}
90116
91protected:117protected:
92 void layout() override;118 void layout() override;
93 void update_desired_size() override;119 void update_desired_size() override;
94120
95private:121private:
122 // Common adding function for textual and pictorial tabs
123 uint32_t add_tab(int32_t width,
124 const std::string& name,
125 const std::string& title,
126 const Image* pic,
127 const std::string& tooltip,
128 Panel* contents);
129
96 // Drawing and event handlers130 // Drawing and event handlers
97 void draw(RenderTarget &) override;131 void draw(RenderTarget &) override;
98132
@@ -102,12 +136,14 @@
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;
103 void handle_mousein(bool inside) override;137 void handle_mousein(bool inside) override;
104138
105139 size_t find_tab(int32_t x, int32_t y) const;
106 TabList m_tabs;140
107 uint32_t m_active; ///< index of the currently active tab141 TabList tabs_;
108 int32_t m_highlight; ///< index of the highlighted button142 size_t active_; ///< index of the currently active tab
109143 size_t highlight_; ///< index of the highlighted button
110 const Image* m_pic_background; ///< picture used to draw background144
145 const Image* pic_background_; ///< picture used to draw background
146 TabPanel::Type border_type_; ///< whether there will be a border around the panels.
111};147};
112}148}
113149
114150
=== modified file 'src/ui_fsmenu/base.h'
--- src/ui_fsmenu/base.h 2015-08-10 19:55:41 +0000
+++ src/ui_fsmenu/base.h 2016-01-01 19:10:55 +0000
@@ -45,7 +45,7 @@
45 kOk = static_cast<int>(UI::Panel::Returncodes::kOk),45 kOk = static_cast<int>(UI::Panel::Returncodes::kOk),
4646
47 // Options47 // Options
48 kRestart,48 kApplyOptions,
4949
50 // Main menu50 // Main menu
51 kTutorial,51 kTutorial,
5252
=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc 2015-12-01 21:52:24 +0000
+++ src/ui_fsmenu/options.cc 2016-01-01 19:10:55 +0000
@@ -96,184 +96,241 @@
96FullscreenMenuOptions::FullscreenMenuOptions96FullscreenMenuOptions::FullscreenMenuOptions
97 (OptionsCtrl::OptionsStruct opt)97 (OptionsCtrl::OptionsStruct opt)
98 :98 :
99 FullscreenMenuBase("optionsmenu.jpg"),99 FullscreenMenuBase("ui_fsmenu.jpg"),
100100
101// Values for alignment and size101// Values for alignment and size
102 m_vbutw (get_h() * 333 / 10000),102 butw_ (get_w() / 5),
103 m_butw (get_w() / 4),103 buth_ (get_h() * 9 / 200),
104 m_buth (get_h() * 9 / 200),104 hmargin_ (get_w() * 19 / 200),
105 m_hmargin (get_w() * 19 / 200),105 padding_ (10),
106 m_padding (10),106 space_ (25),
107 m_space (25),107 tab_panel_width_(get_inner_w() - 2 * hmargin_),
108 m_offset_first_group (get_h() * 1417 / 10000),108 column_width_(tab_panel_width_ - padding_),
109 m_offset_second_group(get_h() * 5833 / 10000),109 tab_panel_y_(get_h() * 14 / 100),
110
111// Buttons
112 m_advanced_options
113 (this, "advanced_options",
114 get_w() * 9 / 80, get_h() * 19 / 20, m_butw, m_buth,
115 g_gr->images().get("pics/but2.png"),
116 _("Advanced Options"), std::string(), true, false),
117 m_cancel
118 (this, "cancel",
119 get_w() * 51 / 80, get_h() * 19 / 20, m_butw, m_buth,
120 g_gr->images().get("pics/but0.png"),
121 _("Cancel"), std::string(), true, false),
122 m_apply
123 (this, "apply",
124 get_w() * 3 / 8, get_h() * 19 / 20, m_butw, m_buth,
125 g_gr->images().get("pics/but2.png"),
126 _("Apply"), std::string(), true, false),
127110
128 // Title111 // Title
129 m_title112 title_
130 (this,113 (this,
131 get_w() / 2, get_h() / 40,114 get_w() / 2, buth_,
132 _("General Options"), UI::Align_HCenter),115 _("Options"), UI::Align_HCenter),
133116
134 // First options block 'general options', first column117 // Buttons
135 m_label_resolution118 cancel_
136 (this,119 (this, "cancel",
137 m_hmargin, m_offset_first_group,120 get_w() * 1 / 4 - butw_ / 2,
138 _("In-game resolution"), UI::Align_VCenter),121 get_inner_h() - hmargin_,
139 m_reslist122 butw_, buth_,
140 (this,123 g_gr->images().get("pics/but0.png"),
141 m_hmargin, m_label_resolution.get_y() + m_label_resolution.get_h(),124 _("Cancel"), std::string(), true, false),
142 (get_w() - 2 * m_hmargin - m_space) / 2, 95,125 apply_
143 UI::Align_Left, true),126 (this, "apply",
144127 get_w() * 2 / 4 - butw_ / 2,
145 m_fullscreen (this, Point(m_hmargin,128 get_inner_h() - hmargin_,
146 m_reslist.get_y() +129 butw_, buth_,
147 m_reslist.get_h() + m_padding),130 g_gr->images().get("pics/but0.png"),
148 _("Fullscreen")),131 _("Apply"), std::string(), true, false),
149 m_inputgrab (this, Point(m_hmargin,132 ok_
150 m_fullscreen.get_y() +133 (this, "ok",
151 m_fullscreen.get_h() + m_padding),134 get_w() * 3 / 4 - butw_ / 2,
152 _("Grab Input")),135 get_inner_h() - hmargin_,
153 m_sb_maxfps136 butw_, buth_,
154 (this,137 g_gr->images().get("pics/but2.png"),
155 m_hmargin,138 _("OK"), std::string(), true, false),
156 m_inputgrab.get_y() + m_inputgrab.get_h() + m_padding,139
157 m_reslist.get_w(), 105,140 tabs_(this, hmargin_, 0,
158 opt.maxfps, 0, 99, _("Maximum FPS:"), ""),141 tab_panel_width_, get_inner_h() - tab_panel_y_ - buth_ - hmargin_,
159142 g_gr->images().get("pics/but1.png"),
160143 UI::TabPanel::Type::kBorder),
161 // First options block 'general options', second column144
162 m_label_language145 box_interface_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_),
163 (this,146 box_windows_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_),
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_),
165 _("Language"), UI::Align_VCenter),148 box_saving_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_),
166 // same height as m_reslist149 box_game_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_),
167 m_language_list150 box_language_(&tabs_, 0, 0, UI::Box::Vertical, 0, 0, padding_),
168 (this,151
169 m_label_language.get_x(), m_label_language.get_y() + m_label_language.get_h(),152 // Interface options
170 (get_w() - 2 * m_hmargin - m_space) / 2, m_reslist.get_h(),153 label_resolution_(&box_interface_, _("In-game resolution"), UI::Align_Left),
171 UI::Align_Left, true),154 resolution_list_(&box_interface_, 0, 0, column_width_ / 2, 80, UI::Align_Left, true),
172155
173 m_music (this, Point(m_label_language.get_x(),156 fullscreen_ (&box_interface_, Point(0, 0), _("Fullscreen"), "", column_width_),
174 m_language_list.get_y() +157 inputgrab_ (&box_interface_, Point(0, 0), _("Grab Input"), "", column_width_),
175 m_language_list.get_h() + m_padding),158
176 _("Enable Music")),159 sb_maxfps_(&box_interface_, 0, 0, column_width_ / 2, column_width_ / 4,
177 m_fx (this, Point(m_label_language.get_x(),160 opt.maxfps, 0, 99,
178 m_music.get_y() +161 _("Maximum FPS:"), ""),
179 m_music.get_h() + m_padding),162
180 _("Enable Sound Effects")),163
181164 // Windows options
182 // Second options block 'In-game options'165 snap_win_overlap_only_(&box_windows_, Point(0, 0), _("Snap windows only when overlapping"),
183 // Title 2166 "", column_width_),
184 m_label_game_options167 dock_windows_to_edges_(&box_windows_, Point(0, 0), _("Dock windows to edges"),
185 (this,168 "", column_width_),
186 get_w() / 2, get_h() / 2,169
187 _("In-game Options"), UI::Align_HCenter),170 sb_dis_panel_
188171 (&box_windows_, 0, 0, column_width_, 200,
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:"),
190 /** TRANSLATORS: and it also lets you jump to it on the map. */173 /** TRANSLATORS: Options: Distance for windows to snap to other panels: */
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 */
192175 ngettext("pixel", "pixels", opt.panel_snap_distance)),
193 m_auto_roadbuild_mode (this, Point(m_single_watchwin.get_x(),176
194 m_single_watchwin.get_y() +177 sb_dis_border_
195 m_single_watchwin.get_h() + m_padding),178 (&box_windows_, 0, 0, column_width_, 200,
196 _("Start building road after placing a flag")),179 opt.border_snap_distance, 0, 99,
197 m_show_workarea_preview180 _("Distance for windows to snap to borders:"),
198 (this, Point(m_auto_roadbuild_mode.get_x(),181 /** TRANSLATORS: Options: Distance for windows to snap to borders: */
199 m_auto_roadbuild_mode.get_y() +182 /** TRANSLATORS: This will have a number added in front of it */
200 m_auto_roadbuild_mode.get_h() + m_padding),183 ngettext("pixel", "pixels", opt.border_snap_distance)),
201 _("Show buildings area preview")),184
202185 // Sound options
203 m_snap_win_overlap_only186 music_ (&box_sound_, Point(0, 0), _("Enable Music"), "", column_width_),
204 (this, Point(m_show_workarea_preview.get_x(),187 fx_ (&box_sound_, Point(0, 0), _("Enable Sound Effects"), "", column_width_),
205 m_show_workarea_preview.get_y() +188 message_sound_(&box_sound_, Point(0, 0), _("Play a sound at message arrival"),
206 m_show_workarea_preview.get_h() + m_padding),189 "", column_width_),
207 _("Snap windows only when overlapping")),190
208191 // Saving options
209 m_dock_windows_to_edges (this, Point(m_snap_win_overlap_only.get_x(),192 sb_autosave_
210 m_snap_win_overlap_only.get_y() +193 (&box_saving_, 0, 0, column_width_, 240,
211 m_snap_win_overlap_only.get_h() + m_padding),194 opt.autosave / 60, 0, 100, _("Save game automatically every"),
212 _("Dock windows to edges")),
213 m_sb_autosave
214 (this,
215 m_hmargin,
216 m_dock_windows_to_edges.get_y() + m_dock_windows_to_edges.get_h() + m_padding,
217 get_w() - 2 * m_hmargin,
218 240,
219 opt.autosave / 60, 0, 100,
220 _("Save game automatically every"),
221 /** TRANSLATORS: Options: Save game automatically every: */195 /** TRANSLATORS: Options: Save game automatically every: */
222 /** TRANSLATORS: This will have a number added in front of it */196 /** TRANSLATORS: This will have a number added in front of it */
223 ngettext("minute", "minutes", opt.autosave / 60),197 ngettext("minute", "minutes", opt.autosave / 60),
224 g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig),198 g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig),
225199
226 m_sb_remove_replays200 sb_rolling_autosave_
227 (this,201 (&box_saving_, 0, 0, column_width_, 240,
228 m_hmargin,202 opt.rolling_autosave, 1, 20, _("Maximum number of autosave files"),
229 m_sb_autosave.get_y() + m_sb_autosave.get_h() + m_padding,203 "",
230 get_w() - 2 * m_hmargin,204 g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig),
231 240,205
232 opt.remove_replays, 0, 365,206 sb_remove_replays_
233 _("Remove replays older than:"),207 (&box_saving_, 0, 0, column_width_, 240,
208 opt.remove_replays, 0, 365, _("Remove replays older than:"),
234 /** TRANSLATORS: Options: Remove Replays older than: */209 /** TRANSLATORS: Options: Remove Replays older than: */
235 /** TRANSLATORS: This will have a number added in front of it */210 /** TRANSLATORS: This will have a number added in front of it */
236 ngettext("day", "days", opt.remove_replays),211 ngettext("day", "days", opt.remove_replays),
237 g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig),212 g_gr->images().get("pics/but3.png"), UI::SpinBox::Type::kBig),
238 os(opt)213
214 nozip_(&box_saving_, Point(0, 0), _("Do not zip widelands data files (maps, replays and savegames)"),
215 "", column_width_),
216 remove_syncstreams_(&box_saving_, Point(0, 0), _("Remove Syncstream dumps on startup"),
217 "", column_width_),
218
219 // Game options
220 auto_roadbuild_mode_(&box_game_, Point(0, 0), _("Start building road after placing a flag")),
221 show_workarea_preview_(&box_game_, Point(0, 0), _("Show buildings area preview")),
222 transparent_chat_(&box_game_, Point(0, 0), _("Show in-game chat with transparent background"),
223 "", column_width_),
224
225 /** TRANSLATORS: A watchwindow is a window where you keep watching an object or a map region,*/
226 /** TRANSLATORS: and it also lets you jump to it on the map. */
227 single_watchwin_(&box_game_, Point(0, 0), _("Use single watchwindow mode")),
228
229 // Language options
230 label_language_(&box_language_, _("Language"), UI::Align_Left),
231 language_list_(&box_language_, 0, 0, column_width_ / 2,
232 get_inner_h() - tab_panel_y_ - buth_ - hmargin_ - 5 * padding_,
233 UI::Align_Left, true),
234
235 os_(opt)
239{236{
240 m_advanced_options.sigclicked.connect237 // Set up UI Elements
241 (boost::bind(&FullscreenMenuOptions::advanced_options, boost::ref(*this)));238 title_ .set_textstyle(UI::TextStyle::ui_big());
242 m_cancel.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_back, this));239
243 m_apply.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_ok, this));240 tabs_.add("options_interface", _("Interface"), &box_interface_, "");
241 tabs_.add("options_windows", _("Windows"), &box_windows_, "");
242 tabs_.add("options_sound", _("Sound"), &box_sound_, "");
243 tabs_.add("options_saving", _("Saving"), &box_saving_, "");
244 tabs_.add("options_game", _("Game"), &box_game_, "");
245 tabs_.add("options_language", _("Language"), &box_language_, "");
246
247 // We want the last active tab when "Apply" was clicked.
248 if (os_.active_tab < tabs_.tabs().size()) {
249 tabs_.activate(os_.active_tab);
250 }
251
252 tabs_.set_pos(Point(hmargin_, tab_panel_y_));
253
254 box_interface_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h());
255 box_windows_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h());
256 box_sound_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h());
257 box_saving_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h());
258 box_game_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h());
259 box_language_.set_size(tabs_.get_inner_w(), tabs_.get_inner_h());
260
261 // Interface
262 box_interface_.add(&label_resolution_, UI::Align_Left);
263 box_interface_.add(&resolution_list_, UI::Align_Left);
264 box_interface_.add(&fullscreen_, UI::Align_Left);
265 box_interface_.add(&inputgrab_, UI::Align_Left);
266 box_interface_.add(&sb_maxfps_, UI::Align_Left);
267
268 // Windows
269 box_windows_.add(&snap_win_overlap_only_, UI::Align_Left);
270 box_windows_.add(&dock_windows_to_edges_, UI::Align_Left);
271 box_windows_.add(&sb_dis_panel_, UI::Align_Left);
272 box_windows_.add(&sb_dis_border_, UI::Align_Left);
273
274 // Sound
275 box_sound_.add(&music_, UI::Align_Left);
276 box_sound_.add(&fx_, UI::Align_Left);
277 box_sound_.add(&message_sound_, UI::Align_Left);
278
279 // Saving
280 box_saving_.add(&sb_autosave_, UI::Align_Left);
281 box_saving_.add(&sb_rolling_autosave_, UI::Align_Left);
282 box_saving_.add(&sb_remove_replays_, UI::Align_Left);
283 box_saving_.add(&nozip_, UI::Align_Left);
284 box_saving_.add(&remove_syncstreams_, UI::Align_Left);
285
286 // Game
287 box_game_.add(&auto_roadbuild_mode_, UI::Align_Left);
288 box_game_.add(&show_workarea_preview_, UI::Align_Left);
289 box_game_.add(&transparent_chat_, UI::Align_Left);
290 box_game_.add(&single_watchwin_, UI::Align_Left);
291
292 // Language
293 box_language_.add(&label_language_, UI::Align_Left);
294 box_language_.add(&language_list_, UI::Align_Left);
295
296
297 // Bind actions
298 cancel_.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_back, this));
299 apply_.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_apply, this));
300 ok_.sigclicked.connect(boost::bind(&FullscreenMenuOptions::clicked_ok, this));
244301
245 /** TRANSLATORS Options: Save game automatically every: */302 /** TRANSLATORS Options: Save game automatically every: */
246 m_sb_autosave .add_replacement(0, _("Off"));303 sb_autosave_ .add_replacement(0, _("Off"));
247 for (UI::Button* temp_button : m_sb_autosave.get_buttons()) {304 for (UI::Button* temp_button : sb_autosave_.get_buttons()) {
248 temp_button->sigclicked.connect305 temp_button->sigclicked.connect
249 (boost::bind306 (boost::bind
250 (&FullscreenMenuOptions::update_sb_autosave_unit,307 (&FullscreenMenuOptions::update_sb_autosave_unit,
251 boost::ref(*this)));308 boost::ref(*this)));
252 }309 }
253 /** TRANSLATORS Options: Remove Replays older than: */310 /** TRANSLATORS Options: Remove Replays older than: */
254 m_sb_remove_replays.add_replacement(0, _("Never"));311 sb_remove_replays_.add_replacement(0, _("Never"));
255 for (UI::Button* temp_button : m_sb_remove_replays.get_buttons()) {312 for (UI::Button* temp_button : sb_remove_replays_.get_buttons()) {
256 temp_button->sigclicked.connect313 temp_button->sigclicked.connect
257 (boost::bind314 (boost::bind
258 (&FullscreenMenuOptions::update_sb_remove_replays_unit,315 (&FullscreenMenuOptions::update_sb_remove_replays_unit,
259 boost::ref(*this)));316 boost::ref(*this)));
260 }317 }
261318 for (UI::Button* temp_button : sb_dis_panel_.get_buttons()) {
262 m_title .set_textstyle(UI::TextStyle::ui_big());319 temp_button->sigclicked.connect
263 m_fullscreen .set_state(opt.fullscreen);320 (boost::bind
264 m_inputgrab .set_state(opt.inputgrab);321 (&FullscreenMenuOptions::update_sb_dis_panel_unit,
265 m_music .set_state(opt.music);322 boost::ref(*this)));
266 m_music .set_enabled(!g_sound_handler.lock_audio_disabling_);323 }
267 m_fx .set_state(opt.fx);324
268 m_fx .set_enabled(!g_sound_handler.lock_audio_disabling_);325 for (UI::Button* temp_button : sb_dis_border_.get_buttons()) {
269326 temp_button->sigclicked.connect
270 m_label_game_options .set_textstyle(UI::TextStyle::ui_big());327 (boost::bind
271 m_single_watchwin .set_state(opt.single_watchwin);328 (&FullscreenMenuOptions::update_sb_dis_border_unit,
272 m_auto_roadbuild_mode .set_state(opt.auto_roadbuild_mode);329 boost::ref(*this)));
273 m_show_workarea_preview .set_state(opt.show_warea);330 }
274 m_snap_win_overlap_only .set_state(opt.snap_win_overlap_only);331
275 m_dock_windows_to_edges .set_state(opt.dock_windows_to_edges);332 // Fill in data
276333 // Interface options
277 for (int modes = 0; modes < SDL_GetNumDisplayModes(0); ++modes) {334 for (int modes = 0; modes < SDL_GetNumDisplayModes(0); ++modes) {
278 SDL_DisplayMode mode;335 SDL_DisplayMode mode;
279 SDL_GetDisplayMode(0, modes, & mode);336 SDL_GetDisplayMode(0, modes, & mode);
@@ -281,64 +338,89 @@
281 (SDL_BITSPERPIXEL(mode.format) == 32 ||338 (SDL_BITSPERPIXEL(mode.format) == 32 ||
282 SDL_BITSPERPIXEL(mode.format) == 24)) {339 SDL_BITSPERPIXEL(mode.format) == 24)) {
283 ScreenResolution this_res = {340 ScreenResolution this_res = {
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))};
285 if (this_res.depth == 24) this_res.depth = 32;342 if (this_res.depth == 24) this_res.depth = 32;
286 if (m_resolutions.empty()343 if (resolutions_.empty()
287 || this_res.xres != m_resolutions.rbegin()->xres344 || this_res.xres != resolutions_.rbegin()->xres
288 || this_res.yres != m_resolutions.rbegin()->yres) {345 || this_res.yres != resolutions_.rbegin()->yres) {
289 m_resolutions.push_back(this_res);346 resolutions_.push_back(this_res);
290 }347 }
291 }348 }
292 }349 }
293350
294 bool did_select_a_res = false;351 bool did_select_a_res = false;
295 for (uint32_t i = 0; i < m_resolutions.size(); ++i) {352 for (uint32_t i = 0; i < resolutions_.size(); ++i) {
296 const bool selected =353 const bool selected =
297 m_resolutions[i].xres == opt.xres &&354 resolutions_[i].xres == opt.xres &&
298 m_resolutions[i].yres == opt.yres;355 resolutions_[i].yres == opt.yres;
299 did_select_a_res |= selected;356 did_select_a_res |= selected;
300 /** TRANSLATORS: Screen resolution, e.g. 800 x 600*/357 /** TRANSLATORS: Screen resolution, e.g. 800 x 600*/
301 m_reslist.add((boost::format(_("%1% x %2%"))358 resolution_list_.add((boost::format(_("%1% x %2%"))
302 % m_resolutions[i].xres359 % resolutions_[i].xres
303 % m_resolutions[i].yres).str(),360 % resolutions_[i].yres).str(),
304 nullptr, nullptr, selected);361 nullptr, nullptr, selected);
305 }362 }
306 if (!did_select_a_res) {363 if (!did_select_a_res) {
307 m_reslist.add((boost::format(_("%1% x %2%"))364 resolution_list_.add((boost::format(_("%1% x %2%"))
308 % opt.xres365 % opt.xres
309 % opt.yres).str(),366 % opt.yres).str(),
310 nullptr, nullptr, true);367 nullptr, nullptr, true);
311 uint32_t entry = m_resolutions.size();368 uint32_t entry = resolutions_.size();
312 m_resolutions.resize(entry + 1);369 resolutions_.resize(entry + 1);
313 m_resolutions[entry].xres = opt.xres;370 resolutions_[entry].xres = opt.xres;
314 m_resolutions[entry].yres = opt.yres;371 resolutions_[entry].yres = opt.yres;
315 }372 }
316373
374 fullscreen_ .set_state(opt.fullscreen);
375 inputgrab_ .set_state(opt.inputgrab);
376
377 // Windows options
378 snap_win_overlap_only_.set_state(opt.snap_win_overlap_only);
379 dock_windows_to_edges_.set_state(opt.dock_windows_to_edges);
380
381 // Sound options
382 music_ .set_state(opt.music);
383 music_ .set_enabled(!g_sound_handler.lock_audio_disabling_);
384 fx_ .set_state(opt.fx);
385 fx_ .set_enabled(!g_sound_handler.lock_audio_disabling_);
386 message_sound_ .set_state(opt.message_sound);
387
388 // Saving options
389 nozip_ .set_state(opt.nozip);
390 remove_syncstreams_ .set_state(opt.remove_syncstreams);
391
392 // Game options
393 auto_roadbuild_mode_ .set_state(opt.auto_roadbuild_mode);
394 show_workarea_preview_.set_state(opt.show_warea);
395 transparent_chat_ .set_state(opt.transparent_chat);
396 single_watchwin_ .set_state(opt.single_watchwin);
397
398 // Language options
317 add_languages_to_list(opt.language);399 add_languages_to_list(opt.language);
318 m_language_list.focus();400 language_list_.focus();
319}401}
320402
321void FullscreenMenuOptions::update_sb_autosave_unit() {403void FullscreenMenuOptions::update_sb_autosave_unit() {
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()));
323}405}
324406
325void FullscreenMenuOptions::update_sb_remove_replays_unit() {407void FullscreenMenuOptions::update_sb_remove_replays_unit() {
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()));
327}409}
328410
329void FullscreenMenuOptions::advanced_options() {411void FullscreenMenuOptions::update_sb_dis_panel_unit() {
330 FullscreenMenuAdvancedOptions aom(os);412 sb_dis_panel_.set_unit(ngettext("pixel", "pixels", sb_dis_panel_.get_value()));
331 if (aom.run<FullscreenMenuBase::MenuTarget>() == FullscreenMenuBase::MenuTarget::kOk) {413}
332 os = aom.get_values();414
333 end_modal<FullscreenMenuBase::MenuTarget>(FullscreenMenuBase::MenuTarget::kRestart);415void FullscreenMenuOptions::update_sb_dis_border_unit() {
334 }416 sb_dis_border_.set_unit(ngettext("pixel", "pixels", sb_dis_border_.get_value()));
335}417}
336418
337void FullscreenMenuOptions::add_languages_to_list(const std::string& current_locale) {419void FullscreenMenuOptions::add_languages_to_list(const std::string& current_locale) {
338420
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.
340 m_language_list.add(_("Try system language"), "", nullptr, current_locale == "");422 language_list_.add(_("Try system language"), "", nullptr, current_locale == "");
341 m_language_list.add("English", "en", nullptr, current_locale == "en");423 language_list_.add("English", "en", nullptr, current_locale == "en");
342424
343 // We start with the locale directory so we can pick up locales425 // We start with the locale directory so we can pick up locales
344 // that don't have a configuration file yet.426 // that don't have a configuration file yet.
@@ -391,241 +473,164 @@
391473
392 std::sort(entries.begin(), entries.end());474 std::sort(entries.begin(), entries.end());
393 for (const LanguageEntry& entry : entries) {475 for (const LanguageEntry& entry : entries) {
394 m_language_list.add(entry.descname.c_str(), entry.localename, nullptr,476 language_list_.add(entry.descname.c_str(), entry.localename, nullptr,
395 entry.localename == selected_locale, "", entry.fontname);477 entry.localename == selected_locale, "", entry.fontname);
396 }478 }
397}479}
398480
399481
482void FullscreenMenuOptions::clicked_apply() {
483 end_modal<FullscreenMenuBase::MenuTarget>(FullscreenMenuBase::MenuTarget::kApplyOptions);
484}
485
486
400OptionsCtrl::OptionsStruct FullscreenMenuOptions::get_values() {487OptionsCtrl::OptionsStruct FullscreenMenuOptions::get_values() {
401 const uint32_t res_index = m_reslist.selection_index();
402
403 // Write all data from UI elements488 // Write all data from UI elements
404 os.xres = m_resolutions[res_index].xres;489 // Interface options
405 os.yres = m_resolutions[res_index].yres;490 const uint32_t res_index = resolution_list_.selection_index();
406 os.inputgrab = m_inputgrab.get_state();491 os_.xres = resolutions_[res_index].xres;
407 os.fullscreen = m_fullscreen.get_state();492 os_.yres = resolutions_[res_index].yres;
408 os.single_watchwin = m_single_watchwin.get_state();493 os_.fullscreen = fullscreen_.get_state();
409 os.auto_roadbuild_mode = m_auto_roadbuild_mode.get_state();494 os_.inputgrab = inputgrab_.get_state();
410 os.show_warea = m_show_workarea_preview.get_state();495 os_.maxfps = sb_maxfps_.get_value();
411 os.snap_win_overlap_only = m_snap_win_overlap_only.get_state();496
412 os.dock_windows_to_edges = m_dock_windows_to_edges.get_state();497 // Windows options
413 os.music = m_music.get_state();498 os_.snap_win_overlap_only = snap_win_overlap_only_.get_state();
414 os.fx = m_fx.get_state();499 os_.dock_windows_to_edges = dock_windows_to_edges_.get_state();
415 if (m_language_list.has_selection())500 os_.panel_snap_distance = sb_dis_panel_.get_value();
416 os.language = m_language_list.get_selected();501 os_.border_snap_distance = sb_dis_border_.get_value();
417 os.autosave = m_sb_autosave.get_value();502
418 os.maxfps = m_sb_maxfps.get_value();503 // Sound options
419 os.remove_replays = m_sb_remove_replays.get_value();504 os_.music = music_.get_state();
420505 os_.fx = fx_.get_state();
421 return os;506 os_.message_sound = message_sound_.get_state();
422}507
423508 // Saving options
424509 os_.autosave = sb_autosave_.get_value();
425/**510 os_.rolling_autosave = sb_rolling_autosave_.get_value();
426 * The advanced option menu511 os_.remove_replays = sb_remove_replays_.get_value();
427 */512 os_.nozip = nozip_.get_state();
428FullscreenMenuAdvancedOptions::FullscreenMenuAdvancedOptions513 os_.remove_syncstreams = remove_syncstreams_.get_state();
429 (OptionsCtrl::OptionsStruct const opt)514
430 :515 // Game options
431 FullscreenMenuBase("ui_fsmenu.jpg"),516 os_.auto_roadbuild_mode = auto_roadbuild_mode_.get_state();
432517 os_.show_warea = show_workarea_preview_.get_state();
433// Values for alignment and size518 os_.transparent_chat = transparent_chat_.get_state();
434 m_vbutw (get_h() * 333 / 10000),519 os_.single_watchwin = single_watchwin_.get_state();
435 m_butw (get_w() / 4),520
436 m_buth (get_h() * 9 / 200),521 // Language options
437 m_hmargin (get_w() * 19 / 200),522 if (language_list_.has_selection()) {
438 m_padding (10),523 os_.language = language_list_.get_selected();
439 m_space (25),524 }
440525
441// Buttons526 // Last tab for reloading the options menu
442 m_cancel527 os_.active_tab = tabs_.active();
443 (this, "cancel",528 return os_;
444 get_w() * 41 / 80, get_h() * 19 / 20, m_butw, m_buth,529}
445 g_gr->images().get("pics/but0.png"),
446 _("Cancel"), std::string(), true, false),
447 m_apply
448 (this, "apply",
449 get_w() / 4, get_h() * 19 / 20, m_butw, m_buth,
450 g_gr->images().get("pics/but2.png"),
451 _("Apply"), std::string(), true, false),
452
453// Title
454 m_title
455 (this,
456 get_w() / 2, get_h() * 17 / 150,
457 _("Advanced Options"), UI::Align_HCenter),
458
459 // Spinboxes
460 m_sb_dis_panel
461 (this,
462 m_hmargin, get_h() * 9 / 30,
463 get_w() - 2 * m_hmargin, get_w() / 5,
464 opt.panel_snap_distance, 0, 99,
465 _("Distance for windows to snap to other panels:"),
466 ngettext("pixel", "pixels", opt.panel_snap_distance)),
467
468 m_sb_dis_border
469 (this,
470 m_hmargin, m_sb_dis_panel.get_y() + m_sb_dis_panel.get_h() + 2 * m_padding,
471 get_w() - 2 * m_hmargin, get_w() / 5,
472 opt.border_snap_distance, 0, 99,
473 _("Distance for windows to snap to borders:"),
474 ngettext("pixel", "pixels", opt.border_snap_distance)),
475
476 m_transparent_chat (this, Point(m_hmargin,
477 m_sb_dis_border.get_y() +
478 m_sb_dis_border.get_h() + m_space),
479 _("Show in-game chat with transparent background"),
480 "", get_w() - 2 * m_hmargin),
481
482 m_message_sound
483 (this, Point(m_hmargin,
484 m_transparent_chat.get_y() +
485 m_transparent_chat.get_h() + m_padding),
486 _("Play a sound at message arrival"),
487 "", get_w() - 2 * m_hmargin),
488
489 m_nozip (this, Point(m_hmargin,
490 m_message_sound.get_y() +
491 m_message_sound.get_h() + m_padding),
492 _("Do not zip widelands data files (maps, replays and savegames)"),
493 "", get_w() - 2 * m_hmargin),
494
495 m_remove_syncstreams (this, Point(m_hmargin,
496 m_nozip.get_y() +
497 m_nozip.get_h() + m_padding),
498 _("Remove Syncstream dumps on startup"),
499 "", get_w() - 2 * m_hmargin),
500
501 os(opt)
502{
503 for (UI::Button* temp_button : m_sb_dis_panel.get_buttons()) {
504 temp_button->sigclicked.connect
505 (boost::bind
506 (&FullscreenMenuAdvancedOptions::update_sb_dis_panel_unit,
507 boost::ref(*this)));
508 }
509
510 for (UI::Button* temp_button : m_sb_dis_border.get_buttons()) {
511 temp_button->sigclicked.connect
512 (boost::bind
513 (&FullscreenMenuAdvancedOptions::update_sb_dis_border_unit,
514 boost::ref(*this)));
515 }
516
517 m_cancel.sigclicked.connect(boost::bind(&FullscreenMenuAdvancedOptions::clicked_back, boost::ref(*this)));
518 m_apply.sigclicked.connect(boost::bind(&FullscreenMenuAdvancedOptions::clicked_ok, boost::ref(*this)));
519
520 m_title .set_textstyle(UI::TextStyle::ui_big());
521 m_message_sound .set_state(opt.message_sound);
522 m_nozip .set_state(opt.nozip);
523 m_remove_syncstreams .set_state(opt.remove_syncstreams);
524 m_transparent_chat .set_state(opt.transparent_chat);
525}
526
527void FullscreenMenuAdvancedOptions::update_sb_dis_panel_unit() {
528 m_sb_dis_panel.set_unit(ngettext("pixel", "pixels", m_sb_dis_panel.get_value()));
529}
530
531void FullscreenMenuAdvancedOptions::update_sb_dis_border_unit() {
532 m_sb_dis_border.set_unit(ngettext("pixel", "pixels", m_sb_dis_border.get_value()));
533}
534
535OptionsCtrl::OptionsStruct FullscreenMenuAdvancedOptions::get_values() {
536 // Write all remaining data from UI elements
537 os.message_sound = m_message_sound.get_state();
538 os.nozip = m_nozip.get_state();
539 os.panel_snap_distance = m_sb_dis_panel.get_value();
540 os.border_snap_distance = m_sb_dis_border.get_value();
541 os.remove_syncstreams = m_remove_syncstreams.get_state();
542 os.transparent_chat = m_transparent_chat.get_state();
543 return os;
544}
545
546530
547/**531/**
548 * Handles communication between window class and options532 * Handles communication between window class and options
549 */533 */
550OptionsCtrl::OptionsCtrl(Section & s)534OptionsCtrl::OptionsCtrl(Section & s)
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))))
552{536{
553 handle_menu();537 handle_menu();
554}538}
555539
556OptionsCtrl::~OptionsCtrl() {
557 delete m_opt_dialog;
558}
559
560void OptionsCtrl::handle_menu()540void OptionsCtrl::handle_menu()
561{541{
562 FullscreenMenuBase::MenuTarget i = m_opt_dialog->run<FullscreenMenuBase::MenuTarget>();542 FullscreenMenuBase::MenuTarget i = opt_dialog_->run<FullscreenMenuBase::MenuTarget>();
563 if (i != FullscreenMenuBase::MenuTarget::kBack)543 if (i != FullscreenMenuBase::MenuTarget::kBack)
564 save_options();544 save_options();
565 if (i == FullscreenMenuBase::MenuTarget::kRestart) {545 if (i == FullscreenMenuBase::MenuTarget::kApplyOptions) {
566 delete m_opt_dialog;546 uint32_t active_tab = opt_dialog_->get_values().active_tab;
567 m_opt_dialog = new FullscreenMenuOptions(options_struct());547 g_gr->change_resolution(opt_dialog_->get_values().xres, opt_dialog_->get_values().yres);
548 g_gr->set_fullscreen(opt_dialog_->get_values().fullscreen);
549 opt_dialog_.reset(new FullscreenMenuOptions(options_struct(active_tab)));
568 handle_menu(); // Restart general options menu550 handle_menu(); // Restart general options menu
569 }551 }
570}552}
571553
572OptionsCtrl::OptionsStruct OptionsCtrl::options_struct() {554OptionsCtrl::OptionsStruct OptionsCtrl::options_struct(uint32_t active_tab) {
573 OptionsStruct opt;555 OptionsStruct opt;
574 opt.xres = m_opt_section.get_int("xres", DEFAULT_RESOLUTION_W);556 // Interface options
575 opt.yres = m_opt_section.get_int("yres", DEFAULT_RESOLUTION_H);557 opt.xres = opt_section_.get_int("xres", DEFAULT_RESOLUTION_W);
576 opt.inputgrab = m_opt_section.get_bool("inputgrab", false);558 opt.yres = opt_section_.get_int("yres", DEFAULT_RESOLUTION_H);
577 opt.fullscreen = m_opt_section.get_bool("fullscreen", false);559 opt.fullscreen = opt_section_.get_bool("fullscreen", false);
578 opt.single_watchwin = m_opt_section.get_bool("single_watchwin", false);560 opt.inputgrab = opt_section_.get_bool("inputgrab", false);
579 opt.auto_roadbuild_mode = m_opt_section.get_bool("auto_roadbuild_mode", true);561 opt.maxfps = opt_section_.get_int("maxfps", 25);
580 opt.show_warea = m_opt_section.get_bool("workareapreview", true);562
563 // Windows options
581 opt.snap_win_overlap_only =564 opt.snap_win_overlap_only =
582 m_opt_section.get_bool("snap_windows_only_when_overlapping", false);565 opt_section_.get_bool("snap_windows_only_when_overlapping", false);
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);
584 opt.language = m_opt_section.get_string("language", "");567 opt.panel_snap_distance = opt_section_.get_int("panel_snap_distance", 0);
585 opt.music = !m_opt_section.get_bool("disable_music", false);568 opt.border_snap_distance = opt_section_.get_int("border_snap_distance", 0);
586 opt.fx = !m_opt_section.get_bool("disable_fx", false);569
587 opt.autosave = m_opt_section.get_int("autosave", DEFAULT_AUTOSAVE_INTERVAL * 60);570 // Sound options
588 opt.rolling_autosave = m_opt_section.get_int("rolling_autosave", 5);571 opt.music = !opt_section_.get_bool("disable_music", false);
589 opt.maxfps = m_opt_section.get_int("maxfps", 25);572 opt.fx = !opt_section_.get_bool("disable_fx", false);
590573 opt.message_sound = opt_section_.get_bool("sound_at_message", true);
591 opt.message_sound = m_opt_section.get_bool("sound_at_message", true);574
592 opt.nozip = m_opt_section.get_bool("nozip", false);575 // Saving options
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);
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);
595 opt.remove_replays = m_opt_section.get_int("remove_replays", 0);578 opt.remove_replays = opt_section_.get_int("remove_replays", 0);
596 opt.remove_syncstreams = m_opt_section.get_bool("remove_syncstreams", true);579 opt.nozip = opt_section_.get_bool("nozip", false);
597 opt.transparent_chat = m_opt_section.get_bool("transparent_chat", true);580 opt.remove_syncstreams = opt_section_.get_bool("remove_syncstreams", true);
581
582 // Game options
583 opt.auto_roadbuild_mode = opt_section_.get_bool("auto_roadbuild_mode", true);
584 opt.show_warea = opt_section_.get_bool("workareapreview", true);
585 opt.transparent_chat = opt_section_.get_bool("transparent_chat", true);
586 opt.single_watchwin = opt_section_.get_bool("single_watchwin", false);
587
588 // Language options
589 opt.language = opt_section_.get_string("language", "");
590
591 // Last tab for reloading the options menu
592 opt.active_tab = active_tab;
598 return opt;593 return opt;
599}594}
600595
601void OptionsCtrl::save_options() {596void OptionsCtrl::save_options() {
602 OptionsCtrl::OptionsStruct opt = m_opt_dialog->get_values();597 OptionsCtrl::OptionsStruct opt = opt_dialog_->get_values();
603 m_opt_section.set_int ("xres", opt.xres);598
604 m_opt_section.set_int ("yres", opt.yres);599 // Interface options
605 m_opt_section.set_bool("fullscreen", opt.fullscreen);600 opt_section_.set_int ("xres", opt.xres);
606 m_opt_section.set_bool("inputgrab", opt.inputgrab);601 opt_section_.set_int ("yres", opt.yres);
607 m_opt_section.set_bool("single_watchwin", opt.single_watchwin);602 opt_section_.set_bool("fullscreen", opt.fullscreen);
608 m_opt_section.set_bool("auto_roadbuild_mode", opt.auto_roadbuild_mode);603 opt_section_.set_bool("inputgrab", opt.inputgrab);
609 m_opt_section.set_bool("workareapreview", opt.show_warea);604 opt_section_.set_int("maxfps", opt.maxfps);
610 m_opt_section.set_bool605
606 // Windows options
607 opt_section_.set_bool
611 ("snap_windows_only_when_overlapping",608 ("snap_windows_only_when_overlapping",
612 opt.snap_win_overlap_only);609 opt.snap_win_overlap_only);
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);
614 m_opt_section.set_bool("disable_music", !opt.music);611 opt_section_.set_int("panel_snap_distance", opt.panel_snap_distance);
615 m_opt_section.set_bool("disable_fx", !opt.fx);612 opt_section_.set_int("border_snap_distance", opt.border_snap_distance);
616 m_opt_section.set_string("language", opt.language);613
617 m_opt_section.set_int("autosave", opt.autosave * 60);614 // Sound options
618 m_opt_section.set_int("rolling_autosave", opt.rolling_autosave);615 opt_section_.set_bool("disable_music", !opt.music);
619 m_opt_section.set_int("maxfps", opt.maxfps);616 opt_section_.set_bool("disable_fx", !opt.fx);
620617 opt_section_.set_bool("sound_at_message", opt.message_sound);
621 m_opt_section.set_bool("sound_at_message", opt.message_sound);618
622 m_opt_section.set_bool("nozip", opt.nozip);619 // Saving options
623 m_opt_section.set_int("border_snap_distance", opt.border_snap_distance);620 opt_section_.set_int("autosave", opt.autosave * 60);
624 m_opt_section.set_int("panel_snap_distance", opt.panel_snap_distance);621 opt_section_.set_int("rolling_autosave", opt.rolling_autosave);
625622 opt_section_.set_int("remove_replays", opt.remove_replays);
626 m_opt_section.set_int("remove_replays", opt.remove_replays);623 opt_section_.set_bool("nozip", opt.nozip);
627 m_opt_section.set_bool("remove_syncstreams", opt.remove_syncstreams);624 opt_section_.set_bool("remove_syncstreams", opt.remove_syncstreams);
628 m_opt_section.set_bool("transparent_chat", opt.transparent_chat);625
626 // Game options
627 opt_section_.set_bool("auto_roadbuild_mode", opt.auto_roadbuild_mode);
628 opt_section_.set_bool("workareapreview", opt.show_warea);
629 opt_section_.set_bool("transparent_chat", opt.transparent_chat);
630 opt_section_.set_bool("single_watchwin", opt.single_watchwin);
631
632 // Language options
633 opt_section_.set_string("language", opt.language);
629634
630 WLApplication::get()->set_input_grab(opt.inputgrab);635 WLApplication::get()->set_input_grab(opt.inputgrab);
631 i18n::set_locale(opt.language);636 i18n::set_locale(opt.language);
632637
=== modified file 'src/ui_fsmenu/options.h'
--- src/ui_fsmenu/options.h 2015-12-01 16:58:54 +0000
+++ src/ui_fsmenu/options.h 2016-01-01 19:10:55 +0000
@@ -21,6 +21,7 @@
21#define WL_UI_FSMENU_OPTIONS_H21#define WL_UI_FSMENU_OPTIONS_H
2222
23#include <cstring>23#include <cstring>
24#include <memory>
24#include <string>25#include <string>
25#include <vector>26#include <vector>
2627
@@ -31,6 +32,7 @@
31#include "ui_basic/multilinetextarea.h"32#include "ui_basic/multilinetextarea.h"
32#include "ui_basic/spinbox.h"33#include "ui_basic/spinbox.h"
33#include "ui_basic/textarea.h"34#include "ui_basic/textarea.h"
35#include "ui_basic/tabpanel.h"
3436
35class FullscreenMenuOptions;37class FullscreenMenuOptions;
36class Section;38class Section;
@@ -39,41 +41,52 @@
39class OptionsCtrl {41class OptionsCtrl {
40public:42public:
41 struct OptionsStruct {43 struct OptionsStruct {
44
45 // Interface options
42 int32_t xres;46 int32_t xres;
43 int32_t yres;47 int32_t yres;
48 bool fullscreen;
44 bool inputgrab;49 bool inputgrab;
45 bool fullscreen;50 uint32_t maxfps;
46 bool single_watchwin;51
47 bool auto_roadbuild_mode;52 // Windows options
48 bool show_warea;
49 bool snap_win_overlap_only;53 bool snap_win_overlap_only;
50 bool dock_windows_to_edges;54 bool dock_windows_to_edges;
55 int32_t panel_snap_distance;
56 int32_t border_snap_distance;
57
58 // Sound options
51 bool music;59 bool music;
52 bool fx;60 bool fx;
53 std::string language;61 bool message_sound;
62
63 // Saving options
54 int32_t autosave; // autosave interval in minutes64 int32_t autosave; // autosave interval in minutes
55 int32_t rolling_autosave; //number of file to use for rolling autosave65 int32_t rolling_autosave; // number of file to use for rolling autosave
56 uint32_t maxfps;
57 uint32_t remove_replays;66 uint32_t remove_replays;
67 bool nozip;
58 bool remove_syncstreams;68 bool remove_syncstreams;
69
70 // Game options
71 bool auto_roadbuild_mode;
72 bool show_warea;
59 bool transparent_chat;73 bool transparent_chat;
6074 bool single_watchwin;
61 // advanced options75
62 bool message_sound;76 // Language options
63 bool nozip;77 std::string language;
64 std::string ui_font;78
65 int32_t border_snap_distance;79 // Last tab for reloading the options menu
66 int32_t panel_snap_distance;80 uint32_t active_tab;
67 };81 };
6882
69 OptionsCtrl(Section &);83 OptionsCtrl(Section &);
70 ~OptionsCtrl();
71 void handle_menu();84 void handle_menu();
72 OptionsCtrl::OptionsStruct options_struct();85 OptionsCtrl::OptionsStruct options_struct(uint32_t active_tab);
73 void save_options();86 void save_options();
74private:87private:
75 Section & m_opt_section;88 Section & opt_section_;
76 FullscreenMenuOptions * m_opt_dialog;89 std::unique_ptr<FullscreenMenuOptions> opt_dialog_;
77};90};
7891
79/**92/**
@@ -86,47 +99,75 @@
86 OptionsCtrl::OptionsStruct get_values();99 OptionsCtrl::OptionsStruct get_values();
87100
88private:101private:
89 uint32_t const m_vbutw;
90 uint32_t const m_butw;
91 uint32_t const m_buth;
92 uint32_t const m_hmargin;
93 uint32_t const m_padding;
94 uint32_t const m_space;
95 uint32_t const m_offset_first_group;
96 uint32_t const m_offset_second_group;
97
98 UI::Button m_advanced_options, m_cancel, m_apply;
99
100 UI::Textarea m_title;
101 UI::Textarea m_label_resolution;
102 UI::Listselect<void *> m_reslist;
103 UI::Checkbox m_fullscreen;
104 UI::Checkbox m_inputgrab;
105 UI::SpinBox m_sb_maxfps;
106
107 UI::Textarea m_label_language;
108 UI::Listselect<std::string> m_language_list;
109 UI::Checkbox m_music;
110 UI::Checkbox m_fx;
111
112 UI::Textarea m_label_game_options;
113 UI::Checkbox m_single_watchwin;
114 UI::Checkbox m_auto_roadbuild_mode;
115 UI::Checkbox m_show_workarea_preview;
116 UI::Checkbox m_snap_win_overlap_only;
117 UI::Checkbox m_dock_windows_to_edges;
118 UI::SpinBox m_sb_autosave;
119 UI::SpinBox m_sb_remove_replays;
120
121 OptionsCtrl::OptionsStruct os;
122
123 void update_sb_autosave_unit();102 void update_sb_autosave_unit();
124 void update_sb_remove_replays_unit();103 void update_sb_remove_replays_unit();
125 void advanced_options();104 void update_sb_dis_panel_unit();
105 void update_sb_dis_border_unit();
126106
127 // Fills the language selection list107 // Fills the language selection list
128 void add_languages_to_list(const std::string& current_locale);108 void add_languages_to_list(const std::string& current_locale);
129109
110 // Saves the options and reloads the active tab
111 void clicked_apply();
112
113 uint32_t const butw_;
114 uint32_t const buth_;
115 uint32_t const hmargin_;
116 uint32_t const padding_;
117 uint32_t const space_;
118 uint32_t const tab_panel_width_;
119 uint32_t const column_width_;
120 uint32_t const tab_panel_y_;
121
122 UI::Textarea title_;
123 UI::Button cancel_, apply_, ok_;
124
125 // UI elements
126 UI::TabPanel tabs_;
127 UI::Box box_interface_;
128 UI::Box box_windows_;
129 UI::Box box_sound_;
130 UI::Box box_saving_;
131 UI::Box box_game_;
132 UI::Box box_language_;
133
134 // Interface options
135 UI::Textarea label_resolution_;
136 UI::Listselect<void *> resolution_list_;
137 UI::Checkbox fullscreen_;
138 UI::Checkbox inputgrab_;
139 UI::SpinBox sb_maxfps_;
140
141 // Windows options
142 UI::Checkbox snap_win_overlap_only_;
143 UI::Checkbox dock_windows_to_edges_;
144 UI::SpinBox sb_dis_panel_;
145 UI::SpinBox sb_dis_border_;
146
147 // Sound options
148 UI::Checkbox music_;
149 UI::Checkbox fx_;
150 UI::Checkbox message_sound_;
151
152 // Saving options
153 UI::SpinBox sb_autosave_;
154 UI::SpinBox sb_rolling_autosave_;
155 UI::SpinBox sb_remove_replays_;
156 UI::Checkbox nozip_;
157 UI::Checkbox remove_syncstreams_;
158
159 // Game options
160 UI::Checkbox auto_roadbuild_mode_;
161 UI::Checkbox show_workarea_preview_;
162 UI::Checkbox transparent_chat_;
163 UI::Checkbox single_watchwin_;
164
165 // Language options
166 UI::Textarea label_language_;
167 UI::Listselect<std::string> language_list_;
168
169 OptionsCtrl::OptionsStruct os_;
170
130 class ScreenResolution {171 class ScreenResolution {
131 public:172 public:
132 int32_t xres;173 int32_t xres;
@@ -135,39 +176,7 @@
135 };176 };
136177
137 /// All supported screen resolutions.178 /// All supported screen resolutions.
138 std::vector<ScreenResolution> m_resolutions;179 std::vector<ScreenResolution> resolutions_;
139};
140
141/**
142 * Fullscreen Optionsmenu. A modal optionsmenu
143 */
144
145class FullscreenMenuAdvancedOptions : public FullscreenMenuBase {
146public:
147 FullscreenMenuAdvancedOptions(OptionsCtrl::OptionsStruct opt);
148 OptionsCtrl::OptionsStruct get_values();
149
150private:
151 void update_sb_dis_panel_unit();
152 void update_sb_dis_border_unit();
153
154 uint32_t const m_vbutw;
155 uint32_t const m_butw;
156 uint32_t const m_buth;
157 uint32_t const m_hmargin;
158 uint32_t const m_padding;
159 uint32_t const m_space;
160
161 UI::Button m_cancel, m_apply;
162 UI::Textarea m_title;
163
164 UI::SpinBox m_sb_dis_panel, m_sb_dis_border;
165 UI::Checkbox m_transparent_chat;
166 UI::Checkbox m_message_sound;
167 UI::Checkbox m_nozip;
168 UI::Checkbox m_remove_syncstreams;
169
170 OptionsCtrl::OptionsStruct os;
171};180};
172181
173#endif // end of include guard: WL_UI_FSMENU_OPTIONS_H182#endif // end of include guard: WL_UI_FSMENU_OPTIONS_H

Subscribers

People subscribed via source and target branches

to status/vote changes: