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