OpenClonk
C4PlayerInfoListBox.h
Go to the documentation of this file.
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 
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  {
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  {
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;
71  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;
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:
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 
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 
171  void SetColor(DWORD dwToClr) // update color of client name label
172  { pNameLabel->SetColor((dwClientClr=dwToClr) | C4GUI_MessageFontAlpha); }
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
180  int32_t GetListItemTopSpacing() override { return ClientListBoxSpacing; }
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 
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 
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...
225  bool GetListItemTopSpacingBar() override { return true; }
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...
246  virtual bool ListItemTopSpacingBar() { return true; }
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...
266  virtual bool ListItemTopSpacingBar() { return true; }
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...
288  bool GetListItemTopSpacingBar() override { return true; }
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 
321  bool IsEvaluation() const { return eMode == PILBM_Evaluation || eMode == PILBM_EvaluationNoWinners; }
322  bool IsLobby() const { return eMode == PILBM_LobbyClientSort || eMode == PILBM_LobbyTeamSort; }
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
327  void OnPlrListSelChange(class C4GUI::Element *pEl) { Update(); }
328 
329  uint32_t GetTextColor() const { return dwTextColor; }
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);
339  void SetTeamFilter(int32_t idNewTeamFilter) { iTeamFilter = idNewTeamFilter; }
340  void SetCustomFont(CStdFont *pNewFont, uint32_t dwTextColor);
341 
342  Mode GetMode() const { return eMode; }
343 
344  friend class PlayerListItem;
345  friend class TeamListItem;
346 };
347 
348 
349 #endif // INC_C4PlayerInfoListBox
#define C4GUI_MessageFontAlpha
Definition: C4Gui.h:44
uint32_t DWORD
virtual bool GetListItemTopSpacingBar()
Definition: C4Gui.h:462
C4Rect rcBounds
Definition: C4Gui.h:385
virtual int32_t GetListItemTopSpacing()
Definition: C4Gui.h:461
void SetIcon(Icons icoNewIconIndex)
void SetColor(DWORD dwToClr, bool fMakeReadableOnBlack=true)
Definition: C4Gui.h:505
void DrawElement(C4TargetFacet &cgo) override
void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) override
void UpdateOwnPos() override
void SetTeamFilter(int32_t idNewTeamFilter)
bool IsPlayerItemCollapsed(PlayerListItem *pItem)
C4PlayerInfoListBox(const C4Rect &rcBounds, Mode eMode, int32_t iTeamFilter=0)
void SetClientSoundIcon(int32_t iForClientID)
void SetCustomFont(CStdFont *pNewFont, uint32_t dwTextColor)
void OnPlrListSelChange(class C4GUI::Element *pEl)
CStdFont * GetCustomFont() const
void SetMode(Mode eNewMode)
~C4PlayerInfoListBox() override=default
uint32_t GetTextColor() const
Definition: C4Rect.h:28
Definition: C4Teams.h:31
Icons
Definition: C4Gui.h:638
enum C4PlayerInfoListBox::ListItem::ID::IDType PLI_NONE