(svn r17951) -Codechange: simplify making the popup list, remove arbirary limitations and unused code/strings.

This commit is contained in:
rubidium
2009-11-02 15:27:05 +00:00
parent c2f0845b92
commit 8611df32f2
45 changed files with 35 additions and 127 deletions

View File

@@ -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);