/src/gui/C4GameOptions.cpp
C++ | 281 lines | 185 code | 45 blank | 51 comment | 27 complexity | 5f1c03b82da26d69f6f10eb640a1d9b0 MD5 | raw file
Possible License(s): WTFPL, 0BSD, LGPL-2.1, CC-BY-3.0
1/*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 2005-2006, 2008 Sven Eberhardt
5 * Copyright (c) 2006 Florian Gro?&#x;
6 * Copyright (c) 2009 Peter Wortmann
7 * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de
8 *
9 * Portions might be copyrighted by other authors who have contributed
10 * to OpenClonk.
11 *
12 * Permission to use, copy, modify, and/or distribute this software for any
13 * purpose with or without fee is hereby granted, provided that the above
14 * copyright notice and this permission notice appear in all copies.
15 * See isc_license.txt for full license and disclaimer.
16 *
17 * "Clonk" is a registered trademark of Matthes Bender.
18 * See clonk_trademark_license.txt for full license.
19 */
20// Custom game options and configuration dialog
21
22#include "C4Include.h"
23#include "C4GameOptions.h"
24#include <C4Game.h>
25#include <C4GameControl.h>
26
27// ----------- C4GameOptionsList::Option ----------------------------------------------------------------
28
29C4GameOptionsList::Option::Option(C4GameOptionsList *pForDlg)
30: BaseClass(C4Rect(0,0,0,0)), pPrimarySubcomponent(NULL) { }
31
32void C4GameOptionsList::Option::InitOption(C4GameOptionsList *pForDlg)
33 {
34 // post-call after initialization: Adds to list box and does initial update
35 // add to listbox (will eventually get moved)
36 pForDlg->AddElement(this);
37 // first-time update
38 Update();
39 }
40
41
42
43// ----------- C4GameOptionsList::OptionDropdown ----------------------------------------------------------------
44
45C4GameOptionsList::OptionDropdown::OptionDropdown(class C4GameOptionsList *pForDlg, const char *szCaption, bool fReadOnly)
46: Option(pForDlg)
47 {
48 CStdFont &rUseFont = C4GUI::GetRes()->TextFont;
49 // get size of caption label
50 bool fTabular = pForDlg->IsTabular();
51 int32_t iCaptWidth, iCaptHeight;
52 if (fTabular)
53 {
54 // tabular layout: Caption label width by largest caption
55 rUseFont.GetTextExtent(LoadResStr("IDS_NET_RUNTIMEJOIN"), iCaptWidth, iCaptHeight, true);
56 iCaptWidth = iCaptWidth * 5 / 4;
57 }
58 else
59 {
60 rUseFont.GetTextExtent(szCaption, iCaptWidth, iCaptHeight, true);
61 }
62 // calc total height for component
63 int iHorizontalMargin = 1;
64 int iVerticalMargin = 1;
65 int iComboMargin = 5;
66 int iSelComboHgt = C4GUI::ComboBox::GetDefaultHeight();
67 SetBounds(C4Rect(0, 0, pForDlg->GetItemWidth(), (!fTabular) * (iCaptHeight + iVerticalMargin*2) + iVerticalMargin*2 + iSelComboHgt));
68 C4GUI::ComponentAligner ca(GetContainedClientRect(), iHorizontalMargin, iVerticalMargin);
69 // create subcomponents
70 AddElement(pCaption = new C4GUI::Label(FormatString("%s:", szCaption).getData(), fTabular ? ca.GetFromLeft(iCaptWidth, iCaptHeight) : ca.GetFromTop(iCaptHeight), ALeft));
71 ca.ExpandLeft(-iComboMargin);
72 AddElement(pPrimarySubcomponent = pDropdownList = new C4GUI::ComboBox(ca.GetAll()));
73 pDropdownList->SetReadOnly(fReadOnly);
74 pDropdownList->SetComboCB(new C4GUI::ComboBox_FillCallback<C4GameOptionsList::OptionDropdown>(this, &C4GameOptionsList::OptionDropdown::OnDropdownFill, &C4GameOptionsList::OptionDropdown::OnDropdownSelChange));
75 // final init
76 InitOption(pForDlg);
77 }
78
79
80
81// ----------- C4GameOptionsList::OptionControlMode ----------------------------------------------------------------
82
83// Unfortunately, the control mode cannot be changed in the lobby
84C4GameOptionsList::OptionControlMode::OptionControlMode(class C4GameOptionsList *pForDlg)
85: C4GameOptionsList::OptionDropdown(pForDlg, LoadResStr("IDS_TEXT_CONTROLMODE"), !::Control.isCtrlHost() || !::Control.isNetwork() || !::Control.Network.IsEnabled() || !pForDlg->IsRuntime())
86 {
87 SetToolTip(LoadResStr("IDS_DESC_CHANGESTHEWAYCONTROLDATAI"));
88 }
89
90void C4GameOptionsList::OptionControlMode::DoDropdownFill(C4GUI::ComboBox_FillCB *pFiller)
91 {
92 // change possible?
93 if (!::Control.isNetwork() || !::Control.Network.IsEnabled() || !::Control.isCtrlHost()) return;
94 // add possible modes
95 pFiller->AddEntry(LoadResStr("IDS_NET_CTRLMODE_CENTRAL"), CNM_Central);
96 pFiller->AddEntry(LoadResStr("IDS_NET_CTRLMODE_DECENTRAL"), CNM_Decentral);
97 }
98
99void C4GameOptionsList::OptionControlMode::DoDropdownSelChange(int32_t idNewSelection)
100 {
101 // change possible?
102 if (!::Control.isNetwork() || !::Control.Network.IsEnabled() || !::Control.isCtrlHost()) return;
103 // perform it
104 ::Network.SetCtrlMode(idNewSelection);
105 // update done in parent call
106 }
107
108void C4GameOptionsList::OptionControlMode::Update()
109 {
110 const char *szControlMode;
111 if (!::Control.isNetwork() || !::Control.Network.IsEnabled())
112 szControlMode = LoadResStr("IDS_NET_NONET");
113 else
114 {
115 switch (::Control.Network.GetCtrlMode())
116 {
117 case CNM_Central: szControlMode = LoadResStr("IDS_NET_CTRLMODE_CENTRAL"); break;
118 case CNM_Decentral: szControlMode = LoadResStr("IDS_NET_CTRLMODE_DECENTRAL"); break;
119 default: szControlMode = LoadResStr("IDS_NET_CTRLMODE_NONE"); break;
120 }
121 }
122 pDropdownList->SetText(szControlMode);
123 }
124
125
126// ----------- C4GameOptionsList::OptionControlRate ----------------------------------------------------------------
127
128C4GameOptionsList::OptionControlRate::OptionControlRate(class C4GameOptionsList *pForDlg)
129: C4GameOptionsList::OptionDropdown(pForDlg, LoadResStr("IDS_CTL_CONTROLRATE"), !::Control.isCtrlHost())
130 {
131 SetToolTip(LoadResStr("IDS_CTL_CONTROLRATE_DESC"));
132 }
133
134void C4GameOptionsList::OptionControlRate::DoDropdownFill(C4GUI::ComboBox_FillCB *pFiller)
135 {
136 for (int i = 1; i < Min(C4MaxControlRate, 10); ++i)
137 pFiller->AddEntry(FormatString("%d", i).getData(), i);
138 }
139
140void C4GameOptionsList::OptionControlRate::DoDropdownSelChange(int32_t idNewSelection)
141 {
142 // adjust rate
143 int32_t iNewRate = idNewSelection;
144 if (!iNewRate || iNewRate == ::Control.ControlRate) return;
145 ::Control.AdjustControlRate(iNewRate - ::Control.ControlRate);
146 }
147
148void C4GameOptionsList::OptionControlRate::Update()
149 {
150 if (atoi(pDropdownList->GetText().getData()) == ::Control.ControlRate) return;
151 pDropdownList->SetText(FormatString("%d", ::Control.ControlRate).getData());
152 }
153
154
155// ----------- C4GameOptionsList::OptionRuntimeJoin ----------------------------------------------------------------
156
157C4GameOptionsList::OptionRuntimeJoin::OptionRuntimeJoin(class C4GameOptionsList *pForDlg)
158: C4GameOptionsList::OptionDropdown(pForDlg, LoadResStr("IDS_NET_RUNTIMEJOIN"), !::Network.isHost())
159 {
160 SetToolTip(LoadResStr("IDS_NET_RUNTIMEJOIN_DESC"));
161 }
162
163void C4GameOptionsList::OptionRuntimeJoin::DoDropdownFill(C4GUI::ComboBox_FillCB *pFiller)
164 {
165 pFiller->AddEntry(LoadResStr("IDS_NET_RUNTIMEJOINBARRED"), 0);
166 pFiller->AddEntry(LoadResStr("IDS_NET_RUNTIMEJOINFREE"), 1);
167 }
168
169void C4GameOptionsList::OptionRuntimeJoin::DoDropdownSelChange(int32_t idNewSelection)
170 {
171 // adjust mode
172 bool fAllowed = !!idNewSelection;
173 Config.Network.NoRuntimeJoin = !fAllowed;
174 if (Game.IsRunning) ::Network.AllowJoin(fAllowed);
175 }
176
177void C4GameOptionsList::OptionRuntimeJoin::Update()
178 {
179 const char *szText;
180 if (Config.Network.NoRuntimeJoin)
181 szText = LoadResStr("IDS_NET_RUNTIMEJOINBARRED");
182 else
183 szText = LoadResStr("IDS_NET_RUNTIMEJOINFREE");
184 pDropdownList->SetText(szText);
185 }
186
187
188// ----------- C4GameOptionsList::OptionTeamDist ----------------------------------------------------------------
189
190C4GameOptionsList::OptionTeamDist::OptionTeamDist(class C4GameOptionsList *pForDlg)
191: C4GameOptionsList::OptionDropdown(pForDlg, LoadResStr("IDS_MSG_TEAMDIST"), !::Control.isCtrlHost())
192 {
193 SetToolTip(LoadResStr("IDS_MSG_TEAMDIST_DESC"));
194 }
195
196void C4GameOptionsList::OptionTeamDist::DoDropdownFill(C4GUI::ComboBox_FillCB *pFiller)
197 {
198 Game.Teams.FillTeamDistOptions(pFiller);
199 }
200
201void C4GameOptionsList::OptionTeamDist::DoDropdownSelChange(int32_t idNewSelection)
202 {
203 // adjust team distribution
204 Game.Teams.SendSetTeamDist(C4TeamList::TeamDist(idNewSelection));
205 }
206
207void C4GameOptionsList::OptionTeamDist::Update()
208 {
209 StdStrBuf sOption; sOption.Take(Game.Teams.GetTeamDistString());
210 pDropdownList->SetText(sOption.getData());
211 }
212
213
214// ----------- C4GameOptionsList::OptionTeamColors ----------------------------------------------------------------
215
216C4GameOptionsList::OptionTeamColors::OptionTeamColors(class C4GameOptionsList *pForDlg)
217: C4GameOptionsList::OptionDropdown(pForDlg, LoadResStr("IDS_MSG_TEAMCOLORS"), !::Control.isCtrlHost())
218 {
219 SetToolTip(LoadResStr("IDS_MSG_TEAMCOLORS_DESC"));
220 }
221
222void C4GameOptionsList::OptionTeamColors::DoDropdownFill(C4GUI::ComboBox_FillCB *pFiller)
223 {
224 pFiller->AddEntry(LoadResStr("IDS_MSG_ENABLED"), 1);
225 pFiller->AddEntry(LoadResStr("IDS_MSG_DISABLED"), 0);
226 }
227
228void C4GameOptionsList::OptionTeamColors::DoDropdownSelChange(int32_t idNewSelection)
229 {
230 bool fEnabled = !!idNewSelection;
231 Game.Teams.SendSetTeamColors(fEnabled);
232 }
233
234void C4GameOptionsList::OptionTeamColors::Update()
235 {
236 pDropdownList->SetText(Game.Teams.IsTeamColors() ? LoadResStr("IDS_MSG_ENABLED") : LoadResStr("IDS_MSG_DISABLED"));
237 }
238
239// ----------- C4GameOptionsList -----------------------------------------------------------------------
240
241C4GameOptionsList::C4GameOptionsList(const C4Rect &rcBounds, bool fActive, bool fRuntime)
242: C4GUI::ListBox(rcBounds), fRuntime(fRuntime)
243 {
244 // initial option fill
245 InitOptions();
246 if (fActive) Activate();
247 }
248
249void C4GameOptionsList::InitOptions()
250 {
251 // creates option selection components
252 new OptionControlMode(this);
253 new OptionControlRate(this);
254 if (::Network.isHost()) new OptionRuntimeJoin(this);
255 if (!IsRuntime())
256 {
257 if (Game.Teams.HasTeamDistOptions()) new OptionTeamDist(this);
258 if (Game.Teams.IsMultiTeams()) new OptionTeamColors(this);
259 }
260 }
261
262void C4GameOptionsList::Update()
263 {
264 // update all option items
265 for(Option *pItem = static_cast<Option *>(pClientWindow->GetFirst()); pItem; pItem = pItem->GetNext())
266 pItem->Update();
267 }
268
269void C4GameOptionsList::Activate()
270 {
271 // register timer if necessary
272 Application.Add(this);
273 // force an update
274 Update();
275 }
276
277void C4GameOptionsList::Deactivate()
278 {
279 // release timer if set
280 Application.Remove(this);
281 }