1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2005, Sven2
6 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// Startup screen for non-parameterized engine start: Player selection dialog
19// Also contains player creation, editing and crew management
20
21#pragma once
22
23#include "C4InfoCore.h"
24#include "C4Group.h"
25#include "C4Startup.h"
26
27// startup dialog: Player selection
28class C4StartupPlrSelDlg : public C4StartupDlg
29{
30private:
31 enum Mode { PSDM_Player = 0, PSDM_Crew }; // player selection list, or crew editing mode
32 enum { IconLabelSpacing = 2 }; // space between an icon and its text
33
34private:
35 // one item in the player or crew list
36 class ListItem : public C4GUI::Control
37 {
38 private:
39 typedef C4GUI::Window BaseClass;
40 // subcomponents
41
42 protected:
43 C4GUI::CheckBox *pCheck; // check box to mark participation
44 C4GUI::Label *pNameLabel; // item caption
45 class C4StartupPlrSelDlg *pPlrSelDlg;
46 C4GUI::Icon *pIcon; // item icon
47
48 private:
49 class C4KeyBinding *pKeyCheck; // space activates/deactivates selected player
50 C4FacetExSurface fctPortrait, fctPortraitBase; // big portrait
51 StdStrBuf Filename; // file info was loaded from
52
53 public:
54 ListItem(C4StartupPlrSelDlg *pForDlg, C4GUI::ListBox *pForListBox, C4GUI::Element *pInsertBeforeElement = nullptr, bool fActivated = false);
55 virtual ~ListItem();
56
57 protected:
58 virtual C4GUI::ContextMenu *ContextMenu() = 0;
59
60 C4GUI::ContextMenu *ContextMenu(C4GUI::Element *pEl, int32_t iX, int32_t iY)
61 {
62 return ContextMenu();
63 }
64
65 void LoadPortrait(C4Group &rGrp, bool fUseDefault);
66 void CreateColoredPortrait();
67 void SetDefaultPortrait();
68
69 virtual void UpdateOwnPos() override; // recalculate item positioning
70 bool KeyCheck() { pCheck->ToggleCheck(fByUser: true); return true; }
71 virtual bool IsFocusOnClick() override { return false; } // do not focus; keep focus on listbox
72
73 void SetName(const char *szNewName);
74 void SetIcon(C4GUI::Icons icoNew);
75
76 void SetFilename(const StdStrBuf &sNewFN);
77
78 public:
79 ListItem *GetNext() const { return static_cast<ListItem *>(BaseClass::GetNext()); }
80 const C4FacetEx &GetPortrait() const { return fctPortrait; }
81 virtual uint32_t GetColorDw() const = 0; // get drawing color for portrait
82 bool IsActivated() const { return pCheck->GetChecked(); }
83 void SetActivated(bool fToVal) { pCheck->SetChecked(fToVal); }
84 const char *GetName() const;
85 virtual void SetSelectionInfo(C4GUI::TextWindow *pSelectionInfo) = 0; // clears text field and writes selection info text into it
86 const StdStrBuf &GetFilename() const { return Filename; }
87 virtual std::string GetDelWarning() = 0;
88 void GrabIcon(C4FacetExSurface &rFromFacet);
89 void GrabPortrait(C4FacetExSurface *pFromFacet);
90
91 virtual bool CheckNameHotkey(const char *c) override; // return whether this item can be selected by entering given char
92
93 class LoadError : public std::runtime_error
94 {
95 public:
96 using runtime_error::runtime_error;
97 }; // class thrown off load function if load failed
98 };
99
100public:
101 // a list item when in player selection mode
102 class PlayerListItem : public ListItem
103 {
104 private:
105 C4PlayerInfoCore Core; // player info core loaded from player file
106 bool fHasCustomIcon; // set for players with a BigIcon.png
107
108 public:
109 PlayerListItem(C4StartupPlrSelDlg *pForDlg, C4GUI::ListBox *pForListBox, C4GUI::Element *pInsertBeforeElement = nullptr, bool fActivated = false);
110 ~PlayerListItem() {}
111
112 void Load(const StdStrBuf &rsFilename); // may throw LoadError
113
114 protected:
115 virtual C4GUI::ContextMenu *ContextMenu() override;
116
117 public:
118 const C4PlayerInfoCore &GetCore() const { return Core; }
119 void UpdateCore(C4PlayerInfoCore &NewCore); // Save Core to disk and update this item
120 void GrabCustomIcon(C4FacetExSurface &fctGrabFrom);
121 virtual void SetSelectionInfo(C4GUI::TextWindow *pSelectionInfo) override;
122 virtual uint32_t GetColorDw() const override { return Core.PrefColorDw; }
123 virtual std::string GetDelWarning() override;
124 bool MoveFilename(const char *szToFilename); // change filename to given
125 };
126
127private:
128 // a list item when in crew editing mode
129 class CrewListItem : public ListItem
130 {
131 private:
132 bool fLoaded;
133 C4ObjectInfoCore Core;
134 uint32_t dwPlrClr;
135 C4Group *pParentGrp;
136
137 public:
138 CrewListItem(C4StartupPlrSelDlg *pForDlg, C4GUI::ListBox *pForListBox, uint32_t dwPlrClr);
139 ~CrewListItem() {}
140
141 void Load(C4Group &rGrp, const StdStrBuf &rsFilename); // may throw LoadError
142
143 protected:
144 virtual C4GUI::ContextMenu *ContextMenu() override;
145
146 void RewriteCore();
147
148 struct RenameParams {};
149 void AbortRenaming(RenameParams par);
150 C4GUI::RenameResult DoRenaming(RenameParams par, const char *szNewName);
151
152 private:
153 std::string GetPhysicalTextLine(int32_t iPhysValue, C4ResStrTableKeyFormat<> idsName); // get string for physical info bar
154
155 public:
156 void UpdateClonkEnabled();
157
158 virtual uint32_t GetColorDw() const override { return dwPlrClr; } // get drawing color for portrait
159 virtual void SetSelectionInfo(C4GUI::TextWindow *pSelectionInfo) override; // clears text field and writes selection info text into it
160 virtual std::string GetDelWarning() override;
161 const C4ObjectInfoCore &GetCore() const { return Core; }
162
163 CrewListItem *GetNext() const { return static_cast<CrewListItem *>(ListItem::GetNext()); }
164
165 void CrewRename(); // shows the edit-field to rename a crew member
166 bool SetName(const char *szNewName); // update clonk name and core
167 void OnDeathMessageCtx(C4GUI::Element *el);
168 void OnDeathMessageSet(const StdStrBuf &rsNewMessage);
169 };
170
171public:
172 C4StartupPlrSelDlg();
173 ~C4StartupPlrSelDlg();
174
175private:
176 class C4KeyBinding *pKeyBack, *pKeyProperties, *pKeyCrew, *pKeyDelete, *pKeyRename, *pKeyNew;
177 class C4GUI::ListBox *pPlrListBox;
178 C4GUI::TextWindow *pSelectionInfo;
179 class C4GUI::Picture *pPortraitPict;
180 Mode eMode;
181
182 // in crew mode:
183 struct CurrPlayer_t
184 {
185 C4PlayerInfoCore Core; // loaded player main core
186 C4Group Grp; // group to player file; opened when in crew mode
187 }
188 CurrPlayer;
189
190private:
191 C4Rect rcBottomButtons; int32_t iBottomButtonWidth;
192 class C4GUI::Button *btnActivatePlr, *btnCrew, *btnProperties, *btnDelete, *btnBack, *btnNew;
193
194 void UpdateBottomButtons(); // update command button texts and positions
195 void UpdatePlayerList(); // refill pPlrListBox with players in player folder, or with crew in selected player
196 void UpdateSelection();
197 void OnSelChange(class C4GUI::Element *pEl) { UpdateSelection(); }
198 void OnSelDblClick(class C4GUI::Element *pEl) { C4GUI::GUISound(szSound: "Click"); OnPropertyBtn(btn: nullptr); }
199 void UpdateActivatedPlayers(); // update Config.General.Participants by currently activated players
200 void SelectItem(const std::string &filename, bool fActivate); // find item by filename and select (and activate it, if desired)
201
202 void SetPlayerMode(); // change view to listing players
203 void SetCrewMode(PlayerListItem *pForPlayer); // change view to listing crew of a player
204
205 static int32_t CrewSortFunc(const C4GUI::Element *pEl1, const C4GUI::Element *pEl2, void *par);
206 void ResortCrew();
207
208protected:
209 void OnItemCheckChange(C4GUI::Element *pCheckBox);
210 static bool CheckPlayerName(const StdStrBuf &Playername, std::string &filename, const StdStrBuf *pPrevFilename, bool fWarnEmpty);
211 ListItem *GetSelection();
212 void SetSelection(ListItem *pNewItem);
213
214 C4GUI::RenameEdit *pRenameEdit; // hack: set by crew list item renaming. Must be cleared when something is done in the dlg
215 void AbortRenaming();
216
217 friend class ListItem; friend class PlayerListItem; friend class CrewListItem;
218 friend class C4StartupPlrPropertiesDlg;
219
220protected:
221 virtual int32_t GetMarginTop() override { return (rcBounds.Hgt / 7); }
222 virtual bool HasBackground() override { return true; }
223 virtual void DrawElement(C4FacetEx &cgo) override;
224
225 virtual bool OnEnter() override { return false; } // Enter ignored
226 virtual bool OnEscape() override { DoBack(); return true; }
227 bool KeyBack() { DoBack(); return true; }
228 bool KeyProperties() { OnPropertyBtn(btn: nullptr); return true; }
229 bool KeyCrew() { OnCrewBtn (btn: nullptr); return true; }
230 bool KeyDelete() { OnDelBtn (btn: nullptr); return true; }
231 bool KeyNew() { OnNewBtn (btn: nullptr); return true; }
232
233 void OnNewBtn(C4GUI::Control *btn);
234 void OnActivateBtn(C4GUI::Control *btn);
235 void OnPropertyBtn(C4GUI::Control *btn);
236 void OnPropertyCtx(C4GUI::Element *el) { OnPropertyBtn(btn: nullptr); }
237 void OnCrewBtn(C4GUI::Control *btn);
238 void OnDelBtn(C4GUI::Control *btn);
239 void OnDelCtx(C4GUI::Element *el) { OnDelBtn(btn: nullptr); }
240 void OnDelBtnConfirm(ListItem *pSel);
241 void OnBackBtn(C4GUI::Control *btn) { DoBack(); }
242
243public:
244 void DoBack(); // back to main menu
245};
246
247// player creation or property editing dialog
248class C4StartupPlrPropertiesDlg : public C4GUI::Dialog
249{
250protected:
251 C4StartupPlrSelDlg *pMainDlg; // may be nullptr if shown as creation dialog in main menu!
252 C4StartupPlrSelDlg::PlayerListItem *pForPlayer;
253 C4GUI::Edit *pNameEdit; // player name edit box
254 C4GUI::Picture *pClrPreview;
255 C4GUI::ScrollBar *pClrSliderR, *pClrSliderG, *pClrSliderB;
256 C4GUI::Picture *pCtrlImg;
257 C4GUI::IconButton *pMouseBtn, *pJumpNRunBtn, *pClassicBtn, *pPictureBtn;
258 C4PlayerInfoCore C4P; // player info core copy currently being edited
259 C4FacetExSurface fctOldBigIcon;
260 C4FacetExSurface fctNewPicture, fctNewBigIcon; // if assigned, save new picture/bigicon
261 bool fClearPicture, fClearBigIcon; // if true, delete current picture/bigicon
262 virtual const char *GetID() override { return "PlrPropertiesDlg"; }
263
264 void DrawElement(C4FacetEx &cgo) override;
265 virtual int32_t GetMarginTop() override { return 16; }
266 virtual int32_t GetMarginLeft() override { return 45; }
267 virtual int32_t GetMarginRight() override { return 55; }
268 virtual int32_t GetMarginBottom() override { return 30; }
269
270 virtual void UserClose(bool fOK) override; // OK only with a valid name
271 virtual bool IsComponentOutsideClientArea() override { return true; } // OK and close btn
272
273 void OnClrChangeLeft(C4GUI::Control *pBtn);
274 void OnClrChangeRight(C4GUI::Control *pBtn);
275 void OnClrSliderRChange(int32_t iNewVal);
276 void OnClrSliderGChange(int32_t iNewVal);
277 void OnClrSliderBChange(int32_t iNewVal);
278 void OnCtrlChangeLeft(C4GUI::Control *pBtn);
279 void OnCtrlChangeRight(C4GUI::Control *pBtn);
280 void OnCtrlChangeMouse(C4GUI::Control *pBtn);
281 void OnMovementBtn(C4GUI::Control *pBtn);
282 void OnPictureBtn(C4GUI::Control *pBtn);
283
284private:
285 void UpdatePlayerColor(bool fUpdateSliders);
286 void UpdatePlayerControl();
287 void UpdatePlayerMovement(); // updates Jump'n'Run vs Classic
288 void UpdateBigIcon();
289
290 bool SetNewPicture(C4Surface &srcSfc, C4FacetExSurface *trgFct, int32_t iMaxSize, bool fColorize);
291 void SetNewPicture(const char *szFromFilename, bool fSetPicture, bool fSetBigIcon); // set new picture/bigicon by loading and scaling if necessary. If szFromFilename==nullptr, clear picture/bigicon
292
293public:
294 C4StartupPlrPropertiesDlg(C4StartupPlrSelDlg::PlayerListItem *pForPlayer, C4StartupPlrSelDlg *pMainDlg);
295 ~C4StartupPlrPropertiesDlg() {}
296
297 virtual void OnClosed(bool fOK) override; // close CB
298};
299