1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/ 5 * Copyright (c) 2009-2016, The OpenClonk Team and contributors 6 * 7 * Distributed under the terms of the ISC license; see accompanying file 8 * "COPYING" for details. 9 * 10 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 11 * See accompanying file "TRADEMARK" for details. 12 * 13 * To redistribute this file separately, substitute the full license texts 14 * for the above references. 15 */ 16 // player listbox used in lobby and game over dlg 17 18 #ifndef INC_C4PlayerInfoListBox 19 #define INC_C4PlayerInfoListBox 20 21 #include "gui/C4Gui.h" 22 23 class C4PlayerInfoListBox : public C4GUI::ListBox 24 { 25 public: 26 enum Spacings 27 { 28 // some spacings 29 IconLabelSpacing = 2, // space between an icon and its text 30 ClientListBoxSpacing = 8, // space between two clients in the list 31 PlayerListBoxIndent = 3, // indent of player list box items 32 NoneLabelSpacing = 20, // indent of "- none -"-label in list box 33 34 SoundIconShowTime = 1 // seconds. min time a sound icon is shown 35 }; 36 37 // list box mode 38 enum Mode 39 { 40 PILBM_LobbyClientSort, 41 PILBM_LobbyTeamSort, 42 PILBM_Evaluation, 43 PILBM_EvaluationNoWinners 44 }; 45 46 private: 47 // generic player list item 48 class ListItem : public C4GUI::Window 49 { 50 protected: 51 C4PlayerInfoListBox *pList; 52 uint32_t dwBackground; // not drawn if 0 53 54 public: 55 struct ID 56 { 57 enum IDType 58 { 59 PLI_NONE=0, 60 PLI_SCRIPTPLR, // script player caption (ID=0) - script players themselbed are regular PLI_PLAYER 61 PLI_SAVEGAMEPLR, // restore savegame player (ID>0), or caption (ID=0) 62 PLI_PLAYER, // player 63 PLI_CLIENT, // client label 64 PLI_TEAM, // team label 65 PLI_REPLAY // replay player (ID>0), or caption (ID=0) 66 } idType{PLI_NONE}; 67 68 int32_t id{0}; // player file ID or team ID or client ID 69 70 ID() = default; IDID71 ID(IDType eType, int32_t id) : idType(eType), id(id) {} 72 73 inline bool operator ==(const ID &r2) 74 { 75 return idType == r2.idType && id == r2.id; 76 } 77 }; 78 79 ID idListItemID; 80 81 C4GameLobby::MainDlg *GetLobby() const; Update()82 virtual void Update() {} // periodic update callback 83 84 protected: 85 void DrawElement(C4TargetFacet &cgo) override; // draw background 86 bool CanLocalChooseTeams(int32_t idPlayer=0) const; // whether the local client can change any teams 87 88 public: ListItem(C4PlayerInfoListBox * pList)89 ListItem(C4PlayerInfoListBox *pList) : C4GUI::Window(), pList(pList), dwBackground(0) {} 90 }; 91 92 // lobby information and display of joined players 93 class PlayerListItem : public ListItem 94 { 95 private: 96 // subcomponents 97 C4GUI::Icon *pIcon; // player icon 98 C4GUI::Label *pNameLabel; // label indicating player name 99 C4GUI::Label *pScoreLabel; // label showing some player score (league) 100 C4GUI::Label *pTimeLabel; // evaluation only: label showing total playing time 101 C4GUI::Label *pExtraLabel; // evaluation only: label showing extra data set by script 102 C4GUI::Icon *pRankIcon; // league rank icon 103 C4GUI::ComboBox *pTeamCombo; // team selection combo - nullptr for no-team-scens 104 C4GUI::Picture *pTeamPic; // evaluation only: Team icon spec 105 106 bool fIconSet; // whether custom icon has been set 107 bool fJoinedInfoSet; // join info for savegame recreation 108 DWORD dwJoinClr, dwPlrClr;//colors currently reflected in icon 109 110 protected: 111 int32_t idClient, idPlayer; // referenced IDs 112 bool fFreeSavegamePlayer; // if set, the player is an (unassociated) savegame player 113 bool fShownCollapsed; // true if small view is shown 114 115 protected: 116 void UpdateOwnPos() override; // recalculate item positioning 117 int32_t GetListItemTopSpacing() override; 118 119 public: 120 PlayerListItem(C4PlayerInfoListBox *pForListBox, int32_t idClient, int32_t idPlayer, bool fSavegamePlayer, C4GUI::Element *pInsertBeforeElement); // ctor 121 ~PlayerListItem() override = default;; // dtor 122 123 void UpdateIcon(C4PlayerInfo *pInfo, C4PlayerInfo *pJoinedInfo); // update player icon 124 void UpdateTeam(); 125 void UpdateScoreLabel(C4PlayerInfo *pInfo); // update league score labels and icons 126 void UpdateCollapsed(); 127 128 public: 129 C4GUI::ContextMenu *OnContext(C4GUI::Element *pListItem, int32_t iX, int32_t iY); // open context menu 130 C4GUI::ContextMenu *OnContextTakeOver(C4GUI::Element *pListItem, int32_t iX, int32_t iY); // takeover savegame player submenu 131 void OnCtxTakeOver(C4GUI::Element *pListItem, const int32_t &idPlayer); 132 void OnCtxRemove(C4GUI::Element *pListItem); 133 void OnCtxNewColor(C4GUI::Element *pListItem); 134 135 void OnTeamComboFill(C4GUI::ComboBox_FillCB *pFiller); 136 bool OnTeamComboSelChange(C4GUI::ComboBox *pForCombo, int32_t idNewSelection); 137 138 void Update() override; // update icon and team 139 GetInfoID()140 int32_t GetInfoID() const { return idPlayer; } 141 C4Network2Client *GetNetClient() const; // return associated network client 142 C4PlayerInfo *GetPlayerInfo() const; 143 144 C4PlayerInfo *GetJoinedInfo() const; // if this player is joined or associated to a joined info, return the joined info 145 146 bool IsLocalClientPlayer() const; // whether this player is going to join locally 147 bool CanLocalChooseTeam() const; // whether the local client can change team for this player 148 149 }; 150 151 // lobby information and display of connected clients 152 class ClientListItem : public ListItem 153 { 154 private: 155 // subcomponents 156 C4GUI::Icon *pStatusIcon; // icon indicating client status (host, etc.) 157 C4GUI::Label *pNameLabel; // label indicating client name 158 C4GUI::Label *pPingLabel; // label indicating ping to client - may be nullptr 159 160 protected: 161 int32_t idClient; // associated network interface ID 162 DWORD dwClientClr; // client color used for chatting 163 164 bool fIsShownActive; // whether client was active in last update 165 time_t tLastSoundTime; // now() when the client last issued a sound (display as sound icon). 0 for no sound. 166 167 public: 168 ClientListItem(C4PlayerInfoListBox *pForListBox, const C4ClientCore &rClientInfo, ListItem *pInsertBefore); // ctor 169 ~ClientListItem() override = default; // dtor 170 SetColor(DWORD dwToClr)171 void SetColor(DWORD dwToClr) // update color of client name label 172 { pNameLabel->SetColor((dwClientClr=dwToClr) | C4GUI_MessageFontAlpha); } SetStatus(C4GUI::Icons icoNewStatus)173 void SetStatus(C4GUI::Icons icoNewStatus) // set new status 174 { pStatusIcon->SetIcon(icoNewStatus); } 175 void SetPing(int32_t iToPing); // update ping label; iToPing=-1 removes the label 176 void UpdateCore(const C4ClientCore &rCore); // core update: re-set name and indicate whether active or not 177 void SetSoundIcon(); // sets the sound icon as current icon and schedules reset after some time 178 179 // spacing inserted between two client list items GetListItemTopSpacing()180 int32_t GetListItemTopSpacing() override { return ClientListBoxSpacing; } GetListItemTopSpacingBar()181 bool GetListItemTopSpacingBar() override { return true; } 182 183 public: 184 void Init(const C4ClientCore &rClientInfo); // init members 185 186 void UpdateInfo(); // update for changed player info 187 GetColor()188 DWORD GetColor() const { return dwClientClr; } // client chat color 189 C4Client *GetClient() const; // get client associated with this list item 190 bool IsLocalClientPlayer() const; // whether this player is going to join locally 191 C4GUI::Icons GetCurrentStatusIcon(); // get status icon that shows the current client state 192 class C4Network2Client *GetNetClient() const; // return assicuated network client; nullptr for local 193 bool IsLocal() const; 194 Update()195 void Update() override { UpdatePing(); UpdateInfo(); } 196 void UpdatePing(); // update ping label 197 198 C4GUI::ContextMenu *OnContext(C4GUI::Element *pListItem, int32_t iX, int32_t iY); // open context menu 199 void OnCtxKick(C4GUI::Element *pListItem); // kick item selected in client ctx menu 200 void OnCtxActivate(C4GUI::Element *pListItem); // toggle player/observer 201 void OnCtxInfo(C4GUI::Element *pListItem); // show info dlg (modal) 202 void OnCtxIgnore(C4GUI::Element *pListItem); 203 void OnBtnAddPlr(C4GUI::Control *btn); 204 }; 205 206 // team label 207 class TeamListItem : public ListItem 208 { 209 private: 210 // subcomponents 211 C4GUI::Icon *pIcon; 212 C4GUI::Label *pNameLabel; 213 214 int32_t idTeam; // team ID 215 216 protected: 217 void UpdateOwnPos() override; // recalculate item positioning 218 219 public: 220 TeamListItem(C4PlayerInfoListBox *pForListBox, int32_t idTeam, ListItem *pInsertBefore); // ctor 221 222 void MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override; // input: mouse movement or buttons 223 224 // spacing inserted between of those list items; usually this is top anyway... GetListItemTopSpacingBar()225 bool GetListItemTopSpacingBar() override { return true; } GetListItemTopSpacing()226 int32_t GetListItemTopSpacing() override { return ClientListBoxSpacing; } 227 228 void Update() override; 229 230 private: 231 void MoveLocalPlayersIntoTeam(); // move all local players into team marked by this label 232 }; 233 234 // list of unassigned savegame recreation players 235 class FreeSavegamePlayersListItem : public ListItem 236 { 237 private: 238 // subcomponents 239 C4GUI::Icon *pIcon; 240 C4GUI::Label *pNameLabel; 241 242 public: 243 FreeSavegamePlayersListItem(C4PlayerInfoListBox *pForListBox, ListItem *pInsertBefore); // ctor 244 245 // spacing inserted between of those list items; usually this is top anyway... ListItemTopSpacingBar()246 virtual bool ListItemTopSpacingBar() { return true; } GetListItemTopSpacing()247 int32_t GetListItemTopSpacing() override { return ClientListBoxSpacing; } 248 249 public: 250 void Update() override; 251 }; 252 253 // list of script players (both savegame recreation and regular) 254 class ScriptPlayersListItem : public ListItem 255 { 256 private: 257 // subcomponents 258 C4GUI::Icon *pIcon; 259 C4GUI::Label *pNameLabel; 260 C4GUI::IconButton *btnAddPlayer; 261 262 public: 263 ScriptPlayersListItem(C4PlayerInfoListBox *pForListBox, ListItem *pInsertBefore); // ctor 264 265 // spacing inserted between of those list items; usually this is top anyway... ListItemTopSpacingBar()266 virtual bool ListItemTopSpacingBar() { return true; } GetListItemTopSpacing()267 int32_t GetListItemTopSpacing() override { return ClientListBoxSpacing; } 268 269 protected: 270 void OnBtnAddPlr(C4GUI::Control *btn); 271 272 public: 273 void Update() override; 274 }; 275 276 // list of players in record (currently not used, because replays in network are not allowed :C) 277 class ReplayPlayersListItem : public ListItem 278 { 279 private: 280 // subcomponents 281 C4GUI::Icon *pIcon; 282 C4GUI::Label *pNameLabel; 283 284 public: 285 ReplayPlayersListItem(C4PlayerInfoListBox *pForListBox, ListItem *pInsertBefore); // ctor 286 287 // spacing inserted between of those list items; usually this is top anyway... GetListItemTopSpacingBar()288 bool GetListItemTopSpacingBar() override { return true; } GetListItemTopSpacing()289 int32_t GetListItemTopSpacing() override { return ClientListBoxSpacing; } 290 }; 291 292 // ----------------------------------------------------------------------------------------------- 293 private: 294 Mode eMode; 295 int32_t iMaxUncollapsedPlayers; // maximum number of players that can be displayed without collapse - valid only if fIsCollapsed 296 bool fIsCollapsed; 297 int32_t iTeamFilter; // if nonzero, only playeers of this team are shown in the listbox 298 299 uint32_t dwTextColor; 300 CStdFont *pCustomFont; 301 302 enum AddMode 303 { 304 AM_Winners, 305 AM_Losers, 306 AM_All 307 }; 308 309 void UpdateSavegamePlayers(ListItem **ppCurrInList); 310 void UpdateReplayPlayers(ListItem **ppCurrInList); 311 void UpdateScriptPlayers(ListItem **ppCurrInList); 312 void UpdatePlayersByTeam(ListItem **ppCurrInList); 313 void UpdatePlayersByRandomTeam(ListItem **ppCurrInList); 314 void UpdatePlayersByClient(ListItem **ppCurrInList); 315 void UpdatePlayersByEvaluation(ListItem **ppCurrInList, bool fShowWinners); 316 void UpdatePlayersByEvaluation(ListItem **ppCurrInList, C4Team *pTeam, AddMode eAddMode); 317 318 ListItem *GetPlayerListItem(ListItem::ID::IDType eType, int32_t id); // search for a player list item 319 bool PlrListItemUpdate(ListItem::ID::IDType eType, int32_t id, class ListItem **pEnsurePos); // search for player list item with given ID in the list starting at ensurepos; ensure it's positioned at given pos; update and return true if found 320 IsEvaluation()321 bool IsEvaluation() const { return eMode == PILBM_Evaluation || eMode == PILBM_EvaluationNoWinners; } IsLobby()322 bool IsLobby() const { return eMode == PILBM_LobbyClientSort || eMode == PILBM_LobbyTeamSort; } IsTeamFilter()323 bool IsTeamFilter() const { return !!iTeamFilter; } 324 325 protected: 326 bool IsPlayerItemCollapsed(PlayerListItem *pItem); // CB from list item: return true if it should be shown small OnPlrListSelChange(class C4GUI::Element * pEl)327 void OnPlrListSelChange(class C4GUI::Element *pEl) { Update(); } 328 GetTextColor()329 uint32_t GetTextColor() const { return dwTextColor; } GetCustomFont()330 CStdFont *GetCustomFont() const { return pCustomFont; } 331 332 public: 333 C4PlayerInfoListBox(const C4Rect &rcBounds, Mode eMode, int32_t iTeamFilter=0); 334 ~C4PlayerInfoListBox() override = default; 335 336 void Update(); // update player list 337 void SetClientSoundIcon(int32_t iForClientID); 338 void SetMode(Mode eNewMode); SetTeamFilter(int32_t idNewTeamFilter)339 void SetTeamFilter(int32_t idNewTeamFilter) { iTeamFilter = idNewTeamFilter; } 340 void SetCustomFont(CStdFont *pNewFont, uint32_t dwTextColor); 341 GetMode()342 Mode GetMode() const { return eMode; } 343 344 friend class PlayerListItem; 345 friend class TeamListItem; 346 }; 347 348 349 #endif // INC_C4PlayerInfoListBox 350