OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4StartupOptionsDlg.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // Startup screen for non-parameterized engine start: Options dialog
17 
18 #include "C4Include.h"
21 
22 #include "game/C4Application.h"
23 #include "graphics/C4Draw.h"
25 #include "gui/C4MouseControl.h"
26 #include "gui/C4StartupMainDlg.h"
27 #include "network/C4Network2.h"
28 #include "platform/C4GamePadCon.h"
29 
30 #include "graphics/C4DrawGL.h"
31 
32 // ------------------------------------------------
33 // --- C4StartupOptionsDlg::SmallButton
34 
35 void C4StartupOptionsDlg::SmallButton::DrawElement(C4TargetFacet &cgo)
36 {
37  // draw the button
39  // get text pos
40  float x0 = cgo.TargetX + rcBounds.x, y0 = cgo.TargetY + rcBounds.y, x1 = cgo.TargetX + rcBounds.x + rcBounds.Wdt, y1 = cgo.TargetY + rcBounds.y + rcBounds.Hgt;
41  int32_t iTextHgt = rUseFont.GetLineHeight();
42  // draw frame
43  uint32_t dwClrHigh = C4StartupBtnBorderColor1, dwClrLow = C4StartupBtnBorderColor2;
44  if (fDown) std::swap(dwClrHigh, dwClrLow);
45  int32_t iIndent = Clamp<int32_t>((rcBounds.Hgt-iTextHgt)/3, 2, 5);
46  float iDrawQuadTop[8] = { x0,y0, x1,y0, x1-iIndent,y0+iIndent, x0,y0+iIndent };
47  float iDrawQuadLeft[8] = { x0,y0, x0+iIndent,y0, x0+iIndent,y1-iIndent, x0,y1 };
48  float iDrawQuadRight[8] = { x1,y0, x1,y1, x1-iIndent,y1, x1-iIndent,y0+iIndent };
49  float iDrawQuadBottom[8] = { x1,y1, x0,y1, x0+iIndent,y1-iIndent, x1,y1-iIndent };
50  // TODO: Switch to PerformMultiTris
51  pDraw->DrawQuadDw(cgo.Surface, iDrawQuadTop, dwClrHigh,dwClrHigh,dwClrHigh,dwClrHigh, nullptr);
52  pDraw->DrawQuadDw(cgo.Surface, iDrawQuadLeft, dwClrHigh,dwClrHigh,dwClrHigh,dwClrHigh, nullptr);
53  pDraw->DrawQuadDw(cgo.Surface, iDrawQuadRight, dwClrLow,dwClrLow,dwClrLow,dwClrLow, nullptr);
54  pDraw->DrawQuadDw(cgo.Surface, iDrawQuadBottom, dwClrLow,dwClrLow,dwClrLow,dwClrLow, nullptr);
55  // draw selection highlight
56  int32_t iTxtOff = fDown ? iIndent : 0;
57  if (fEnabled) if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
58  {
60  ::GraphicsResource.fctButtonHighlight.DrawX(cgo.Surface, x0+5+iTxtOff, y0+3+iTxtOff, rcBounds.Wdt-10, rcBounds.Hgt-6);
62  }
63  // draw button text
64  pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, (x0+x1)/2 + iTxtOff, (y0+y1-iTextHgt)/2 + iTxtOff, C4StartupBtnFontClr, ACenter, true);
65 }
66 
67 int32_t C4StartupOptionsDlg::SmallButton::GetDefaultButtonHeight()
68 {
69  // button height is used font height plus a small indent
70  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
71  return pUseFont->GetLineHeight()*6/5+6;
72 }
73 
74 
75 // ------------------------------------------------
76 // --- C4StartupOptionsDlg::ResChangeConfirmDlg
77 
78 C4StartupOptionsDlg::ResChangeConfirmDlg::ResChangeConfirmDlg()
79  : C4GUI::Dialog(C4GUI_MessageDlgWdt, 100 /* will be resized */, LoadResStr("IDS_MNU_SWITCHRESOLUTION"), false)
80 {
81  // update-timer
82  Application.Add(this);
83  // An independant group of fourteen highly trained apes and one blind lawnmower have determined
84  // that twelve seconds is just right for normal people
85  iResChangeSwitchTime = 12;
86  // However, some people need more time
87  // Those can be identified by their configuration settings
88  if (SEqualNoCase(Config.GetRegistrationData("Nick"), "flgr")) iResChangeSwitchTime *= 10;
89  // get positions
91  // place icon
92  C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt); rcIcon.Hgt = C4GUI_IconHgt;
93  C4GUI::Icon *pIcon = new C4GUI::Icon(rcIcon, C4GUI::Ico_Confirm); AddElement(pIcon);
94  // place message labels
95  // use text with line breaks
96  StdStrBuf sMsgBroken;
97  int iMsgHeight = ::GraphicsResource.TextFont.BreakMessage(LoadResStr("IDS_MNU_SWITCHRESOLUTION_LIKEIT"), caMain.GetInnerWidth(), &sMsgBroken, true);
98  C4GUI::Label *pLblMessage = new C4GUI::Label(sMsgBroken.getData(), caMain.GetFromTop(iMsgHeight), ACenter, C4GUI_MessageFontClr, &::GraphicsResource.TextFont, false);
99  AddElement(pLblMessage);
100  iMsgHeight = ::GraphicsResource.TextFont.BreakMessage(FormatString(LoadResStr("IDS_MNU_SWITCHRESOLUTION_UNDO"),
101  (int)iResChangeSwitchTime).getData(),
102  caMain.GetInnerWidth(), &sMsgBroken, true);
103  pOperationCancelLabel = new C4GUI::Label(sMsgBroken.getData(), caMain.GetFromTop(iMsgHeight), ACenter, C4GUI_MessageFontClr, &::GraphicsResource.TextFont, false, false);
104  AddElement(pOperationCancelLabel);
105  // place buttons
106  C4GUI::ComponentAligner caButtonArea(caMain.GetFromTop(C4GUI_ButtonAreaHgt), 0,0);
107  int32_t iButtonCount = 2;
108  C4Rect rcBtn = caButtonArea.GetCentered(iButtonCount*C4GUI_DefButton2Wdt+(iButtonCount-1)*C4GUI_DefButton2HSpace, C4GUI_ButtonHgt);
109  rcBtn.Wdt = C4GUI_DefButton2Wdt;
110  // Yes
111  C4GUI::Button *pBtnYes = new C4GUI::YesButton(rcBtn);
112  AddElement(pBtnYes);
114  // No
115  C4GUI::Button *pBtnNo = new C4GUI::NoButton(rcBtn);
116  AddElement(pBtnNo);
117  // initial focus on abort button, to prevent accidental acceptance of setting by "blind" users
118  SetFocus(pBtnNo, false);
119  // resize to actually needed size
120  SetClientSize(GetClientRect().Wdt, GetClientRect().Hgt - caMain.GetHeight());
121 }
122 
123 C4StartupOptionsDlg::ResChangeConfirmDlg::~ResChangeConfirmDlg()
124 {
125  Application.Remove(this);
126 }
127 
128 void C4StartupOptionsDlg::ResChangeConfirmDlg::OnSec1Timer()
129 {
130  // timer ran out? Then cancel dlg
131  if (!--iResChangeSwitchTime)
132  {
133  Close(false); return;
134  }
135  // update timer label
136  StdStrBuf sTimerText;
137  ::GraphicsResource.TextFont.BreakMessage(FormatString(LoadResStr("IDS_MNU_SWITCHRESOLUTION_UNDO"),
138  (int)iResChangeSwitchTime).getData(),
139  pOperationCancelLabel->GetBounds().Wdt, &sTimerText, true);
140  pOperationCancelLabel->SetText(sTimerText.getData());
141 }
142 
143 // ------------------------------------------------
144 // --- C4StartupOptionsDlg::KeySelDialog
145 
146 C4StartupOptionsDlg::KeySelDialog::KeySelDialog(const C4PlayerControlAssignment *assignment, const C4PlayerControlAssignmentSet *assignment_set)
147  : C4GUI::MessageDialog(GetDlgMessage(assignment, assignment_set).getData(), LoadResStr("IDS_MSG_DEFINEKEY"), C4GUI::MessageDialog::btnAbort | C4GUI::MessageDialog::btnReset, GetDlgIcon(assignment_set), C4GUI::MessageDialog::dsRegular),
148  key(KEY_Undefined), assignment(assignment), assignment_set(assignment_set)
149 {
150  pKeyListener = new C4KeyBinding(C4KeyCodeEx(KEY_Any, KEYS_None), "DefineKey", KEYSCOPE_Gui, new C4GUI::DlgKeyCBPassKey<C4StartupOptionsDlg::KeySelDialog>(*this, &C4StartupOptionsDlg::KeySelDialog::KeyDown), C4CustomKey::PRIO_PlrControl);
151 }
152 
153 StdStrBuf C4StartupOptionsDlg::KeySelDialog::GetDlgMessage(const C4PlayerControlAssignment *assignment, const C4PlayerControlAssignmentSet *assignment_set)
154 {
155  // compose message asking for key, gamepad button and/or mouse button depending on used control set
156  if (!assignment || !assignment_set) return StdStrBuf("err");
157  StdStrBuf result_string;
158  if (assignment_set->HasGamepad())
159  result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSBTN"), assignment->GetGUIName(Game.PlayerControlDefs)));
160  else
161  result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSKEY"), assignment->GetGUIName(Game.PlayerControlDefs)));
162  const char *ctrl_desc = assignment->GetGUIDesc(Game.PlayerControlDefs);
163 
164  if (ctrl_desc && *ctrl_desc)
165  {
166  result_string.Append("||");
167  result_string.Append(ctrl_desc);
168  }
169  return result_string;
170 }
171 
172 C4GUI::Icons C4StartupOptionsDlg::KeySelDialog::GetDlgIcon(const C4PlayerControlAssignmentSet *assignment_set)
173 {
174  if (!assignment_set) return C4GUI::Ico_Error;
175  if (assignment_set->HasGamepad()) return C4GUI::Ico_Gamepad;
176  return C4GUI::Ico_Keyboard;
177 }
178 
179 
180 
181 C4StartupOptionsDlg::KeySelDialog::~KeySelDialog()
182 {
183  delete pKeyListener;
184 }
185 
186 bool C4StartupOptionsDlg::KeySelDialog::KeyDown(const C4KeyCodeEx &key)
187 {
188  // safety
189  if (!assignment || !assignment_set) return false;
190  // check if key is valid for this set
191  if (Key_IsGamepad(key.Key))
192  {
193  if (!assignment_set->HasGamepad()) return false;
194  }
195  else if (Key_IsMouse(key.Key))
196  {
197  if (!assignment_set->HasMouse()) return false;
198  }
199  else
200  {
201  if (!assignment_set->HasKeyboard()) return false;
202  }
203  // okay, use it
204  this->key=key;
205  Close(true);
206  return true;
207 }
208 
209 
210 // ------------------------------------------------
211 // --- C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel
212 
213 C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::ControlAssignmentLabel(class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set, const C4Rect &bounds)
214  : C4GUI::Label("", bounds, ALeft, 0xffffffff, nullptr, false, false, true), assignment(assignment), assignment_set(assignment_set)
215 {
216  UpdateAssignmentString();
217 }
218 
219 void C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
220  {
221  // left-click to change key
222  if (iButton == C4MC_Button_LeftDown && assignment)
223  {
224  if(!assignment->IsGUIDisabled())
225  {
226  KeySelDialog *dlg = new KeySelDialog(assignment, assignment_set);
227  dlg->SetDelOnClose(false);
228  bool success = GetScreen()->ShowModalDlg(dlg, false);
229  C4KeyCodeEx key = dlg->GetKeyCode();
230  delete dlg;
231  if (success)
232  {
233  // dialog closed by pressing a key or by the Reset button (in which case, key==KEY_Undefined)
234  // assign new config
235  C4StartupOptionsDlg::ControlConfigListBox::SetUserKey(assignment_set, assignment, key);
236  UpdateAssignmentString();
237  }
238  }
239  }
240  // inherited
241  Element::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
242  }
243 
244 void C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::UpdateAssignmentString()
245 {
246  // assignment label text from assigned key
247  StdStrBuf strKey;
248  C4KeyCodeEx key(0);
249  if (assignment)
250  {
251  SetText(assignment->GetKeysAsString(true, false).getData());
252  }
253  else
254  {
255  SetText("");
256  }
257  DWORD color = C4GUI_CaptionFontClr;
258  if (assignment)
259  {
260  if(assignment->IsGUIDisabled())
262  else if(assignment->IsKeyChanged())
263  color = C4GUI_Caption2FontClr;
264  }
265  SetColor(color);
266 }
267 
268 // ------------------------------------------------
269 // --- C4StartupOptionsDlg::ControlConfigListBox::ListItem
270 
271 C4StartupOptionsDlg::ControlConfigListBox::ListItem::ListItem(ControlConfigListBox *parent_list, class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set, bool has_extra_spacing)
272  : C4GUI::Window(), parent_list(parent_list), assignment_label(nullptr), has_extra_spacing(has_extra_spacing)
273 {
274  int32_t margin = 2;
275  // adding to listbox will size the element horizontally and move to proper position
276  int32_t height = ::GraphicsResource.TextFont.GetLineHeight() + 2 * margin;
277  SetBounds(C4Rect(0,0,42,height));
278  parent_list->InsertElement(this, nullptr);
279  int32_t name_col_width = GetBounds().Wdt * 2/3;
280  // child elements: two labels for two columns
281  const char *gui_name = assignment->GetGUIName(Game.PlayerControlDefs);
282  const char *gui_desc = assignment->GetGUIDesc(Game.PlayerControlDefs);
283  C4GUI::Label *name_label = new C4GUI::Label(gui_name ? gui_name : "?undefined?", margin, margin);
284  C4Rect assignment_label_bounds = C4Rect(name_col_width + margin, margin, GetBounds().Wdt - name_col_width - margin, GetBounds().Hgt - 2 * margin);
285  assignment_label = new ControlAssignmentLabel(assignment, assignment_set, assignment_label_bounds);
286  AddElement(name_label);
287  AddElement(assignment_label);
288  if (gui_desc && *gui_desc) SetToolTip(gui_desc);
289 }
290 
291 
292 // ------------------------------------------------
293 // --- C4StartupOptionsDlg::ControlConfigListBox
294 
295 C4StartupOptionsDlg::ControlConfigListBox::ControlConfigListBox(const C4Rect &rcBounds, class C4PlayerControlAssignmentSet *set)
296  : C4GUI::ListBox(rcBounds), set(nullptr)
297 {
298  SetAssignmentSet(set);
299 }
300 
301 void C4StartupOptionsDlg::ControlConfigListBox::SetAssignmentSet(class C4PlayerControlAssignmentSet *new_set)
302 {
303  set = new_set;
304  // clear previous elements
305  if (pClientWindow) pClientWindow->ClearChildren();
306  // populate with new assignments
307  if (set)
308  {
309  C4PlayerControlAssignment *assignment;
310 
311  std::vector<C4PlayerControlAssignment *> grouped_assignments;
312  for (int32_t i=0; (assignment = set->GetAssignmentByIndex(i)); ++i)
313  grouped_assignments.push_back(assignment);
314 
315  std::stable_sort(grouped_assignments.begin(),grouped_assignments.end(),&C4StartupOptionsDlg::ControlConfigListBox::sort_by_group);
316 
317  int32_t current_group = 0;
318  for (auto & grouped_assignment : grouped_assignments)
319  {
320  assignment = grouped_assignment;
321  bool first_element_of_group = assignment->GetGUIGroup() > current_group;
322  current_group = assignment->GetGUIGroup();
323  // only show assignments of GUI-named controls
324  const char *gui_name = assignment->GetGUIName(Game.PlayerControlDefs);
325  if (gui_name && *gui_name)
326  {
327  ListItem *element = new ListItem(this, assignment, set, first_element_of_group);
328  AddElement(element);
329  }
330  }
331  }
332 }
333 
334 void C4StartupOptionsDlg::ControlConfigListBox::SetUserKey(class C4PlayerControlAssignmentSet *assignment_set, class C4PlayerControlAssignment *assignment, C4KeyCodeEx &key)
335 {
336  // change key in the specified assignment set to the specified value
337  // also changes config values so change is kept after restart
338  // safety
339  if (!assignment || !assignment_set) return;
340  class C4PlayerControlAssignmentSet *config_set = Config.Controls.UserSets.GetSetByName(assignment_set->GetName());
341  // change key
342  if (key.Key == KEY_Undefined)
343  {
344  // reset to default
345  assignment->ResetKeyToInherited();
346  // also reset in config
347  if (config_set)
348  {
349  config_set->RemoveAssignmentByControlName(assignment->GetControlName());
350  if (!config_set->GetAssignmentByIndex(0))
351  {
352  // if config set is empty, no overrides exist and the set can be deleted (unless it's a custom config set)
354  {
355  Config.Controls.UserSets.RemoveSetByName(assignment_set->GetName());
356  }
357  }
358  }
359  }
360  else
361  {
362  // set to specified value
363  assignment->SetKey(key);
364  // also set in config
365  if (!config_set) config_set = Config.Controls.UserSets.CreateEmptySetByTemplate(*assignment_set);
366  C4PlayerControlAssignment *config_assignment = config_set->GetAssignmentByControlName(assignment->GetControlName());
367  if (!config_assignment) config_assignment = config_set->CreateAssignmentForControl(assignment->GetControlName());
368  config_assignment->SetKey(key);
369  // check for duplicates. Allow them in principle because they can be used with priorities
370  // however, do warn because usually it may be unintended
371  // Just deleting the old assignments is also usually undesirable, because half of the time a newbi changes a control and creates a conflict,
372  // they may want to change the key they just assigned to something else instead
373  C4PlayerControlAssignment *other_assignment;
374  for (int32_t i = 0; (other_assignment = assignment_set->GetAssignmentByIndex(i)); ++i)
375  if (other_assignment != assignment)
376  if (other_assignment->GetTriggerKey() == key)
377  {
378  const char *gui_name = other_assignment->GetGUIName(Game.PlayerControlDefs);
379  // only warn for assignable keys, because other keys are typically derived from the settable keys
380  if (gui_name && *gui_name)
381  {
382  C4GUI::TheScreen.ShowMessage(FormatString(LoadResStr("IDS_MSG_DEFINEKEYDUPLICATE"), key.ToString(true, false).getData(), gui_name).getData(), LoadResStr("IDS_MSG_DEFINEKEY"), C4GUI::Ico_Error);
383  }
384  }
385 
386  }
387 }
388 
389 // ------------------------------------------------
390 // --- C4StartupOptionsDlg::ControlConfigArea
391 
392 C4StartupOptionsDlg::ControlConfigArea::ControlConfigArea(const C4Rect &rcArea, int32_t iHMargin, int32_t iVMargin, bool fGamepad, C4StartupOptionsDlg *pOptionsDlg)
393  : C4GUI::Window(), fGamepad(fGamepad), pOptionsDlg(pOptionsDlg), pGUICtrl(nullptr)
394 {
395  CStdFont *pUseFontSmall = &(C4Startup::Get()->Graphics.BookSmallFont);
396  SetBounds(rcArea);
397  C4GUI::ComponentAligner caArea(rcArea, iHMargin, iVMargin, true);
398  // get number of control sets to be configured
400  iMaxControlSets = std::max<size_t>(assignment_sets.GetSetCount(),1u); // do not devide by zero
401  ppKeyControlSetBtns = new C4GUI::IconButton *[iMaxControlSets];
402  // top line buttons to select control configuration
403  C4Facet fctCtrlDefPic = ::GraphicsResource.fctKeyboard; //
404  int32_t iCtrlSetWdt = caArea.GetWidth() - caArea.GetHMargin()*2;
405  int32_t iCtrlSetHMargin = 5, iCtrlSetVMargin = 5;
406  int32_t iCtrlSetBtnWdt = Clamp<int32_t>((iCtrlSetWdt - iMaxControlSets*iCtrlSetHMargin*2) / iMaxControlSets, 5, fctCtrlDefPic.Wdt);
407  int32_t iCtrlSetBtnHgt = fctCtrlDefPic.GetHeightByWidth(iCtrlSetBtnWdt);
408  iCtrlSetHMargin = (iCtrlSetWdt - iCtrlSetBtnWdt*iMaxControlSets) / (iMaxControlSets*2);
409  C4GUI::ComponentAligner caKeyboardSetSel(caArea.GetFromTop(2*iCtrlSetVMargin+iCtrlSetBtnHgt), iCtrlSetHMargin, iCtrlSetVMargin);
410  const char *szCtrlSetHotkeys = "1234567890"; /* 2do */
411  uint32_t i;
412  for (i = 0; i < assignment_sets.GetSetCount(); ++i)
413  {
414  C4PlayerControlAssignmentSet *assignment_set = assignment_sets.GetSetByIndex(i);
415  char cCtrlSetHotkey = 0;
416  if (i <= strlen(szCtrlSetHotkeys)) cCtrlSetHotkey = szCtrlSetHotkeys[i];
417  C4GUI::CallbackButton<C4StartupOptionsDlg::ControlConfigArea, C4GUI::IconButton> *pBtn = new C4GUI::CallbackButton<C4StartupOptionsDlg::ControlConfigArea, C4GUI::IconButton>(C4GUI::Ico_None, caKeyboardSetSel.GetFromLeft(iCtrlSetBtnWdt), cCtrlSetHotkey, &C4StartupOptionsDlg::ControlConfigArea::OnCtrlSetBtn, this);
418  C4Facet fctCtrlPic = assignment_set->GetPicture();
419  pBtn->SetFacet(fctCtrlPic);
420  AddElement(ppKeyControlSetBtns[i] = pBtn);
421  pBtn->SetText(assignment_set->GetGUIName());
422  pBtn->SetFont(pUseFontSmall, C4StartupFontClr);
423  pBtn->SetToolTip(LoadResStr("IDS_DLGTIP_CHANGECTRL"));
424  }
425  iSelectedCtrlSet = 0;
426  caArea.ExpandTop(caArea.GetVMargin());
427  AddElement(new C4GUI::HorizontalLine(caArea.GetFromTop(2)));
428  caArea.ExpandTop(caArea.GetVMargin());
429  control_list = new ControlConfigListBox(caArea.GetFromLeft(caArea.GetInnerWidth()), nullptr);
430  AddElement(control_list);
431 
432  UpdateCtrlSet();
433 }
434 
435 C4StartupOptionsDlg::ControlConfigArea::~ControlConfigArea()
436 {
437  delete [] ppKeyControlSetBtns;
438 }
439 
440 void C4StartupOptionsDlg::ControlConfigArea::OnCtrlSetBtn(C4GUI::Control *btn)
441 {
442  // select Ctrl set of pressed btn
443  int i;
444  for (i = 0; i < iMaxControlSets; ++i)
445  if (btn == ppKeyControlSetBtns[i])
446  {
447  iSelectedCtrlSet = i;
448  break;
449  }
450  // update shown keys
451  UpdateCtrlSet();
452 }
453 
454 void C4StartupOptionsDlg::ControlConfigArea::UpdateCtrlSet()
455 {
456  // selected keyboard set btn gets a highlight
457  int i;
458  for (i = 0; i < iMaxControlSets; ++i)
459  ppKeyControlSetBtns[i]->SetHighlight(i == iSelectedCtrlSet);
460  // update list
461  control_list->SetAssignmentSet(Game.PlayerControlUserAssignmentSets.GetSetByIndex(iSelectedCtrlSet));
462 }
463 
464 void C4StartupOptionsDlg::ControlConfigArea::OnResetKeysBtn(C4GUI::Control *btn)
465 {
466  // default keys and axis reset
468  UpdateCtrlSet();
469 }
470 
471 void C4StartupOptionsDlg::ControlConfigArea::OnGUIGamepadCheckChange(C4GUI::Element *pCheckBox)
472 {
473  // same as before?
474  bool fChecked = ((C4GUI::CheckBox *)(pCheckBox))->GetChecked();
475  if (fChecked == !!Config.Controls.GamepadGuiControl) return;
476  // reflect change
477  Config.Controls.GamepadGuiControl = fChecked;
479  pOptionsDlg->RecreateDialog(false);
480 }
481 
482 
483 
484 // ------------------------------------------------
485 // --- C4StartupOptionsDlg::NetworkPortConfig
486 
487 C4StartupOptionsDlg::NetworkPortConfig::NetworkPortConfig(const C4Rect &rcBounds, const char *szName, int32_t *pConfigValue, int32_t iDefault)
488  : C4GUI::Window(), pConfigValue(pConfigValue)
489 {
490  // ctor
491  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
492  SetBounds(rcBounds);
493  C4GUI::ComponentAligner caMain(GetClientRect(), 0,2, true);
494  bool fEnabled = (*pConfigValue != -1);
495  C4GUI::Label *pLbl = new C4GUI::Label(szName, caMain.GetFromTop(pUseFont->GetLineHeight()), ALeft, C4StartupFontClr, pUseFont, false);
496  AddElement(pLbl);
497  C4GUI::ComponentAligner caBottomLine(caMain.GetAll(), 2,0, false);
498  const char *szText = LoadResStr("IDS_CTL_ACTIVE");
499  int iWdt=100, iHgt=12;
500  C4GUI::CheckBox::GetStandardCheckBoxSize(&iWdt, &iHgt, szText, pUseFont);
501  pEnableCheck = new C4GUI::CheckBox(caBottomLine.GetFromLeft(iWdt, iHgt), szText, fEnabled);
502  pEnableCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
503  pEnableCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg::NetworkPortConfig>(this, &C4StartupOptionsDlg::NetworkPortConfig::OnEnabledCheckChange));
504  AddElement(pEnableCheck);
505  pPortEdit = new C4GUI::Edit(caBottomLine.GetAll(), true);
507  pPortEdit->SetFont(pUseFont);
508  pPortEdit->InsertText(FormatString("%d", fEnabled ? ((int) *pConfigValue) : (int) iDefault).getData(), false);
509  pPortEdit->SetMaxText(10); // 65535 is five characters long - but allow some more for easier editing
510  pPortEdit->SetVisibility(fEnabled);
511  AddElement(pPortEdit);
512 }
513 
514 void C4StartupOptionsDlg::NetworkPortConfig::OnEnabledCheckChange(C4GUI::Element *pCheckBox)
515 {
516  pPortEdit->SetVisibility(pEnableCheck->GetChecked());
517 }
518 
519 void C4StartupOptionsDlg::NetworkPortConfig::SavePort()
520 {
521  *pConfigValue=GetPort();
522 }
523 
524 int32_t C4StartupOptionsDlg::NetworkPortConfig::GetPort()
525 {
526  // controls to config
527  if (!pEnableCheck->GetChecked())
528  return -1;
529  else
530  return atoi(pPortEdit->GetText());
531 }
532 
533 bool C4StartupOptionsDlg::NetworkPortConfig::GetControlSize(int *piWdt, int *piHgt)
534 {
535  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
536  // get size needed for control
537  if (piWdt)
538  {
539  const char *szText = LoadResStr("IDS_CTL_ACTIVE");
540  if (!C4GUI::CheckBox::GetStandardCheckBoxSize(piWdt, piHgt, szText, pUseFont)) return false;
541  *piWdt *= 2;
542  }
543  if (piHgt) *piHgt = C4GUI::Edit::GetCustomEditHeight(pUseFont) + pUseFont->GetLineHeight()+2*4;
544  return true;
545 }
546 
547 
548 // ------------------------------------------------
549 // --- C4StartupOptionsDlg::NetworkServerAddressConfig
550 
551 C4StartupOptionsDlg::NetworkServerAddressConfig::NetworkServerAddressConfig(const C4Rect &rcBounds, const char *szName, int32_t *piConfigEnableValue, char *szConfigAddressValue, int iTabWidth)
552  : C4GUI::Window(), piConfigEnableValue(piConfigEnableValue), szConfigAddressValue(szConfigAddressValue)
553 {
554  // ctor
555  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
556  SetBounds(rcBounds);
557  C4GUI::ComponentAligner caMain(GetClientRect(), 0,2, true);
558  pEnableCheck = new C4GUI::CheckBox(caMain.GetFromLeft(iTabWidth, pUseFont->GetLineHeight()), szName, !!*piConfigEnableValue);
559  pEnableCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
560  pEnableCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg::NetworkServerAddressConfig>(this, &C4StartupOptionsDlg::NetworkServerAddressConfig::OnEnabledCheckChange));
561  AddElement(pEnableCheck);
562  caMain.ExpandLeft(-2);
563  pAddressEdit = new C4GUI::Edit(caMain.GetAll(), true);
565  pAddressEdit->SetFont(pUseFont);
566  pAddressEdit->InsertText(szConfigAddressValue, false);
567  pAddressEdit->SetMaxText(CFG_MaxString);
568  pAddressEdit->SetVisibility(!!*piConfigEnableValue);
569  AddElement(pAddressEdit);
570 }
571 
572 void C4StartupOptionsDlg::NetworkServerAddressConfig::OnEnabledCheckChange(C4GUI::Element *pCheckBox)
573 {
574  // warn about using alternate servers
575  if (pEnableCheck->GetChecked())
576  {
577  GetScreen()->ShowMessage(LoadResStr("IDS_NET_NOOFFICIALLEAGUE"), LoadResStr("IDS_NET_QUERY_MASTERSRV"), C4GUI::Ico_Notify, &Config.Startup.HideMsgNoOfficialLeague);
578  }
579  // callback when checkbox is ticked
580  pAddressEdit->SetVisibility(pEnableCheck->GetChecked());
581 }
582 
583 void C4StartupOptionsDlg::NetworkServerAddressConfig::Save2Config()
584 {
585  // controls to config
586  *piConfigEnableValue = pEnableCheck->GetChecked();
587  SCopy(pAddressEdit->GetText(), szConfigAddressValue, CFG_MaxString);
588 }
589 
590 bool C4StartupOptionsDlg::NetworkServerAddressConfig::GetControlSize(int *piWdt, int *piHgt, int *piTabPos, const char *szForText)
591 {
592  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
593  int iWdt=120;
594  C4GUI::CheckBox::GetStandardCheckBoxSize(&iWdt, piHgt, szForText, pUseFont);
595  int32_t iEdtWdt=120, iEdtHgt=24;
596  pUseFont->GetTextExtent("sorgentelefon@treffpunktclonk.net", iEdtWdt, iEdtHgt, false);
597  if (piWdt) *piWdt = iWdt+iEdtWdt+2;
598  if (piTabPos) *piTabPos = iWdt+2;
599  if (piHgt) *piHgt = C4GUI::Edit::GetCustomEditHeight(pUseFont)+2*2;
600  return true;
601 }
602 
603 
604 
605 // ------------------------------------------------
606 // --- C4StartupOptionsDlg::BoolConfig
607 
608 C4StartupOptionsDlg::BoolConfig::BoolConfig(const C4Rect &rcBounds, const char *szName, bool *pbVal, int32_t *piVal, bool fInvert, int32_t *piRestartChangeCfgVal)
609  : C4GUI::CheckBox(rcBounds, szName, fInvert != (pbVal ? *pbVal : !!*piVal)), pbVal(pbVal), fInvert(fInvert), piVal(piVal), piRestartChangeCfgVal(piRestartChangeCfgVal)
610 {
611  SetOnChecked(new C4GUI::CallbackHandler<BoolConfig>(this, &BoolConfig::OnCheckChange));
612 }
613 
614 void C4StartupOptionsDlg::BoolConfig::OnCheckChange(C4GUI::Element *pCheckBox)
615 {
616  if (pbVal) *pbVal = (GetChecked() != fInvert);
617  if (piVal) *piVal = (GetChecked() != fInvert);
618  if (piRestartChangeCfgVal) GetScreen()->ShowMessage(LoadResStr("IDS_MSG_RESTARTCHANGECFG"), GetText(),
619  C4GUI::Ico_Notify, piRestartChangeCfgVal);
620 }
621 
622 // ------------------------------------------------
623 // --- C4StartupOptionsDlg::EditConfig
624 
625 C4StartupOptionsDlg::EditConfig::EditConfig(const C4Rect &rcBounds, const char *szName, ValidatedStdCopyStrBufBase *psConfigVal, int32_t *piConfigVal, bool fMultiline)
626  : C4GUI::LabeledEdit(rcBounds, szName, fMultiline, psConfigVal ? psConfigVal->getData() : nullptr, &(C4Startup::Get()->Graphics.BookFont), C4StartupFontClr), psConfigVal(psConfigVal), piConfigVal(piConfigVal)
627 {
628  // ctor
630  if (piConfigVal) SetIntVal(*piConfigVal);
631  GetEdit()->SetMaxText(CFG_MaxString);
632 }
633 
634 void C4StartupOptionsDlg::EditConfig::Save2Config()
635 {
636  // controls to config
637  if (psConfigVal)
638  psConfigVal->CopyValidated(GetEdit()->GetText());
639  if (piConfigVal)
640  *piConfigVal = GetIntVal();
641 }
642 
643 bool C4StartupOptionsDlg::EditConfig::GetControlSize(int *piWdt, int *piHgt, const char *szForText, bool fMultiline)
644 {
645  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
646  typedef C4GUI::LabeledEdit BaseEdit;
647  return BaseEdit::GetControlSize(piWdt, piHgt, szForText, pUseFont, fMultiline);
648 }
649 
650 // ------------------------------------------------
651 // --- C4StartupOptionsDlg
652 
654 {
655  // ctor
656  UpdateSize();
657  bool fSmall = (GetClientRect().Wdt < 750);
658  CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
659 
660  // key bindings
662  keys.emplace_back(K_BACK); keys.emplace_back(K_LEFT);
663  pKeyBack = new C4KeyBinding(keys, "StartupOptionsBack", KEYSCOPE_Gui,
665  keys.clear();
666  keys.emplace_back(K_F3); // overloading global toggle with higher priority here, so a new name is required
667  pKeyToggleMusic = new C4KeyBinding(keys, "OptionsMusicToggle", KEYSCOPE_Gui,
669 
670  // screen calculations
671  int32_t iButtonWidth,iCaptionFontHgt;
672  int32_t iButtonHeight = C4GUI_ButtonHgt;
673  ::GraphicsResource.CaptionFont.GetTextExtent("<< BACK", iButtonWidth, iCaptionFontHgt, true);
674  iButtonWidth *= 3;
675  int iIndentX1, iIndentY1, iIndentY2;
676  if (fSmall)
677  {
678  iIndentX1=20;
679  }
680  else
681  {
682  iIndentX1 = GetClientRect().Wdt/40;
683  }
684  if (fSmall)
685  {
686  iIndentY1=1; iIndentY2=1;
687  }
688  else
689  {
690  iIndentY1 = GetClientRect().Hgt/200;
691  iIndentY2 = std::max<int32_t>(1, iIndentY1/2);
692  }
693  C4GUI::ComponentAligner caMain(GetClientRect(), 0,0, true);
694  C4GUI::ComponentAligner caButtonArea(caMain.GetFromBottom(caMain.GetHeight()/(fSmall ? 20 : 7)),0,0);
695  C4GUI::ComponentAligner caButtons(caButtonArea.GetCentered(caMain.GetWidth()*7/8, iButtonHeight),0,0);
696  C4GUI::ComponentAligner caConfigArea(caMain.GetAll(), fSmall ? 0 : (caMain.GetWidth()*69/1730), fSmall ? 0 : (caMain.GetHeight()/200));
697 
698  // back button
700  AddElement(btn = new C4GUI::CallbackButton<C4StartupOptionsDlg>(LoadResStr("IDS_BTN_BACK"), caButtons.GetFromLeft(iButtonWidth), &C4StartupOptionsDlg::OnBackBtn));
701  btn->SetToolTip(LoadResStr("IDS_DLGTIP_BACKMAIN"));
702 
703  // main config area tabular
704  pOptionsTabular = new C4GUI::Tabular(caConfigArea.GetAll(), C4GUI::Tabular::tbLeft);
706  AddElement(pOptionsTabular);
707  C4GUI::Tabular::Sheet *pSheetGeneral = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_PROGRAM") , 0);
708  C4GUI::Tabular::Sheet *pSheetGraphics = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_GRAPHICS"), 1);
709  C4GUI::Tabular::Sheet *pSheetSound = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_SOUND") , 2);
710  C4GUI::Tabular::Sheet *pSheetControls= pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_CONTROLS"), 3);
711  C4GUI::Tabular::Sheet *pSheetNetwork = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_NETWORK") , 5);
712 
713  C4GUI::CheckBox *pCheck; C4GUI::Label *pLbl;
714  int iCheckWdt=100, iCheckHgt=20, iEdit2Wdt=100, iEdit2Hgt=40;
715  BoolConfig::GetStandardCheckBoxSize(&iCheckWdt, &iCheckHgt, "Default text", pUseFont);
716  EditConfig::GetControlSize(&iEdit2Wdt, &iEdit2Hgt, "Default text", false);
717 
718  // --- page program
719  C4GUI::ComponentAligner caSheetProgram(pSheetGeneral->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/20, true);
720  // language
721  const char *szLangTip = LoadResStr("IDS_MSG_SELECTLANG");
722  C4GUI::ComponentAligner caLanguage(caSheetProgram.GetGridCell(0,1,0,7,-1,-1,true,1,2), 0, C4GUI_DefDlgSmallIndent, false);
723  C4GUI::ComponentAligner caLanguageBox(caLanguage.GetFromTop(C4GUI::ComboBox::GetDefaultHeight()), 0, 0, false);
724  StdStrBuf sLangStr; sLangStr.Copy(LoadResStr("IDS_CTL_LANGUAGE")); sLangStr.AppendChar(':');
725  int32_t w,q;
726  pUseFont->GetTextExtent(sLangStr.getData(), w,q,true);
727  pLbl = new C4GUI::Label(sLangStr.getData(), caLanguageBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent), ALeft, C4StartupFontClr, pUseFont, false);
728  pLbl->SetToolTip(szLangTip);
729  pSheetGeneral->AddElement(pLbl);
730  pUseFont->GetTextExtent("XX: Top Secret Language", w,q,true);
731  pLangCombo = new C4GUI::ComboBox(caLanguageBox.GetFromLeft(std::min(w, caLanguageBox.GetWidth())));
732  pLangCombo->SetToolTip(szLangTip);
733  pLangCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnLangComboFill, &C4StartupOptionsDlg::OnLangComboSelChange));
734  pLangCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
735  pLangCombo->SetFont(pUseFont);
736  pLangCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
737  pSheetGeneral->AddElement(pLangCombo);
738  pLangInfoLabel = new C4GUI::Label(nullptr, caLanguage.GetFromTop(::GraphicsResource.TextFont.GetLineHeight()*3), ALeft, C4StartupFontClr, pUseFont, false);
739  pLangInfoLabel->SetToolTip(szLangTip);
740  pSheetGeneral->AddElement(pLangInfoLabel);
741  UpdateLanguage();
742  // font
743  const char *szFontTip = LoadResStr("IDS_DESC_SELECTFONT");
744  C4GUI::ComponentAligner caFontBox(caSheetProgram.GetGridCell(0,1,2,7,-1,C4GUI::ComboBox::GetDefaultHeight(), true), 0, 0, false);
745  StdStrBuf sFontStr; sFontStr.Copy(LoadResStr("IDS_CTL_FONT")); sFontStr.AppendChar(':');
746  pUseFont->GetTextExtent(sFontStr.getData(), w,q,true);
747  pLbl = new C4GUI::Label(sFontStr.getData(), caFontBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent), ALeft, C4StartupFontClr, pUseFont, false);
748  pLbl->SetToolTip(szFontTip);
749  pSheetGeneral->AddElement(pLbl);
750  pUseFont->GetTextExtent("Comic Sans MS", w,q,true);
751  pFontFaceCombo = new C4GUI::ComboBox(caFontBox.GetFromLeft(std::min<int32_t>(caFontBox.GetInnerWidth()*3/4, w*3)));
752  pFontFaceCombo->SetToolTip(szFontTip);
753  pFontFaceCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnFontFaceComboFill, &C4StartupOptionsDlg::OnFontComboSelChange));
754  pFontFaceCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
755  pFontFaceCombo->SetFont(pUseFont);
756  pFontFaceCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
757  caFontBox.ExpandLeft(-C4GUI_DefDlgSmallIndent);
758  pSheetGeneral->AddElement(pFontFaceCombo);
759  pFontSizeCombo = new C4GUI::ComboBox(caFontBox.GetFromLeft(std::min<int32_t>(caFontBox.GetInnerWidth(), w)));
760  pFontSizeCombo->SetToolTip(LoadResStr("IDS_DESC_FONTSIZE"));
761  pFontSizeCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnFontSizeComboFill, &C4StartupOptionsDlg::OnFontComboSelChange));
762  pFontSizeCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
763  pFontSizeCombo->SetFont(pUseFont);
764  pFontSizeCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
765  pSheetGeneral->AddElement(pFontSizeCombo);
766  UpdateFontControls();
767  // MM timer
768  pCheck = new BoolConfig(caSheetProgram.GetGridCell(0,1,3,7,-1,iCheckHgt, true), LoadResStr("IDS_CTL_MMTIMER"), nullptr, &Config.General.MMTimer, true, &Config.Startup.HideMsgMMTimerChange);
769  pCheck->SetToolTip(LoadResStr("IDS_MSG_MMTIMER_DESC"));
770  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
771  pSheetGeneral->AddElement(pCheck);
772  // reset configuration
773  const char *szBtnText = LoadResStr("IDS_BTN_RESETCONFIG");
775  ::GraphicsResource.CaptionFont.GetTextExtent(szBtnText, iButtonWidth, iButtonHeight, true);
776  C4Rect rcResetBtn = caSheetProgram.GetGridCell(1,2,6,7, std::min<int32_t>(iButtonWidth+iButtonHeight*4, caSheetProgram.GetInnerWidth()*2/5), SmallButton::GetDefaultButtonHeight(), true);
777  pSmallBtn = new C4GUI::CallbackButton<C4StartupOptionsDlg, SmallButton>(szBtnText, rcResetBtn, &C4StartupOptionsDlg::OnResetConfigBtn, this);
778  pSheetGeneral->AddElement(pSmallBtn);
779  pSmallBtn->SetToolTip(LoadResStr("IDS_DESC_RESETCONFIG"));
780 
781  // --- page graphics
782  C4GUI::ComponentAligner caSheetGraphics(pSheetGraphics->GetClientRect(), iIndentX1, iIndentY1, true);
783  // --subgroup display
784  C4GUI::GroupBox *pGroupResolution = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,1,0,2));
785  pGroupResolution->SetTitle(LoadResStrNoAmp("IDS_CTL_DISPLAY"));
786  pGroupResolution->SetFont(pUseFont);
787  pGroupResolution->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
788  pSheetGraphics->AddElement(pGroupResolution);
789  C4GUI::ComponentAligner caGroupResolution(pGroupResolution->GetClientRect(), iIndentX1, iIndentY2, true);
790  int32_t iNumGfxOptions = 3, iOpt = 0;
791  // resolution combobox
792  C4GUI::ComponentAligner resBox(caGroupResolution.GetGridCell(0,1,iOpt++,iNumGfxOptions), 0, 0, false);
793  w=20; q=12; pUseFont->GetTextExtent(LoadResStr("IDS_CTL_RESOLUTION"), w,q, true);
794  pGroupResolution->AddElement(new C4GUI::Label(LoadResStr("IDS_CTL_RESOLUTION"), resBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent,q), ALeft, C4StartupFontClr, pUseFont, false, false));
795  pUseFont->GetTextExtent("1600 x 1200", w,q,true); w = std::min<int32_t>(caGroupResolution.GetInnerWidth(), w+40);
796  C4GUI::ComboBox *pGfxResCombo = new C4GUI::ComboBox(resBox.GetFromLeft(w+40,C4GUI::ComboBox::GetDefaultHeight()));
797  pGfxResCombo->SetToolTip(LoadResStr("IDS_MSG_RESOLUTION_DESC"));
798  pGfxResCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnGfxResComboFill, &C4StartupOptionsDlg::OnGfxResComboSelChange));
799  pGfxResCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
800  pGfxResCombo->SetFont(pUseFont);
801  pGfxResCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
802  pGfxResCombo->SetText(GetGfxResString(Config.Graphics.ResX, Config.Graphics.ResY).getData());
803  pGroupResolution->AddElement(pGfxResCombo);
804  // fullscreen combobox
805  C4GUI::ComponentAligner fsBox(caGroupResolution.GetGridCell(0,1,iOpt++,iNumGfxOptions), 0, 0, false);
806  w=20; q=12; pUseFont->GetTextExtent(LoadResStr("IDS_CTL_FULLSCREENMODE"), w,q, true);
807  pGroupResolution->AddElement(new C4GUI::Label(LoadResStr("IDS_CTL_FULLSCREENMODE"), fsBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent,q), ALeft, C4StartupFontClr, pUseFont, false, false));
808  uint32_t wmax = 0;
809  for(int i = 0; i < 3; ++i)
810  {
811  pUseFont->GetTextExtent(GetWindowedName(i),w,q,true);
812  wmax = std::max<int32_t>(w, wmax);
813  }
814  C4GUI::ComboBox * pCombo = new C4GUI::ComboBox(fsBox.GetFromLeft(w+40,C4GUI::ComboBox::GetDefaultHeight()));
815  pCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnWindowedModeComboFill, &C4StartupOptionsDlg::OnWindowedModeComboSelChange));
816  pCombo->SetToolTip(LoadResStr("IDS_MSG_FULLSCREEN_DESC"));
817  pCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
818  pCombo->SetFont(pUseFont);
819  pCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
820  pCombo->SetText(GetWindowedName());
821  pGroupResolution->AddElement(pCombo);
822  // --subgroup options
823  iNumGfxOptions = 5, iOpt=0;
824  C4GUI::GroupBox *pGroupOptions = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,1,1,2));
825  pGroupOptions->SetTitle(LoadResStrNoAmp("IDS_DLG_OPTIONS"));
826  pGroupOptions->SetFont(pUseFont);
827  pGroupOptions->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
828  pSheetGraphics->AddElement(pGroupOptions);
829  C4GUI::ComponentAligner caGroupOptions(pGroupOptions->GetClientRect(), iIndentX1, iIndentY2, true);
830  // multisampling
831  C4GUI::ComponentAligner msBox(caGroupOptions.GetFromTop(C4GUI::ComboBox::GetDefaultHeight()), 0, 0, false);
832  w=20; q=12; pUseFont->GetTextExtent(LoadResStr("IDS_CTL_ANTIALIASING"), w,q, true);
833  pGroupOptions->AddElement(new C4GUI::Label(LoadResStr("IDS_CTL_ANTIALIASING"), msBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent), ALeft, C4StartupFontClr, pUseFont, false, false));
834 
835  pUseFont->GetTextExtent("Off", w, q, true);
836  C4GUI::ComboBox *pGfxMSCombo = new C4GUI::ComboBox(msBox.GetFromLeft(w+40,C4GUI::ComboBox::GetDefaultHeight()));
837  pGfxMSCombo->SetToolTip(LoadResStr("IDS_MSG_ANTIALIASING_DESC"));
838  pGfxMSCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnGfxMSComboFill, &C4StartupOptionsDlg::OnGfxMSComboSelChange));
839  pGfxMSCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
840  pGfxMSCombo->SetFont(pUseFont);
841  pGfxMSCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
842  // Pre-Select current setting
843  StdStrBuf Current;
845  else Current.Copy("Off");
846  pGfxMSCombo->SetText(Current.getData());
847  // Set control read only if multisampling is not available
848  std::vector<int> multisamples;
850  pGfxMSCombo->SetReadOnly(multisamples.empty());
851  pGroupOptions->AddElement(pGfxMSCombo);
852  // automatic gfx frame skip
853  pCheck = new BoolConfig(caGroupOptions.GetGridCell(0,1,iOpt++,iNumGfxOptions,-1,iCheckHgt,true), LoadResStr("IDS_MSG_AUTOFRAMESKIP"), nullptr, &Config.Graphics.AutoFrameSkip);
854  pCheck->SetToolTip(LoadResStr("IDS_DESC_AUTOFRAMESKIP"));
855  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
856  pGroupOptions->AddElement(pCheck);
857 
858  // --- page sound
859  C4GUI::ComponentAligner caSheetSound(pSheetSound->GetClientRect(), iIndentX1, iIndentY1, true);
860  if (!C4GUI::CheckBox::GetStandardCheckBoxSize(&iCheckWdt, &iCheckHgt, "Lorem ipsum", pUseFont)) { iCheckWdt=100; iCheckHgt=20; }
861  int32_t iGridWdt = iCheckWdt * 2, iGridHgt = iCheckHgt * 5/2;
862  // --subgroup menu system sound
863  C4GUI::GroupBox *pGroupFESound = new C4GUI::GroupBox(caSheetSound.GetGridCell(0,2,0,5, iGridWdt, iGridHgt, false, 1,2));
864  pGroupFESound->SetTitle(LoadResStrNoAmp("IDS_CTL_FRONTEND"));
865  pGroupFESound->SetFont(pUseFont);
866  pGroupFESound->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
867  pSheetSound->AddElement(pGroupFESound);
868  C4GUI::ComponentAligner caGroupFESound(pGroupFESound->GetClientRect(), iIndentX1, iIndentY2, true);
869  // menu system music
870  pCheck = pFEMusicCheck = new C4GUI::CheckBox(caGroupFESound.GetGridCell(0,1,0,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_MUSIC"), !!Config.Sound.FEMusic);
871  pCheck->SetToolTip(LoadResStr("IDS_DESC_MENUMUSIC"));
872  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
873  pCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnFEMusicCheck));
874  pGroupFESound->AddElement(pCheck);
875  // menu system sound effects
876  pCheck = pFESoundCheck = new BoolConfig(caGroupFESound.GetGridCell(0,1,1,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_SOUNDFX"), nullptr, &Config.Sound.FESamples);
877  pCheck->SetToolTip(LoadResStr("IDS_DESC_MENUSOUND"));
878  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
879  pGroupFESound->AddElement(pCheck);
880  // --subgroup game sound
881  C4GUI::GroupBox *pGroupRXSound = new C4GUI::GroupBox(caSheetSound.GetGridCell(1,2,0,5, iGridWdt, iGridHgt, false, 1,2));
882  pGroupRXSound->SetTitle(LoadResStrNoAmp("IDS_CTL_GAME"));
883  pGroupRXSound->SetFont(pUseFont);
884  pGroupRXSound->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
885  pSheetSound->AddElement(pGroupRXSound);
886  C4GUI::ComponentAligner caGroupRXSound(pGroupRXSound->GetClientRect(), iIndentX1, iIndentY2, true);
887  // game music
888  pCheck = new BoolConfig(caGroupRXSound.GetGridCell(0,1,0,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_MUSIC"), nullptr, &Config.Sound.RXMusic);
889  pCheck->SetToolTip(LoadResStr("IDS_DESC_GAMEMUSIC"));
890  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
891  pGroupRXSound->AddElement(pCheck);
892  // game sound effects
893  pCheck = new C4GUI::CheckBox(caGroupRXSound.GetGridCell(0,1,1,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_SOUNDFX"), !!Config.Sound.RXSound);
894  pCheck->SetToolTip(LoadResStr("IDS_DESC_GAMESOUND"));
895  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
896  pCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnRXSoundCheck));
897  pGroupRXSound->AddElement(pCheck);
898  // -- subgroup volume
899  C4GUI::GroupBox *pGroupVolume = new C4GUI::GroupBox(caSheetSound.GetGridCell(0,2,2,5, iGridWdt, iGridHgt, false, 2,3));
900  pGroupVolume->SetTitle(LoadResStrNoAmp("IDS_BTN_VOLUME"));
901  pGroupVolume->SetFont(pUseFont);
902  pGroupVolume->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
903  pSheetSound->AddElement(pGroupVolume);
904  C4GUI::ComponentAligner caGroupVolume(pGroupVolume->GetClientRect(), iIndentX1, iIndentY2, true);
905  // volume sliders
906  int32_t i;
907  for (i=0; i<2; ++i)
908  {
909  StdStrBuf sLabelTxt;
910  C4GUI::ComponentAligner caVolumeSlider(caGroupVolume.GetGridCell(0,1,i,2, -1, pUseFont->GetLineHeight()+iIndentY2*2+C4GUI_ScrollBarHgt, true), 1,0,false);
911  pGroupVolume->AddElement(new C4GUI::Label(FormatString("%s:", LoadResStr(i ? "IDS_CTL_SOUNDFX" : "IDS_CTL_MUSIC")).getData(), caVolumeSlider.GetFromTop(pUseFont->GetLineHeight()), ALeft, C4StartupFontClr, pUseFont, false, false));
912  sLabelTxt.Copy(LoadResStr("IDS_CTL_SILENT"));
913  w=20; q=12; pUseFont->GetTextExtent(sLabelTxt.getData(), w,q, true);
914  pGroupVolume->AddElement(new C4GUI::Label(sLabelTxt.getData(), caVolumeSlider.GetFromLeft(w,q), ACenter, C4StartupFontClr, pUseFont, false, false));
915  sLabelTxt.Copy(LoadResStr("IDS_CTL_LOUD"));
916  pUseFont->GetTextExtent(sLabelTxt.getData(), w,q, true);
917  pGroupVolume->AddElement(new C4GUI::Label(sLabelTxt.getData(), caVolumeSlider.GetFromRight(w,q), ACenter, C4StartupFontClr, pUseFont, false, false));
918  auto *pCB = new C4GUI::ParCallbackHandler<C4StartupOptionsDlg, int32_t>(this, i ? &C4StartupOptionsDlg::OnSoundVolumeSliderChange : &C4StartupOptionsDlg::OnMusicVolumeSliderChange);
919  auto *pSlider = new C4GUI::ScrollBar(caVolumeSlider.GetCentered(caVolumeSlider.GetInnerWidth(), C4GUI_ScrollBarHgt), true, pCB, 101);
920  pSlider->SetDecoration(&C4Startup::Get()->Graphics.sfctBookScroll, false);
921  pSlider->SetToolTip(i ? LoadResStr("IDS_DESC_VOLUMESOUND") : LoadResStr("IDS_DESC_VOLUMEMUSIC"));
922  pSlider->SetScrollPos(i ? Config.Sound.SoundVolume : Config.Sound.MusicVolume);
923  pGroupVolume->AddElement(pSlider);
924  }
925 
926  // --- page controls
927  pSheetControls->AddElement(pControlConfigArea = new ControlConfigArea(pSheetControls->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/40, false, this));
928 
929  // --- page network
930  int iPortCfgWdt=200, iPortCfgHgt=48; NetworkPortConfig::GetControlSize(&iPortCfgWdt, &iPortCfgHgt);
931  int iServerCfgWdt = 120, iServerCfgHgt = 20, iServerCfgWdtMid = 0;
932  StdStrBuf sServerText; sServerText.Copy(LoadResStr("IDS_CTL_USEOTHERSERVER"));
933  NetworkServerAddressConfig::GetControlSize(&iServerCfgWdt, &iServerCfgHgt, &iServerCfgWdtMid, sServerText.getData());
934  int32_t net_component_hgt = iPortCfgHgt * 4 + iServerCfgHgt + 3 * pUseFont->GetLineHeight();
935  C4GUI::ComponentAligner caSheetNetwork(pSheetNetwork->GetClientRect(), caMain.GetWidth() / 20, std::max<int32_t>(0, (caMain.GetHeight() - net_component_hgt)/20), true);
936  pPortCfgTCP = new NetworkPortConfig(caSheetNetwork.GetGridCell(0,2,0,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_TCP"), &(Config.Network.PortTCP), C4NetStdPortTCP);
937  pPortCfgUDP = new NetworkPortConfig(caSheetNetwork.GetGridCell(1,2,0,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_UDP"), &(Config.Network.PortUDP), C4NetStdPortUDP);
938  pPortCfgRef = new NetworkPortConfig(caSheetNetwork.GetGridCell(0,2,1,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_REFERENCE"), &(Config.Network.PortRefServer), C4NetStdPortRefServer);
939  pPortCfgDsc = new NetworkPortConfig(caSheetNetwork.GetGridCell(1,2,1,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_DISCOVERY"), &(Config.Network.PortDiscovery), C4NetStdPortDiscovery);
940  pPortCfgTCP->SetToolTip(LoadResStr("IDS_NET_PORT_TCP_DESC"));
941  pPortCfgUDP->SetToolTip(LoadResStr("IDS_NET_PORT_UDP_DESC"));
942  pPortCfgRef->SetToolTip(LoadResStr("IDS_NET_PORT_REFERENCE_DESC"));
943  pPortCfgDsc->SetToolTip(LoadResStr("IDS_NET_PORT_DISCOVERY_DESC"));
944  pSheetNetwork->AddElement(pPortCfgTCP);
945  pSheetNetwork->AddElement(pPortCfgUDP);
946  pSheetNetwork->AddElement(pPortCfgRef);
947  pSheetNetwork->AddElement(pPortCfgDsc);
948  int iNetHgt0=pPortCfgDsc->GetBounds().GetBottom();
949  caSheetNetwork.ExpandTop(-iNetHgt0);
950  pLeagueServerCfg = new NetworkServerAddressConfig(caSheetNetwork.GetFromTop(iServerCfgHgt), sServerText.getData(), &(Config.Network.UseAlternateServer), Config.Network.AlternateServerAddress, iServerCfgWdtMid);
951  pLeagueServerCfg->SetToolTip(LoadResStr("IDS_NET_MASTERSRV_DESC"));
952  pSheetNetwork->AddElement(pLeagueServerCfg);
953 #ifdef WITH_AUTOMATIC_UPDATE
954  pCheck = new BoolConfig(caSheetNetwork.GetFromTop(pUseFont->GetLineHeight()), LoadResStr("IDS_CTL_AUTOMATICUPDATES"), nullptr, &Config.Network.AutomaticUpdate, false);
955  pCheck->SetToolTip(LoadResStr("IDS_DESC_AUTOMATICUPDATES"));
956  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
957  pSheetNetwork->AddElement(pCheck);
958 #endif
959  pCheck = new BoolConfig(caSheetNetwork.GetFromTop(pUseFont->GetLineHeight()), LoadResStr("IDS_CTL_UPNP"), nullptr, &Config.Network.EnableUPnP, false);
960  pCheck->SetToolTip(LoadResStr("IDS_DESC_UPNP"));
961  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
962  pSheetNetwork->AddElement(pCheck);
963  pCheck = new BoolConfig(caSheetNetwork.GetFromTop(pUseFont->GetLineHeight()), LoadResStr("IDS_CTL_PACKETLOGGING"), nullptr, &Config.Network.PacketLogging, false);
964  pCheck->SetToolTip(LoadResStr("IDS_DESC_PACKETLOGGING"));
965  pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
966  pSheetNetwork->AddElement(pCheck);
967  const char *szNameCfgText = LoadResStr("IDS_NET_USERNAME");
968  int iNameCfgWdt=200, iNameCfgHgt=48; C4StartupOptionsDlg::EditConfig::GetControlSize(&iNameCfgWdt, &iNameCfgHgt, szNameCfgText, false);
969  iNameCfgWdt += 5;
970  pNetworkNickEdit = new EditConfig(caSheetNetwork.GetFromTop(iNameCfgHgt), szNameCfgText, &Config.Network.Nick, nullptr, false);
971  pNetworkNickEdit->SetToolTip(LoadResStr("IDS_NET_USERNAME_DESC"));
972  pSheetNetwork->AddElement(pNetworkNickEdit);
973 
974  StdCopyStrBuf NickBuf(Config.Network.Nick);
975  if (!NickBuf.getLength()) NickBuf.Copy(Config.GetRegistrationData("Nick"));
976  pNetworkNickEdit->GetEdit()->SetText(NickBuf.getData(), false);
977 
978  // initial focus is on tab selection
979  SetFocus(pOptionsTabular, false);
980 }
981 
983 {
984  delete pKeyToggleMusic;
985  delete pKeyBack;
986 }
987 
989 {
990  // callback when dlg got closed - save config
991  SaveConfig(true, false);
993 }
994 
995 void C4StartupOptionsDlg::OnResetConfigBtn(C4GUI::Control *btn)
996 {
997  // confirmation
998  StdStrBuf sWarningText; sWarningText.Copy(LoadResStr("IDS_MSG_PROMPTRESETCONFIG"));
999  sWarningText.AppendChar('|');
1000  sWarningText.Append(LoadResStr("IDS_MSG_RESTARTCHANGECFG"));
1001  if (!GetScreen()->ShowMessageModal(sWarningText.getData(), LoadResStr("IDS_BTN_RESETCONFIG"), C4GUI::MessageDialog::btnYesNo, C4GUI::Ico_Notify))
1002  // user cancelled
1003  return;
1004  // reset cfg
1005  Config.Default();
1006  Config.fConfigLoaded = true;
1007  // engine must be restarted now, because some crucial fields such as resolution and used gfx engine do not match their initialization
1008  Application.Quit();
1009 }
1010 
1011 void C4StartupOptionsDlg::OnGfxMSComboFill(C4GUI::ComboBox_FillCB *pFiller)
1012 {
1013  // clear all old entries first to allow a clean refill
1014  pFiller->ClearEntries();
1015 
1016  pFiller->AddEntry("Off", 0);
1017 
1018  std::vector<int> multisamples;
1019  Application.pWindow->EnumerateMultiSamples(multisamples);
1020 
1021  std::sort(multisamples.begin(), multisamples.end());
1022  for(int multisample : multisamples)
1023  {
1024  StdStrBuf text;
1025  text.Format("%dx", multisample);
1026  pFiller->AddEntry(text.getData(), multisample);
1027  }
1028 }
1029 
1030 bool C4StartupOptionsDlg::OnGfxMSComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
1031 {
1032  if(pTexMgr) pTexMgr->IntLock();
1033 #ifndef USE_CONSOLE
1035  // Note: This assumes there is only one GL context (the main context). This
1036  // is true in fullscreen mode, and since the startup dlg is only shown in
1037  // fullscreen mode we are safe this way.
1038  if(pGL) pGL->pMainCtx->Clear(true);
1039 #endif
1040  int32_t PrevMultiSampling = Config.Graphics.MultiSampling;
1041  Config.Graphics.MultiSampling = idNewSelection;
1042  bool success = Application.pWindow->ReInit(&Application);
1043 
1044 #ifndef USE_CONSOLE
1048 #endif
1049  if(pTexMgr) pTexMgr->IntUnlock();
1050  if(!success) Config.Graphics.MultiSampling = PrevMultiSampling;
1051  return !success;
1052 }
1053 
1054 void C4StartupOptionsDlg::OnGfxResComboFill(C4GUI::ComboBox_FillCB *pFiller)
1055 {
1056  // clear all old entries first to allow a clean refill
1057  pFiller->ClearEntries();
1058  pFiller->AddEntry(LoadResStr("IDS_MNU_DEFAULTRESOLUTION"), -1);
1059  // fill with all possible resolutions
1060  int32_t idx = 0, iXRes, iYRes, iBitDepth, iRefreshRate;
1061  while (Application.GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, &iRefreshRate, Config.Graphics.Monitor))
1062 #ifdef _WIN32 // why only WIN32?
1063  if (iBitDepth == C4Draw::COLOR_DEPTH)
1064 #endif
1065  {
1066  StdStrBuf sGfxString = GetGfxResString(iXRes, iYRes);
1067  if (!pFiller->FindEntry(sGfxString.getData()))
1068  pFiller->AddEntry(sGfxString.getData(), iXRes + (uint32_t(iYRes) << 12) + (uint32_t(iRefreshRate) << 24));
1069  }
1070 }
1071 
1072 bool C4StartupOptionsDlg::OnGfxResComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
1073 {
1074  // get new resolution from string
1075  int iResX=(idNewSelection & 0xfff), iResY=(uint32_t(idNewSelection) >> 12) & 0xfff, iRefreshRate = (uint32_t(idNewSelection) >> 24) & 0xff;
1076  if (idNewSelection == -1)
1077  {
1078  iResX = iResY = -1;
1079  iRefreshRate = 0;
1080  }
1081 
1082  // different than current?
1083  if (iResX == Config.Graphics.ResX && iResY == Config.Graphics.ResY && iRefreshRate == Config.Graphics.RefreshRate) return true;
1084 
1085  // try setting it
1086  if (!TryNewResolution(iResX, iResY, iRefreshRate))
1087  {
1088  // didn't work or declined by user
1089  return true; // do not change label, because dialog might hae been recreated!
1090  }
1091  // dialog has been recreated; so do not change the combo label
1092  return true;
1093 }
1094 
1095 bool C4StartupOptionsDlg::TryNewResolution(int32_t iResX, int32_t iResY, int32_t iRefreshRate)
1096 {
1097  int32_t iOldResX = Config.Graphics.ResX, iOldResY = Config.Graphics.ResY;
1098  int32_t iOldRefreshRate = Config.Graphics.RefreshRate;
1099  int32_t iOldFontSize = Config.General.RXFontSize;
1100  C4GUI::Screen *pScreen = GetScreen();
1101  // resolution change may imply font size change
1102  int32_t iNewFontSize = 14; // default (at 800x600)
1103  if (iResY >= 0 && iResY < 600)
1104  iNewFontSize = 12;
1105  else if (iResY > 800)
1106  iNewFontSize = 16;
1107  // call application to set it
1108  if (!Application.SetVideoMode(iResX, iResY, iRefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
1109  {
1110  StdCopyStrBuf strChRes(LoadResStr("IDS_MNU_SWITCHRESOLUTION"));
1111  pScreen->ShowMessage(FormatString(LoadResStr("IDS_ERR_SWITCHRES"), Application.GetLastError()).getData(), strChRes.getData(), C4GUI::Ico_Clonk, nullptr);
1112  return false;
1113  }
1114  // implied font change
1115  if (iNewFontSize != iOldFontSize)
1116  if (!Application.SetGameFont(Config.General.RXFontName, iNewFontSize))
1117  {
1118  // not changing font size is not fatal - just keep old size
1119  iNewFontSize = iOldFontSize;
1120  }
1121  // Set new resolution in config before dialog recreation so that the initial combo box value is correct (#230)
1122  Config.Graphics.ResX = iResX;
1123  Config.Graphics.ResY = iResY;
1124  Config.Graphics.RefreshRate = iRefreshRate;
1125  // since the resolution was changed, everything needs to be moved around a bit
1126  RecreateDialog(false);
1127  // Now set old resolution again to make sure config is restored even if the program is closed during the confirmation dialog
1128  Config.Graphics.ResX = iOldResX;
1129  Config.Graphics.ResY = iOldResY;
1130  Config.Graphics.RefreshRate = iOldRefreshRate;
1131  // Show confirmation dialog
1132  ResChangeConfirmDlg *pConfirmDlg = new ResChangeConfirmDlg();
1133  if (!pScreen->ShowModalDlg(pConfirmDlg, true))
1134  {
1135  // abort: Restore screen, if this was not some program abort
1136  if (Application.SetVideoMode(iOldResX, iOldResY, iOldRefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
1137  {
1138  if (iNewFontSize != iOldFontSize) Application.SetGameFont(Config.General.RXFontName, iOldFontSize);
1139  RecreateDialog(false);
1140  }
1141 
1142  return false;
1143  }
1144  // resolution may be kept!
1145  Config.Graphics.ResX = iResX;
1146  Config.Graphics.ResY = iResY;
1147  Config.Graphics.RefreshRate = iRefreshRate;
1150  return true;
1151 }
1152 
1153 StdStrBuf C4StartupOptionsDlg::GetGfxResString(int32_t iResX, int32_t iResY)
1154 {
1155  // Display in format like "640 x 480"
1156  if (iResX == -1)
1157  return StdStrBuf(LoadResStr("IDS_MNU_DEFAULTRESOLUTION"));
1158  return FormatString("%d x %d", (int)iResX, (int)iResY);
1159 }
1160 
1161 const char * C4StartupOptionsDlg::GetWindowedName(int32_t mode /* = -1*/)
1162 {
1163  if(mode == -1)
1164  mode = Config.Graphics.Windowed;
1165  if(mode == 0) return LoadResStr("IDS_MSG_FULLSCREEN");
1166  else if(mode == 1) return LoadResStr("IDS_MSG_WINDOWED");
1167  else if(mode == 2) return LoadResStr("IDS_MSG_AUTOWINDOWED");
1168  assert(!"Requested name for config value which does not exist");
1169  return "ERR: Unknown";
1170 }
1171 
1172 void C4StartupOptionsDlg::OnWindowedModeComboFill(C4GUI::ComboBox_FillCB *pFiller)
1173 {
1174  pFiller->ClearEntries();
1175  for(int32_t i = 0; i < 3; ++i)
1176  pFiller->AddEntry(GetWindowedName(i), i);
1177 }
1178 
1179 bool C4StartupOptionsDlg::OnWindowedModeComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
1180 {
1181  Config.Graphics.Windowed = idNewSelection;
1183  pForCombo->SetText(GetWindowedName(idNewSelection));
1184  return true;
1185 }
1186 
1187 bool C4StartupOptionsDlg::SaveConfig(bool fForce, bool fKeepOpen)
1188 {
1189  // prevent double save
1190  if (fConfigSaved) return true;
1191  // save any config fields that are not stored directly; return whether all values are OK
1192  // check port validity
1193  if (!fForce)
1194  {
1195  StdCopyStrBuf strError(LoadResStr("IDS_ERR_CONFIG"));
1196  if (pPortCfgTCP->GetPort()>0 && pPortCfgTCP->GetPort() == pPortCfgRef->GetPort())
1197  {
1198  GetScreen()->ShowMessage(LoadResStr("IDS_NET_ERR_PORT_TCPREF"), strError.getData(), C4GUI::Ico_Error);
1199  return false;
1200  }
1201  if (pPortCfgUDP->GetPort()>0 && pPortCfgUDP->GetPort() == pPortCfgDsc->GetPort())
1202  {
1203  GetScreen()->ShowMessage(LoadResStr("IDS_NET_ERR_PORT_UDPDISC"), strError.getData(), C4GUI::Ico_Error);
1204  return false;
1205  }
1206  }
1207  // store some config values
1208  pPortCfgTCP->SavePort();
1209  pPortCfgUDP->SavePort();
1210  pPortCfgRef->SavePort();
1211  pPortCfgDsc->SavePort();
1212  pLeagueServerCfg->Save2Config();
1213  pNetworkNickEdit->Save2Config();
1214  // if nick is same as default by registry, don't save in config
1215  // so regkey updates will change the nick as well
1216  const char *szRegNick = Config.GetRegistrationData("Nick");
1217  if (SEqual(Config.Network.Nick.getData(), szRegNick)) Config.Network.Nick.Clear();
1218  // make sure config is saved, in case the game crashes later on or another instance is started
1219  Config.Save();
1220  if (!fKeepOpen) fConfigSaved = true;
1221  // done; config OK
1222  return true;
1223 }
1224 
1226 {
1227  if (!SaveConfig(false, false)) return;
1228  // back 2 main
1230 }
1231 
1232 bool C4StartupOptionsDlg::SetSubscreen(const char *szToScreen)
1233 {
1234  // go to specified property sheet
1235  // option sheets do not have a good identifier associated to them - just lookup from a static array
1236  const char *page_names[] = { "general", "graphics", "sound", "controls", "network", nullptr };
1237  int32_t i = 0;
1238  while (page_names[i])
1239  {
1240  if (SEqualNoCase(szToScreen, page_names[i])) break;
1241  ++i;
1242  }
1243  // page name does not match?
1244  if (!page_names[i]) return false;
1245  // page name OK; switch it
1246  pOptionsTabular->SelectSheet(i, false);
1247  return true;
1248 }
1249 
1250 void C4StartupOptionsDlg::UpdateLanguage()
1251 {
1252  // find currently specified language in language list and display its info
1254  if (pNfo)
1255  {
1256  pLangCombo->SetText(FormatString("%s - %s", pNfo->Code, pNfo->Name).getData());
1257  pLangInfoLabel->SetText(pNfo->Info);
1258  }
1259  else
1260  {
1261  pLangCombo->SetText(FormatString("unknown (%s)", Config.General.Language).getData());
1262  pLangInfoLabel->SetText(LoadResStr("IDS_CTL_NOLANGINFO"));
1263  return; // no need to mess with fallbacks
1264  }
1265  // update language fallbacks
1266  char *szLang = Config.General.LanguageEx;
1267  SCopy(pNfo->Code, szLang);
1268  if (*(pNfo->Fallback))
1269  {
1270  SAppend(",", szLang);
1271  Config.General.GetLanguageSequence(pNfo->Fallback, szLang + SLen(szLang));
1272  }
1273  // internal fallbacks
1274  if (!SSearch(Config.General.LanguageEx, "US"))
1275  {
1276  if (*szLang) SAppendChar(',', szLang);
1277  SAppend("US", szLang);
1278  }
1279  if (!SSearch(Config.General.LanguageEx, "DE"))
1280  {
1281  if (*szLang) SAppendChar(',', szLang);
1282  SAppend("DE", szLang);
1283  }
1284 }
1285 
1286 void C4StartupOptionsDlg::OnLangComboFill(C4GUI::ComboBox_FillCB *pFiller)
1287 {
1288  // fill with all possible languages
1289  C4LanguageInfo *pNfo;
1290  for (int i=0; i<Languages.GetInfoCount(); ++i)
1291  if ((pNfo = Languages.GetInfo(i)))
1292  pFiller->AddEntry(FormatString("%s - %s", pNfo->Code, pNfo->Name).getData(), (unsigned char)(pNfo->Code[0]) + ((unsigned char)(pNfo->Code[1])<<8));
1293 }
1294 
1295 bool C4StartupOptionsDlg::OnLangComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
1296 {
1297  // set new language by two-character-code
1298  Config.General.Language[0] = idNewSelection & 0xff;
1299  Config.General.Language[1] = (idNewSelection & 0xff00) >> 8;
1300  Config.General.Language[2] = '\0';
1301  UpdateLanguage();
1303  Game.UpdateLanguage();
1304  // recreate everything to reflect language changes
1305  RecreateDialog(true);
1306  return true;
1307 }
1308 
1309 void C4StartupOptionsDlg::UpdateFontControls()
1310 {
1311  // display current language and size in comboboxes
1312  pFontFaceCombo->SetText(Config.General.RXFontName);
1313  StdStrBuf sSize; sSize.Format("%d", (int) Config.General.RXFontSize);
1314  pFontSizeCombo->SetText(sSize.getData());
1315 }
1316 
1317 #ifdef _WIN32
1318 const char *DefaultFonts[] = { "Arial Unicode MS", "Comic Sans MS", C4DEFAULT_FONT_NAME, "Verdana", nullptr };
1319 #else
1320 const char *DefaultFonts[] = { C4DEFAULT_FONT_NAME, nullptr };
1321 #endif
1322 
1323 void C4StartupOptionsDlg::OnFontFaceComboFill(C4GUI::ComboBox_FillCB *pFiller)
1324 {
1325  // 2do: enumerate Fonts.txt fonts; then enumerate system fonts
1326  for (int32_t i=0; DefaultFonts[i]; ++i) pFiller->AddEntry(DefaultFonts[i], i);
1327 }
1328 
1329 void C4StartupOptionsDlg::OnFontSizeComboFill(C4GUI::ComboBox_FillCB *pFiller)
1330 {
1331  // 2do: enumerate possible font sizes by the font here
1332  // 2do: Hide font sizes that would be too large for the selected resolution
1333  pFiller->AddEntry("10", 10);
1334  pFiller->AddEntry("12", 12);
1335  pFiller->AddEntry("14", 14);
1336  pFiller->AddEntry("16", 16);
1337  pFiller->AddEntry("18", 18);
1338  pFiller->AddEntry("20", 20);
1339  pFiller->AddEntry("22", 22);
1340  pFiller->AddEntry("24", 24);
1341  pFiller->AddEntry("26", 26);
1342  pFiller->AddEntry("28", 28);
1343 }
1344 
1345 bool C4StartupOptionsDlg::OnFontComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
1346 {
1347  // set new value
1348  const char *szNewFontFace = Config.General.RXFontName;
1349  int32_t iNewFontSize = Config.General.RXFontSize;
1350  if (pForCombo == pFontFaceCombo)
1351  szNewFontFace = DefaultFonts[idNewSelection];
1352  else if (pForCombo == pFontSizeCombo)
1353  iNewFontSize = idNewSelection;
1354  else
1355  // can't happen
1356  return true;
1357  // set new fonts
1358  if (!Application.SetGameFont(szNewFontFace, iNewFontSize))
1359  {
1360  GetScreen()->ShowErrorMessage(LoadResStr("IDS_ERR_INITFONTS"));
1361  return true;
1362  }
1363  // recreate everything to reflect font changes
1364  RecreateDialog(true);
1365  return true;
1366 }
1367 
1369 {
1370  // MUST fade for now, or calling function will fail because dialog is deleted immediately
1371  fFade = true;
1372  // this actually breaks the possibility to go back :(
1373  int32_t iPage = pOptionsTabular->GetActiveSheetIndex();
1375  pNewDlg->pOptionsTabular->SelectSheet(iPage, false);
1376  pNewDlg->fCanGoBack = false;
1377 }
1378 
1379 void C4StartupOptionsDlg::OnFEMusicCheck(C4GUI::Element *pCheckBox)
1380 {
1381  // option change is reflected immediately
1382  bool fIsOn = static_cast<C4GUI::CheckBox *>(pCheckBox)->GetChecked();
1383  if ((Config.Sound.FEMusic = fIsOn))
1385  else
1387 }
1388 
1389 void C4StartupOptionsDlg::OnMusicVolumeSliderChange(int32_t iNewVal)
1390 {
1391  // option change is reflected immediately;
1392  Config.Sound.MusicVolume = iNewVal;
1394 }
1395 
1396 void C4StartupOptionsDlg::OnSoundVolumeSliderChange(int32_t iNewVal)
1397 {
1398  // sound system reads this value directly
1399  Config.Sound.SoundVolume = iNewVal;
1400  // test sound
1401  StartSoundEffect("Objects::Arrow::HitGround", false, 100, nullptr);
1402 }
1403 
1404 void C4StartupOptionsDlg::OnRXSoundCheck(C4GUI::Element *pCheckBox)
1405 {
1406  // toggling sounds on off must init/deinit sound system
1407  bool fIsOn = static_cast<C4GUI::CheckBox *>(pCheckBox)->GetChecked();
1408  if (fIsOn == !!Config.Sound.RXSound) return;
1409  if (fIsOn)
1410  {
1411  Config.Sound.RXSound = true;
1412  if (!Application.SoundSystem.Init())
1413  {
1414  GetScreen()->ShowMessage(StdCopyStrBuf(LoadResStr("IDS_PRC_NOSND")).getData(), StdCopyStrBuf(LoadResStr("IDS_DLG_LOG")).getData(), C4GUI::Ico_Error);
1416  Config.Sound.RXSound = false;
1417  static_cast<C4GUI::CheckBox *>(pCheckBox)->SetChecked(false);
1418  fIsOn = false;
1419  }
1420  }
1421  else
1422  {
1424  Config.Sound.RXSound = false;
1425  }
1426  // FE sound only enabled if global sound is enabled
1427  pFESoundCheck->SetEnabled(fIsOn);
1428  pFESoundCheck->SetChecked(fIsOn ? !!Config.Sound.FESamples : false);
1429 }
1430 
1432 {
1433  // do toggle
1435  // reflect in checkbox
1436  pFEMusicCheck->SetChecked(!!Config.Sound.FEMusic);
1437  // key processed
1438  return true;
1439 }
1440 
1442 {
1443  // keyboard layout changed and thus some keys might have been updated from scan codes
1444  // update display in control set
1445  pControlConfigArea->UpdateCtrlSet();
1446 }
const char * getData() const
Definition: StdBuf.h:442
C4SoundSystem SoundSystem
Definition: C4Application.h:42
const char * GetName() const
int32_t RefreshRate
Definition: C4Config.h:105
int32_t GetHeight() const
Definition: C4Gui.h:2801
void Default()
Definition: C4Config.cpp:283
#define C4GUI_CaptionFontClr
Definition: C4Gui.h:37
#define C4GUI_ButtonAreaHgt
Definition: C4Gui.h:113
int32_t MultiSampling
Definition: C4Config.h:115
C4Config Config
Definition: C4Config.cpp:833
const int32_t C4MC_Button_LeftDown
int GetLineHeight() const
Definition: C4FontLoader.h:125
C4ConfigStartup Startup
Definition: C4Config.h:260
void SetComboCB(ComboBox_FillCB *pNewFillCallback)
#define C4GUI_MessageDlgWdt
Definition: C4Gui.h:127
#define C4GUI_ButtonHgt
Definition: C4Gui.h:111
void SetClientSize(int32_t iToWdt, int32_t iToHgt)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:130
void GetAll(C4Rect &rcOut)
Definition: C4Gui.cpp:1125
void SAppendChar(char cChar, char *szStr)
Definition: Standard.cpp:243
int32_t PortDiscovery
Definition: C4Config.h:153
const int32_t C4StartupBtnFontClr
Definition: C4Startup.h:31
bool SetSubscreen(const char *szToScreen) override
C4PlayerControlAssignmentSet * GetSetByName(const char *szName)
virtual bool RestoreDeviceObjects()=0
#define C4GUI_MessageFontClr
Definition: C4Gui.h:43
const int16_t C4NetStdPortUDP
Definition: C4Network2.h:30
void SAppend(const char *szSource, char *szTarget, int iMaxL)
Definition: Standard.cpp:235
static int GetLanguageSequence(const char *strSource, char *strTarget)
Definition: C4Config.cpp:724
C4Game Game
Definition: C4Globals.cpp:52
void OnClosed(bool fOK) override
void Clear()
Definition: StdBuf.h:466
void IntLock()
Definition: C4Surface.cpp:840
C4ConfigGeneral General
Definition: C4Config.h:251
void ResetBlitMode()
Definition: C4Draw.h:192
static constexpr int COLOR_DEPTH
Definition: C4Draw.h:89
int32_t FEMusic
Definition: C4Config.h:128
int32_t PacketLogging
Definition: C4Config.h:168
const char * SSearch(const char *szString, const char *szIndex)
Definition: Standard.cpp:341
void SetToolTip(const char *szNewTooltip, bool is_immediate=false)
Definition: C4Gui.cpp:409
void SetFont(CStdFont *pToFont)
Definition: C4Gui.h:2017
#define C4GUI_DefDlgSmallIndent
Definition: C4Gui.h:133
CStdGLCtx * pMainCtx
Definition: C4DrawGL.h:178
int32_t RXSound
Definition: C4Config.h:126
int32_t Windowed
Definition: C4Config.h:106
int32_t PortRefServer
Definition: C4Config.h:153
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
Definition: C4Draw.cpp:567
#define C4GFXBLIT_ADDITIVE
Definition: C4Surface.h:26
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:185
bool SetVideoMode(int iXRes, int iYRes, unsigned int iRefreshRate, unsigned int iMonitor, bool fFullScreen)
Definition: C4AppSDL.cpp:354
#define C4GUI_DefButton2HSpace
Definition: C4Gui.h:116
friend class ListBox
Definition: C4Gui.h:472
void OnBackBtn(C4GUI::Control *btn)
Definition: C4Rect.h:27
bool GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, bool fCheckMarkup=true)
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
const char * GetGUIDesc(const C4PlayerControlDefs &defs) const
char Name[C4MaxLanguageInfo+1]
Definition: C4Language.h:33
void AddElement(Element *pChild)
const int32_t C4StartupEditBorderColor
Definition: C4Startup.h:30
int32_t HideMsgMMTimerChange
Definition: C4Config.h:183
const int32_t C4StartupFontClrDisabled
Definition: C4Startup.h:28
virtual void EnumerateMultiSamples(std::vector< int > &samples) const
Definition: C4AppT.cpp:102
int32_t SoundVolume
Definition: C4Config.h:132
const int32_t C4StartupBtnBorderColor2
Definition: C4Startup.h:33
size_t SLen(const char *sptr)
Definition: Standard.h:74
C4GraphicsResource GraphicsResource
void SelectSheet(int32_t iIndex, bool fByUser)
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
void SetFont(CStdFont *pFont, uint32_t dwEnabledClr, uint32_t dwDisabledClr)
Definition: C4Gui.h:1483
const int32_t C4StartupFontClr
Definition: C4Startup.h:27
void Add(StdSchedulerProc *pProc)
#define C4GUI_DefButton2Wdt
Definition: C4Gui.h:115
void SetBlitMode(DWORD dwBlitMode)
Definition: C4Draw.h:191
C4PlayerControlAssignment * GetAssignmentByControlName(const char *szControlName)
ValidatedStdCopyStrBuf< C4InVal::VAL_NameAllowEmpty > Nick
Definition: C4Config.h:156
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
const char * GetRegistrationData(const char *strField)
Definition: C4Config.h:281
virtual bool ReInit(C4AbstractApp *pApp)
Definition: C4AppT.cpp:107
void SetReadOnly(bool fToVal)
Definition: C4Gui.h:2014
void AppendChar(char cChar)
Definition: StdBuf.h:588
char Code[2+1]
Definition: C4Language.h:32
static bool GetControlSize(int *piWdt, int *piHgt, const char *szForText, CStdFont *pForFont, bool fMultiline)
Definition: C4GuiEdit.cpp:812
C4SoundInstance * StartSoundEffect(const char *szSndName, bool fLoop, int32_t iVolume, C4Object *pObj, int32_t iCustomFalloffDistance, int32_t iPitch, C4SoundModifier *modifier)
C4ConfigGraphics Graphics
Definition: C4Config.h:253
int32_t Wdt
Definition: C4Rect.h:30
C4PlayerControlAssignmentSet * GetSetByIndex(int32_t index)
std::vector< C4KeyCodeEx > CodeList
void OnKeyboardLayoutChanged() override
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1191
#define C4DEFAULT_FONT_NAME
Definition: C4Config.h:27
const int16_t C4NetStdPortTCP
Definition: C4Network2.h:29
C4TexMgr * pTexMgr
Definition: C4Surface.cpp:880
CStdFont BookSmallFont
Definition: C4Startup.h:65
const C4KeyCodeEx & GetTriggerKey() const
bool GetFromTop(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1059
const int16_t C4NetStdPortRefServer
Definition: C4Network2.h:32
const char * LoadResStrNoAmp(const char *id)
Definition: StdResStr2.cpp:23
int32_t y
Definition: C4Rect.h:30
const int16_t C4NetStdPortDiscovery
Definition: C4Network2.h:31
#define C4GUI_IconWdt
Definition: C4Gui.h:93
const int ACenter
Definition: C4Surface.h:41
C4FacetID fctOptionsIcons
Definition: C4Startup.h:71
void SetChecked(bool fToVal)
Definition: C4Gui.h:1476
C4Language Languages
Definition: C4Language.cpp:42
void DrawX(C4Surface *sfcTarget, float iX, float iY, float iWdt, float iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0) const
Definition: C4Facet.cpp:358
void SetTitle(const char *szToTitle)
Definition: C4Gui.h:1018
bool ShowErrorMessage(const char *szMessage)
void SetGfx(C4Facet *pafctBack, C4Facet *pafctClip, C4Facet *pafctIcons, CStdFont *paSheetCaptionFont, bool fResizeByAspect)
void UpdateLanguage()
Definition: C4Game.cpp:3024
C4Rect rcBounds
Definition: C4Gui.h:385
StdStrBuf GetKeysAsString(bool human_readable, bool short_name) const
void DrawQuadDw(C4Surface *sfcTarget, float *ipVtx, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4, C4ShaderCall *shader_call)
Definition: C4Draw.cpp:659
void Take(char *pnData)
Definition: StdBuf.h:457
void Append(const char *pnData, size_t iChars)
Definition: StdBuf.h:519
bool SetGameFont(const char *szFontFace, int32_t iFontSize)
bool Key_IsMouse(C4KeyCode key)
C4Rect & GetClientRect() override
Definition: C4Gui.h:864
void SetDecoration(C4Facet *pFctSideArrow)
Definition: C4Gui.h:2020
#define C4GUI_IconHgt
Definition: C4Gui.h:94
char Fallback[C4MaxLanguageInfo+1]
Definition: C4Language.h:35
#define C4GUI_InactCaptionFontClr
Definition: C4Gui.h:39
C4ConfigNetwork Network
Definition: C4Config.h:255
char AlternateServerAddress[CFG_MaxString+1]
Definition: C4Config.h:159
static int32_t GetDefaultHeight()
class C4StartupDlg * SwitchDialog(DialogID eToDlg, bool fFade=true, const char *szSubDialog=nullptr)
Definition: C4Startup.cpp:137
C4LanguageInfo * GetInfo(int iIndex)
Definition: C4Language.cpp:343
bool Key_IsGamepad(C4KeyCode key)
C4Draw * pDraw
Definition: C4Draw.cpp:42
int32_t HideMsgNoOfficialLeague
Definition: C4Config.h:187
void UpdateSize() override
const char * GetControlName() const
void SetColors(uint32_t dwFontClr, uint32_t dwBGClr, uint32_t dwBorderClr)
Definition: C4Gui.h:2018
#define C4GUI_ScrollBarHgt
Definition: C4Gui.h:104
C4PlayerControlDefs PlayerControlDefs
Definition: C4Game.h:92
char LanguageEx[CFG_MaxString+1]
Definition: C4Config.h:37
CStdFont BookFont
Definition: C4Startup.h:65
const char * GetGUIName() const
bool SaveConfig(bool fForce, bool fKeepOpen)
C4Rect & GetBounds()
Definition: C4Gui.h:445
int GetInfoCount()
Definition: C4Language.cpp:138
int32_t GetWidth() const
Definition: C4Gui.h:2800
char Language[CFG_MaxString+1]
Definition: C4Config.h:36
void RecreateDialog(bool fFade)
int GetConfigWidth()
Definition: C4Application.h:82
std::tuple< std::string, int > BreakMessage(const char *szMsg, int iWdt, bool fCheckMarkup, float fZoom=1.0f)
void SetColors(uint32_t dwNewBGClr, uint32_t dwNewFontClr, uint32_t dwNewBorderColor)
Definition: C4Gui.h:1348
Icons
Definition: C4Gui.h:637
static bool GetStandardCheckBoxSize(int *piWdt, int *piHgt, const char *szForCaptionText, CStdFont *pUseFont)
C4KeyCode Key
void SetColors(uint32_t dwFrameClr, uint32_t dwTitleClr, uint32_t dwBackClr=0xffffffff)
Definition: C4Gui.h:1017
void Quit() override
C4PlayerControlAssignmentSet * CreateEmptySetByTemplate(const C4PlayerControlAssignmentSet &template_set)
C4LanguageInfo * FindInfo(const char *strCode)
Definition: C4Language.cpp:353
int32_t x
Definition: C4Rect.h:30
bool ShowMessage(const char *szMessage, const char *szCaption, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
void SetKey(const C4KeyCodeEx &key)
void Remove(StdSchedulerProc *pProc)
int32_t GamepadGuiControl
Definition: C4Config.h:229
bool GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, int32_t *piRefreshRate, uint32_t iMonitor)
Definition: C4AppSDL.cpp:335
int32_t Monitor
Definition: C4Config.h:112
const C4KeyCode KEY_Undefined
C4PlayerControlAssignment * CreateAssignmentForControl(const char *control_name)
static int32_t GetCustomEditHeight(CStdFont *pUseFont)
Definition: C4GuiEdit.cpp:119
bool LoadLanguage(const char *strLanguages)
Definition: C4Language.cpp:361
float TargetX
Definition: C4Facet.h:165
char RXFontName[CFG_MaxString+1]
Definition: C4Config.h:41
void SetFocus(Control *pCtrl, bool fByMouse)
C4ConfigControls Controls
Definition: C4Config.h:259
const int32_t C4StartupEditBGColor
Definition: C4Startup.h:29
void SetBounds(const C4Rect &rcNewBound)
Definition: C4Gui.h:446
bool FindEntry(const char *szText)
int32_t RXFontSize
Definition: C4Config.h:42
int32_t MMTimer
Definition: C4Config.h:48
const int32_t C4StartupBtnBorderColor1
Definition: C4Startup.h:32
int32_t ResX
Definition: C4Config.h:103
#define C4GUI_Caption2FontClr
Definition: C4Gui.h:38
C4PlayerControlAssignment * GetAssignmentByIndex(int32_t index)
const int ALeft
Definition: C4Surface.h:41
virtual bool Init(C4Window *pWindow, C4AbstractApp *pApp)
virtual void OnClosed(bool fOK)
int32_t ResY
Definition: C4Config.h:103
bool InitShaders(C4GroupSet *pGroups)
Definition: C4DrawGL.cpp:715
StdStrBuf ToString(bool fHumanReadable, bool fShort) const
const char * GetGUIName(const C4PlayerControlDefs &defs) const
const char * DefaultFonts[]
#define C4GUI_DefDlgIndent
Definition: C4Gui.h:132
static C4Startup * Get()
Definition: C4Startup.h:133
bool Save()
Definition: C4Config.cpp:400
const C4KeyCode KEY_Any
bool fConfigLoaded
Definition: C4Config.h:262
const char * GetLastError()
Definition: C4App.h:98
void AddEntry(const char *szText, int32_t id)
bool GetFromRight(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1093
int32_t FESamples
Definition: C4Config.h:129
Sheet * AddSheet(const char *szTitle, int32_t icoTitle=Ico_None)
virtual void Clear(bool multisample_change=false)
size_t getLength() const
Definition: StdBuf.h:445
int32_t MusicVolume
Definition: C4Config.h:131
int GetConfigHeight()
Definition: C4Application.h:83
bool ShowModalDlg(Dialog *pDlg, bool fDestruct=true)
virtual Screen * GetScreen()
Definition: C4Gui.cpp:289
C4PlayerControlAssignmentSets UserSets
Definition: C4Config.h:231
CStdGL * pGL
Definition: C4DrawGL.cpp:905
int32_t Hgt
Definition: C4Rect.h:30
int32_t EnableUPnP
Definition: C4Config.h:154
int32_t GetHeightByWidth(int32_t iWidth)
Definition: C4Facet.h:155
C4Surface * Surface
Definition: C4Facet.h:117
bool GetFromLeft(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1076
float TargetY
Definition: C4Facet.h:165
int32_t UseAlternateServer
Definition: C4Config.h:152
C4FacetID fctOptionsTabClip
Definition: C4Startup.h:71
void SetText(const char *szToText)
Screen TheScreen
Definition: C4Gui.cpp:1054
uint32_t DWORD
C4ConfigSound Sound
Definition: C4Config.h:254
int32_t AutoFrameSkip
Definition: C4Config.h:116
C4PlayerControlAssignmentSets PlayerControlDefaultAssignmentSets
Definition: C4Game.h:93
void SetFont(CStdFont *pToFont)
Definition: C4Gui.h:1016
void Copy()
Definition: StdBuf.h:467
float Wdt
Definition: C4Facet.h:118
int32_t PortTCP
Definition: C4Config.h:153
void CopyValidated(const char *szFromVal)
C4PlayerControlAssignmentSets PlayerControlUserAssignmentSets
Definition: C4Game.h:93
C4StartupGraphics Graphics
Definition: C4Startup.h:100
C4Window * pWindow
Definition: C4App.h:80
C4Application Application
Definition: C4Globals.cpp:44
bool GetCentered(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1133
virtual bool InvalidateDeviceObjects()=0
bool GetFromBottom(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1109
int32_t GetInnerWidth() const
Definition: C4Gui.h:2805
void IntUnlock()
Definition: C4Surface.cpp:864
void RemoveAssignmentByControlName(const char *control_name)
bool IsInActiveDlg(bool fForKeyboard)
Definition: C4Gui.cpp:435
void SetText(const char *szToText, bool fAllowHotkey=true)
Definition: C4GuiLabels.cpp:74
int32_t GetActiveSheetIndex()
int32_t PortUDP
Definition: C4Config.h:153
int32_t RXMusic
Definition: C4Config.h:127
bool Play(const char *szSongname=nullptr, bool fLoop=false, int fadetime_ms=0, double max_resume_time=0.0, bool allow_break=false)
void UpdateGamepadGUIControlEnabled()
Definition: C4Gui.cpp:1049
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
void RemoveSetByName(const char *set_name)
char Info[C4MaxLanguageInfo+1]
Definition: C4Language.h:34
C4MusicSystem MusicSystem
Definition: C4Application.h:41