Mercurial > hg > openttd
diff src/network/network_gui.cpp @ 9242:b400b0761465 draft
(svn r13108) -Codechange: make a Window subclass of the main toolbars sub menus.
author | rubidium <rubidium@openttd.org> |
---|---|
date | Thu, 15 May 2008 20:04:10 +0000 |
parents | 8299dc138e1c |
children | 9ba3a5bccb10 |
line wrap: on
line diff
--- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1217,14 +1217,6 @@ // Max 10 actions per client #define MAX_CLIENTLIST_ACTION 10 -// Some standard bullshit.. defines variables ;) -static void ClientListWndProc(Window *w, WindowEvent *e); -static void ClientListPopupWndProc(Window *w, WindowEvent *e); -static byte _selected_clientlist_item = 255; -static byte _selected_clientlist_y = 0; -static char _clientlist_action[MAX_CLIENTLIST_ACTION][50]; -static ClientList_Action_Proc *_clientlist_proc[MAX_CLIENTLIST_ACTION]; - enum { CLNWND_OFFSET = 16, CLNWND_ROWSIZE = 10 @@ -1249,7 +1241,7 @@ WC_CLIENT_LIST, WC_NONE, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON, _client_list_widgets, - ClientListWndProc + NULL }; // Finds the Xth client-info that is active @@ -1321,267 +1313,271 @@ -/** - * An action is clicked! What do we do? - */ -static void HandleClientListPopupClick(byte index, byte clientno) -{ - /* A click on the Popup of the ClientList.. handle the command */ - if (index < MAX_CLIENTLIST_ACTION && _clientlist_proc[index] != NULL) { - _clientlist_proc[index](clientno); - } -} +struct NetworkClientListPopupWindow : Window { + int sel_index; + int client_no; + char action[MAX_CLIENTLIST_ACTION][50]; + ClientList_Action_Proc *proc[MAX_CLIENTLIST_ACTION]; + + NetworkClientListPopupWindow(int x, int y, const Widget *widgets, int client_no) : + Window(x, y, 150, 100, NULL, 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_index != ci->client_index) { + GetString(this->action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(this->action[i])); + this->proc[i++] = &ClientList_SpeakToClient; + } + + if (IsValidPlayer(ci->client_playas) || ci->client_playas == PLAYER_SPECTATOR) { + GetString(this->action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(this->action[i])); + this->proc[i++] = &ClientList_SpeakToCompany; + } + GetString(this->action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(this->action[i])); + this->proc[i++] = &ClientList_SpeakToAll; -/** - * Finds the amount of clients and set the height correct - */ -static bool CheckClientListHeight(Window *w) -{ - int num = 0; - const NetworkClientInfo *ci; + if (_network_own_client_index != ci->client_index) { + /* We are no spectator and the player we want to give money to is no spectator and money gifts are allowed */ + if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas) && _patches.give_money) { + GetString(this->action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(this->action[i])); + this->proc[i++] = &ClientList_GiveMoney; + } + } + + /* A server can kick clients (but not himself) */ + if (_network_server && _network_own_client_index != ci->client_index) { + GetString(this->action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(this->action[i])); + this->proc[i++] = &ClientList_Kick; - /* Should be replaced with a loop through all clients */ - FOR_ALL_ACTIVE_CLIENT_INFOS(ci) { - num++; + sprintf(this->action[i],"Ban"); // XXX GetString? + 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; + } + + /* Calculate the height */ + int h = ClientListPopupHeight(); + + /* Allocate the popup */ + this->widget[0].bottom = this->widget[0].top + h; + this->widget[0].right = this->widget[0].left + 150; + + this->flags4 &= ~WF_WHITE_BORDER_MASK; + + this->FindWindowPlacementAndResize(150, h + 1); } - num *= CLNWND_ROWSIZE; - - /* If height is changed */ - if (w->height != CLNWND_OFFSET + num + 1) { - // XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1) - w->SetDirty(); - w->widget[3].bottom = w->widget[3].top + num + 2; - w->height = CLNWND_OFFSET + num + 1; - w->SetDirty(); - return false; + /** + * 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); + } } - return true; -} + + /** + * Finds the amount of actions in the popup and set the height correct + */ + uint ClientListPopupHeight() + { + int num = 0; -/** - * Finds the amount of actions in the popup and set the height correct - */ -static 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++; + } - // Find the amount of actions - for (int i = 0; i < MAX_CLIENTLIST_ACTION; i++) { - if (_clientlist_action[i][0] == '\0') continue; - if (_clientlist_proc[i] == NULL) continue; - num++; + num *= CLNWND_ROWSIZE; + + return num + 1; } - num *= CLNWND_ROWSIZE; + + virtual void OnPaint() + { + DrawWindowWidgets(this); + + /* Draw the actions */ + int sel = this->sel_index; + int y = 1; + for (int i = 0; i < MAX_CLIENTLIST_ACTION; i++, y += CLNWND_ROWSIZE) { + if (this->action[i][0] == '\0') continue; + if (this->proc[i] == NULL) continue; + + TextColour colour; + if (sel-- == 0) { // Selected item, highlight it + GfxFillRect(1, y, 150 - 2, y + CLNWND_ROWSIZE - 1, 0); + colour = TC_WHITE; + } else { + colour = TC_BLACK; + } - return num + 1; -} + DoDrawString(this->action[i], 4, y, colour); + } + } + + virtual void OnMouseLoop() + { + /* We selected an action */ + int index = (_cursor.pos.y - this->top) / CLNWND_ROWSIZE; + + if (_left_button_down) { + if (index == -1 || index == this->sel_index) return; + + this->sel_index = index; + this->SetDirty(); + } else { + if (index >= 0 && _cursor.pos.y >= this->top) { + HandleClientListPopupClick(index); + } + + DeleteWindowById(WC_TOOLBAR_MENU, 0); + } + } +}; /** * Show the popup (action list) */ -static Window *PopupClientList(Window *w, int client_no, int x, int y) +static void PopupClientList(int client_no, int x, int y) { - int i; - const NetworkClientInfo *ci; DeleteWindowById(WC_TOOLBAR_MENU, 0); - /* Clean the current actions */ - for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) { - _clientlist_action[i][0] = '\0'; - _clientlist_proc[i] = NULL; - } - - /* - * Fill the actions this client has. - * Watch is, max 50 chars long! - */ - - ci = NetworkFindClientInfo(client_no); - if (ci == NULL) return NULL; - - i = 0; - if (_network_own_client_index != ci->client_index) { - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_SpeakToClient; - } - - if (IsValidPlayer(ci->client_playas) || ci->client_playas == PLAYER_SPECTATOR) { - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_SpeakToCompany; - } - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_SpeakToAll; - - if (_network_own_client_index != ci->client_index) { - /* We are no spectator and the player we want to give money to is no spectator and money gifts are allowed */ - if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas) && _patches.give_money) { - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_GiveMoney; - } - } - - /* A server can kick clients (but not himself) */ - if (_network_server && _network_own_client_index != ci->client_index) { - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_KICK, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_Kick; - - sprintf(_clientlist_action[i],"Ban"); // XXX GetString? - _clientlist_proc[i++] = &ClientList_Ban; - } - - if (i == 0) { - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_None; - } - - /* Calculate the height */ - int h = ClientListPopupHeight(); + if (NetworkFindClientInfo(client_no) == NULL) return; - /* Allocate the popup */ - w = new Window(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets); - w->widget[0].bottom = w->widget[0].top + h; - w->widget[0].right = w->widget[0].left + 150; - - w->flags4 &= ~WF_WHITE_BORDER_MASK; - WP(w, menu_d).item_count = 0; - // Save our client - WP(w, menu_d).main_button = client_no; - WP(w, menu_d).sel_index = 0; - - return w; -} - -/** Main handle for the client popup list - * uses menu_d WP macro */ -static void ClientListPopupWndProc(Window *w, WindowEvent *e) -{ - switch (e->event) { - case WE_PAINT: { - DrawWindowWidgets(w); - - /* Draw the actions */ - int sel = WP(w, menu_d).sel_index; - int y = 1; - for (int i = 0; i < MAX_CLIENTLIST_ACTION; i++, y += CLNWND_ROWSIZE) { - if (_clientlist_action[i][0] == '\0') continue; - if (_clientlist_proc[i] == NULL) continue; - - TextColour colour; - if (sel-- == 0) { // Selected item, highlight it - GfxFillRect(1, y, 150 - 2, y + CLNWND_ROWSIZE - 1, 0); - colour = TC_WHITE; - } else { - colour = TC_BLACK; - } - - DoDrawString(_clientlist_action[i], 4, y, colour); - } - } break; - - case WE_MOUSELOOP: { - /* We selected an action */ - int index = (_cursor.pos.y - w->top) / CLNWND_ROWSIZE; - - if (_left_button_down) { - if (index == -1 || index == WP(w, menu_d).sel_index) return; - - WP(w, menu_d).sel_index = index; - w->SetDirty(); - } else { - if (index >= 0 && _cursor.pos.y >= w->top) { - HandleClientListPopupClick(index, WP(w, menu_d).main_button); - } - - DeleteWindowById(WC_TOOLBAR_MENU, 0); - } - } break; - } + new NetworkClientListPopupWindow(x, y, _client_list_popup_widgets, client_no); } /** * Main handle for clientlist */ -static void ClientListWndProc(Window *w, WindowEvent *e) +struct NetworkClientListWindow : Window { - switch (e->event) { - case WE_PAINT: { - NetworkClientInfo *ci; - int i = 0; + byte selected_item; + byte selected_y; - /* Check if we need to reset the height */ - if (!CheckClientListHeight(w)) break; - - DrawWindowWidgets(w); - - int y = CLNWND_OFFSET; + NetworkClientListWindow(const WindowDesc *desc, WindowNumber window_number) : + Window(desc, window_number), + selected_item(0), + selected_y(255) + { + this->FindWindowPlacementAndResize(desc); + } - FOR_ALL_ACTIVE_CLIENT_INFOS(ci) { - TextColour colour; - if (_selected_clientlist_item == i++) { // Selected item, highlight it - GfxFillRect(1, y, 248, y + CLNWND_ROWSIZE - 1, 0); - colour = TC_WHITE; - } else { - colour = TC_BLACK; - } + /** + * Finds the amount of clients and set the height correct + */ + bool CheckClientListHeight() + { + int num = 0; + const NetworkClientInfo *ci; - if (ci->client_index == NETWORK_SERVER_INDEX) { - DrawString(4, y, STR_NETWORK_SERVER, colour); - } else { - DrawString(4, y, STR_NETWORK_CLIENT, colour); - } + /* Should be replaced with a loop through all clients */ + FOR_ALL_ACTIVE_CLIENT_INFOS(ci) { + num++; + } + + num *= CLNWND_ROWSIZE; - /* Filter out spectators */ - if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1); - - DoDrawString(ci->client_name, 81, y, colour); - - y += CLNWND_ROWSIZE; - } - } break; - - case WE_CLICK: - /* Show the popup with option */ - if (_selected_clientlist_item != 255) { - PopupClientList(w, _selected_clientlist_item, e->we.click.pt.x + w->left, e->we.click.pt.y + w->top); - } - break; + /* If height is changed */ + if (this->height != CLNWND_OFFSET + num + 1) { + // XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1) + this->SetDirty(); + this->widget[3].bottom = this->widget[3].top + num + 2; + this->height = CLNWND_OFFSET + num + 1; + this->SetDirty(); + return false; + } + return true; + } - case WE_MOUSEOVER: - /* -1 means we left the current window */ - if (e->we.mouseover.pt.y == -1) { - _selected_clientlist_y = 0; - _selected_clientlist_item = 255; - w->SetDirty(); - break; - } - /* It did not change.. no update! */ - if (e->we.mouseover.pt.y == _selected_clientlist_y) break; + virtual void OnPaint() + { + NetworkClientInfo *ci; + int i = 0; + + /* Check if we need to reset the height */ + if (!this->CheckClientListHeight()) return; + + DrawWindowWidgets(this); - /* Find the new selected item (if any) */ - _selected_clientlist_y = e->we.mouseover.pt.y; - if (e->we.mouseover.pt.y > CLNWND_OFFSET) { - _selected_clientlist_item = (e->we.mouseover.pt.y - CLNWND_OFFSET) / CLNWND_ROWSIZE; + int y = CLNWND_OFFSET; + + FOR_ALL_ACTIVE_CLIENT_INFOS(ci) { + TextColour colour; + if (this->selected_item == i++) { // Selected item, highlight it + GfxFillRect(1, y, 248, y + CLNWND_ROWSIZE - 1, 0); + colour = TC_WHITE; } else { - _selected_clientlist_item = 255; + colour = TC_BLACK; } - /* Repaint */ - w->SetDirty(); - break; + if (ci->client_index == NETWORK_SERVER_INDEX) { + DrawString(4, y, STR_NETWORK_SERVER, colour); + } else { + DrawString(4, y, STR_NETWORK_CLIENT, colour); + } + + /* Filter out spectators */ + if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1); + + DoDrawString(ci->client_name, 81, y, colour); + + y += CLNWND_ROWSIZE; + } + } + + virtual void OnClick(Point pt, int widget) + { + /* Show the popup with option */ + if (this->selected_item != 255) { + PopupClientList(this->selected_item, pt.x + this->left, pt.y + this->top); + } + } - case WE_DESTROY: case WE_CREATE: - /* When created or destroyed, data is reset */ - _selected_clientlist_item = 255; - _selected_clientlist_y = 0; - break; + virtual void OnMouseOver(Point pt, int widget) + { + /* -1 means we left the current window */ + if (pt.y == -1) { + this->selected_y = 0; + this->selected_item = 255; + this->SetDirty(); + return; + } + /* It did not change.. no update! */ + if (pt.y == this->selected_y) return; + + /* Find the new selected item (if any) */ + this->selected_y = pt.y; + if (pt.y > CLNWND_OFFSET) { + this->selected_item = (pt.y - CLNWND_OFFSET) / CLNWND_ROWSIZE; + } else { + this->selected_item = 255; + } + + /* Repaint */ + this->SetDirty(); } -} +}; void ShowClientList() { - AllocateWindowDescFront<Window>(&_client_list_desc, 0); + AllocateWindowDescFront<NetworkClientListWindow>(&_client_list_desc, 0); }