forked from Mirrors/openclonk
1490 lines
66 KiB
C++
1490 lines
66 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
// Startup screen for non-parameterized engine start: Options dialog
|
|
|
|
#include "C4Include.h"
|
|
#include "C4ForbidLibraryCompilation.h"
|
|
#include "gui/C4StartupOptionsDlg.h"
|
|
|
|
#include "game/C4Application.h"
|
|
#include "graphics/C4Draw.h"
|
|
#include "graphics/C4GraphicsResource.h"
|
|
#include "gui/C4MouseControl.h"
|
|
#include "gui/C4KeyboardInput.h"
|
|
#include "gui/C4StartupMainDlg.h"
|
|
#include "network/C4Network2.h"
|
|
#include "platform/C4GamePadCon.h"
|
|
|
|
#include "graphics/C4DrawGL.h"
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::SmallButton
|
|
|
|
void C4StartupOptionsDlg::SmallButton::DrawElement(C4TargetFacet &cgo)
|
|
{
|
|
// draw the button
|
|
CStdFont &rUseFont = C4Startup::Get()->Graphics.BookFont;
|
|
// get text pos
|
|
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;
|
|
int32_t iTextHgt = rUseFont.GetLineHeight();
|
|
// draw frame
|
|
uint32_t dwClrHigh = C4StartupBtnBorderColor1, dwClrLow = C4StartupBtnBorderColor2;
|
|
if (fDown) std::swap(dwClrHigh, dwClrLow);
|
|
int32_t iIndent = Clamp<int32_t>((rcBounds.Hgt-iTextHgt)/3, 2, 5);
|
|
float iDrawQuadTop[8] = { x0,y0, x1,y0, x1-iIndent,y0+iIndent, x0,y0+iIndent };
|
|
float iDrawQuadLeft[8] = { x0,y0, x0+iIndent,y0, x0+iIndent,y1-iIndent, x0,y1 };
|
|
float iDrawQuadRight[8] = { x1,y0, x1,y1, x1-iIndent,y1, x1-iIndent,y0+iIndent };
|
|
float iDrawQuadBottom[8] = { x1,y1, x0,y1, x0+iIndent,y1-iIndent, x1,y1-iIndent };
|
|
// TODO: Switch to PerformMultiTris
|
|
pDraw->DrawQuadDw(cgo.Surface, iDrawQuadTop, dwClrHigh,dwClrHigh,dwClrHigh,dwClrHigh, nullptr);
|
|
pDraw->DrawQuadDw(cgo.Surface, iDrawQuadLeft, dwClrHigh,dwClrHigh,dwClrHigh,dwClrHigh, nullptr);
|
|
pDraw->DrawQuadDw(cgo.Surface, iDrawQuadRight, dwClrLow,dwClrLow,dwClrLow,dwClrLow, nullptr);
|
|
pDraw->DrawQuadDw(cgo.Surface, iDrawQuadBottom, dwClrLow,dwClrLow,dwClrLow,dwClrLow, nullptr);
|
|
// draw selection highlight
|
|
int32_t iTxtOff = fDown ? iIndent : 0;
|
|
if (fEnabled) if (HasDrawFocus() || (fMouseOver && IsInActiveDlg(false)))
|
|
{
|
|
pDraw->SetBlitMode(C4GFXBLIT_ADDITIVE);
|
|
::GraphicsResource.fctButtonHighlight.DrawX(cgo.Surface, x0+5+iTxtOff, y0+3+iTxtOff, rcBounds.Wdt-10, rcBounds.Hgt-6);
|
|
pDraw->ResetBlitMode();
|
|
}
|
|
// draw button text
|
|
pDraw->TextOut(sText.getData(), rUseFont, 1.0f, cgo.Surface, (x0+x1)/2 + iTxtOff, (y0+y1-iTextHgt)/2 + iTxtOff, C4StartupBtnFontClr, ACenter, true);
|
|
}
|
|
|
|
int32_t C4StartupOptionsDlg::SmallButton::GetDefaultButtonHeight()
|
|
{
|
|
// button height is used font height plus a small indent
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
return pUseFont->GetLineHeight()*6/5+6;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::ResChangeConfirmDlg
|
|
|
|
C4StartupOptionsDlg::ResChangeConfirmDlg::ResChangeConfirmDlg()
|
|
: C4GUI::Dialog(C4GUI_MessageDlgWdt, 100 /* will be resized */, LoadResStr("IDS_MNU_SWITCHRESOLUTION"), false)
|
|
{
|
|
// update-timer
|
|
Application.Add(this);
|
|
// An independant group of fourteen highly trained apes and one blind lawnmower have determined
|
|
// that twelve seconds is just right for normal people
|
|
iResChangeSwitchTime = 12;
|
|
// However, some people need more time
|
|
// Those can be identified by their configuration settings
|
|
if (SEqualNoCase(Config.GetRegistrationData("Nick"), "flgr")) iResChangeSwitchTime *= 10;
|
|
// get positions
|
|
C4GUI::ComponentAligner caMain(GetClientRect(), C4GUI_DefDlgIndent, C4GUI_DefDlgIndent, true);
|
|
// place icon
|
|
C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt); rcIcon.Hgt = C4GUI_IconHgt;
|
|
C4GUI::Icon *pIcon = new C4GUI::Icon(rcIcon, C4GUI::Ico_Confirm); AddElement(pIcon);
|
|
// place message labels
|
|
// use text with line breaks
|
|
StdStrBuf sMsgBroken;
|
|
int iMsgHeight = ::GraphicsResource.TextFont.BreakMessage(LoadResStr("IDS_MNU_SWITCHRESOLUTION_LIKEIT"), caMain.GetInnerWidth(), &sMsgBroken, true);
|
|
C4GUI::Label *pLblMessage = new C4GUI::Label(sMsgBroken.getData(), caMain.GetFromTop(iMsgHeight), ACenter, C4GUI_MessageFontClr, &::GraphicsResource.TextFont, false);
|
|
AddElement(pLblMessage);
|
|
iMsgHeight = ::GraphicsResource.TextFont.BreakMessage(FormatString(LoadResStr("IDS_MNU_SWITCHRESOLUTION_UNDO"),
|
|
(int)iResChangeSwitchTime).getData(),
|
|
caMain.GetInnerWidth(), &sMsgBroken, true);
|
|
pOperationCancelLabel = new C4GUI::Label(sMsgBroken.getData(), caMain.GetFromTop(iMsgHeight), ACenter, C4GUI_MessageFontClr, &::GraphicsResource.TextFont, false, false);
|
|
AddElement(pOperationCancelLabel);
|
|
// place buttons
|
|
C4GUI::ComponentAligner caButtonArea(caMain.GetFromTop(C4GUI_ButtonAreaHgt), 0,0);
|
|
int32_t iButtonCount = 2;
|
|
C4Rect rcBtn = caButtonArea.GetCentered(iButtonCount*C4GUI_DefButton2Wdt+(iButtonCount-1)*C4GUI_DefButton2HSpace, C4GUI_ButtonHgt);
|
|
rcBtn.Wdt = C4GUI_DefButton2Wdt;
|
|
// Yes
|
|
C4GUI::Button *pBtnYes = new C4GUI::YesButton(rcBtn);
|
|
AddElement(pBtnYes);
|
|
rcBtn.x += C4GUI_DefButton2Wdt+C4GUI_DefButton2HSpace;
|
|
// No
|
|
C4GUI::Button *pBtnNo = new C4GUI::NoButton(rcBtn);
|
|
AddElement(pBtnNo);
|
|
// initial focus on abort button, to prevent accidental acceptance of setting by "blind" users
|
|
SetFocus(pBtnNo, false);
|
|
// resize to actually needed size
|
|
SetClientSize(GetClientRect().Wdt, GetClientRect().Hgt - caMain.GetHeight());
|
|
}
|
|
|
|
C4StartupOptionsDlg::ResChangeConfirmDlg::~ResChangeConfirmDlg()
|
|
{
|
|
Application.Remove(this);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ResChangeConfirmDlg::OnSec1Timer()
|
|
{
|
|
// timer ran out? Then cancel dlg
|
|
if (!--iResChangeSwitchTime)
|
|
{
|
|
Close(false); return;
|
|
}
|
|
// update timer label
|
|
StdStrBuf sTimerText;
|
|
::GraphicsResource.TextFont.BreakMessage(FormatString(LoadResStr("IDS_MNU_SWITCHRESOLUTION_UNDO"),
|
|
(int)iResChangeSwitchTime).getData(),
|
|
pOperationCancelLabel->GetBounds().Wdt, &sTimerText, true);
|
|
pOperationCancelLabel->SetText(sTimerText.getData());
|
|
}
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::KeySelDialog
|
|
|
|
C4StartupOptionsDlg::KeySelDialog::KeySelDialog(const C4PlayerControlAssignment *assignment, const C4PlayerControlAssignmentSet *assignment_set)
|
|
: C4GUI::MessageDialog(GetDlgMessage(assignment, assignment_set).getData(), LoadResStr("IDS_MSG_DEFINEKEY"), C4GUI::MessageDialog::btnAbort | C4GUI::MessageDialog::btnReset, GetDlgIcon(assignment_set), C4GUI::MessageDialog::dsRegular),
|
|
key(KEY_Undefined), assignment(assignment), assignment_set(assignment_set)
|
|
{
|
|
const uint32_t KEYS_Allmod = KEYS_Shift | KEYS_Control | KEYS_Alt;
|
|
C4CustomKey::CodeList keys;
|
|
static_assert(KEYS_None == 0, "");
|
|
for (uint32_t k = KEYS_None; k <= KEYS_Allmod; k++) {
|
|
if (~KEYS_Allmod & k) // There is some efficient bit-twiddling (k = KEYS_Allmod & (k - KEYS_Allmod) instead of k++), but I figure that's overkill. (Relies on (defined) unsigned overflow)
|
|
continue;
|
|
keys.emplace_back(KEY_Any, k);
|
|
}
|
|
KeyListeners = std::make_unique<C4KeyBinding>(
|
|
keys,
|
|
"DefineKey",
|
|
KEYSCOPE_Gui,
|
|
new C4GUI::DlgKeyCBPassKey<C4StartupOptionsDlg::KeySelDialog>(
|
|
*this,
|
|
&C4StartupOptionsDlg::KeySelDialog::KeyDown,
|
|
&C4StartupOptionsDlg::KeySelDialog::KeyUp
|
|
),
|
|
C4CustomKey::PRIO_PlrControl
|
|
);
|
|
}
|
|
|
|
StdStrBuf C4StartupOptionsDlg::KeySelDialog::GetDlgMessage(const C4PlayerControlAssignment *assignment, const C4PlayerControlAssignmentSet *assignment_set)
|
|
{
|
|
// compose message asking for key, gamepad button and/or mouse button depending on used control set
|
|
if (!assignment || !assignment_set) return StdStrBuf("err");
|
|
StdStrBuf result_string;
|
|
if (assignment_set->HasGamepad())
|
|
result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSBTN"), assignment->GetGUIName(Game.PlayerControlDefs)));
|
|
else
|
|
result_string.Take(FormatString(LoadResStr("IDS_MSG_PRESSKEY"), assignment->GetGUIName(Game.PlayerControlDefs)));
|
|
const char *ctrl_desc = assignment->GetGUIDesc(Game.PlayerControlDefs);
|
|
|
|
if (ctrl_desc && *ctrl_desc)
|
|
{
|
|
result_string.Append("||");
|
|
result_string.Append(ctrl_desc);
|
|
}
|
|
return result_string;
|
|
}
|
|
|
|
C4GUI::Icons C4StartupOptionsDlg::KeySelDialog::GetDlgIcon(const C4PlayerControlAssignmentSet *assignment_set)
|
|
{
|
|
if (!assignment_set) return C4GUI::Ico_Error;
|
|
if (assignment_set->HasGamepad()) return C4GUI::Ico_Gamepad;
|
|
return C4GUI::Ico_Keyboard;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::KeySelDialog::MouseInput(C4GUI::CMouse& rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
|
|
{
|
|
// Original action
|
|
C4GUI::MessageDialog::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
|
|
|
|
// Find out to where the input was made (code duplication with C4GUI::Window::MouseInput)
|
|
// get client pos
|
|
C4Rect &rcClientRect = GetClientRect(), &rcBounds = GetBounds();
|
|
iX -= rcClientRect.x - rcBounds.x; iY -= rcClientRect.y - rcBounds.y;
|
|
// forward to topmost child element
|
|
for (Element *pChild = pLast; pChild; pChild = pChild->GetPrev())
|
|
if (pChild->fVisible && pChild->GetBounds().Contains(iX, iY))
|
|
{
|
|
if (dynamic_cast<C4GUI::Label*>(pChild))
|
|
break;
|
|
else
|
|
return;
|
|
}
|
|
// Only process the input event if the user certainly didn't click a button or anything...
|
|
|
|
if (iButton == C4MC_Button_None) // mouse got moved
|
|
return;
|
|
bool down;
|
|
auto key = C4KeyCodeEx::FromC4MC(0 /* FIXME: more mice! */, iButton, dwKeyParam, &down);
|
|
KeyPress(key, down);
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::KeySelDialog::KeyPress(const C4KeyCodeEx &key, bool fDown)
|
|
{
|
|
// safety
|
|
if (!assignment || !assignment_set) return false;
|
|
// check if key is valid for this set
|
|
if (Key_IsGamepad(key.Key))
|
|
{
|
|
if (!assignment_set->HasGamepad()) return false;
|
|
}
|
|
else if (Key_IsMouse(key.Key))
|
|
{
|
|
if (!assignment_set->HasMouse()) return false;
|
|
}
|
|
else
|
|
{
|
|
if (!assignment_set->HasKeyboard()) return false;
|
|
}
|
|
// FIXME: There doesn't seem to be any kind of KEY_IsModifier function…
|
|
if ((KEY_IsModifier(key.Key) && fDown) ||
|
|
(!KEY_IsModifier(key.Key) && !fDown))
|
|
return false;
|
|
// okay, use it
|
|
this->key=key;
|
|
Close(true);
|
|
return true;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel
|
|
|
|
C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::ControlAssignmentLabel(class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set, const C4Rect &bounds)
|
|
: C4GUI::Label("", bounds, ALeft, 0xffffffff, nullptr, false, false, true), assignment(assignment), assignment_set(assignment_set)
|
|
{
|
|
UpdateAssignmentString();
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
|
|
{
|
|
// left-click to change key
|
|
if (iButton == C4MC_Button_LeftDown && assignment)
|
|
{
|
|
if(!assignment->IsGUIDisabled())
|
|
{
|
|
KeySelDialog *dlg = new KeySelDialog(assignment, assignment_set);
|
|
dlg->SetDelOnClose(false);
|
|
bool success = GetScreen()->ShowModalDlg(dlg, false);
|
|
C4KeyCodeEx key = dlg->GetKeyCode();
|
|
delete dlg;
|
|
if (success)
|
|
{
|
|
// dialog closed by pressing a key or by the Reset button (in which case, key==KEY_Undefined)
|
|
// assign new config
|
|
C4StartupOptionsDlg::ControlConfigListBox::SetUserKey(assignment_set, assignment, key);
|
|
UpdateAssignmentString();
|
|
}
|
|
}
|
|
}
|
|
// inherited
|
|
Element::MouseInput(rMouse, iButton, iX, iY, dwKeyParam);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigListBox::ControlAssignmentLabel::UpdateAssignmentString()
|
|
{
|
|
// assignment label text from assigned key
|
|
StdStrBuf strKey;
|
|
C4KeyCodeEx key(0);
|
|
if (assignment)
|
|
{
|
|
SetText(assignment->GetKeysAsString(true, false).getData());
|
|
}
|
|
else
|
|
{
|
|
SetText("");
|
|
}
|
|
DWORD color = C4GUI_CaptionFontClr;
|
|
if (assignment)
|
|
{
|
|
if(assignment->IsGUIDisabled())
|
|
color = C4GUI_InactCaptionFontClr;
|
|
else if(assignment->IsKeyChanged())
|
|
color = C4GUI_Caption2FontClr;
|
|
}
|
|
SetColor(color);
|
|
}
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::ControlConfigListBox::ListItem
|
|
|
|
C4StartupOptionsDlg::ControlConfigListBox::ListItem::ListItem(ControlConfigListBox *parent_list, class C4PlayerControlAssignment *assignment, class C4PlayerControlAssignmentSet *assignment_set, bool has_extra_spacing)
|
|
: C4GUI::Window(), parent_list(parent_list), assignment_label(nullptr), has_extra_spacing(has_extra_spacing)
|
|
{
|
|
int32_t margin = 2;
|
|
// adding to listbox will size the element horizontally and move to proper position
|
|
int32_t height = ::GraphicsResource.TextFont.GetLineHeight() + 2 * margin;
|
|
SetBounds(C4Rect(0,0,42,height));
|
|
parent_list->InsertElement(this, nullptr);
|
|
int32_t name_col_width = GetBounds().Wdt * 2/3;
|
|
// child elements: two labels for two columns
|
|
const char *gui_name = assignment->GetGUIName(Game.PlayerControlDefs);
|
|
const char *gui_desc = assignment->GetGUIDesc(Game.PlayerControlDefs);
|
|
C4GUI::Label *name_label = new C4GUI::Label(gui_name ? gui_name : "?undefined?", margin, margin);
|
|
C4Rect assignment_label_bounds = C4Rect(name_col_width + margin, margin, GetBounds().Wdt - name_col_width - margin, GetBounds().Hgt - 2 * margin);
|
|
assignment_label = new ControlAssignmentLabel(assignment, assignment_set, assignment_label_bounds);
|
|
AddElement(name_label);
|
|
AddElement(assignment_label);
|
|
if (gui_desc && *gui_desc) SetToolTip(gui_desc);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::ControlConfigListBox
|
|
|
|
C4StartupOptionsDlg::ControlConfigListBox::ControlConfigListBox(const C4Rect &rcBounds, class C4PlayerControlAssignmentSet *set)
|
|
: C4GUI::ListBox(rcBounds), set(nullptr)
|
|
{
|
|
SetAssignmentSet(set);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigListBox::SetAssignmentSet(class C4PlayerControlAssignmentSet *new_set)
|
|
{
|
|
set = new_set;
|
|
// clear previous elements
|
|
if (pClientWindow) pClientWindow->ClearChildren();
|
|
// populate with new assignments
|
|
if (set)
|
|
{
|
|
C4PlayerControlAssignment *assignment;
|
|
|
|
std::vector<C4PlayerControlAssignment *> grouped_assignments;
|
|
for (int32_t i=0; (assignment = set->GetAssignmentByIndex(i)); ++i)
|
|
grouped_assignments.push_back(assignment);
|
|
|
|
std::stable_sort(grouped_assignments.begin(),grouped_assignments.end(),&C4StartupOptionsDlg::ControlConfigListBox::sort_by_group);
|
|
|
|
int32_t current_group = 0;
|
|
for (auto & grouped_assignment : grouped_assignments)
|
|
{
|
|
assignment = grouped_assignment;
|
|
bool first_element_of_group = assignment->GetGUIGroup() > current_group;
|
|
current_group = assignment->GetGUIGroup();
|
|
// only show assignments of GUI-named controls
|
|
const char *gui_name = assignment->GetGUIName(Game.PlayerControlDefs);
|
|
if (gui_name && *gui_name)
|
|
{
|
|
ListItem *element = new ListItem(this, assignment, set, first_element_of_group);
|
|
AddElement(element);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigListBox::SetUserKey(class C4PlayerControlAssignmentSet *assignment_set, class C4PlayerControlAssignment *assignment, C4KeyCodeEx &key)
|
|
{
|
|
// change key in the specified assignment set to the specified value
|
|
// also changes config values so change is kept after restart
|
|
// safety
|
|
if (!assignment || !assignment_set) return;
|
|
class C4PlayerControlAssignmentSet *config_set = Config.Controls.UserSets.GetSetByName(assignment_set->GetName());
|
|
// change key
|
|
if (key.Key == KEY_Undefined)
|
|
{
|
|
// reset to default
|
|
assignment->ResetKeyToInherited();
|
|
// also reset in config
|
|
if (config_set)
|
|
{
|
|
config_set->RemoveAssignmentByControlName(assignment->GetControlName());
|
|
if (!config_set->GetAssignmentByIndex(0))
|
|
{
|
|
// if config set is empty, no overrides exist and the set can be deleted (unless it's a custom config set)
|
|
if (Game.PlayerControlDefaultAssignmentSets.GetSetByName(config_set->GetName()))
|
|
{
|
|
Config.Controls.UserSets.RemoveSetByName(assignment_set->GetName());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// set to specified value
|
|
assignment->SetKey(key);
|
|
// also set in config
|
|
if (!config_set) config_set = Config.Controls.UserSets.CreateEmptySetByTemplate(*assignment_set);
|
|
C4PlayerControlAssignment *config_assignment = config_set->GetAssignmentByControlName(assignment->GetControlName());
|
|
if (!config_assignment) config_assignment = config_set->CreateAssignmentForControl(assignment->GetControlName());
|
|
config_assignment->SetKey(key);
|
|
// check for duplicates. Allow them in principle because they can be used with priorities
|
|
// however, do warn because usually it may be unintended
|
|
// Just deleting the old assignments is also usually undesirable, because half of the time a newbi changes a control and creates a conflict,
|
|
// they may want to change the key they just assigned to something else instead
|
|
C4PlayerControlAssignment *other_assignment;
|
|
for (int32_t i = 0; (other_assignment = assignment_set->GetAssignmentByIndex(i)); ++i)
|
|
if (other_assignment != assignment)
|
|
if (other_assignment->GetTriggerKey() == key)
|
|
{
|
|
const char *gui_name = other_assignment->GetGUIName(Game.PlayerControlDefs);
|
|
// only warn for assignable keys, because other keys are typically derived from the settable keys
|
|
if (gui_name && *gui_name)
|
|
{
|
|
C4GUI::TheScreen.ShowMessage(FormatString(LoadResStr("IDS_MSG_DEFINEKEYDUPLICATE"), key.ToString(true, false).getData(), gui_name).getData(), LoadResStr("IDS_MSG_DEFINEKEY"), C4GUI::Ico_Error);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::ControlConfigArea
|
|
|
|
C4StartupOptionsDlg::ControlConfigArea::ControlConfigArea(const C4Rect &rcArea, int32_t iHMargin, int32_t iVMargin, bool fGamepad, C4StartupOptionsDlg *pOptionsDlg)
|
|
: C4GUI::Window(), fGamepad(fGamepad), pOptionsDlg(pOptionsDlg), pGUICtrl(nullptr)
|
|
{
|
|
CStdFont *pUseFontSmall = &(C4Startup::Get()->Graphics.BookSmallFont);
|
|
SetBounds(rcArea);
|
|
C4GUI::ComponentAligner caArea(rcArea, iHMargin, iVMargin, true);
|
|
// get number of control sets to be configured
|
|
C4PlayerControlAssignmentSets &assignment_sets = Game.PlayerControlUserAssignmentSets;
|
|
iMaxControlSets = std::max<size_t>(assignment_sets.GetSetCount(),1u); // do not devide by zero
|
|
ppKeyControlSetBtns = new C4GUI::IconButton *[iMaxControlSets];
|
|
// top line buttons to select control configuration
|
|
C4Facet fctCtrlDefPic = ::GraphicsResource.fctKeyboard; //
|
|
int32_t iCtrlSetWdt = caArea.GetWidth() - caArea.GetHMargin()*2;
|
|
int32_t iCtrlSetHMargin = 5, iCtrlSetVMargin = 5;
|
|
int32_t iCtrlSetBtnWdt = Clamp<int32_t>((iCtrlSetWdt - iMaxControlSets*iCtrlSetHMargin*2) / iMaxControlSets, 5, fctCtrlDefPic.Wdt);
|
|
int32_t iCtrlSetBtnHgt = fctCtrlDefPic.GetHeightByWidth(iCtrlSetBtnWdt);
|
|
iCtrlSetHMargin = (iCtrlSetWdt - iCtrlSetBtnWdt*iMaxControlSets) / (iMaxControlSets*2);
|
|
C4GUI::ComponentAligner caKeyboardSetSel(caArea.GetFromTop(2*iCtrlSetVMargin+iCtrlSetBtnHgt), iCtrlSetHMargin, iCtrlSetVMargin);
|
|
const char *szCtrlSetHotkeys = "1234567890"; /* 2do */
|
|
uint32_t i;
|
|
for (i = 0; i < assignment_sets.GetSetCount(); ++i)
|
|
{
|
|
C4PlayerControlAssignmentSet *assignment_set = assignment_sets.GetSetByIndex(i);
|
|
char cCtrlSetHotkey = 0;
|
|
if (i <= strlen(szCtrlSetHotkeys)) cCtrlSetHotkey = szCtrlSetHotkeys[i];
|
|
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);
|
|
C4Facet fctCtrlPic = assignment_set->GetPicture();
|
|
pBtn->SetFacet(fctCtrlPic);
|
|
AddElement(ppKeyControlSetBtns[i] = pBtn);
|
|
pBtn->SetText(assignment_set->GetGUIName());
|
|
pBtn->SetFont(pUseFontSmall, C4StartupFontClr);
|
|
pBtn->SetToolTip(LoadResStr("IDS_DLGTIP_CHANGECTRL"));
|
|
}
|
|
iSelectedCtrlSet = 0;
|
|
caArea.ExpandTop(caArea.GetVMargin());
|
|
AddElement(new C4GUI::HorizontalLine(caArea.GetFromTop(2)));
|
|
caArea.ExpandTop(caArea.GetVMargin());
|
|
control_list = new ControlConfigListBox(caArea.GetFromLeft(caArea.GetInnerWidth()), nullptr);
|
|
AddElement(control_list);
|
|
|
|
UpdateCtrlSet();
|
|
}
|
|
|
|
C4StartupOptionsDlg::ControlConfigArea::~ControlConfigArea()
|
|
{
|
|
delete [] ppKeyControlSetBtns;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigArea::OnCtrlSetBtn(C4GUI::Control *btn)
|
|
{
|
|
// select Ctrl set of pressed btn
|
|
int i;
|
|
for (i = 0; i < iMaxControlSets; ++i)
|
|
if (btn == ppKeyControlSetBtns[i])
|
|
{
|
|
iSelectedCtrlSet = i;
|
|
break;
|
|
}
|
|
// update shown keys
|
|
UpdateCtrlSet();
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigArea::UpdateCtrlSet()
|
|
{
|
|
// selected keyboard set btn gets a highlight
|
|
int i;
|
|
for (i = 0; i < iMaxControlSets; ++i)
|
|
ppKeyControlSetBtns[i]->SetHighlight(i == iSelectedCtrlSet);
|
|
// update list
|
|
control_list->SetAssignmentSet(Game.PlayerControlUserAssignmentSets.GetSetByIndex(iSelectedCtrlSet));
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigArea::OnResetKeysBtn(C4GUI::Control *btn)
|
|
{
|
|
// default keys and axis reset
|
|
Config.Controls.ResetKeys();
|
|
UpdateCtrlSet();
|
|
}
|
|
|
|
void C4StartupOptionsDlg::ControlConfigArea::OnGUIGamepadCheckChange(C4GUI::Element *pCheckBox)
|
|
{
|
|
// same as before?
|
|
bool fChecked = ((C4GUI::CheckBox *)(pCheckBox))->GetChecked();
|
|
if (fChecked == !!Config.Controls.GamepadGuiControl) return;
|
|
// reflect change
|
|
Config.Controls.GamepadGuiControl = fChecked;
|
|
::pGUI->UpdateGamepadGUIControlEnabled();
|
|
pOptionsDlg->RecreateDialog(false);
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::NetworkPortConfig
|
|
|
|
C4StartupOptionsDlg::NetworkPortConfig::NetworkPortConfig(const C4Rect &rcBounds, const char *szName, int32_t *pConfigValue, int32_t iDefault)
|
|
: C4GUI::Window(), pConfigValue(pConfigValue)
|
|
{
|
|
// ctor
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
SetBounds(rcBounds);
|
|
C4GUI::ComponentAligner caMain(GetClientRect(), 0,2, true);
|
|
bool fEnabled = (*pConfigValue != -1);
|
|
C4GUI::Label *pLbl = new C4GUI::Label(szName, caMain.GetFromTop(pUseFont->GetLineHeight()), ALeft, C4StartupFontClr, pUseFont, false);
|
|
AddElement(pLbl);
|
|
C4GUI::ComponentAligner caBottomLine(caMain.GetAll(), 2,0, false);
|
|
const char *szText = LoadResStr("IDS_CTL_ACTIVE");
|
|
int iWdt=100, iHgt=12;
|
|
C4GUI::CheckBox::GetStandardCheckBoxSize(&iWdt, &iHgt, szText, pUseFont);
|
|
pEnableCheck = new C4GUI::CheckBox(caBottomLine.GetFromLeft(iWdt, iHgt), szText, fEnabled);
|
|
pEnableCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pEnableCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg::NetworkPortConfig>(this, &C4StartupOptionsDlg::NetworkPortConfig::OnEnabledCheckChange));
|
|
AddElement(pEnableCheck);
|
|
pPortEdit = new C4GUI::Edit(caBottomLine.GetAll(), true);
|
|
pPortEdit->SetColors(C4StartupEditBGColor, C4StartupFontClr, C4StartupEditBorderColor);
|
|
pPortEdit->SetFont(pUseFont);
|
|
pPortEdit->InsertText(FormatString("%d", fEnabled ? ((int) *pConfigValue) : (int) iDefault).getData(), false);
|
|
pPortEdit->SetMaxText(10); // 65535 is five characters long - but allow some more for easier editing
|
|
pPortEdit->SetVisibility(fEnabled);
|
|
AddElement(pPortEdit);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::NetworkPortConfig::OnEnabledCheckChange(C4GUI::Element *pCheckBox)
|
|
{
|
|
pPortEdit->SetVisibility(pEnableCheck->GetChecked());
|
|
}
|
|
|
|
void C4StartupOptionsDlg::NetworkPortConfig::SavePort()
|
|
{
|
|
*pConfigValue=GetPort();
|
|
}
|
|
|
|
int32_t C4StartupOptionsDlg::NetworkPortConfig::GetPort()
|
|
{
|
|
// controls to config
|
|
if (!pEnableCheck->GetChecked())
|
|
return -1;
|
|
else
|
|
return atoi(pPortEdit->GetText());
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::NetworkPortConfig::GetControlSize(int *piWdt, int *piHgt)
|
|
{
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
// get size needed for control
|
|
if (piWdt)
|
|
{
|
|
const char *szText = LoadResStr("IDS_CTL_ACTIVE");
|
|
if (!C4GUI::CheckBox::GetStandardCheckBoxSize(piWdt, piHgt, szText, pUseFont)) return false;
|
|
*piWdt *= 2;
|
|
}
|
|
if (piHgt) *piHgt = C4GUI::Edit::GetCustomEditHeight(pUseFont) + pUseFont->GetLineHeight()+2*4;
|
|
return true;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::NetworkServerAddressConfig
|
|
|
|
C4StartupOptionsDlg::NetworkServerAddressConfig::NetworkServerAddressConfig(const C4Rect &rcBounds, const char *szName, int32_t *piConfigEnableValue, char *szConfigAddressValue, int iTabWidth)
|
|
: C4GUI::Window(), piConfigEnableValue(piConfigEnableValue), szConfigAddressValue(szConfigAddressValue)
|
|
{
|
|
// ctor
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
SetBounds(rcBounds);
|
|
C4GUI::ComponentAligner caMain(GetClientRect(), 0,2, true);
|
|
pEnableCheck = new C4GUI::CheckBox(caMain.GetFromLeft(iTabWidth, pUseFont->GetLineHeight()), szName, !!*piConfigEnableValue);
|
|
pEnableCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pEnableCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg::NetworkServerAddressConfig>(this, &C4StartupOptionsDlg::NetworkServerAddressConfig::OnEnabledCheckChange));
|
|
AddElement(pEnableCheck);
|
|
caMain.ExpandLeft(-2);
|
|
pAddressEdit = new C4GUI::Edit(caMain.GetAll(), true);
|
|
pAddressEdit->SetColors(C4StartupEditBGColor, C4StartupFontClr, C4StartupEditBorderColor);
|
|
pAddressEdit->SetFont(pUseFont);
|
|
pAddressEdit->InsertText(szConfigAddressValue, false);
|
|
pAddressEdit->SetMaxText(CFG_MaxString);
|
|
pAddressEdit->SetVisibility(!!*piConfigEnableValue);
|
|
AddElement(pAddressEdit);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::NetworkServerAddressConfig::OnEnabledCheckChange(C4GUI::Element *pCheckBox)
|
|
{
|
|
// warn about using alternate servers
|
|
if (pEnableCheck->GetChecked())
|
|
{
|
|
GetScreen()->ShowMessage(LoadResStr("IDS_NET_NOOFFICIALLEAGUE"), LoadResStr("IDS_NET_QUERY_MASTERSRV"), C4GUI::Ico_Notify, &Config.Startup.HideMsgNoOfficialLeague);
|
|
}
|
|
// callback when checkbox is ticked
|
|
pAddressEdit->SetVisibility(pEnableCheck->GetChecked());
|
|
}
|
|
|
|
void C4StartupOptionsDlg::NetworkServerAddressConfig::Save2Config()
|
|
{
|
|
// controls to config
|
|
*piConfigEnableValue = pEnableCheck->GetChecked();
|
|
SCopy(pAddressEdit->GetText(), szConfigAddressValue, CFG_MaxString);
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::NetworkServerAddressConfig::GetControlSize(int *piWdt, int *piHgt, int *piTabPos, const char *szForText)
|
|
{
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
int iWdt=120;
|
|
C4GUI::CheckBox::GetStandardCheckBoxSize(&iWdt, piHgt, szForText, pUseFont);
|
|
int32_t iEdtWdt=120, iEdtHgt=24;
|
|
pUseFont->GetTextExtent("sorgentelefon@treffpunktclonk.net", iEdtWdt, iEdtHgt, false);
|
|
if (piWdt) *piWdt = iWdt+iEdtWdt+2;
|
|
if (piTabPos) *piTabPos = iWdt+2;
|
|
if (piHgt) *piHgt = C4GUI::Edit::GetCustomEditHeight(pUseFont)+2*2;
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::BoolConfig
|
|
|
|
C4StartupOptionsDlg::BoolConfig::BoolConfig(const C4Rect &rcBounds, const char *szName, bool *pbVal, int32_t *piVal, bool fInvert, int32_t *piRestartChangeCfgVal)
|
|
: C4GUI::CheckBox(rcBounds, szName, fInvert != (pbVal ? *pbVal : !!*piVal)), pbVal(pbVal), fInvert(fInvert), piVal(piVal), piRestartChangeCfgVal(piRestartChangeCfgVal)
|
|
{
|
|
SetOnChecked(new C4GUI::CallbackHandler<BoolConfig>(this, &BoolConfig::OnCheckChange));
|
|
}
|
|
|
|
void C4StartupOptionsDlg::BoolConfig::OnCheckChange(C4GUI::Element *pCheckBox)
|
|
{
|
|
if (pbVal) *pbVal = (GetChecked() != fInvert);
|
|
if (piVal) *piVal = (GetChecked() != fInvert);
|
|
if (piRestartChangeCfgVal) GetScreen()->ShowMessage(LoadResStr("IDS_MSG_RESTARTCHANGECFG"), GetText(),
|
|
C4GUI::Ico_Notify, piRestartChangeCfgVal);
|
|
}
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg::EditConfig
|
|
|
|
C4StartupOptionsDlg::EditConfig::EditConfig(const C4Rect &rcBounds, const char *szName, ValidatedStdCopyStrBufBase *psConfigVal, int32_t *piConfigVal, bool fMultiline)
|
|
: C4GUI::LabeledEdit(rcBounds, szName, fMultiline, psConfigVal ? psConfigVal->getData() : nullptr, &(C4Startup::Get()->Graphics.BookFont), C4StartupFontClr), psConfigVal(psConfigVal), piConfigVal(piConfigVal)
|
|
{
|
|
// ctor
|
|
GetEdit()->SetColors(C4StartupEditBGColor, C4StartupFontClr, C4StartupEditBorderColor);
|
|
if (piConfigVal) SetIntVal(*piConfigVal);
|
|
GetEdit()->SetMaxText(CFG_MaxString);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::EditConfig::Save2Config()
|
|
{
|
|
// controls to config
|
|
if (psConfigVal)
|
|
psConfigVal->CopyValidated(GetEdit()->GetText());
|
|
if (piConfigVal)
|
|
*piConfigVal = GetIntVal();
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::EditConfig::GetControlSize(int *piWdt, int *piHgt, const char *szForText, bool fMultiline)
|
|
{
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
typedef C4GUI::LabeledEdit BaseEdit;
|
|
return BaseEdit::GetControlSize(piWdt, piHgt, szForText, pUseFont, fMultiline);
|
|
}
|
|
|
|
// ------------------------------------------------
|
|
// --- C4StartupOptionsDlg
|
|
|
|
C4StartupOptionsDlg::C4StartupOptionsDlg() : C4StartupDlg(LoadResStrNoAmp("IDS_DLG_OPTIONS"))
|
|
{
|
|
// ctor
|
|
UpdateSize();
|
|
bool fSmall = (GetClientRect().Wdt < 750);
|
|
CStdFont *pUseFont = &(C4Startup::Get()->Graphics.BookFont);
|
|
|
|
// key bindings
|
|
C4CustomKey::CodeList keys;
|
|
keys.emplace_back(K_BACK); keys.emplace_back(K_LEFT);
|
|
pKeyBack = new C4KeyBinding(keys, "StartupOptionsBack", KEYSCOPE_Gui,
|
|
new C4GUI::DlgKeyCB<C4StartupOptionsDlg>(*this, &C4StartupOptionsDlg::KeyBack), C4CustomKey::PRIO_Dlg);
|
|
keys.clear();
|
|
keys.emplace_back(K_F3); // overloading global toggle with higher priority here, so a new name is required
|
|
pKeyToggleMusic = new C4KeyBinding(keys, "OptionsMusicToggle", KEYSCOPE_Gui,
|
|
new C4GUI::DlgKeyCB<C4StartupOptionsDlg>(*this, &C4StartupOptionsDlg::KeyMusicToggle), C4CustomKey::PRIO_Dlg);
|
|
|
|
// screen calculations
|
|
int32_t iButtonWidth,iCaptionFontHgt;
|
|
int32_t iButtonHeight = C4GUI_ButtonHgt;
|
|
::GraphicsResource.CaptionFont.GetTextExtent("<< BACK", iButtonWidth, iCaptionFontHgt, true);
|
|
iButtonWidth *= 3;
|
|
int iIndentX1, iIndentY1, iIndentY2;
|
|
if (fSmall)
|
|
{
|
|
iIndentX1=20;
|
|
}
|
|
else
|
|
{
|
|
iIndentX1 = GetClientRect().Wdt/40;
|
|
}
|
|
if (fSmall)
|
|
{
|
|
iIndentY1=1; iIndentY2=1;
|
|
}
|
|
else
|
|
{
|
|
iIndentY1 = GetClientRect().Hgt/200;
|
|
iIndentY2 = std::max<int32_t>(1, iIndentY1/2);
|
|
}
|
|
C4GUI::ComponentAligner caMain(GetClientRect(), 0,0, true);
|
|
C4GUI::ComponentAligner caButtonArea(caMain.GetFromBottom(caMain.GetHeight()/(fSmall ? 20 : 7)),0,0);
|
|
C4GUI::ComponentAligner caButtons(caButtonArea.GetCentered(caMain.GetWidth()*7/8, iButtonHeight),0,0);
|
|
C4GUI::ComponentAligner caConfigArea(caMain.GetAll(), fSmall ? 0 : (caMain.GetWidth()*69/1730), fSmall ? 0 : (caMain.GetHeight()/200));
|
|
|
|
// back button
|
|
C4GUI::CallbackButton<C4StartupOptionsDlg> *btn;
|
|
AddElement(btn = new C4GUI::CallbackButton<C4StartupOptionsDlg>(LoadResStr("IDS_BTN_BACK"), caButtons.GetFromLeft(iButtonWidth), &C4StartupOptionsDlg::OnBackBtn));
|
|
btn->SetToolTip(LoadResStr("IDS_DLGTIP_BACKMAIN"));
|
|
|
|
// main config area tabular
|
|
pOptionsTabular = new C4GUI::Tabular(caConfigArea.GetAll(), C4GUI::Tabular::tbLeft);
|
|
pOptionsTabular->SetGfx(&C4Startup::Get()->Graphics.fctDlgPaper, &C4Startup::Get()->Graphics.fctOptionsTabClip, &C4Startup::Get()->Graphics.fctOptionsIcons, &C4Startup::Get()->Graphics.BookSmallFont, true);
|
|
AddElement(pOptionsTabular);
|
|
C4GUI::Tabular::Sheet *pSheetGeneral = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_PROGRAM") , 0);
|
|
C4GUI::Tabular::Sheet *pSheetGraphics = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_GRAPHICS"), 1);
|
|
C4GUI::Tabular::Sheet *pSheetSound = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_SOUND") , 2);
|
|
C4GUI::Tabular::Sheet *pSheetControls= pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_CONTROLS"), 3);
|
|
C4GUI::Tabular::Sheet *pSheetNetwork = pOptionsTabular->AddSheet(LoadResStr("IDS_DLG_NETWORK") , 5);
|
|
|
|
C4GUI::CheckBox *pCheck; C4GUI::Label *pLbl;
|
|
int iCheckWdt=100, iCheckHgt=20, iEdit2Wdt=100, iEdit2Hgt=40;
|
|
BoolConfig::GetStandardCheckBoxSize(&iCheckWdt, &iCheckHgt, "Default text", pUseFont);
|
|
EditConfig::GetControlSize(&iEdit2Wdt, &iEdit2Hgt, "Default text", false);
|
|
|
|
// --- page program
|
|
C4GUI::ComponentAligner caSheetProgram(pSheetGeneral->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/20, true);
|
|
// language
|
|
const char *szLangTip = LoadResStr("IDS_MSG_SELECTLANG");
|
|
C4GUI::ComponentAligner caLanguage(caSheetProgram.GetGridCell(0,1,0,7,-1,-1,true,1,2), 0, C4GUI_DefDlgSmallIndent, false);
|
|
C4GUI::ComponentAligner caLanguageBox(caLanguage.GetFromTop(C4GUI::ComboBox::GetDefaultHeight()), 0, 0, false);
|
|
StdStrBuf sLangStr; sLangStr.Copy(LoadResStr("IDS_CTL_LANGUAGE")); sLangStr.AppendChar(':');
|
|
int32_t w,q;
|
|
pUseFont->GetTextExtent(sLangStr.getData(), w,q,true);
|
|
pLbl = new C4GUI::Label(sLangStr.getData(), caLanguageBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent), ALeft, C4StartupFontClr, pUseFont, false);
|
|
pLbl->SetToolTip(szLangTip);
|
|
pSheetGeneral->AddElement(pLbl);
|
|
pUseFont->GetTextExtent("XX: Top Secret Language", w,q,true);
|
|
pLangCombo = new C4GUI::ComboBox(caLanguageBox.GetFromLeft(std::min(w, caLanguageBox.GetWidth())));
|
|
pLangCombo->SetToolTip(szLangTip);
|
|
pLangCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnLangComboFill, &C4StartupOptionsDlg::OnLangComboSelChange));
|
|
pLangCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
|
|
pLangCombo->SetFont(pUseFont);
|
|
pLangCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
|
|
pSheetGeneral->AddElement(pLangCombo);
|
|
pLangInfoLabel = new C4GUI::Label(nullptr, caLanguage.GetFromTop(::GraphicsResource.TextFont.GetLineHeight()*3), ALeft, C4StartupFontClr, pUseFont, false);
|
|
pLangInfoLabel->SetToolTip(szLangTip);
|
|
pSheetGeneral->AddElement(pLangInfoLabel);
|
|
UpdateLanguage();
|
|
// font
|
|
const char *szFontTip = LoadResStr("IDS_DESC_SELECTFONT");
|
|
C4GUI::ComponentAligner caFontBox(caSheetProgram.GetGridCell(0,1,2,7,-1,C4GUI::ComboBox::GetDefaultHeight(), true), 0, 0, false);
|
|
StdStrBuf sFontStr; sFontStr.Copy(LoadResStr("IDS_CTL_FONT")); sFontStr.AppendChar(':');
|
|
pUseFont->GetTextExtent(sFontStr.getData(), w,q,true);
|
|
pLbl = new C4GUI::Label(sFontStr.getData(), caFontBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent), ALeft, C4StartupFontClr, pUseFont, false);
|
|
pLbl->SetToolTip(szFontTip);
|
|
pSheetGeneral->AddElement(pLbl);
|
|
pUseFont->GetTextExtent("Comic Sans MS", w,q,true);
|
|
pFontFaceCombo = new C4GUI::ComboBox(caFontBox.GetFromLeft(std::min<int32_t>(caFontBox.GetInnerWidth()*3/4, w*3)));
|
|
pFontFaceCombo->SetToolTip(szFontTip);
|
|
pFontFaceCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnFontFaceComboFill, &C4StartupOptionsDlg::OnFontComboSelChange));
|
|
pFontFaceCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
|
|
pFontFaceCombo->SetFont(pUseFont);
|
|
pFontFaceCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
|
|
caFontBox.ExpandLeft(-C4GUI_DefDlgSmallIndent);
|
|
pSheetGeneral->AddElement(pFontFaceCombo);
|
|
pFontSizeCombo = new C4GUI::ComboBox(caFontBox.GetFromLeft(std::min<int32_t>(caFontBox.GetInnerWidth(), w)));
|
|
pFontSizeCombo->SetToolTip(LoadResStr("IDS_DESC_FONTSIZE"));
|
|
pFontSizeCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnFontSizeComboFill, &C4StartupOptionsDlg::OnFontComboSelChange));
|
|
pFontSizeCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
|
|
pFontSizeCombo->SetFont(pUseFont);
|
|
pFontSizeCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
|
|
pSheetGeneral->AddElement(pFontSizeCombo);
|
|
UpdateFontControls();
|
|
// MM timer
|
|
pCheck = new BoolConfig(caSheetProgram.GetGridCell(0,1,3,7,-1,iCheckHgt, true), LoadResStr("IDS_CTL_MMTIMER"), nullptr, &Config.General.MMTimer, true, &Config.Startup.HideMsgMMTimerChange);
|
|
pCheck->SetToolTip(LoadResStr("IDS_MSG_MMTIMER_DESC"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pSheetGeneral->AddElement(pCheck);
|
|
// reset configuration
|
|
const char *szBtnText = LoadResStr("IDS_BTN_RESETCONFIG");
|
|
C4GUI::CallbackButton<C4StartupOptionsDlg, SmallButton> *pSmallBtn;
|
|
::GraphicsResource.CaptionFont.GetTextExtent(szBtnText, iButtonWidth, iButtonHeight, true);
|
|
C4Rect rcResetBtn = caSheetProgram.GetGridCell(1,2,6,7, std::min<int32_t>(iButtonWidth+iButtonHeight*4, caSheetProgram.GetInnerWidth()*2/5), SmallButton::GetDefaultButtonHeight(), true);
|
|
pSmallBtn = new C4GUI::CallbackButton<C4StartupOptionsDlg, SmallButton>(szBtnText, rcResetBtn, &C4StartupOptionsDlg::OnResetConfigBtn, this);
|
|
pSheetGeneral->AddElement(pSmallBtn);
|
|
pSmallBtn->SetToolTip(LoadResStr("IDS_DESC_RESETCONFIG"));
|
|
|
|
// --- page graphics
|
|
C4GUI::ComponentAligner caSheetGraphics(pSheetGraphics->GetClientRect(), iIndentX1, iIndentY1, true);
|
|
// --subgroup display
|
|
C4GUI::GroupBox *pGroupResolution = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,1,0,2));
|
|
pGroupResolution->SetTitle(LoadResStrNoAmp("IDS_CTL_DISPLAY"));
|
|
pGroupResolution->SetFont(pUseFont);
|
|
pGroupResolution->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
|
|
pSheetGraphics->AddElement(pGroupResolution);
|
|
C4GUI::ComponentAligner caGroupResolution(pGroupResolution->GetClientRect(), iIndentX1, iIndentY2, true);
|
|
int32_t iNumGfxOptions = 3, iOpt = 0;
|
|
// resolution combobox
|
|
C4GUI::ComponentAligner resBox(caGroupResolution.GetGridCell(0,1,iOpt++,iNumGfxOptions), 0, 0, false);
|
|
w=20; q=12; pUseFont->GetTextExtent(LoadResStr("IDS_CTL_RESOLUTION"), w,q, true);
|
|
pGroupResolution->AddElement(new C4GUI::Label(LoadResStr("IDS_CTL_RESOLUTION"), resBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent,q), ALeft, C4StartupFontClr, pUseFont, false, false));
|
|
pUseFont->GetTextExtent("1600 x 1200", w,q,true); w = std::min<int32_t>(caGroupResolution.GetInnerWidth(), w+40);
|
|
C4GUI::ComboBox *pGfxResCombo = new C4GUI::ComboBox(resBox.GetFromLeft(w+40,C4GUI::ComboBox::GetDefaultHeight()));
|
|
pGfxResCombo->SetToolTip(LoadResStr("IDS_MSG_RESOLUTION_DESC"));
|
|
pGfxResCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnGfxResComboFill, &C4StartupOptionsDlg::OnGfxResComboSelChange));
|
|
pGfxResCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
|
|
pGfxResCombo->SetFont(pUseFont);
|
|
pGfxResCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
|
|
pGfxResCombo->SetText(GetGfxResString(Config.Graphics.ResX, Config.Graphics.ResY).getData());
|
|
pGroupResolution->AddElement(pGfxResCombo);
|
|
// fullscreen combobox
|
|
C4GUI::ComponentAligner fsBox(caGroupResolution.GetGridCell(0,1,iOpt++,iNumGfxOptions), 0, 0, false);
|
|
w=20; q=12; pUseFont->GetTextExtent(LoadResStr("IDS_CTL_FULLSCREENMODE"), w,q, true);
|
|
pGroupResolution->AddElement(new C4GUI::Label(LoadResStr("IDS_CTL_FULLSCREENMODE"), fsBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent,q), ALeft, C4StartupFontClr, pUseFont, false, false));
|
|
uint32_t wmax = 0;
|
|
for(int i = 0; i < 3; ++i)
|
|
{
|
|
pUseFont->GetTextExtent(GetWindowedName(i),w,q,true);
|
|
wmax = std::max<int32_t>(w, wmax);
|
|
}
|
|
C4GUI::ComboBox * pCombo = new C4GUI::ComboBox(fsBox.GetFromLeft(w+40,C4GUI::ComboBox::GetDefaultHeight()));
|
|
pCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnWindowedModeComboFill, &C4StartupOptionsDlg::OnWindowedModeComboSelChange));
|
|
pCombo->SetToolTip(LoadResStr("IDS_MSG_FULLSCREEN_DESC"));
|
|
pCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
|
|
pCombo->SetFont(pUseFont);
|
|
pCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
|
|
pCombo->SetText(GetWindowedName());
|
|
pGroupResolution->AddElement(pCombo);
|
|
// --subgroup options
|
|
iNumGfxOptions = 5, iOpt=0;
|
|
C4GUI::GroupBox *pGroupOptions = new C4GUI::GroupBox(caSheetGraphics.GetGridCell(0,1,1,2));
|
|
pGroupOptions->SetTitle(LoadResStrNoAmp("IDS_DLG_OPTIONS"));
|
|
pGroupOptions->SetFont(pUseFont);
|
|
pGroupOptions->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
|
|
pSheetGraphics->AddElement(pGroupOptions);
|
|
C4GUI::ComponentAligner caGroupOptions(pGroupOptions->GetClientRect(), iIndentX1, iIndentY2, true);
|
|
// multisampling
|
|
C4GUI::ComponentAligner msBox(caGroupOptions.GetFromTop(C4GUI::ComboBox::GetDefaultHeight()), 0, 0, false);
|
|
w=20; q=12; pUseFont->GetTextExtent(LoadResStr("IDS_CTL_ANTIALIASING"), w,q, true);
|
|
pGroupOptions->AddElement(new C4GUI::Label(LoadResStr("IDS_CTL_ANTIALIASING"), msBox.GetFromLeft(w+C4GUI_DefDlgSmallIndent), ALeft, C4StartupFontClr, pUseFont, false, false));
|
|
|
|
pUseFont->GetTextExtent("Off", w, q, true);
|
|
C4GUI::ComboBox *pGfxMSCombo = new C4GUI::ComboBox(msBox.GetFromLeft(w+40,C4GUI::ComboBox::GetDefaultHeight()));
|
|
pGfxMSCombo->SetToolTip(LoadResStr("IDS_MSG_ANTIALIASING_DESC"));
|
|
pGfxMSCombo->SetComboCB(new C4GUI::ComboBox_FillCallback<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnGfxMSComboFill, &C4StartupOptionsDlg::OnGfxMSComboSelChange));
|
|
pGfxMSCombo->SetColors(C4StartupFontClr, C4StartupEditBGColor, C4StartupEditBorderColor);
|
|
pGfxMSCombo->SetFont(pUseFont);
|
|
pGfxMSCombo->SetDecoration(&(C4Startup::Get()->Graphics.fctContext));
|
|
// Pre-Select current setting
|
|
StdStrBuf Current;
|
|
if(Config.Graphics.MultiSampling) Current.Format("%dx", Config.Graphics.MultiSampling);
|
|
else Current.Copy("Off");
|
|
pGfxMSCombo->SetText(Current.getData());
|
|
// Set control read only if multisampling is not available
|
|
std::vector<int> multisamples;
|
|
Application.pWindow->EnumerateMultiSamples(multisamples);
|
|
pGfxMSCombo->SetReadOnly(multisamples.empty());
|
|
pGroupOptions->AddElement(pGfxMSCombo);
|
|
// automatic gfx frame skip
|
|
pCheck = new BoolConfig(caGroupOptions.GetGridCell(0,1,iOpt++,iNumGfxOptions,-1,iCheckHgt,true), LoadResStr("IDS_MSG_AUTOFRAMESKIP"), nullptr, &Config.Graphics.AutoFrameSkip);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_AUTOFRAMESKIP"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pGroupOptions->AddElement(pCheck);
|
|
|
|
// --- page sound
|
|
C4GUI::ComponentAligner caSheetSound(pSheetSound->GetClientRect(), iIndentX1, iIndentY1, true);
|
|
if (!C4GUI::CheckBox::GetStandardCheckBoxSize(&iCheckWdt, &iCheckHgt, "Lorem ipsum", pUseFont)) { iCheckWdt=100; iCheckHgt=20; }
|
|
int32_t iGridWdt = iCheckWdt * 2, iGridHgt = iCheckHgt * 5/2;
|
|
// --subgroup menu system sound
|
|
C4GUI::GroupBox *pGroupFESound = new C4GUI::GroupBox(caSheetSound.GetGridCell(0,2,0,5, iGridWdt, iGridHgt, false, 1,2));
|
|
pGroupFESound->SetTitle(LoadResStrNoAmp("IDS_CTL_FRONTEND"));
|
|
pGroupFESound->SetFont(pUseFont);
|
|
pGroupFESound->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
|
|
pSheetSound->AddElement(pGroupFESound);
|
|
C4GUI::ComponentAligner caGroupFESound(pGroupFESound->GetClientRect(), iIndentX1, iIndentY2, true);
|
|
// menu system music
|
|
pCheck = pFEMusicCheck = new C4GUI::CheckBox(caGroupFESound.GetGridCell(0,1,0,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_MUSIC"), !!Config.Sound.FEMusic);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_MENUMUSIC"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnFEMusicCheck));
|
|
pGroupFESound->AddElement(pCheck);
|
|
// menu system sound effects
|
|
pCheck = pFESoundCheck = new BoolConfig(caGroupFESound.GetGridCell(0,1,1,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_SOUNDFX"), nullptr, &Config.Sound.FESamples);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_MENUSOUND"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pGroupFESound->AddElement(pCheck);
|
|
// --subgroup game sound
|
|
C4GUI::GroupBox *pGroupRXSound = new C4GUI::GroupBox(caSheetSound.GetGridCell(1,2,0,5, iGridWdt, iGridHgt, false, 1,2));
|
|
pGroupRXSound->SetTitle(LoadResStrNoAmp("IDS_CTL_GAME"));
|
|
pGroupRXSound->SetFont(pUseFont);
|
|
pGroupRXSound->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
|
|
pSheetSound->AddElement(pGroupRXSound);
|
|
C4GUI::ComponentAligner caGroupRXSound(pGroupRXSound->GetClientRect(), iIndentX1, iIndentY2, true);
|
|
// game music
|
|
pCheck = new BoolConfig(caGroupRXSound.GetGridCell(0,1,0,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_MUSIC"), nullptr, &Config.Sound.RXMusic);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_GAMEMUSIC"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pGroupRXSound->AddElement(pCheck);
|
|
// game sound effects
|
|
pCheck = new C4GUI::CheckBox(caGroupRXSound.GetGridCell(0,1,1,2,-1,iCheckHgt,true), LoadResStr("IDS_CTL_SOUNDFX"), !!Config.Sound.RXSound);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_GAMESOUND"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pCheck->SetOnChecked(new C4GUI::CallbackHandler<C4StartupOptionsDlg>(this, &C4StartupOptionsDlg::OnRXSoundCheck));
|
|
pGroupRXSound->AddElement(pCheck);
|
|
// -- subgroup volume
|
|
C4GUI::GroupBox *pGroupVolume = new C4GUI::GroupBox(caSheetSound.GetGridCell(0,2,2,5, iGridWdt, iGridHgt, false, 2,3));
|
|
pGroupVolume->SetTitle(LoadResStrNoAmp("IDS_BTN_VOLUME"));
|
|
pGroupVolume->SetFont(pUseFont);
|
|
pGroupVolume->SetColors(C4StartupEditBorderColor, C4StartupFontClr);
|
|
pSheetSound->AddElement(pGroupVolume);
|
|
C4GUI::ComponentAligner caGroupVolume(pGroupVolume->GetClientRect(), iIndentX1, iIndentY2, true);
|
|
// volume sliders
|
|
int32_t i;
|
|
for (i=0; i<2; ++i)
|
|
{
|
|
StdStrBuf sLabelTxt;
|
|
C4GUI::ComponentAligner caVolumeSlider(caGroupVolume.GetGridCell(0,1,i,2, -1, pUseFont->GetLineHeight()+iIndentY2*2+C4GUI_ScrollBarHgt, true), 1,0,false);
|
|
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));
|
|
sLabelTxt.Copy(LoadResStr("IDS_CTL_SILENT"));
|
|
w=20; q=12; pUseFont->GetTextExtent(sLabelTxt.getData(), w,q, true);
|
|
pGroupVolume->AddElement(new C4GUI::Label(sLabelTxt.getData(), caVolumeSlider.GetFromLeft(w,q), ACenter, C4StartupFontClr, pUseFont, false, false));
|
|
sLabelTxt.Copy(LoadResStr("IDS_CTL_LOUD"));
|
|
pUseFont->GetTextExtent(sLabelTxt.getData(), w,q, true);
|
|
pGroupVolume->AddElement(new C4GUI::Label(sLabelTxt.getData(), caVolumeSlider.GetFromRight(w,q), ACenter, C4StartupFontClr, pUseFont, false, false));
|
|
auto *pCB = new C4GUI::ParCallbackHandler<C4StartupOptionsDlg, int32_t>(this, i ? &C4StartupOptionsDlg::OnSoundVolumeSliderChange : &C4StartupOptionsDlg::OnMusicVolumeSliderChange);
|
|
auto *pSlider = new C4GUI::ScrollBar(caVolumeSlider.GetCentered(caVolumeSlider.GetInnerWidth(), C4GUI_ScrollBarHgt), true, pCB, 101);
|
|
pSlider->SetDecoration(&C4Startup::Get()->Graphics.sfctBookScroll, false);
|
|
pSlider->SetToolTip(i ? LoadResStr("IDS_DESC_VOLUMESOUND") : LoadResStr("IDS_DESC_VOLUMEMUSIC"));
|
|
pSlider->SetScrollPos(i ? Config.Sound.SoundVolume : Config.Sound.MusicVolume);
|
|
pGroupVolume->AddElement(pSlider);
|
|
}
|
|
|
|
// --- page controls
|
|
pSheetControls->AddElement(pControlConfigArea = new ControlConfigArea(pSheetControls->GetClientRect(), caMain.GetWidth()/20, caMain.GetHeight()/40, false, this));
|
|
|
|
// --- page network
|
|
int iPortCfgWdt=200, iPortCfgHgt=48; NetworkPortConfig::GetControlSize(&iPortCfgWdt, &iPortCfgHgt);
|
|
int iServerCfgWdt = 120, iServerCfgHgt = 20, iServerCfgWdtMid = 0;
|
|
StdStrBuf sServerText; sServerText.Copy(LoadResStr("IDS_CTL_USEOTHERSERVER"));
|
|
NetworkServerAddressConfig::GetControlSize(&iServerCfgWdt, &iServerCfgHgt, &iServerCfgWdtMid, sServerText.getData());
|
|
int32_t net_component_hgt = iPortCfgHgt * 4 + iServerCfgHgt + 3 * pUseFont->GetLineHeight();
|
|
C4GUI::ComponentAligner caSheetNetwork(pSheetNetwork->GetClientRect(), caMain.GetWidth() / 20, std::max<int32_t>(0, (caMain.GetHeight() - net_component_hgt)/20), true);
|
|
pPortCfgTCP = new NetworkPortConfig(caSheetNetwork.GetGridCell(0,2,0,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_TCP"), &(Config.Network.PortTCP), C4NetStdPortTCP);
|
|
pPortCfgUDP = new NetworkPortConfig(caSheetNetwork.GetGridCell(1,2,0,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_UDP"), &(Config.Network.PortUDP), C4NetStdPortUDP);
|
|
pPortCfgRef = new NetworkPortConfig(caSheetNetwork.GetGridCell(0,2,1,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_REFERENCE"), &(Config.Network.PortRefServer), C4NetStdPortRefServer);
|
|
pPortCfgDsc = new NetworkPortConfig(caSheetNetwork.GetGridCell(1,2,1,2, iPortCfgWdt, iPortCfgHgt), LoadResStr("IDS_NET_PORT_DISCOVERY"), &(Config.Network.PortDiscovery), C4NetStdPortDiscovery);
|
|
pPortCfgTCP->SetToolTip(LoadResStr("IDS_NET_PORT_TCP_DESC"));
|
|
pPortCfgUDP->SetToolTip(LoadResStr("IDS_NET_PORT_UDP_DESC"));
|
|
pPortCfgRef->SetToolTip(LoadResStr("IDS_NET_PORT_REFERENCE_DESC"));
|
|
pPortCfgDsc->SetToolTip(LoadResStr("IDS_NET_PORT_DISCOVERY_DESC"));
|
|
pSheetNetwork->AddElement(pPortCfgTCP);
|
|
pSheetNetwork->AddElement(pPortCfgUDP);
|
|
pSheetNetwork->AddElement(pPortCfgRef);
|
|
pSheetNetwork->AddElement(pPortCfgDsc);
|
|
int iNetHgt0=pPortCfgDsc->GetBounds().GetBottom();
|
|
caSheetNetwork.ExpandTop(-iNetHgt0);
|
|
pLeagueServerCfg = new NetworkServerAddressConfig(caSheetNetwork.GetFromTop(iServerCfgHgt), sServerText.getData(), &(Config.Network.UseAlternateServer), Config.Network.AlternateServerAddress, iServerCfgWdtMid);
|
|
pLeagueServerCfg->SetToolTip(LoadResStr("IDS_NET_MASTERSRV_DESC"));
|
|
pSheetNetwork->AddElement(pLeagueServerCfg);
|
|
#ifdef WITH_AUTOMATIC_UPDATE
|
|
pCheck = new BoolConfig(caSheetNetwork.GetFromTop(pUseFont->GetLineHeight()), LoadResStr("IDS_CTL_AUTOMATICUPDATES"), nullptr, &Config.Network.AutomaticUpdate, false);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_AUTOMATICUPDATES"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pSheetNetwork->AddElement(pCheck);
|
|
#endif
|
|
pCheck = new BoolConfig(caSheetNetwork.GetFromTop(pUseFont->GetLineHeight()), LoadResStr("IDS_CTL_UPNP"), nullptr, &Config.Network.EnableUPnP, false);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_UPNP"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pSheetNetwork->AddElement(pCheck);
|
|
pCheck = new BoolConfig(caSheetNetwork.GetFromTop(pUseFont->GetLineHeight()), LoadResStr("IDS_CTL_PACKETLOGGING"), nullptr, &Config.Network.PacketLogging, false);
|
|
pCheck->SetToolTip(LoadResStr("IDS_DESC_PACKETLOGGING"));
|
|
pCheck->SetFont(pUseFont, C4StartupFontClr, C4StartupFontClrDisabled);
|
|
pSheetNetwork->AddElement(pCheck);
|
|
const char *szNameCfgText = LoadResStr("IDS_NET_USERNAME");
|
|
int iNameCfgWdt=200, iNameCfgHgt=48; C4StartupOptionsDlg::EditConfig::GetControlSize(&iNameCfgWdt, &iNameCfgHgt, szNameCfgText, false);
|
|
iNameCfgWdt += 5;
|
|
pNetworkNickEdit = new EditConfig(caSheetNetwork.GetFromTop(iNameCfgHgt), szNameCfgText, &Config.Network.Nick, nullptr, false);
|
|
pNetworkNickEdit->SetToolTip(LoadResStr("IDS_NET_USERNAME_DESC"));
|
|
pSheetNetwork->AddElement(pNetworkNickEdit);
|
|
|
|
StdCopyStrBuf NickBuf(Config.Network.Nick);
|
|
if (!NickBuf.getLength()) NickBuf.Copy(Config.GetRegistrationData("Nick"));
|
|
pNetworkNickEdit->GetEdit()->SetText(NickBuf.getData(), false);
|
|
|
|
// initial focus is on tab selection
|
|
SetFocus(pOptionsTabular, false);
|
|
}
|
|
|
|
C4StartupOptionsDlg::~C4StartupOptionsDlg()
|
|
{
|
|
delete pKeyToggleMusic;
|
|
delete pKeyBack;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnClosed(bool fOK)
|
|
{
|
|
// callback when dlg got closed - save config
|
|
SaveConfig(true, false);
|
|
C4StartupDlg::OnClosed(fOK);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnResetConfigBtn(C4GUI::Control *btn)
|
|
{
|
|
// confirmation
|
|
StdStrBuf sWarningText; sWarningText.Copy(LoadResStr("IDS_MSG_PROMPTRESETCONFIG"));
|
|
sWarningText.AppendChar('|');
|
|
sWarningText.Append(LoadResStr("IDS_MSG_RESTARTCHANGECFG"));
|
|
if (!GetScreen()->ShowMessageModal(sWarningText.getData(), LoadResStr("IDS_BTN_RESETCONFIG"), C4GUI::MessageDialog::btnYesNo, C4GUI::Ico_Notify))
|
|
// user cancelled
|
|
return;
|
|
// reset cfg
|
|
Config.Default();
|
|
Config.fConfigLoaded = true;
|
|
// engine must be restarted now, because some crucial fields such as resolution and used gfx engine do not match their initialization
|
|
Application.Quit();
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnGfxMSComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|
{
|
|
// clear all old entries first to allow a clean refill
|
|
pFiller->ClearEntries();
|
|
|
|
pFiller->AddEntry("Off", 0);
|
|
|
|
std::vector<int> multisamples;
|
|
Application.pWindow->EnumerateMultiSamples(multisamples);
|
|
|
|
std::sort(multisamples.begin(), multisamples.end());
|
|
for(int multisample : multisamples)
|
|
{
|
|
StdStrBuf text;
|
|
text.Format("%dx", multisample);
|
|
pFiller->AddEntry(text.getData(), multisample);
|
|
}
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::OnGfxMSComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
|
|
{
|
|
if(pTexMgr) pTexMgr->IntLock();
|
|
#ifndef USE_CONSOLE
|
|
pDraw->InvalidateDeviceObjects();
|
|
// Note: This assumes there is only one GL context (the main context). This
|
|
// is true in fullscreen mode, and since the startup dlg is only shown in
|
|
// fullscreen mode we are safe this way.
|
|
if(pGL) pGL->pMainCtx->Clear(true);
|
|
#endif
|
|
int32_t PrevMultiSampling = Config.Graphics.MultiSampling;
|
|
Config.Graphics.MultiSampling = idNewSelection;
|
|
bool success = Application.pWindow->ReInit(&Application);
|
|
|
|
#ifndef USE_CONSOLE
|
|
if(pGL) pGL->pMainCtx->Init(Application.pWindow, &Application);
|
|
pDraw->RestoreDeviceObjects();
|
|
if(pGL) pGL->InitShaders(&::GraphicsResource.Files);
|
|
#endif
|
|
if(pTexMgr) pTexMgr->IntUnlock();
|
|
if(!success) Config.Graphics.MultiSampling = PrevMultiSampling;
|
|
return !success;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnGfxResComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|
{
|
|
// clear all old entries first to allow a clean refill
|
|
pFiller->ClearEntries();
|
|
pFiller->AddEntry(LoadResStr("IDS_MNU_DEFAULTRESOLUTION"), -1);
|
|
// fill with all possible resolutions
|
|
int32_t idx = 0, iXRes, iYRes, iBitDepth, iRefreshRate;
|
|
while (Application.GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, &iRefreshRate, Config.Graphics.Monitor))
|
|
#ifdef _WIN32 // why only WIN32?
|
|
if (iBitDepth == C4Draw::COLOR_DEPTH)
|
|
#endif
|
|
{
|
|
StdStrBuf sGfxString = GetGfxResString(iXRes, iYRes);
|
|
if (!pFiller->FindEntry(sGfxString.getData()))
|
|
pFiller->AddEntry(sGfxString.getData(), iXRes + (uint32_t(iYRes) << 12) + (uint32_t(iRefreshRate) << 24));
|
|
}
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::OnGfxResComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
|
|
{
|
|
// get new resolution from string
|
|
int iResX=(idNewSelection & 0xfff), iResY=(uint32_t(idNewSelection) >> 12) & 0xfff, iRefreshRate = (uint32_t(idNewSelection) >> 24) & 0xff;
|
|
if (idNewSelection == -1)
|
|
{
|
|
iResX = iResY = -1;
|
|
iRefreshRate = 0;
|
|
}
|
|
|
|
// different than current?
|
|
if (iResX == Config.Graphics.ResX && iResY == Config.Graphics.ResY && iRefreshRate == Config.Graphics.RefreshRate) return true;
|
|
|
|
// try setting it
|
|
if (!TryNewResolution(iResX, iResY, iRefreshRate))
|
|
{
|
|
// didn't work or declined by user
|
|
return true; // do not change label, because dialog might hae been recreated!
|
|
}
|
|
// dialog has been recreated; so do not change the combo label
|
|
return true;
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::TryNewResolution(int32_t iResX, int32_t iResY, int32_t iRefreshRate)
|
|
{
|
|
int32_t iOldResX = Config.Graphics.ResX, iOldResY = Config.Graphics.ResY;
|
|
int32_t iOldRefreshRate = Config.Graphics.RefreshRate;
|
|
int32_t iOldFontSize = Config.General.RXFontSize;
|
|
C4GUI::Screen *pScreen = GetScreen();
|
|
// resolution change may imply font size change
|
|
int32_t iNewFontSize = 14; // default (at 800x600)
|
|
if (iResY >= 0 && iResY < 600)
|
|
iNewFontSize = 12;
|
|
else if (iResY > 800)
|
|
iNewFontSize = 16;
|
|
// call application to set it
|
|
if (!Application.SetVideoMode(iResX, iResY, iRefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
|
|
{
|
|
StdCopyStrBuf strChRes(LoadResStr("IDS_MNU_SWITCHRESOLUTION"));
|
|
pScreen->ShowMessage(FormatString(LoadResStr("IDS_ERR_SWITCHRES"), Application.GetLastError()).getData(), strChRes.getData(), C4GUI::Ico_Clonk, nullptr);
|
|
return false;
|
|
}
|
|
// implied font change
|
|
if (iNewFontSize != iOldFontSize)
|
|
if (!Application.SetGameFont(Config.General.RXFontName, iNewFontSize))
|
|
{
|
|
// not changing font size is not fatal - just keep old size
|
|
iNewFontSize = iOldFontSize;
|
|
}
|
|
// Set new resolution in config before dialog recreation so that the initial combo box value is correct (#230)
|
|
Config.Graphics.ResX = iResX;
|
|
Config.Graphics.ResY = iResY;
|
|
Config.Graphics.RefreshRate = iRefreshRate;
|
|
// since the resolution was changed, everything needs to be moved around a bit
|
|
RecreateDialog(false);
|
|
// Now set old resolution again to make sure config is restored even if the program is closed during the confirmation dialog
|
|
Config.Graphics.ResX = iOldResX;
|
|
Config.Graphics.ResY = iOldResY;
|
|
Config.Graphics.RefreshRate = iOldRefreshRate;
|
|
// Show confirmation dialog
|
|
ResChangeConfirmDlg *pConfirmDlg = new ResChangeConfirmDlg();
|
|
if (!pScreen->ShowModalDlg(pConfirmDlg, true))
|
|
{
|
|
// abort: Restore screen, if this was not some program abort
|
|
if (Application.SetVideoMode(iOldResX, iOldResY, iOldRefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed))
|
|
{
|
|
if (iNewFontSize != iOldFontSize) Application.SetGameFont(Config.General.RXFontName, iOldFontSize);
|
|
RecreateDialog(false);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
// resolution may be kept!
|
|
Config.Graphics.ResX = iResX;
|
|
Config.Graphics.ResY = iResY;
|
|
Config.Graphics.RefreshRate = iRefreshRate;
|
|
if(Config.Graphics.Windowed)
|
|
Application.SetVideoMode(Application.GetConfigWidth(), Application.GetConfigHeight(), Config.Graphics.RefreshRate, Config.Graphics.Monitor, false);
|
|
return true;
|
|
}
|
|
|
|
StdStrBuf C4StartupOptionsDlg::GetGfxResString(int32_t iResX, int32_t iResY)
|
|
{
|
|
// Display in format like "640 x 480"
|
|
if (iResX == -1)
|
|
return StdStrBuf(LoadResStr("IDS_MNU_DEFAULTRESOLUTION"));
|
|
return FormatString("%d x %d", (int)iResX, (int)iResY);
|
|
}
|
|
|
|
const char * C4StartupOptionsDlg::GetWindowedName(int32_t mode /* = -1*/)
|
|
{
|
|
if(mode == -1)
|
|
mode = Config.Graphics.Windowed;
|
|
if(mode == 0) return LoadResStr("IDS_MSG_FULLSCREEN");
|
|
else if(mode == 1) return LoadResStr("IDS_MSG_WINDOWED");
|
|
else if(mode == 2) return LoadResStr("IDS_MSG_AUTOWINDOWED");
|
|
assert(!"Requested name for config value which does not exist");
|
|
return "ERR: Unknown";
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnWindowedModeComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|
{
|
|
pFiller->ClearEntries();
|
|
for(int32_t i = 0; i < 3; ++i)
|
|
pFiller->AddEntry(GetWindowedName(i), i);
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::OnWindowedModeComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
|
|
{
|
|
Config.Graphics.Windowed = idNewSelection;
|
|
Application.SetVideoMode(Config.Graphics.ResX, Config.Graphics.ResY, Config.Graphics.RefreshRate, Config.Graphics.Monitor, !Config.Graphics.Windowed);
|
|
pForCombo->SetText(GetWindowedName(idNewSelection));
|
|
return true;
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::SaveConfig(bool fForce, bool fKeepOpen)
|
|
{
|
|
// prevent double save
|
|
if (fConfigSaved) return true;
|
|
// save any config fields that are not stored directly; return whether all values are OK
|
|
// check port validity
|
|
if (!fForce)
|
|
{
|
|
StdCopyStrBuf strError(LoadResStr("IDS_ERR_CONFIG"));
|
|
if (pPortCfgTCP->GetPort()>0 && pPortCfgTCP->GetPort() == pPortCfgRef->GetPort())
|
|
{
|
|
GetScreen()->ShowMessage(LoadResStr("IDS_NET_ERR_PORT_TCPREF"), strError.getData(), C4GUI::Ico_Error);
|
|
return false;
|
|
}
|
|
if (pPortCfgUDP->GetPort()>0 && pPortCfgUDP->GetPort() == pPortCfgDsc->GetPort())
|
|
{
|
|
GetScreen()->ShowMessage(LoadResStr("IDS_NET_ERR_PORT_UDPDISC"), strError.getData(), C4GUI::Ico_Error);
|
|
return false;
|
|
}
|
|
}
|
|
// store some config values
|
|
pPortCfgTCP->SavePort();
|
|
pPortCfgUDP->SavePort();
|
|
pPortCfgRef->SavePort();
|
|
pPortCfgDsc->SavePort();
|
|
pLeagueServerCfg->Save2Config();
|
|
pNetworkNickEdit->Save2Config();
|
|
// if nick is same as default by registry, don't save in config
|
|
// so regkey updates will change the nick as well
|
|
const char *szRegNick = Config.GetRegistrationData("Nick");
|
|
if (SEqual(Config.Network.Nick.getData(), szRegNick)) Config.Network.Nick.Clear();
|
|
// make sure config is saved, in case the game crashes later on or another instance is started
|
|
Config.Save();
|
|
if (!fKeepOpen) fConfigSaved = true;
|
|
// done; config OK
|
|
return true;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::DoBack()
|
|
{
|
|
if (!SaveConfig(false, false)) return;
|
|
// back 2 main
|
|
C4Startup::Get()->SwitchDialog(fCanGoBack ? (C4Startup::SDID_Back) : (C4Startup::SDID_Main));
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::SetSubscreen(const char *szToScreen)
|
|
{
|
|
// go to specified property sheet
|
|
// option sheets do not have a good identifier associated to them - just lookup from a static array
|
|
const char *page_names[] = { "general", "graphics", "sound", "controls", "network", nullptr };
|
|
int32_t i = 0;
|
|
while (page_names[i])
|
|
{
|
|
if (SEqualNoCase(szToScreen, page_names[i])) break;
|
|
++i;
|
|
}
|
|
// page name does not match?
|
|
if (!page_names[i]) return false;
|
|
// page name OK; switch it
|
|
pOptionsTabular->SelectSheet(i, false);
|
|
return true;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::UpdateLanguage()
|
|
{
|
|
// find currently specified language in language list and display its info
|
|
C4LanguageInfo *pNfo = Languages.FindInfo(Config.General.Language);
|
|
if (pNfo)
|
|
{
|
|
pLangCombo->SetText(FormatString("%s - %s", pNfo->Code, pNfo->Name).getData());
|
|
pLangInfoLabel->SetText(pNfo->Info);
|
|
}
|
|
else
|
|
{
|
|
pLangCombo->SetText(FormatString("unknown (%s)", Config.General.Language).getData());
|
|
pLangInfoLabel->SetText(LoadResStr("IDS_CTL_NOLANGINFO"));
|
|
return; // no need to mess with fallbacks
|
|
}
|
|
// update language fallbacks
|
|
char *szLang = Config.General.LanguageEx;
|
|
SCopy(pNfo->Code, szLang);
|
|
if (*(pNfo->Fallback))
|
|
{
|
|
SAppend(",", szLang);
|
|
Config.General.GetLanguageSequence(pNfo->Fallback, szLang + SLen(szLang));
|
|
}
|
|
// internal fallbacks
|
|
if (!SSearch(Config.General.LanguageEx, "US"))
|
|
{
|
|
if (*szLang) SAppendChar(',', szLang);
|
|
SAppend("US", szLang);
|
|
}
|
|
if (!SSearch(Config.General.LanguageEx, "DE"))
|
|
{
|
|
if (*szLang) SAppendChar(',', szLang);
|
|
SAppend("DE", szLang);
|
|
}
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnLangComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|
{
|
|
// fill with all possible languages
|
|
C4LanguageInfo *pNfo;
|
|
for (int i=0; i<Languages.GetInfoCount(); ++i)
|
|
if ((pNfo = Languages.GetInfo(i)))
|
|
pFiller->AddEntry(FormatString("%s - %s", pNfo->Code, pNfo->Name).getData(), (unsigned char)(pNfo->Code[0]) + ((unsigned char)(pNfo->Code[1])<<8));
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::OnLangComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
|
|
{
|
|
// set new language by two-character-code
|
|
Config.General.Language[0] = idNewSelection & 0xff;
|
|
Config.General.Language[1] = (idNewSelection & 0xff00) >> 8;
|
|
Config.General.Language[2] = '\0';
|
|
UpdateLanguage();
|
|
Languages.LoadLanguage(Config.General.LanguageEx);
|
|
Game.UpdateLanguage();
|
|
// recreate everything to reflect language changes
|
|
RecreateDialog(true);
|
|
return true;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::UpdateFontControls()
|
|
{
|
|
// display current language and size in comboboxes
|
|
pFontFaceCombo->SetText(Config.General.RXFontName);
|
|
StdStrBuf sSize; sSize.Format("%d", (int) Config.General.RXFontSize);
|
|
pFontSizeCombo->SetText(sSize.getData());
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
const char *DefaultFonts[] = { "Arial Unicode MS", "Comic Sans MS", C4DEFAULT_FONT_NAME, "Verdana", nullptr };
|
|
#else
|
|
const char *DefaultFonts[] = { C4DEFAULT_FONT_NAME, nullptr };
|
|
#endif
|
|
|
|
void C4StartupOptionsDlg::OnFontFaceComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|
{
|
|
// 2do: enumerate Fonts.txt fonts; then enumerate system fonts
|
|
for (int32_t i=0; DefaultFonts[i]; ++i) pFiller->AddEntry(DefaultFonts[i], i);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnFontSizeComboFill(C4GUI::ComboBox_FillCB *pFiller)
|
|
{
|
|
// 2do: enumerate possible font sizes by the font here
|
|
// 2do: Hide font sizes that would be too large for the selected resolution
|
|
pFiller->AddEntry("10", 10);
|
|
pFiller->AddEntry("12", 12);
|
|
pFiller->AddEntry("14", 14);
|
|
pFiller->AddEntry("16", 16);
|
|
pFiller->AddEntry("18", 18);
|
|
pFiller->AddEntry("20", 20);
|
|
pFiller->AddEntry("22", 22);
|
|
pFiller->AddEntry("24", 24);
|
|
pFiller->AddEntry("26", 26);
|
|
pFiller->AddEntry("28", 28);
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::OnFontComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection)
|
|
{
|
|
// set new value
|
|
const char *szNewFontFace = Config.General.RXFontName;
|
|
int32_t iNewFontSize = Config.General.RXFontSize;
|
|
if (pForCombo == pFontFaceCombo)
|
|
szNewFontFace = DefaultFonts[idNewSelection];
|
|
else if (pForCombo == pFontSizeCombo)
|
|
iNewFontSize = idNewSelection;
|
|
else
|
|
// can't happen
|
|
return true;
|
|
// set new fonts
|
|
if (!Application.SetGameFont(szNewFontFace, iNewFontSize))
|
|
{
|
|
GetScreen()->ShowErrorMessage(LoadResStr("IDS_ERR_INITFONTS"));
|
|
return true;
|
|
}
|
|
// recreate everything to reflect font changes
|
|
RecreateDialog(true);
|
|
return true;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::RecreateDialog(bool fFade)
|
|
{
|
|
// MUST fade for now, or calling function will fail because dialog is deleted immediately
|
|
fFade = true;
|
|
// this actually breaks the possibility to go back :(
|
|
int32_t iPage = pOptionsTabular->GetActiveSheetIndex();
|
|
C4StartupOptionsDlg *pNewDlg = static_cast<C4StartupOptionsDlg *>(C4Startup::Get()->SwitchDialog(C4Startup::SDID_Options, fFade));
|
|
pNewDlg->pOptionsTabular->SelectSheet(iPage, false);
|
|
pNewDlg->fCanGoBack = false;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnFEMusicCheck(C4GUI::Element *pCheckBox)
|
|
{
|
|
// option change is reflected immediately
|
|
bool fIsOn = static_cast<C4GUI::CheckBox *>(pCheckBox)->GetChecked();
|
|
if ((Config.Sound.FEMusic = fIsOn))
|
|
Application.MusicSystem.Play();
|
|
else
|
|
Application.MusicSystem.Stop();
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnMusicVolumeSliderChange(int32_t iNewVal)
|
|
{
|
|
// option change is reflected immediately;
|
|
Config.Sound.MusicVolume = iNewVal;
|
|
Application.MusicSystem.UpdateVolume();
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnSoundVolumeSliderChange(int32_t iNewVal)
|
|
{
|
|
// sound system reads this value directly
|
|
Config.Sound.SoundVolume = iNewVal;
|
|
// test sound
|
|
StartSoundEffect("Objects::Arrow::HitGround", false, 100, nullptr);
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnRXSoundCheck(C4GUI::Element *pCheckBox)
|
|
{
|
|
// toggling sounds on off must init/deinit sound system
|
|
bool fIsOn = static_cast<C4GUI::CheckBox *>(pCheckBox)->GetChecked();
|
|
if (fIsOn == !!Config.Sound.RXSound) return;
|
|
if (fIsOn)
|
|
{
|
|
Config.Sound.RXSound = true;
|
|
if (!Application.SoundSystem.Init())
|
|
{
|
|
GetScreen()->ShowMessage(StdCopyStrBuf(LoadResStr("IDS_PRC_NOSND")).getData(), StdCopyStrBuf(LoadResStr("IDS_DLG_LOG")).getData(), C4GUI::Ico_Error);
|
|
Application.SoundSystem.Clear();
|
|
Config.Sound.RXSound = false;
|
|
static_cast<C4GUI::CheckBox *>(pCheckBox)->SetChecked(false);
|
|
fIsOn = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Application.SoundSystem.Clear();
|
|
Config.Sound.RXSound = false;
|
|
}
|
|
// FE sound only enabled if global sound is enabled
|
|
pFESoundCheck->SetEnabled(fIsOn);
|
|
pFESoundCheck->SetChecked(fIsOn ? !!Config.Sound.FESamples : false);
|
|
}
|
|
|
|
bool C4StartupOptionsDlg::KeyMusicToggle()
|
|
{
|
|
// do toggle
|
|
Application.MusicSystem.ToggleOnOff();
|
|
// reflect in checkbox
|
|
pFEMusicCheck->SetChecked(!!Config.Sound.FEMusic);
|
|
// key processed
|
|
return true;
|
|
}
|
|
|
|
void C4StartupOptionsDlg::OnKeyboardLayoutChanged()
|
|
{
|
|
// keyboard layout changed and thus some keys might have been updated from scan codes
|
|
// update display in control set
|
|
pControlConfigArea->UpdateCtrlSet();
|
|
}
|