From b08d728ac9dfa53241fd006a4e3c146932c196fe Mon Sep 17 00:00:00 2001 From: rubidium Date: Thu, 15 May 2008 20:04:10 +0000 Subject: (svn r13108) -Codechange: make a Window subclass of the main toolbars sub menus. --- src/network/network_gui.cpp | 422 ++++++++++++++++++++++---------------------- src/toolbar_gui.cpp | 349 ++++++++++++++++++------------------ src/window_gui.h | 11 -- 3 files changed, 385 insertions(+), 397 deletions(-) (limited to 'src') diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index b4c2e0c33..db1a045f8 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1217,14 +1217,6 @@ typedef void ClientList_Action_Proc(byte client_no); // 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 @@ static WindowDesc _client_list_desc = { 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 @@ static void ClientList_None(byte client_no) -/** - * 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); - } -} - -/** - * Finds the amount of clients and set the height correct - */ -static bool CheckClientListHeight(Window *w) -{ - int num = 0; - const NetworkClientInfo *ci; - - /* Should be replaced with a loop through all clients */ - FOR_ALL_ACTIVE_CLIENT_INFOS(ci) { - num++; - } +struct NetworkClientListPopupWindow : Window { + int sel_index; + int client_no; + char action[MAX_CLIENTLIST_ACTION][50]; + ClientList_Action_Proc *proc[MAX_CLIENTLIST_ACTION]; - num *= CLNWND_ROWSIZE; + 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! + */ - /* 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; - } - return true; -} + const NetworkClientInfo *ci = NetworkFindClientInfo(client_no); -/** - * Finds the amount of actions in the popup and set the height correct - */ -static uint ClientListPopupHeight() -{ - int num = 0; + 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; + } - // 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++; - } + 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; + + 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; + } + } - num *= CLNWND_ROWSIZE; + /* 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; - return num + 1; -} + sprintf(this->action[i],"Ban"); // XXX GetString? + this->proc[i++] = &ClientList_Ban; + } -/** - * Show the popup (action list) - */ -static Window *PopupClientList(Window *w, int client_no, int x, int y) -{ - int i; - const NetworkClientInfo *ci; - DeleteWindowById(WC_TOOLBAR_MENU, 0); + if (i == 0) { + GetString(this->action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(this->action[i])); + this->proc[i++] = &ClientList_None; + } - /* Clean the current actions */ - for (i = 0; i < MAX_CLIENTLIST_ACTION; i++) { - _clientlist_action[i][0] = '\0'; - _clientlist_proc[i] = NULL; - } + /* Calculate the height */ + int h = ClientListPopupHeight(); - /* - * Fill the actions this client has. - * Watch is, max 50 chars long! - */ + /* Allocate the popup */ + this->widget[0].bottom = this->widget[0].top + h; + this->widget[0].right = this->widget[0].left + 150; - ci = NetworkFindClientInfo(client_no); - if (ci == NULL) return NULL; + this->flags4 &= ~WF_WHITE_BORDER_MASK; - 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; + this->FindWindowPlacementAndResize(150, h + 1); } - 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; + /** + * 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); } } - /* 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; + /** + * 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++; + } - sprintf(_clientlist_action[i],"Ban"); // XXX GetString? - _clientlist_proc[i++] = &ClientList_Ban; - } + num *= CLNWND_ROWSIZE; - if (i == 0) { - GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_NONE, lastof(_clientlist_action[i])); - _clientlist_proc[i++] = &ClientList_None; + return num + 1; } - /* Calculate the height */ - int h = ClientListPopupHeight(); - /* 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; + virtual void OnPaint() + { + DrawWindowWidgets(this); - 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; + /* 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 w; -} + DoDrawString(this->action[i], 4, y, colour); + } + } -/** 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); + virtual void OnMouseLoop() + { + /* We selected an action */ + int index = (_cursor.pos.y - this->top) / CLNWND_ROWSIZE; - /* 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; - } + if (_left_button_down) { + if (index == -1 || index == this->sel_index) return; - DoDrawString(_clientlist_action[i], 4, y, colour); + this->sel_index = index; + this->SetDirty(); + } else { + if (index >= 0 && _cursor.pos.y >= this->top) { + HandleClientListPopupClick(index); } - } break; - case WE_MOUSELOOP: { - /* We selected an action */ - int index = (_cursor.pos.y - w->top) / CLNWND_ROWSIZE; + DeleteWindowById(WC_TOOLBAR_MENU, 0); + } + } +}; - if (_left_button_down) { - if (index == -1 || index == WP(w, menu_d).sel_index) return; +/** + * Show the popup (action list) + */ +static void PopupClientList(int client_no, int x, int y) +{ + DeleteWindowById(WC_TOOLBAR_MENU, 0); - 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); - } + if (NetworkFindClientInfo(client_no) == NULL) return; - 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; + NetworkClientListWindow(const WindowDesc *desc, WindowNumber window_number) : + Window(desc, window_number), + selected_item(0), + selected_y(255) + { + this->FindWindowPlacementAndResize(desc); + } - DrawWindowWidgets(w); + /** + * Finds the amount of clients and set the height correct + */ + bool CheckClientListHeight() + { + int num = 0; + const NetworkClientInfo *ci; - int y = CLNWND_OFFSET; + /* Should be replaced with a loop through all clients */ + FOR_ALL_ACTIVE_CLIENT_INFOS(ci) { + num++; + } - 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; - } + num *= CLNWND_ROWSIZE; - if (ci->client_index == NETWORK_SERVER_INDEX) { - DrawString(4, y, STR_NETWORK_SERVER, colour); - } else { - DrawString(4, y, STR_NETWORK_CLIENT, colour); - } + /* 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; + } - /* Filter out spectators */ - if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1); + virtual void OnPaint() + { + NetworkClientInfo *ci; + int i = 0; - DoDrawString(ci->client_name, 81, y, colour); + /* Check if we need to reset the height */ + if (!this->CheckClientListHeight()) return; - y += CLNWND_ROWSIZE; - } - } break; + DrawWindowWidgets(this); - 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; + int y = CLNWND_OFFSET; - 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; + 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 { + colour = TC_BLACK; } - /* It did not change.. no update! */ - if (e->we.mouseover.pt.y == _selected_clientlist_y) break; - /* 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; + if (ci->client_index == NETWORK_SERVER_INDEX) { + DrawString(4, y, STR_NETWORK_SERVER, colour); } else { - _selected_clientlist_item = 255; + DrawString(4, y, STR_NETWORK_CLIENT, colour); } - /* Repaint */ - w->SetDirty(); - break; + /* Filter out spectators */ + if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1); - case WE_DESTROY: case WE_CREATE: - /* When created or destroyed, data is reset */ - _selected_clientlist_item = 255; - _selected_clientlist_y = 0; - break; + 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); + } + } + + 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(&_client_list_desc, 0); + AllocateWindowDescFront(&_client_list_desc, 0); } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 2b7b00cfc..45274bce3 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -78,13 +78,13 @@ static Point GetToolbarDropdownPos(uint16 parent_button, int width, int height) } /** - * In a window with menu_d custom extension, retrieve the menu item number from a position + * Retrieve the menu item number from a position * @param w Window holding the menu items * @param x X coordinate of the position * @param y Y coordinate of the position * @return Index number of the menu item, or \c -1 if no valid selection under position */ -static int GetMenuItemIndex(const Window *w) +static int GetMenuItemIndex(const Window *w, int item_count, int disabled_items) { int x = _cursor.pos.x; int y = _cursor.pos.y; @@ -92,8 +92,8 @@ static int GetMenuItemIndex(const Window *w) if ((x -= w->left) >= 0 && x < w->width && (y -= w->top + 1) >= 0) { y /= 10; - if (y < WP(w, const menu_d).item_count && - !HasBit(WP(w, const menu_d).disabled_items, y)) { + if (y < item_count && + !HasBit(disabled_items, y)) { return y; } } @@ -1113,71 +1113,77 @@ static MenuClickedProc * const _menu_clicked_procs[] = { MenuClickHelp, /* 26 */ }; -static void MenuWndProc(Window *w, WindowEvent *e) -{ - switch (e->event) { - case WE_CREATE: - w->widget[0].right = w->width - 1; - break; - - case WE_PAINT: { - byte count = WP(w, menu_d).item_count; - byte sel = WP(w, menu_d).sel_index; - uint16 chk = WP(w, menu_d).checked_items; - StringID string = WP(w, menu_d).string_id; - byte dis = WP(w, menu_d).disabled_items; - - DrawWindowWidgets(w); - - int x = 1; - int y = 1; +struct ToolbarMenuWindow : Window { + int item_count; + int sel_index; + int main_button; + int action_id; + int checked_items; + int disabled_items; + StringID base_string; + + ToolbarMenuWindow(int x, int y, int width, int height, const Widget *widgets, int item_count, + int sel_index, int parent_button, StringID base_string, int checked_items, + int disabled_mask) : + Window(x, y, width, height, NULL, WC_TOOLBAR_MENU, widgets), + item_count(item_count), sel_index(sel_index), main_button(GB(parent_button, 0, 8)), + action_id((GB(parent_button, 8, 8) != 0) ? GB(parent_button, 8, 8) : parent_button), + checked_items(checked_items), disabled_items(disabled_items), base_string(base_string) + { + this->widget[0].bottom = item_count * 10 + 1; + this->widget[0].right = this->width - 1; + this->flags4 &= ~WF_WHITE_BORDER_MASK; + + this->FindWindowPlacementAndResize(width, height); + } - for (; count != 0; count--, string++, sel--) { - TextColour color = HasBit(dis, 0) ? TC_GREY : (sel == 0) ? TC_WHITE : TC_BLACK; - if (sel == 0) GfxFillRect(x, y, x + w->width - 3, y + 9, 0); + ~ToolbarMenuWindow() + { + Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); + w->RaiseWidget(this->main_button); + w->SetDirty(); + } - if (HasBit(chk, 0)) DrawString(x + 2, y, STR_CHECKMARK, color); - DrawString(x + 2, y, string, color); + virtual void OnPaint() + { + DrawWindowWidgets(this); - y += 10; - chk >>= 1; - dis >>= 1; - } - } break; + for (int i = 0, x = 1, y = 1; i != this->item_count; i++, y += 10) { + TextColour color = HasBit(this->disabled_items, i) ? TC_GREY : (this->sel_index == i) ? TC_WHITE : TC_BLACK; + if (this->sel_index == i) GfxFillRect(x, y, x + this->width - 3, y + 9, 0); - case WE_DESTROY: { - Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); - v->RaiseWidget(WP(w, menu_d).main_button); - v->SetDirty(); - return; - } + if (HasBit(this->checked_items, i)) DrawString(x + 2, y, STR_CHECKMARK, color); + DrawString(x + 2, y, this->base_string + i, color); + } + } - case WE_MOUSELOOP: { - int index = GetMenuItemIndex(w); + virtual void OnMouseLoop() + { + int index = GetMenuItemIndex(this, this->item_count, this->disabled_items); - if (_left_button_down) { - if (index == -1 || index == WP(w, menu_d).sel_index) return; + if (_left_button_down) { + if (index == -1 || index == this->sel_index) return; - WP(w, menu_d).sel_index = index; - w->SetDirty(); - } else { - if (index < 0) { - Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0); - if (GetWidgetFromPos(w2, _cursor.pos.x - w2->left, _cursor.pos.y - w2->top) == WP(w, menu_d).main_button) - index = WP(w, menu_d).sel_index; + this->sel_index = index; + this->SetDirty(); + } else { + if (index < 0) { + Window *w = FindWindowById(WC_MAIN_TOOLBAR,0); + if (GetWidgetFromPos(w, _cursor.pos.x - w->left, _cursor.pos.y - w->top) == this->main_button) { + index = this->sel_index; } + } - int action_id = WP(w, menu_d).action_id; - delete w; + int action_id = this->action_id; + delete this; - if (index >= 0) { - assert((uint)index <= lengthof(_menu_clicked_procs)); - _menu_clicked_procs[action_id](index); - } + if (index >= 0) { + assert((uint)index <= lengthof(_menu_clicked_procs)); + _menu_clicked_procs[action_id](index); } - } break; + } } -} +}; /* Dynamic widget length determined by toolbar-string length. * See PopupMainToolbMenu en MenuWndProc */ @@ -1248,17 +1254,7 @@ static void PopupMainToolbMenu(Window *parent, uint16 parent_button, StringID ba Point pos = GetToolbarDropdownPos(parent_button, width, height); - Window *w = new Window(pos.x, pos.y, width, height, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets); - w->widget[0].bottom = item_count * 10 + 1; - w->flags4 &= ~WF_WHITE_BORDER_MASK; - - WP(w, menu_d).item_count = item_count; - WP(w, menu_d).sel_index = sel_index; - WP(w, menu_d).main_button = GB(parent_button, 0, 8); - WP(w, menu_d).action_id = (GB(parent_button, 8, 8) != 0) ? GB(parent_button, 8, 8) : parent_button; - WP(w, menu_d).string_id = base_string; - WP(w, menu_d).checked_items = checked_items; - WP(w, menu_d).disabled_items = disabled_mask; + new ToolbarMenuWindow(pos.x, pos.y, width, height, _menu_widgets, item_count, sel_index, parent_button, base_string, checked_items, disabled_mask); SndPlayFx(SND_15_BEEP); } @@ -1276,119 +1272,141 @@ static int GetPlayerIndexFromMenu(int index) return -1; } -static void UpdatePlayerMenuHeight(Window *w) -{ - byte num = ActivePlayerCount(); - - /* Increase one to fit in PlayerList in the menu when in network */ - if (_networking && WP(w, menu_d).main_button == 9) num++; +struct ToolbarPlayerMenuWindow : Window { + int item_count; + int sel_index; + int main_button; + int action_id; + int gray_items; + + ToolbarPlayerMenuWindow(int x, int y, int width, int height, const Widget *widgets, int main_button, int gray) : + Window(x, y, width, height, NULL, WC_TOOLBAR_MENU, widgets), + item_count(0), main_button(main_button), action_id(main_button), gray_items(gray) + { + this->flags4 &= ~WF_WHITE_BORDER_MASK; + this->sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0); + if (_networking && main_button == 9) { + if (_local_player != PLAYER_SPECTATOR) { + this->sel_index++; + } else { + /* Select client list by default for spectators */ + this->sel_index = 0; + } + } + } - if (WP(w, menu_d).item_count != num) { - WP(w, menu_d).item_count = num; - w->SetDirty(); - num = num * 10 + 2; - w->height = num; - w->widget[0].bottom = w->widget[0].top + num - 1; - w->top = GetToolbarDropdownPos(0, w->width, w->height).y; + ~ToolbarPlayerMenuWindow() + { + Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); + w->RaiseWidget(this->main_button); w->SetDirty(); } -} -static void PlayerMenuWndProc(Window *w, WindowEvent *e) -{ - switch (e->event) { - case WE_PAINT: { - UpdatePlayerMenuHeight(w); - DrawWindowWidgets(w); + void UpdatePlayerMenuHeight() + { + byte num = ActivePlayerCount(); + + /* Increase one to fit in PlayerList in the menu when in network */ + if (_networking && this->main_button == 9) num++; + + if (this->item_count != num) { + this->item_count = num; + this->SetDirty(); + num = num * 10 + 2; + this->height = num; + this->widget[0].bottom = this->widget[0].top + num - 1; + this->top = GetToolbarDropdownPos(0, this->width, this->height).y; + this->SetDirty(); + } + } - int x = 1; - int y = 1; - int sel = WP(w, menu_d).sel_index; - int chk = WP(w, menu_d).checked_items; // let this mean gray items. + virtual void OnPaint() + { + this->UpdatePlayerMenuHeight(); + DrawWindowWidgets(this); - /* 9 = playerlist */ - if (_networking && WP(w, menu_d).main_button == 9) { - if (sel == 0) { - GfxFillRect(x, y, x + 238, y + 9, 0); - } - DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, TC_FROMSTRING); - y += 10; - sel--; + int x = 1; + int y = 1; + int sel = this->sel_index; + int gray = this->gray_items; + + /* 9 = playerlist */ + if (_networking && this->main_button == 9) { + if (sel == 0) { + GfxFillRect(x, y, x + 238, y + 9, 0); } + DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, TC_FROMSTRING); + y += 10; + sel--; + } - const Player *p; - FOR_ALL_PLAYERS(p) { - if (p->is_active) { - if (p->index == sel) { - GfxFillRect(x, y, x + 238, y + 9, 0); - } + const Player *p; + FOR_ALL_PLAYERS(p) { + if (p->is_active) { + if (p->index == sel) { + GfxFillRect(x, y, x + 238, y + 9, 0); + } - DrawPlayerIcon(p->index, x + 2, y + 1); + DrawPlayerIcon(p->index, x + 2, y + 1); - SetDParam(0, p->index); - SetDParam(1, p->index); + SetDParam(0, p->index); + SetDParam(1, p->index); - TextColour color = (p->index == sel) ? TC_WHITE : TC_BLACK; - if (chk & 1) color = TC_GREY; - DrawString(x + 19, y, STR_7021, color); + TextColour color = (p->index == sel) ? TC_WHITE : TC_BLACK; + if (gray & 1) color = TC_GREY; + DrawString(x + 19, y, STR_7021, color); - y += 10; - } - chk >>= 1; + y += 10; } - } break; - - case WE_DESTROY: { - Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0); - v->RaiseWidget(WP(w, menu_d).main_button); - v->SetDirty(); - return; + gray >>= 1; } + } - case WE_MOUSELOOP: { - int index = GetMenuItemIndex(w); - - if (_left_button_down) { - UpdatePlayerMenuHeight(w); - /* We have a new entry at the top of the list of menu 9 when networking - * so keep that in count */ - if (_networking && WP(w, menu_d).main_button == 9) { - if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1; - } else { - index = GetPlayerIndexFromMenu(index); - } + virtual void OnMouseLoop() + { + int index = GetMenuItemIndex(this, this->item_count, 0); - if (index == -1 || index == WP(w, menu_d).sel_index) return; + if (_left_button_down) { + this->UpdatePlayerMenuHeight(); + /* We have a new entry at the top of the list of menu 9 when networking + * so keep that in count */ + if (_networking && this->main_button == 9) { + if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1; + } else { + index = GetPlayerIndexFromMenu(index); + } - WP(w, menu_d).sel_index = index; - w->SetDirty(); + if (index == -1 || index == this->sel_index) return; + + this->sel_index = index; + this->SetDirty(); + } else { + int action_id = this->action_id; + + /* We have a new entry at the top of the list of menu 9 when networking + * so keep that in count */ + if (_networking && this->main_button == 9) { + if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1; } else { - int action_id = WP(w, menu_d).action_id; - - /* We have a new entry at the top of the list of menu 9 when networking - * so keep that in count */ - if (_networking && WP(w, menu_d).main_button == 9) { - if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1; - } else { - index = GetPlayerIndexFromMenu(index); - } + index = GetPlayerIndexFromMenu(index); + } - if (index < 0) { - Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0); - if (GetWidgetFromPos(w2, _cursor.pos.x - w2->left, _cursor.pos.y - w2->top) == WP(w, menu_d).main_button) - index = WP(w, menu_d).sel_index; + if (index < 0) { + Window *w = FindWindowById(WC_MAIN_TOOLBAR,0); + if (GetWidgetFromPos(w, _cursor.pos.x - w->left, _cursor.pos.y - w->top) == this->main_button) { + index = this->sel_index; } + } - delete w; + delete this; - if (index >= 0) { - assert(index >= 0 && index < 30); - _menu_clicked_procs[action_id](index); - } + if (index >= 0) { + assert(index >= 0 && index < 30); + _menu_clicked_procs[action_id](index); } - } break; + } } -} +}; static const Widget _player_menu_widgets[] = { { WWT_PANEL, RESIZE_NONE, 14, 0, 240, 0, 81, 0x0, STR_NULL}, @@ -1402,22 +1420,7 @@ static void PopupMainPlayerToolbMenu(Window *parent, int main_button, int gray) DeleteWindowById(WC_TOOLBAR_MENU, 0); Point pos = GetToolbarDropdownPos(main_button, 241, 82); - Window *w = new Window(pos.x, pos.y, 241, 82, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets); - w->flags4 &= ~WF_WHITE_BORDER_MASK; - WP(w, menu_d).item_count = 0; - WP(w, menu_d).sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0); - if (_networking && main_button == 9) { - if (_local_player != PLAYER_SPECTATOR) { - WP(w, menu_d).sel_index++; - } else { - /* Select client list by default for spectators */ - WP(w, menu_d).sel_index = 0; - } - } - WP(w, menu_d).action_id = main_button; - WP(w, menu_d).main_button = main_button; - WP(w, menu_d).checked_items = gray; - WP(w, menu_d).disabled_items = 0; + new ToolbarPlayerMenuWindow(pos.x, pos.y, 241, 82, _player_menu_widgets, main_button, gray); SndPlayFx(SND_15_BEEP); } diff --git a/src/window_gui.h b/src/window_gui.h index 84a1c22d3..e63716279 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -515,17 +515,6 @@ public: /*** End of the event handling ***/ }; -struct menu_d { - byte item_count; ///< follow_vehicle - byte sel_index; ///< scrollpos_x - byte main_button; ///< scrollpos_y - byte action_id; - StringID string_id; ///< unk30 - uint16 checked_items; ///< unk32 - byte disabled_items; -}; -assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(menu_d)); - struct def_d { int16 data_1, data_2, data_3; }; -- cgit v1.2.3-70-g09d2