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