diff options
Diffstat (limited to 'src/network/network_gui.cpp')
-rw-r--r-- | src/network/network_gui.cpp | 118 |
1 files changed, 35 insertions, 83 deletions
diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 8506ca6b9..f96a72297 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1757,13 +1757,6 @@ extern void DrawCompanyIcon(CompanyID cid, int x, int y); /* Every action must be of this form */ typedef void ClientList_Action_Proc(byte client_no); -/* Max 10 actions per client */ -#define MAX_CLIENTLIST_ACTION 10 - -enum { - CLNWND_OFFSET = 16, -}; - static const Widget _client_list_popup_widgets[] = { { WWT_PANEL, RESIZE_NONE, COLOUR_GREY, 0, 99, 0, 0, 0, STR_NULL}, { WIDGETS_END}, @@ -1831,67 +1824,60 @@ static void ClientList_SpeakToAll(byte client_no) ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0); } -static void ClientList_None(byte client_no) -{ - /* No action ;) */ -} - - - +/** Popup selection window to chose an action to perform */ struct NetworkClientListPopupWindow : Window { - int sel_index; + /** Container for actions that can be executed. */ + struct ClientListAction { + StringID name; ///< Name of the action to execute + ClientList_Action_Proc *proc; ///< Action to execute + }; + + uint sel_index; int client_no; - char action[MAX_CLIENTLIST_ACTION][50]; - ClientList_Action_Proc *proc[MAX_CLIENTLIST_ACTION]; + SmallVector<ClientListAction, 2> actions; ///< Actions to execute + + /** + * Add an action to the list of actions to execute. + * @param name the name of the action + * @param proc the procedure to execute for the action + */ + inline void AddAction(StringID name, ClientList_Action_Proc *proc) + { + ClientListAction *action = this->actions.Append(); + action->name = name; + action->proc = proc; + } NetworkClientListPopupWindow(int x, int y, const Widget *widgets, int client_no) : Window(x, y, 150, 100, WC_TOOLBAR_MENU, widgets), sel_index(0), client_no(client_no) { - /* - * Fill the actions this client has. - * Watch is, max 50 chars long! - */ - const NetworkClientInfo *ci = NetworkFindClientInfo(client_no); - int i = 0; if (_network_own_client_id != ci->client_id) { - GetString(this->action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(this->action[i])); - this->proc[i++] = &ClientList_SpeakToClient; + this->AddAction(STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, &ClientList_SpeakToClient); } if (Company::IsValidID(ci->client_playas) || ci->client_playas == COMPANY_SPECTATOR) { - GetString(this->action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(this->action[i])); - this->proc[i++] = &ClientList_SpeakToCompany; + this->AddAction(STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, &ClientList_SpeakToCompany); } - GetString(this->action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(this->action[i])); - this->proc[i++] = &ClientList_SpeakToAll; + this->AddAction(STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, &ClientList_SpeakToAll); if (_network_own_client_id != ci->client_id) { /* We are no spectator and the company we want to give money to is no spectator and money gifts are allowed */ if (Company::IsValidID(_local_company) && Company::IsValidID(ci->client_playas) && _settings_game.economy.give_money) { - GetString(this->action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(this->action[i])); - this->proc[i++] = &ClientList_GiveMoney; + this->AddAction(STR_NETWORK_CLIENTLIST_GIVE_MONEY, &ClientList_GiveMoney); } } /* A server can kick clients (but not himself) */ if (_network_server && _network_own_client_id != ci->client_id) { - GetString(this->action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(this->action[i])); - this->proc[i++] = &ClientList_Kick; - - GetString(this->action[i], STR_NETWORK_CLIENTLIST_BAN, lastof(this->action[i])); - this->proc[i++] = &ClientList_Ban; - } - - if (i == 0) { - GetString(this->action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(this->action[i])); - this->proc[i++] = &ClientList_None; + this->AddAction(STR_NETWORK_CLIENTLIST_KICK, &ClientList_Kick); + this->AddAction(STR_NETWORK_CLIENTLIST_BAN, &ClientList_Ban); } /* Calculate the height */ - int h = ClientListPopupHeight(); + int h = this->actions.Length() * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; /* Allocate the popup */ this->widget[0].bottom = this->widget[0].top + h; @@ -1902,48 +1888,14 @@ struct NetworkClientListPopupWindow : Window { this->FindWindowPlacementAndResize(150, h + 1); } - /** - * An action is clicked! What do we do? - */ - void HandleClientListPopupClick(byte index) - { - /* A click on the Popup of the ClientList.. handle the command */ - if (index < MAX_CLIENTLIST_ACTION && this->proc[index] != NULL) { - this->proc[index](this->client_no); - } - } - - /** - * Finds the amount of actions in the popup and set the height correct - */ - uint ClientListPopupHeight() - { - int num = 0; - - /* Find the amount of actions */ - for (int i = 0; i < MAX_CLIENTLIST_ACTION; i++) { - if (this->action[i][0] == '\0') continue; - if (this->proc[i] == NULL) continue; - num++; - } - - num *= FONT_HEIGHT_NORMAL; - - return num + 1; - } - - virtual void OnPaint() { this->DrawWidgets(); /* Draw the actions */ int sel = this->sel_index; - int y = 1; - for (int i = 0; i < MAX_CLIENTLIST_ACTION; i++, y += FONT_HEIGHT_NORMAL) { - if (this->action[i][0] == '\0') continue; - if (this->proc[i] == NULL) continue; - + int y = WD_FRAMERECT_TOP; + for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++, y += FONT_HEIGHT_NORMAL) { TextColour colour; if (sel-- == 0) { // Selected item, highlight it GfxFillRect(1, y, 150 - 2, y + FONT_HEIGHT_NORMAL - 1, 0); @@ -1952,23 +1904,23 @@ struct NetworkClientListPopupWindow : Window { colour = TC_BLACK; } - DrawString(4, this->width - 4, y, this->action[i], colour); + DrawString(4, this->width - 4, y, action->name, colour); } } virtual void OnMouseLoop() { /* We selected an action */ - int index = (_cursor.pos.y - this->top) / FONT_HEIGHT_NORMAL; + uint index = (_cursor.pos.y - this->top - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL; if (_left_button_down) { - if (index == -1 || index == this->sel_index) return; + if (index == this->sel_index || index >= this->actions.Length()) return; this->sel_index = index; this->SetDirty(); } else { - if (index >= 0 && _cursor.pos.y >= this->top) { - HandleClientListPopupClick(index); + if (index < this->actions.Length() && _cursor.pos.y >= this->top) { + this->actions[index].proc(this->client_no); } DeleteWindowById(WC_TOOLBAR_MENU, 0); |