C4Network2ClientListBox::ClientListItem::ClientListItem(class C4Network2ClientListBox *pForDlg, int iClientID) // ctor : ListItem(pForDlg, iClientID), pStatusIcon(nullptr), pName(nullptr), pPing(nullptr), pActivateBtn(nullptr), pKickBtn(nullptr), last_sound_time(0) { // get associated client const C4Client *pClient = GetClient(); // get size int iIconSize = ::GraphicsResource.TextFont.GetLineHeight(); if (pForDlg->IsStartup()) iIconSize *= 2; int iWidth = pForDlg->GetItemWidth(); int iVerticalIndent = 2; SetBounds(C4Rect(0, 0, iWidth, iIconSize+2*iVerticalIndent)); C4GUI::ComponentAligner ca(GetContainedClientRect(), 0,iVerticalIndent); // create subcomponents bool fIsHost = pClient && pClient->isHost(); pStatusIcon = new C4GUI::Icon(ca.GetFromLeft(iIconSize), fIsHost ? C4GUI::Ico_Host : C4GUI::Ico_Client); StdStrBuf sNameLabel; if (pClient) { if (pForDlg->IsStartup()) sNameLabel.Ref(pClient->getName()); else sNameLabel.Format("%s:%s", pClient->getName(), pClient->getNick()); } else { sNameLabel.Ref("???"); } pName = new C4GUI::Label(sNameLabel.getData(), iIconSize + IconLabelSpacing,iVerticalIndent, ALeft); int iPingRightPos = GetBounds().Wdt - IconLabelSpacing; if (::Network.isHost()) iPingRightPos -= 48; if (::Network.isHost() && pClient && !pClient->isHost()) { // activate/deactivate and kick btns for clients at host if (!pForDlg->IsStartup()) { pActivateBtn = new C4GUI::CallbackButtonEx<C4Network2ClientListBox::ClientListItem, C4GUI::IconButton>(C4GUI::Ico_Active, GetToprightCornerRect(std::max(iIconSize, 16),std::max(iIconSize, 16),2,1,1), 0, this, &ClientListItem::OnButtonActivate); fShownActive = true; } pKickBtn = new C4GUI::CallbackButtonEx<C4Network2ClientListBox::ClientListItem, C4GUI::IconButton>(C4GUI::Ico_Kick, GetToprightCornerRect(std::max(iIconSize, 16),std::max(iIconSize, 16),2,1,0), 0, this, &ClientListItem::OnButtonKick); pKickBtn->SetToolTip(LoadResStrNoAmp("IDS_NET_KICKCLIENT")); } if (!pForDlg->IsStartup()) if (pClient && !pClient->isLocal()) { // wait time pPing = new C4GUI::Label("???", iPingRightPos, iVerticalIndent, ARight); pPing->SetToolTip(LoadResStr("IDS_DESC_CONTROLWAITTIME")); } // add components AddElement(pStatusIcon); AddElement(pName); if (pPing) AddElement(pPing); if (pActivateBtn) AddElement(pActivateBtn); if (pKickBtn) AddElement(pKickBtn); // add to listbox (will eventually get moved) pForDlg->AddElement(this); // first-time update Update(); }
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); }
void C4Network2ClientListBox::ClientListItem::Update() { // update wait label if (pPing) { int iWait = ::Control.Network.ClientPerfStat(iClientID); pPing->SetText(FormatString("%d ms", iWait).getData()); pPing->SetColor(C4RGB( Clamp(255-Abs(iWait)*5, 0, 255), Clamp(255-iWait*5, 0, 255), Clamp(255+iWait*5, 0, 255))); } // update activation status const C4Client *pClient = GetClient(); if (!pClient) return; bool fIsActive = pClient->isActivated(); if (fIsActive != fShownActive) { fShownActive = fIsActive; if (!pClient->isHost()) pStatusIcon->SetIcon(fIsActive ? C4GUI::Ico_Client : C4GUI::Ico_ObserverClient); if (pActivateBtn) { pActivateBtn->SetIcon(fIsActive ? C4GUI::Ico_Active : C4GUI::Ico_Inactive); pActivateBtn->SetToolTip(LoadResStrNoAmp(fIsActive ? "IDS_NET_DEACTIVATECLIENT" : "IDS_NET_ACTIVATECLIENT")); } } // update players in tooltip StdStrBuf sCltPlrs(Game.PlayerInfos.GetActivePlayerNames(false, iClientID)); pName->SetToolTip(sCltPlrs.getData()); // update icon: Network status C4GUI::Icons icoStatus = C4GUI::Ico_UnknownClient; C4Network2Client *pClt = pClient->getNetClient(); if (pClt) { switch (pClt->getStatus()) { case NCS_Joining: // waiting for join data case NCS_Chasing: // client is behind (status not acknowledged, isn't waited for) case NCS_NotReady: // client is behind (status not acknowledged) icoStatus = C4GUI::Ico_Loading; break; case NCS_Ready: // client acknowledged network status icoStatus = C4GUI::Ico_Ready; break; case NCS_Remove: // client is to be removed icoStatus = C4GUI::Ico_Kick; break; default: // whatever assert(false); icoStatus = C4GUI::Ico_Loading; break; } } // sound icon? if (last_sound_time) { time_t dt = time(nullptr) - last_sound_time; if (dt >= SoundIconShowTime) { // stop showing sound icon last_sound_time = 0; } else { // time not up yet: show sound icon icoStatus = C4GUI::Ico_Sound; } } // network OK - control ready? if (!pForDlg->IsStartup() && (icoStatus == C4GUI::Ico_Ready)) { if (!::Control.Network.ClientReady(iClientID, ::Control.ControlTick)) { // control not ready icoStatus = C4GUI::Ico_NetWait; } } // set new icon pStatusIcon->SetIcon(icoStatus); }