C4FileSelDlg::C4FileSelDlg(const char *szRootPath, const char *szTitle, C4FileSel_BaseCB *pSelCallback, bool fInitElements) : C4GUI::Dialog(BoundBy(C4GUI::GetScreenWdt() * 2 / 3 + 10, 300, 600), BoundBy(C4GUI::GetScreenHgt() * 2 / 3 + 10, 220, 500), szTitle, false), pFileListBox(NULL), pSelectionInfoBox(NULL), btnOK(NULL), pSelection(NULL), pSelCallback(pSelCallback), pLocations(NULL), iLocationCount(0), pLocationComboBox(NULL) { sTitle.Copy(szTitle); // key bindings pKeyRefresh = new C4KeyBinding( C4KeyCodeEx(K_F5), "FileSelReload", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4FileSelDlg>(*this, &C4FileSelDlg::KeyRefresh), C4CustomKey::PRIO_CtrlOverride); pKeyEnterOverride = new C4KeyBinding( C4KeyCodeEx(K_RETURN), "FileSelConfirm", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4FileSelDlg>(*this, &C4FileSelDlg::KeyEnter), C4CustomKey::PRIO_CtrlOverride); if (fInitElements) InitElements(); sPath.Copy(szRootPath); }
void C4GamePadControl::FeedEvent(const SDL_Event& event, int feed) { switch (event.type) { case SDL_CONTROLLERAXISMOTION: { C4KeyCode minCode = KEY_Gamepad(KEY_CONTROLLER_Axis(event.caxis.axis, false)); C4KeyCode maxCode = KEY_Gamepad(KEY_CONTROLLER_Axis(event.caxis.axis, true)); int32_t value = abs_strength(event.caxis.value); uint8_t which = event.caxis.which; C4KeyCode keyCode = event.caxis.value >= 0 ? maxCode : minCode; auto doInput = [&](C4KeyEventType event, int32_t strength) { Game.DoKeyboardInput( C4KeyCodeEx(KEY_Gamepad(keyCode), KEYS_None, false, which), event, NULL, false, strength); }; if (feed & FEED_BUTTONS) { // Also emulate button presses. if (PressedAxis.count(keyCode) && value <= deadZone) { PressedAxis.erase(keyCode); doInput(KEYEV_Up, -1); } else if (!PressedAxis.count(keyCode) && value > deadZone) { PressedAxis.insert(keyCode); doInput(KEYEV_Down, -1); } } if (feed & FEED_MOVED) doInput(KEYEV_Moved, value); AxisEvents[keyCode] = event; break; } case SDL_CONTROLLERBUTTONDOWN: if (feed & FEED_BUTTONS) Game.DoKeyboardInput( C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_Button(event.cbutton.button)), KEYS_None, false, event.cbutton.which), KEYEV_Down); break; case SDL_CONTROLLERBUTTONUP: if (feed & FEED_BUTTONS) Game.DoKeyboardInput( C4KeyCodeEx(KEY_Gamepad(KEY_CONTROLLER_Button(event.cbutton.button)), KEYS_None, false, event.cbutton.which), KEYEV_Up); break; } }
C4ChatControl::ChatSheet::ChatSheet(C4ChatControl *pChatControl, const char *szTitle, const char *szIdent, SheetType eType) : C4GUI::Tabular::Sheet(szTitle, C4Rect(0, 0, 10, 10), C4GUI::Ico_None, true, false), iBackBufferIndex(-1), eType(eType), pNickList(NULL), pInputLbl(NULL), pChatControl(pChatControl), fHasUnread(false) { if (szIdent) sIdent.Copy(szIdent); // create elements - positioned later C4Rect rcDefault(0, 0, 10, 10); pChatBox = new C4GUI::TextWindow(rcDefault); // pChatBox->SetToolTip(LoadResStr("IDS_DLGTIP_CHATWIN")); tooltip doesn't // really help, only makes things unübersichtlich pChatBox->SetDecoration(false, false, NULL, false); AddElement(pChatBox); if (eType == CS_Channel) { pNickList = new C4GUI::ListBox(rcDefault); pNickList->SetDecoration(false, NULL, true, false); pNickList->SetSelectionDblClickFn( new C4GUI::CallbackHandler<C4ChatControl::ChatSheet>( this, &C4ChatControl::ChatSheet::OnNickDblClick)); AddElement(pNickList); } if (eType != CS_Server) pInputLbl = new C4GUI::WoodenLabel(LoadResStr("IDS_DLG_CHAT"), rcDefault, C4GUI_CaptionFontClr, &C4GUI::GetRes()->TextFont); pInputEdit = new C4GUI::CallbackEdit<C4ChatControl::ChatSheet>( rcDefault, this, &C4ChatControl::ChatSheet::OnChatInput); pInputEdit->SetToolTip(LoadResStr("IDS_DLGTIP_CHAT")); if (pInputLbl) { pInputLbl->SetToolTip(LoadResStr("IDS_DLGTIP_CHAT")); pInputLbl->SetClickFocusControl(pInputEdit); AddElement(pInputLbl); } AddElement(pInputEdit); // key bindings pKeyHistoryUp = new C4KeyBinding( C4KeyCodeEx(K_UP), "ChatHistoryUp", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx<C4ChatControl::ChatSheet, bool>( *this, true, &C4ChatControl::ChatSheet::KeyHistoryUpDown), C4CustomKey::PRIO_CtrlOverride); pKeyHistoryDown = new C4KeyBinding( C4KeyCodeEx(K_DOWN), "ChatHistoryDown", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx<C4ChatControl::ChatSheet, bool>( *this, false, &C4ChatControl::ChatSheet::KeyHistoryUpDown), C4CustomKey::PRIO_CtrlOverride); }
Button::Button(const char *szBtnText, const C4Rect &rtBounds) : Control(rtBounds), pCustomGfx(NULL), pCustomGfxDown(NULL), fDown(false), fMouseOver(false), fEnabled(true), dwCustomFontClr(0), pCustomFont(NULL) { // key callbacks C4CustomKey::CodeList keys; keys.push_back(C4KeyCodeEx(K_SPACE)); keys.push_back(C4KeyCodeEx(K_RETURN)); if (Config.Controls.GamepadGuiControl) keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_AnyLowButton))); pKeyButton = new C4KeyBinding(keys, "GUIButtonPress", KEYSCOPE_Gui, new ControlKeyCB<Button>(*this, &Button::KeyButtonDown, &Button::KeyButtonUp), C4CustomKey::PRIO_Ctrl); sText = ""; // set new button text SetText(szBtnText); }
C4StartupMainDlg::C4StartupMainDlg() : C4StartupDlg(NULL) // create w/o title; it is drawn in custom draw proc { // ctor fFirstShown = true; // screen calculations int iButtonPadding = 2; int iButtonHeight = C4GUI_BigButtonHgt; C4GUI::ComponentAligner caMain(rcBounds, 0,0,true); C4GUI::ComponentAligner caRightPanel(caMain.GetFromLeft(rcBounds.Wdt*2/5), rcBounds.Wdt/26, 40+rcBounds.Hgt/5); C4GUI::ComponentAligner caButtons(caRightPanel.GetAll(), 0, iButtonPadding); // main menu buttons C4GUI::CallbackButton<C4StartupMainDlg> *btn; AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_BTN_LOCALGAME"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnStartBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_STARTGAME")); btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown); pStartButton = btn; AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_BTN_NETWORKGAME"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnNetJoinBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_NETWORKGAME")); btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown); AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_PLAYERSELECTION"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnPlayerSelectionBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_PLAYERSELECTION")); btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown); AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_OPTIONS"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnOptionsBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_OPTIONS")); btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown); AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_ABOUT"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnAboutBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_ABOUT")); btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown); AddElement(btn = new C4GUI::CallbackButton<C4StartupMainDlg>(LoadResStr("IDS_DLG_EXIT"), caButtons.GetFromTop(iButtonHeight), &C4StartupMainDlg::OnExitBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_EXIT")); btn->SetCustomGraphics(&C4Startup::Get()->Graphics.barMainButtons, &C4Startup::Get()->Graphics.barMainButtonsDown); // list of selected players AddElement(pParticipantsLbl = new C4GUI::Label("test", GetClientRect().Wdt*39/40, GetClientRect().Hgt*9/10, ARight, 0xffffffff, &::GraphicsResource.TitleFont, false)); pParticipantsLbl->SetToolTip(LoadResStr("IDS_DLGTIP_SELECTEDPLAYERS")); // player selection shortcut - to be made optional UpdateParticipants(); pParticipantsLbl->SetContextHandler(new C4GUI::CBContextHandler<C4StartupMainDlg>(this, &C4StartupMainDlg::OnPlayerSelContext)); // key bindings C4CustomKey::CodeList keys; keys.push_back(C4KeyCodeEx(K_DOWN)); keys.push_back(C4KeyCodeEx(K_RIGHT)); if (Config.Controls.GamepadGuiControl) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_Down))); // right will be done by Dialog already } pKeyDown = new C4KeyBinding(keys, "StartupMainCtrlNext", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx<C4StartupMainDlg, bool>(*this, false, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride); keys.clear(); keys.push_back(C4KeyCodeEx(K_UP)); keys.push_back(C4KeyCodeEx(K_LEFT)); if (Config.Controls.GamepadGuiControl) { keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_Up))); // left will be done by Dialog already } pKeyUp = new C4KeyBinding(keys, "StartupMainCtrlPrev", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx<C4StartupMainDlg, bool>(*this, true, &C4StartupMainDlg::KeyAdvanceFocus), C4CustomKey::PRIO_CtrlOverride); keys.clear(); keys.push_back(C4KeyCodeEx(K_RETURN)); pKeyEnter = new C4KeyBinding(keys, "StartupMainOK", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4StartupMainDlg>(*this, &C4StartupMainDlg::KeyEnterDown, &C4StartupMainDlg::KeyEnterUp), C4CustomKey::PRIO_CtrlOverride); }
CheckBox::CheckBox(const C4Rect &rtBounds, const char *szCaption, bool fChecked) : Control(rtBounds), fChecked(fChecked), fMouseOn(false), fEnabled(true), pFont(NULL) , dwEnabledClr(C4GUI_CheckboxFontClr), dwDisabledClr(C4GUI_CheckboxDisabledFontClr), cHotkey(0) { if (szCaption) { sCaption.Copy(szCaption); ExpandHotkeyMarkup(sCaption, cHotkey); } // key callbacks: Check/Uncheck on space and primary joy button C4CustomKey::CodeList Keys; Keys.push_back(C4KeyCodeEx(K_SPACE)); if (Config.Controls.GamepadGuiControl) { Keys.push_back(C4KeyCodeEx(KEY_Gamepad(0, KEY_JOY_AnyLowButton))); } pKeyCheck = new C4KeyBinding(Keys, "GUICheckboxToggle", KEYSCOPE_Gui, new ControlKeyCB<CheckBox>(*this, &CheckBox::KeyCheck), C4CustomKey::PRIO_Ctrl); pCBHandler = NULL; }
C4FileSelDlg::DefaultListItem::DefaultListItem(const char *szFilename, bool fTruncateExtension, bool fCheckbox, bool fGrayed, C4GUI::Icons eIcon) : C4FileSelDlg::ListItem(szFilename), pLbl(NULL), pCheck(NULL), pKeyCheck(NULL), fGrayed(fGrayed) { StdStrBuf sLabel; if (szFilename) sLabel.Ref(::GetFilename(szFilename)); else sLabel.Ref(LoadResStr("IDS_CTL_NONE")); if (szFilename && fTruncateExtension) { sLabel.Copy(); char *szFilename = sLabel.GrabPointer(); RemoveExtension(szFilename); sLabel.Take(szFilename); } rcBounds.Hgt = C4GUI::GetRes()->TextFont.GetLineHeight(); UpdateSize(); C4GUI::ComponentAligner caMain(GetContainedClientRect(), 0, 0); int32_t iHeight = caMain.GetInnerHeight(); if (fCheckbox) { pCheck = new C4GUI::CheckBox(caMain.GetFromLeft(iHeight), NULL, false); if (fGrayed) pCheck->SetEnabled(false); AddElement(pCheck); pKeyCheck = new C4KeyBinding( C4KeyCodeEx(K_SPACE), "FileSelToggleFileActive", KEYSCOPE_Gui, new C4GUI::ControlKeyCB<ListItem>(*this, &ListItem::UserToggleCheck), C4CustomKey::PRIO_Ctrl); } C4GUI::Icon *pIco = new C4GUI::Icon(caMain.GetFromLeft(iHeight), eIcon); AddElement(pIco); pLbl = new C4GUI::Label( sLabel.getData(), caMain.GetAll(), ALeft, fGrayed ? C4GUI_CheckboxDisabledFontClr : C4GUI_CheckboxFontClr); AddElement(pLbl); }
C4StartupNetDlg::C4StartupNetDlg() : C4StartupDlg(LoadResStr("IDS_DLG_NETSTART")) { // ctor // key bindings C4CustomKey::CodeList keys; keys.emplace_back(K_BACK); keys.emplace_back(K_LEFT); pKeyBack = new C4KeyBinding(keys, "StartupNetBack", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4StartupNetDlg>(*this, &C4StartupNetDlg::KeyBack), C4CustomKey::PRIO_Dlg); pKeyRefresh = new C4KeyBinding(C4KeyCodeEx(K_F5), "StartupNetReload", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4StartupNetDlg>(*this, &C4StartupNetDlg::KeyRefresh), C4CustomKey::PRIO_CtrlOverride); // screen calculations UpdateSize(); int32_t iIconSize = C4GUI_IconExWdt; int32_t iButtonWidth,iCaptionFontHgt, iSideSize = std::max<int32_t>(GetBounds().Wdt/6, iIconSize); int32_t iButtonHeight = C4GUI_ButtonHgt, iButtonIndent = GetBounds().Wdt/40; ::GraphicsResource.CaptionFont.GetTextExtent("<< BACK", iButtonWidth, iCaptionFontHgt, true); iButtonWidth *= 3; C4GUI::ComponentAligner caMain(GetClientRect(), 0,0, true); C4GUI::ComponentAligner caButtonArea(caMain.GetFromBottom(caMain.GetHeight()/7),0,0); int32_t iButtonAreaWdt = caButtonArea.GetWidth()*7/8; iButtonWidth = std::min<int32_t>(iButtonWidth, (iButtonAreaWdt - 8 * iButtonIndent)/4); iButtonIndent = (iButtonAreaWdt - 4 * iButtonWidth) / 8; C4GUI::ComponentAligner caButtons(caButtonArea.GetCentered(iButtonAreaWdt, iButtonHeight),iButtonIndent,0); C4GUI::ComponentAligner caLeftBtnArea(caMain.GetFromLeft(iSideSize), std::min<int32_t>(caMain.GetWidth()/20, (iSideSize-C4GUI_IconExWdt)/2), caMain.GetHeight()/40); C4GUI::ComponentAligner caConfigArea(caMain.GetFromRight(iSideSize), std::min<int32_t>(caMain.GetWidth()/20, (iSideSize-C4GUI_IconExWdt)/2), caMain.GetHeight()/40); // left button area: Switch between chat and game list if (C4ChatDlg::IsChatEnabled()) { btnGameList = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(C4GUI::Ico_Ex_GameList, caLeftBtnArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnGameList); btnGameList->SetToolTip(LoadResStr("IDS_DESC_SHOWSAVAILABLENETWORKGAME")); btnGameList->SetText(LoadResStr("IDS_BTN_GAMES")); AddElement(btnGameList); btnChat = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(C4GUI::Ico_Ex_Chat, caLeftBtnArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnChat); btnChat->SetToolTip(LoadResStr("IDS_DESC_CONNECTSTOANIRCCHATSERVER")); btnChat->SetText(LoadResStr("IDS_BTN_CHAT")); AddElement(btnChat); } else btnChat = nullptr; // main area: Tabular to switch between game list and chat pMainTabular = new C4GUI::Tabular(caMain.GetAll(), C4GUI::Tabular::tbNone); pMainTabular->SetDrawDecoration(false); pMainTabular->SetSheetMargin(0); AddElement(pMainTabular); // main area: game selection sheet C4GUI::Tabular::Sheet *pSheetGameList = pMainTabular->AddSheet(nullptr); C4GUI::ComponentAligner caGameList(pSheetGameList->GetContainedClientRect(), 0,0, false); C4GUI::WoodenLabel *pGameListLbl; int32_t iCaptHgt = C4GUI::WoodenLabel::GetDefaultHeight(&::GraphicsResource.TextFont); pGameListLbl = new C4GUI::WoodenLabel(LoadResStr("IDS_NET_GAMELIST"), caGameList.GetFromTop(iCaptHgt), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont, ALeft); // search field C4GUI::WoodenLabel *pSearchLbl; const char *szSearchLblText = LoadResStr("IDS_NET_MSSEARCH"); int32_t iSearchWdt=100, iSearchHgt; ::GraphicsResource.TextFont.GetTextExtent(szSearchLblText, iSearchWdt, iSearchHgt, true); C4GUI::ComponentAligner caSearch(caGameList.GetFromTop(iSearchHgt), 0,0); pSearchLbl = new C4GUI::WoodenLabel(szSearchLblText, caSearch.GetFromLeft(iSearchWdt+10), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont); const char *szSearchTip = LoadResStr("IDS_NET_MSSEARCH_DESC"); pSearchLbl->SetToolTip(szSearchTip); pSheetGameList->AddElement(pSearchLbl); pSearchFieldEdt = new C4GUI::CallbackEdit<C4StartupNetDlg>(caSearch.GetAll(), this, &C4StartupNetDlg::OnSearchFieldEnter); pSearchFieldEdt->SetToolTip(szSearchTip); pSheetGameList->AddElement(pSearchFieldEdt); pSheetGameList->AddElement(pGameListLbl); pGameSelList = new C4GUI::ListBox(caGameList.GetFromTop(caGameList.GetHeight() - iCaptHgt)); pGameSelList->SetDecoration(true, nullptr, true, true); pGameSelList->UpdateElementPositions(); pGameSelList->SetSelectionDblClickFn(new C4GUI::CallbackHandler<C4StartupNetDlg>(this, &C4StartupNetDlg::OnSelDblClick)); pGameSelList->SetSelectionChangeCallbackFn(new C4GUI::CallbackHandler<C4StartupNetDlg>(this, &C4StartupNetDlg::OnSelChange)); pSheetGameList->AddElement(pGameSelList); C4GUI::ComponentAligner caIP(caGameList.GetAll(), 0,0); C4GUI::WoodenLabel *pIPLbl; const char *szIPLblText = LoadResStr("IDS_NET_IP"); int32_t iIPWdt=100, Q; ::GraphicsResource.TextFont.GetTextExtent(szIPLblText, iIPWdt, Q, true); pIPLbl = new C4GUI::WoodenLabel(szIPLblText, caIP.GetFromLeft(iIPWdt+10), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont); const char *szIPTip = LoadResStr("IDS_NET_IP_DESC"); pIPLbl->SetToolTip(szIPTip); pSheetGameList->AddElement(pIPLbl); pJoinAddressEdt = new C4GUI::CallbackEdit<C4StartupNetDlg>(caIP.GetAll(), this, &C4StartupNetDlg::OnJoinAddressEnter); pJoinAddressEdt->SetToolTip(szIPTip); pSheetGameList->AddElement(pJoinAddressEdt); // main area: chat sheet if (C4ChatDlg::IsChatEnabled()) { C4GUI::Tabular::Sheet *pSheetChat = pMainTabular->AddSheet(nullptr); C4GUI::ComponentAligner caChat(pSheetChat->GetContainedClientRect(), 0,0, false); pSheetChat->AddElement(pChatTitleLabel = new C4GUI::WoodenLabel("", caChat.GetFromTop(iCaptHgt), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont, ALeft, false)); C4GUI::GroupBox *pChatGroup = new C4GUI::GroupBox(caChat.GetAll()); pChatGroup->SetColors(0u, C4GUI_CaptionFontClr, C4GUI_StandardBGColor); pChatGroup->SetMargin(2); pSheetChat->AddElement(pChatGroup); pChatCtrl = new C4ChatControl(&Application.IRCClient); pChatCtrl->SetBounds(pChatGroup->GetContainedClientRect()); pChatCtrl->SetTitleChangeCB(new C4GUI::InputCallback<C4StartupNetDlg>(this, &C4StartupNetDlg::OnChatTitleChange)); StdStrBuf sCurrTitle; sCurrTitle.Ref(pChatCtrl->GetTitle()); OnChatTitleChange(sCurrTitle); pChatGroup->AddElement(pChatCtrl); } // config area btnInternet = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(Config.Network.MasterServerSignUp ? C4GUI::Ico_Ex_InternetOn : C4GUI::Ico_Ex_InternetOff, caConfigArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnInternet); btnInternet->SetToolTip(LoadResStr("IDS_DLGTIP_SEARCHINTERNETGAME")); btnInternet->SetText(LoadResStr("IDS_CTL_INETSERVER")); AddElement(btnInternet); btnRecord = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(Game.Record ? C4GUI::Ico_Ex_RecordOn : C4GUI::Ico_Ex_RecordOff, caConfigArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnRecord); btnRecord->SetToolTip(LoadResStr("IDS_DLGTIP_RECORD")); btnRecord->SetText(LoadResStr("IDS_CTL_RECORD")); AddElement(btnRecord); #ifdef WITH_AUTOMATIC_UPDATE btnUpdate = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(C4GUI::Ico_Ex_Update, caConfigArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnUpdate); btnUpdate->SetVisibility(false); // update only available if masterserver notifies it btnUpdate->SetToolTip(LoadResStr("IDS_DLGTIP_UPDATE")); btnUpdate->SetText(LoadResStr("IDS_CTL_UPDATE")); AddElement(btnUpdate); #endif // button area C4GUI::CallbackButton<C4StartupNetDlg> *btn; AddElement(btn = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_BTN_BACK"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnBackBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_BACKMAIN")); AddElement(btnRefresh = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_BTN_RELOAD"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnRefreshBtn)); btnRefresh->SetToolTip(LoadResStr("IDS_NET_RELOAD_DESC")); AddElement(btnJoin = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_NET_JOINGAME_BTN"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnJoinGameBtn)); btnJoin->SetToolTip(LoadResStr("IDS_NET_JOINGAME_DESC")); AddElement(btn = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_NET_NEWGAME"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnCreateGameBtn)); btn->SetToolTip(LoadResStr("IDS_NET_NEWGAME_DESC")); // initial dlg mode UpdateDlgMode(); // initial focus SetFocus(GetDlgModeFocusControl(), false); // initialize discovery DiscoverClient.Init(Config.Network.PortDiscovery); DiscoverClient.StartDiscovery(); iGameDiscoverInterval = C4NetGameDiscoveryInterval; // register timer Application.Add(this); // register as receiver of reference notifies Application.InteractiveThread.SetCallback(Ev_HTTP_Response, this); }
C4ChatInputDialog::C4ChatInputDialog(bool fObjInput, C4Object *pScriptTarget, bool fUppercase, bool fTeam, int32_t iPlr, const StdStrBuf &rsInputQuery) : C4GUI::InputDialog( fObjInput ? rsInputQuery.getData() : LoadResStrNoAmp("IDS_CTL_CHAT"), NULL, C4GUI::Ico_None, NULL, !fObjInput || IsSmallInputQuery(rsInputQuery.getData())), fObjInput(fObjInput), fUppercase(fUppercase), pTarget(pScriptTarget), BackIndex(-1), iPlr(iPlr), fProcessed(false) { // singleton-var pInstance = this; // set custom edit control SetCustomEdit(new C4GUI::CallbackEdit<C4ChatInputDialog>( C4Rect(0, 0, 10, 10), this, &C4ChatInputDialog::OnChatInput, &C4ChatInputDialog::OnChatCancel)); // key bindings pKeyHistoryUp = new C4KeyBinding(C4KeyCodeEx(K_UP), "ChatHistoryUp", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx<C4ChatInputDialog, bool>( *this, true, &C4ChatInputDialog::KeyHistoryUpDown), C4CustomKey::PRIO_CtrlOverride); pKeyHistoryDown = new C4KeyBinding(C4KeyCodeEx(K_DOWN), "ChatHistoryDown", KEYSCOPE_Gui, new C4GUI::DlgKeyCBEx<C4ChatInputDialog, bool>( *this, false, &C4ChatInputDialog::KeyHistoryUpDown), C4CustomKey::PRIO_CtrlOverride); pKeyAbort = new C4KeyBinding( C4KeyCodeEx(K_F2), "ChatAbort", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4GUI::Dialog>(*this, &C4GUI::Dialog::KeyEscape), C4CustomKey::PRIO_CtrlOverride); pKeyNickComplete = new C4KeyBinding(C4KeyCodeEx(K_TAB), "ChatNickComplete", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4ChatInputDialog>( *this, &C4ChatInputDialog::KeyCompleteNick), C4CustomKey::PRIO_CtrlOverride); pKeyPlrControl = new C4KeyBinding( C4KeyCodeEx(KEY_Any, KEYS_Control), "ChatForwardPlrCtrl", KEYSCOPE_Gui, new C4GUI::DlgKeyCBPassKey<C4ChatInputDialog>( *this, &C4ChatInputDialog::KeyPlrControl), C4CustomKey::PRIO_Dlg); pKeyGamepadControl = new C4KeyBinding( C4KeyCodeEx(KEY_Any), "ChatForwardGamepadCtrl", KEYSCOPE_Gui, new C4GUI::DlgKeyCBPassKey<C4ChatInputDialog>( *this, &C4ChatInputDialog::KeyGamepadControlDown, &C4ChatInputDialog::KeyGamepadControlUp, &C4ChatInputDialog::KeyGamepadControlPressed), C4CustomKey::PRIO_PlrControl); pKeyBackClose = new C4KeyBinding(C4KeyCodeEx(K_BACK), "ChatBackspaceClose", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4ChatInputDialog>( *this, &C4ChatInputDialog::KeyBackspaceClose), C4CustomKey::PRIO_CtrlOverride); // free when closed... SetDelOnClose(); // initial team text if (fTeam) pEdit->InsertText("/team ", true); }
bool C4KeyboardInput::DoInput(const C4KeyCodeEx &InKey, C4KeyEventType InEvent, DWORD InScope, int32_t iStrength) { // store last-key-info LastKeyExtraData.iStrength = (iStrength >= 0) ? iStrength : ((InEvent != KEYEV_Up) * 100); LastKeyExtraData.game_x = LastKeyExtraData.game_y = LastKeyExtraData.vp_x = LastKeyExtraData.vp_y = C4KeyEventData::KeyPos_None; // check all key events generated by this key: First the keycode itself, then any more generic key events like KEY_Any const int32_t iKeyRangeMax = 5; int32_t iKeyRangeCnt=0, j; C4KeyCode FallbackKeys[iKeyRangeMax]; FallbackKeys[iKeyRangeCnt++] = InKey.Key; if (Key_IsGamepadButton(InKey.Key)) { uint8_t byGamepad = Key_GetGamepad(InKey.Key); uint8_t byBtnIndex = Key_GetGamepadButtonIndex(InKey.Key); // even/odd button events: Add even button indices as odd events, because byBtnIndex is zero-based and the event naming scheme is for one-based button indices if (byBtnIndex % 2) FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyEvenButton); else FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyOddButton); // high/low button events if (byBtnIndex < 4) FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyLowButton); else FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyHighButton); // "any gamepad button"-event FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, KEY_JOY_AnyButton); } else if (Key_IsGamepadAxis(InKey.Key)) { // xy-axis-events for all even/odd axises uint8_t byGamepad = Key_GetGamepad(InKey.Key); uint8_t byAxis = Key_GetGamepadAxisIndex(InKey.Key); bool fHigh = Key_IsGamepadAxisHigh(InKey.Key); C4KeyCode keyAxisDir; if (byAxis % 2) if (fHigh) keyAxisDir = KEY_JOY_Down; else keyAxisDir = KEY_JOY_Up; else if (fHigh) keyAxisDir = KEY_JOY_Right; else keyAxisDir = KEY_JOY_Left; FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(byGamepad, (uint8_t)keyAxisDir); } if (InKey.Key != KEY_Any) FallbackKeys[iKeyRangeCnt++] = KEY_Any; // now get key ranges for fallback chain std::pair<KeyCodeMap::iterator, KeyCodeMap::iterator> KeyRanges[iKeyRangeMax]; assert(iKeyRangeCnt <= iKeyRangeMax); for (int32_t i = 0; i<iKeyRangeCnt; ++i) { KeyRanges[i] = KeysByCode.equal_range(FallbackKeys[i]); } // check all assigned keys // exec from highest to lowest priority unsigned int uiLastPrio = C4CustomKey::PRIO_MoreThanMax; for (;;) { KeyCodeMap::const_iterator i; // get priority to exec unsigned int uiExecPrio = C4CustomKey::PRIO_None, uiCurr; for (j = 0; j < iKeyRangeCnt; ++j) for (i = KeyRanges[j].first; i != KeyRanges[j].second; ++i) { uiCurr = i->second->GetPriority(); if (uiCurr > uiExecPrio && uiCurr < uiLastPrio) uiExecPrio = uiCurr; } // nothing with correct priority set left? if (uiExecPrio == C4CustomKey::PRIO_None) break; // exec all of this priority for (j = 0; j < iKeyRangeCnt; ++j) for (i = KeyRanges[j].first; i != KeyRanges[j].second; ++i) { C4CustomKey *pKey = i->second; assert(pKey); // check priority if (pKey->GetPriority() == uiExecPrio) // check scope and modifier // (not on release of a key that has been down, because a key release might happen with a different modifier or in different scope than its pressing!) if ((InEvent == KEYEV_Up && pKey->IsDown()) || ((pKey->GetScope() & InScope) && pKey->IsCodeMatched(C4KeyCodeEx(FallbackKeys[j], C4KeyShiftState(InKey.dwShift))))) // exec it if (pKey->Execute(InEvent, InKey)) return true; } // nothing found in this priority: exec next uiLastPrio = uiExecPrio; } // no key matched or all returned false in Execute: Not processed return false; }