1 /*
2 * The ManaPlus Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2010 The Mana Developers
5 * Copyright (C) 2011-2019 The ManaPlus Developers
6 * Copyright (C) 2019-2021 Andrei Karas
7 *
8 * This file is part of The ManaPlus Client.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "gui/windows/setupwindow.h"
25
26 #include "configuration.h"
27 #include "game.h"
28 #include "main.h"
29
30 #include "gui/windows/chatwindow.h"
31 #include "gui/windows/statuswindow.h"
32
33 #include "gui/widgets/createwidget.h"
34
35 #include "gui/widgets/tabs/setup_audio.h"
36 #include "gui/widgets/tabs/setup_chat.h"
37 #include "gui/widgets/tabs/setup_colors.h"
38 #include "gui/widgets/tabs/setup_input.h"
39 #include "gui/widgets/tabs/setup_joystick.h"
40 #include "gui/widgets/tabs/setup_misc.h"
41 #include "gui/widgets/tabs/setup_mods.h"
42 #include "gui/widgets/tabs/setup_perfomance.h"
43 #include "gui/widgets/tabs/setup_players.h"
44 #include "gui/widgets/tabs/setup_quick.h"
45 #include "gui/widgets/tabs/setup_relations.h"
46 #include "gui/widgets/tabs/setup_theme.h"
47 #include "gui/widgets/tabs/setup_touch.h"
48 #include "gui/widgets/tabs/setup_video.h"
49 #include "gui/widgets/tabs/setup_visual.h"
50
51 #include "gui/widgets/button.h"
52 #include "gui/widgets/label.h"
53 #include "gui/widgets/tabbedarea.h"
54
55 #include "input/touch/touchmanager.h"
56
57 #include "utils/delete2.h"
58 #include "utils/dtor.h"
59 #include "utils/foreach.h"
60 #include "utils/gettext.h"
61
62 #include "debug.h"
63
64 SetupWindow *setupWindow = nullptr;
65
SetupWindow()66 SetupWindow::SetupWindow() :
67 // TRANSLATORS: setup window name
68 Window(_("Setup"), Modal_false, nullptr, "setup.xml"),
69 ActionListener(),
70 mTabs(),
71 mWindowsToReset(),
72 mButtons(),
73 mModsTab(nullptr),
74 mQuickTab(nullptr),
75 mResetWindows(nullptr),
76 mPanel(CREATEWIDGETR(TabbedArea, this)),
77 mVersion(new Label(this, FULL_VERSION)),
78 mButtonPadding(5)
79 {
80 setCloseButton(true);
81 setResizable(true);
82 setStickyButtonLock(true);
83 }
84
postInit()85 void SetupWindow::postInit()
86 {
87 Window::postInit();
88 int width = 620;
89 const int height = 450;
90
91 if (config.getIntValue("screenwidth") >= 730)
92 width += 100;
93
94 setContentSize(width, height);
95 setMinWidth(310);
96 setMinHeight(210);
97
98 mPanel->setSelectable(false);
99 mPanel->getTabContainer()->setSelectable(false);
100 mPanel->getWidgetContainer()->setSelectable(false);
101
102 static const char *const buttonNames[] =
103 {
104 // TRANSLATORS: setup button
105 N_("Apply"),
106 // TRANSLATORS: setup button
107 N_("Cancel"),
108 // TRANSLATORS: setup button
109 N_("Store"),
110 // TRANSLATORS: setup button
111 N_("Reset Windows"),
112 nullptr
113 };
114 int x = width;
115 mButtonPadding = getOption("buttonPadding", 5);
116 for (const char *const * curBtn = buttonNames;
117 *curBtn != nullptr;
118 ++ curBtn)
119 {
120 Button *const btn = new Button(this,
121 gettext(*curBtn),
122 *curBtn,
123 BUTTON_SKIN,
124 this);
125 mButtons.push_back(btn);
126 x -= btn->getWidth() + mButtonPadding;
127 btn->setPosition(x, height - btn->getHeight() - mButtonPadding);
128 add(btn);
129
130 // Store this button, as it needs to be enabled/disabled
131 if (strcmp(*curBtn, "Reset Windows") == 0)
132 mResetWindows = btn;
133 }
134
135 mPanel->setDimension(Rect(5, 5, width - 10, height - 40));
136 mPanel->enableScrollButtons(true);
137
138 mTabs.push_back(new Setup_Video(this));
139 mTabs.push_back(new Setup_Visual(this));
140 mTabs.push_back(new Setup_Audio(this));
141 mTabs.push_back(new Setup_Perfomance(this));
142 mTabs.push_back(new Setup_Touch(this));
143 mTabs.push_back(new Setup_Input(this));
144 mTabs.push_back(new Setup_Joystick(this));
145 mTabs.push_back(new Setup_Colors(this));
146 mTabs.push_back(new Setup_Chat(this));
147 mTabs.push_back(new Setup_Players(this));
148 mTabs.push_back(new Setup_Relations(this));
149 mTabs.push_back(new Setup_Theme(this));
150 mTabs.push_back(new Setup_Misc(this));
151
152 FOR_EACH (std::list<SetupTab*>::const_iterator, i, mTabs)
153 {
154 SetupTab *const tab = *i;
155 mPanel->addTab(tab->getName(), tab);
156 }
157 add(mPanel);
158
159 if (mResetWindows != nullptr)
160 {
161 mVersion->setPosition(9,
162 height - mVersion->getHeight() - mResetWindows->getHeight() - 9);
163 }
164 else
165 {
166 mVersion->setPosition(9, height - mVersion->getHeight() - 30);
167 }
168 add(mVersion);
169
170 center();
171
172 widgetResized(Event(nullptr));
173 setInGame(false);
174 enableVisibleSound(true);
175 }
176
~SetupWindow()177 SetupWindow::~SetupWindow()
178 {
179 delete_all(mTabs);
180 mButtons.clear();
181 setupWindow = nullptr;
182 }
183
action(const ActionEvent & event)184 void SetupWindow::action(const ActionEvent &event)
185 {
186 if (Game::instance() != nullptr)
187 Game::instance()->resetAdjustLevel();
188 const std::string &eventId = event.getId();
189
190 if (eventId == "Apply")
191 {
192 setVisible(Visible_false);
193 FOR_EACH (std::list<SetupTab*>::iterator, it, mTabs)
194 {
195 (*it)->apply();
196 }
197 }
198 else if (eventId == "Cancel")
199 {
200 doCancel();
201 }
202 else if (eventId == "Store")
203 {
204 if (chatWindow != nullptr)
205 chatWindow->saveState();
206 config.write();
207 serverConfig.write();
208 }
209 else if (eventId == "Reset Windows")
210 {
211 // Bail out if this action happens to be activated before the windows
212 // are created (though it should be disabled then)
213 if (statusWindow == nullptr)
214 return;
215
216 FOR_EACH (std::list<Window*>::const_iterator, it, mWindowsToReset)
217 {
218 if (*it != nullptr)
219 (*it)->resetToDefaultSize();
220 }
221 }
222 }
223
setInGame(const bool inGame)224 void SetupWindow::setInGame(const bool inGame)
225 {
226 if (mResetWindows != nullptr)
227 mResetWindows->setEnabled(inGame);
228 }
229
externalUpdate()230 void SetupWindow::externalUpdate()
231 {
232 unloadAdditionalTabs();
233 mModsTab = new Setup_Mods(this);
234 mTabs.push_back(mModsTab);
235 mPanel->addTab(mModsTab->getName(), mModsTab);
236 mQuickTab = new Setup_Quick(this);
237 mTabs.push_back(mQuickTab);
238 mPanel->addTab(mQuickTab->getName(), mQuickTab);
239 FOR_EACH (std::list<SetupTab*>::const_iterator, it, mTabs)
240 {
241 if (*it != nullptr)
242 (*it)->externalUpdated();
243 }
244 }
245
unloadTab(SetupTab * const page)246 void SetupWindow::unloadTab(SetupTab *const page)
247 {
248 if (page != nullptr)
249 {
250 mTabs.remove(page);
251 mPanel->removeTab(mPanel->getTab(page->getName()));
252 }
253 }
254
unloadAdditionalTabs()255 void SetupWindow::unloadAdditionalTabs()
256 {
257 unloadTab(mModsTab);
258 unloadTab(mQuickTab);
259 delete2(mModsTab)
260 delete2(mQuickTab)
261 }
262
externalUnload()263 void SetupWindow::externalUnload()
264 {
265 FOR_EACH (std::list<SetupTab*>::const_iterator, it, mTabs)
266 {
267 if (*it != nullptr)
268 (*it)->externalUnloaded();
269 }
270 unloadAdditionalTabs();
271 }
272
registerWindowForReset(Window * const window)273 void SetupWindow::registerWindowForReset(Window *const window)
274 {
275 mWindowsToReset.push_back(window);
276 }
277
unregisterWindowForReset(const Window * const window)278 void SetupWindow::unregisterWindowForReset(const Window *const window)
279 {
280 FOR_EACH (std::list<Window*>::iterator, it, mWindowsToReset)
281 {
282 if (*it == window)
283 {
284 mWindowsToReset.erase(it);
285 return;
286 }
287 }
288 }
289
hideWindows()290 void SetupWindow::hideWindows()
291 {
292 FOR_EACH (std::list<Window*>::const_iterator, it, mWindowsToReset)
293 {
294 Window *const window = *it;
295 if ((window != nullptr) && !window->isSticky())
296 window->setVisible(Visible_false);
297 }
298 setVisible(Visible_false);
299 }
300
doCancel()301 void SetupWindow::doCancel()
302 {
303 setVisible(Visible_false);
304 FOR_EACH (std::list<SetupTab*>::iterator, it, mTabs)
305 {
306 (*it)->cancel();
307 }
308 }
309
activateTab(const std::string & name)310 void SetupWindow::activateTab(const std::string &name)
311 {
312 std::string tmp = gettext(name.c_str());
313 mPanel->setSelectedTabByName(tmp);
314 }
315
setVisible(Visible visible)316 void SetupWindow::setVisible(Visible visible)
317 {
318 touchManager.setTempHide(visible == Visible_true);
319 Window::setVisible(visible);
320 }
321
widgetResized(const Event & event)322 void SetupWindow::widgetResized(const Event &event)
323 {
324 Window::widgetResized(event);
325
326 const Rect area = getChildrenArea();
327 int x = area.width;
328 const int height = area.height;
329 const int width = area.width;
330 mPanel->setDimension(Rect(5, 5, width - 10, height - 40));
331 FOR_EACH (STD_VECTOR<Button*>::iterator, it, mButtons)
332 {
333 Button *const btn = *it;
334 x -= btn->getWidth() + mButtonPadding;
335 btn->setPosition(x, height - btn->getHeight() - mButtonPadding);
336 }
337 if (mResetWindows != nullptr)
338 {
339 mVersion->setPosition(9,
340 height - mVersion->getHeight() - mResetWindows->getHeight() - 9);
341 }
342 else
343 {
344 mVersion->setPosition(9, height - mVersion->getHeight() - 30);
345 }
346 }
347