1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2005, Sven2
6 * Copyright (c) 2017-2021, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// Startup screen for non-parameterized engine start: Options dialog
19
20#pragma once
21
22#include "C4GuiSpinBox.h"
23#include "C4Startup.h"
24
25// startup dialog: Options
26class C4StartupOptionsDlg : public C4StartupDlg
27{
28 // main dlg stuff
29
30public:
31 C4StartupOptionsDlg();
32 ~C4StartupOptionsDlg();
33
34private:
35 class C4KeyBinding *pKeyBack;
36 bool fConfigSaved; // set when config has been saved because dlg is closed; prevents double save
37 bool fCanGoBack; // set if dlg has not been recreated yet, in which case going back to a previous dialog is not possible
38 C4GUI::Tabular *pOptionsTabular;
39
40protected:
41 virtual bool OnEnter() override { return false; } // Enter ignored
42 virtual bool OnEscape() override { DoBack(); return true; }
43 bool KeyBack() { DoBack(); return true; }
44 virtual void OnClosed(bool fOK) override; // callback when dlg got closed - save config
45
46 virtual void UserClose(bool fOK) override // callback when the user tried to close the dialog (e.g., by pressing Enter in an edit) - just ignore this and save config instead
47 {
48 if (fOK) SaveConfig(fForce: false, fKeepOpen: true);
49 }
50
51 void OnBackBtn(C4GUI::Control *btn) { DoBack(); }
52
53 bool SaveConfig(bool fForce, bool fKeepOpen); // save any config fields that are not stored directly; return whether all values are OK
54
55public:
56 void DoBack(); // back to main menu
57
58public:
59 void RecreateDialog(bool fFade);
60
61 // program tab
62private:
63 // button without fancy background
64 class SmallButton : public C4GUI::Button
65 {
66 protected:
67 virtual void DrawElement(C4FacetEx &cgo) override; // draw the button
68
69 public:
70 SmallButton(const char *szText, const C4Rect &rtBounds)
71 : C4GUI::Button(szText, rtBounds) {}
72 static int32_t GetDefaultButtonHeight();
73 };
74
75 class C4GUI::ComboBox *pLangCombo;
76 class C4GUI::Label *pLangInfoLabel;
77 class C4GUI::ComboBox *pFontFaceCombo, *pFontSizeCombo;
78 class C4GUI::ComboBox *pDisplayModeCombo;
79
80 void OnLangComboFill(C4GUI::ComboBox_FillCB *pFiller);
81 bool OnLangComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection);
82 void UpdateLanguage();
83 void OnFontFaceComboFill(C4GUI::ComboBox_FillCB *pFiller);
84 void OnFontSizeComboFill(C4GUI::ComboBox_FillCB *pFiller);
85 bool OnFontComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection);
86 void UpdateFontControls();
87 int32_t FairCrewSlider2Strength(int32_t iSliderVal);
88 int32_t FairCrewStrength2Slider(int32_t iStrengthVal);
89 void OnFairCrewStrengthSliderChange(int32_t iNewVal);
90 void OnResetConfigBtn(C4GUI::Control *btn);
91 void OnAdvancedConfigBtn(C4GUI::Control *btn);
92 void OnDisplayModeComboFill(C4GUI::ComboBox_FillCB *pFiller);
93 bool OnDisplayModeComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection);
94
95 // graphics tab
96private:
97 // checkbox that changes a config boolean directly
98 class BoolConfig : public C4GUI::CheckBox
99 {
100 private:
101 bool *pbVal, fInvert; bool *pbRestartChangeCfgVal;
102
103 protected:
104 void OnCheckChange(C4GUI::Element *pCheckBox);
105
106 public:
107 BoolConfig(const C4Rect &rcBounds, const char *szName, bool *pbVal, bool fInvert = false, bool *pbRestartChangeCfgVal = nullptr);
108 };
109 // editbox below descriptive label sharing one window for common tooltip
110 class EditConfig;
111 EditConfig *pNetworkNameEdit, *pNetworkNickEdit;
112
113 // message dialog with a timer; used to restore the resolution if the user didn't press anything for a while
114 class ResChangeConfirmDlg : public C4GUI::TimedDialog
115 {
116 public:
117 ResChangeConfirmDlg();
118 ~ResChangeConfirmDlg() = default;
119
120 protected:
121 virtual bool OnEnter() override { return true; } // Pressing Enter does not confirm this dialog, so "blind" users are less likely to accept their change
122 virtual const char *GetID() override { return "ResChangeConfirmDialog"; }
123 void UpdateText() override;
124 };
125
126 void OnEffectsSliderChange(int32_t iNewVal);
127
128 C4GUI::ScrollBar *pEffectLevelSlider;
129
130 void SaveGfxTroubleshoot();
131
132 class ScaleEdit;
133
134 C4GUI::ScrollBar *pScaleSlider;
135 ScaleEdit *pScaleEdit;
136 int32_t iNewScale;
137
138 void OnScaleSliderChanged(int32_t val);
139 void OnTestScaleBtn(C4GUI::Control *);
140
141 // sound tab
142private:
143 C4KeyBinding *pKeyToggleMusic; // extra key binding for music: Must also update checkbox in real-time
144 C4GUI::CheckBox *pFEMusicCheck;
145
146 void OnFEMusicCheck(C4GUI::Element *pCheckBox); // toggling frontend music is reflected immediately
147 void OnMusicVolumeSliderChange(int32_t iNewVal);
148 void OnSoundVolumeSliderChange(int32_t iNewVal);
149
150protected:
151 bool KeyMusicToggle();
152
153 // keyboard and gamepad control tabs
154private:
155 // dialog shown to user so he can select a key
156 class KeySelDialog : public C4GUI::MessageDialog
157 {
158 private:
159 class C4KeyBinding *pKeyListener;
160 C4KeyCode key;
161 bool fGamepad;
162 int32_t iCtrlSet;
163
164 protected:
165 bool KeyDown(C4KeyCodeEx key);
166
167 public:
168 KeySelDialog(int32_t iKeyID, int32_t iCtrlSet, bool fGamepad);
169 virtual ~KeySelDialog();
170
171 C4KeyCode GetKeyCode() { return key; }
172 };
173
174 // Clonk-key-button with a label showing its key name beside it
175 class KeySelButton : public C4GUI::IconButton
176 {
177 private:
178 int32_t iKeyID;
179 C4KeyCode key;
180
181 protected:
182 virtual void DrawElement(C4FacetEx &cgo) override;
183 virtual bool IsComponentOutsideClientArea() override { return true; }
184
185 public:
186 KeySelButton(int32_t iKeyID, const C4Rect &rcBounds, char cHotkey);
187 void SetKey(C4KeyCode keyTo) { key = keyTo; }
188 };
189
190 // config area to define a keyboard set
191 class ControlConfigArea : public C4GUI::Window
192 {
193 private:
194 bool fGamepad; // if set, gamepad control sets are being configured
195 int32_t iMaxControlSets; // number of control sets configured in this area - must be smaller or equal to C4MaxControlSet
196 int32_t iSelectedCtrlSet; // keyboard or gamepad set that is currently being configured
197 class C4GUI::IconButton **ppKeyControlSetBtns; // buttons to select configured control set - array in length of iMaxControlSets
198 class KeySelButton *KeyControlBtns[C4MaxKey]; // buttons to configure individual kbd set buttons
199 C4GamePadOpener *pGamepadOpener; // opened gamepad for configuration
200 C4StartupOptionsDlg *pOptionsDlg;
201 class C4GUI::CheckBox *pGUICtrl;
202
203 public:
204 ControlConfigArea(const C4Rect &rcArea, int32_t iHMargin, int32_t iVMargin, bool fGamepad, C4StartupOptionsDlg *pOptionsDlg);
205 virtual ~ControlConfigArea();
206
207 protected:
208 void UpdateCtrlSet();
209
210 void OnCtrlSetBtn(C4GUI::Control *btn);
211 void OnCtrlKeyBtn(C4GUI::Control *btn);
212 void OnResetKeysBtn(C4GUI::Control *btn);
213 void OnGUIGamepadCheckChange(C4GUI::Element *pCheckBox);
214 };
215
216 // network tab
217private:
218 // checkbox to enable protocol and editbox to input port number
219 class NetworkPortConfig : public C4GUI::Window
220 {
221 public:
222 NetworkPortConfig(const C4Rect &rcBounds, const char *szName, int32_t *pConfigValue, int32_t iDefault);
223
224 private:
225 int32_t *pConfigValue; // pointer into config set
226 C4GUI::CheckBox *pEnableCheck; // check box for whether port is enabled
227 C4GUI::SpinBox<std::int32_t> *pPortEdit; // edit field for port number
228
229 public:
230 void OnEnabledCheckChange(C4GUI::Element *pCheckBox); // callback when checkbox is ticked
231 void SavePort(); // controls to config
232 int32_t GetPort(); // get port as currently configured by control (or 0 for deactivated)
233
234 static bool GetControlSize(int *piWdt, int *piHgt);
235 } *pPortCfgTCP, *pPortCfgUDP, *pPortCfgRef, *pPortCfgDsc;
236
237 class NetworkServerAddressConfig : public C4GUI::Window
238 {
239 public:
240 NetworkServerAddressConfig(const C4Rect &rcBounds, const char *szName, bool *pbConfigEnableValue, char *szConfigAddressValue, int iTabWidth);
241
242 private:
243 bool *pbConfigEnableValue; char *szConfigAddressValue;
244 C4GUI::CheckBox *pEnableCheck;
245 C4GUI::Edit *pAddressEdit;
246
247 public:
248 void OnEnabledCheckChange(C4GUI::Element *pCheckBox); // callback when checkbox is ticked
249 void Save2Config(); // controls to config
250
251 static bool GetControlSize(int *piWdt, int *piHgt, int *piTabPos, const char *szForText);
252 } *pLeagueServerCfg;
253};
254