]> git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/preferences.h
Appveyor
[xonotic/netradiant.git] / radiant / preferences.h
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 /*
23    The following source code is licensed by Id Software and subject to the terms of
24    its LIMITED USE SOFTWARE LICENSE AGREEMENT, a copy of which is included with
25    GtkRadiant. If you did not receive a LIMITED USE SOFTWARE LICENSE AGREEMENT,
26    please contact Id Software immediately at info@idsoftware.com.
27  */
28
29 #if !defined( INCLUDED_PREFERENCES_H )
30 #define INCLUDED_PREFERENCES_H
31
32 #include "libxml/parser.h"
33 #include "dialog.h"
34 #include <list>
35 #include <map>
36
37 void Widget_connectToggleDependency( ui::Widget self, ui::Widget toggleButton );
38
39 class PreferencesPage
40 {
41 Dialog& m_dialog;
42 ui::Widget m_vbox;
43 public:
44 PreferencesPage( Dialog& dialog, ui::Widget vbox ) : m_dialog( dialog ), m_vbox( vbox ){
45 }
46 ui::CheckButton appendCheckBox( const char* name, const char* flag, bool& data ){
47         return m_dialog.addCheckBox( m_vbox, name, flag, data );
48 }
49 ui::CheckButton appendCheckBox( const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ){
50         return m_dialog.addCheckBox( m_vbox, name, flag, importCallback, exportCallback );
51 }
52 void appendCombo( const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
53         m_dialog.addCombo( m_vbox, name, values, importCallback, exportCallback );
54 }
55 void appendCombo( const char* name, int& data, StringArrayRange values ){
56         m_dialog.addCombo( m_vbox, name, data, values );
57 }
58 void appendSlider( const char* name, int& data, gboolean draw_value, const char* low, const char* high, double value, double lower, double upper, double step_increment, double page_increment ){
59         m_dialog.addSlider( m_vbox, name, data, draw_value, low, high, value, lower, upper, step_increment, page_increment );
60 }
61 void appendRadio( const char* name, StringArrayRange names, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
62         m_dialog.addRadio( m_vbox, name, names, importCallback, exportCallback );
63 }
64 void appendRadio( const char* name, int& data, StringArrayRange names ){
65         m_dialog.addRadio( m_vbox, name, data, names );
66 }
67 void appendRadioIcons( const char* name, StringArrayRange icons, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
68         m_dialog.addRadioIcons( m_vbox, name, icons, importCallback, exportCallback );
69 }
70 void appendRadioIcons( const char* name, int& data, StringArrayRange icons ){
71         m_dialog.addRadioIcons( m_vbox, name, data, icons );
72 }
73 ui::Widget appendEntry( const char* name, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
74         return m_dialog.addIntEntry( m_vbox, name, importCallback, exportCallback );
75 }
76 ui::Widget appendEntry( const char* name, int& data ){
77         return m_dialog.addEntry( m_vbox, name, data );
78 }
79 ui::Widget appendEntry( const char* name, const SizeImportCallback& importCallback, const SizeExportCallback& exportCallback ){
80         return m_dialog.addSizeEntry( m_vbox, name, importCallback, exportCallback );
81 }
82 ui::Widget appendEntry( const char* name, std::size_t& data ){
83         return m_dialog.addEntry( m_vbox, name, data );
84 }
85 ui::Widget appendEntry( const char* name, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){
86         return m_dialog.addFloatEntry( m_vbox, name, importCallback, exportCallback );
87 }
88 ui::Widget appendEntry( const char* name, float& data ){
89         return m_dialog.addEntry( m_vbox, name, data );
90 }
91 ui::Widget appendPathEntry( const char* name, bool browse_directory, const StringImportCallback& importCallback, const StringExportCallback& exportCallback ){
92         return m_dialog.addPathEntry( m_vbox, name, browse_directory, importCallback, exportCallback );
93 }
94 ui::Widget appendPathEntry( const char* name, std::string& data, bool directory ){
95         return m_dialog.addPathEntry( m_vbox, name, data, directory );
96 }
97 ui::SpinButton appendSpinner( const char* name, int& data, double value, double lower, double upper ){
98         return m_dialog.addSpinner( m_vbox, name, data, value, lower, upper );
99 }
100 ui::SpinButton appendSpinner( const char* name, double value, double lower, double upper, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
101         return m_dialog.addSpinner( m_vbox, name, value, lower, upper, importCallback, exportCallback );
102 }
103 ui::SpinButton appendSpinner( const char* name, double value, double lower, double upper, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){
104         return m_dialog.addSpinner( m_vbox, name, value, lower, upper, importCallback, exportCallback );
105 }
106 };
107
108 typedef Callback1<PreferencesPage&> PreferencesPageCallback;
109
110 class PreferenceGroup
111 {
112 public:
113 virtual PreferencesPage createPage( const char* treeName, const char* frameName ) = 0;
114 };
115
116 typedef Callback1<PreferenceGroup&> PreferenceGroupCallback;
117
118 void PreferencesDialog_addInterfacePreferences( const PreferencesPageCallback& callback );
119 void PreferencesDialog_addInterfacePage( const PreferenceGroupCallback& callback );
120 void PreferencesDialog_addDisplayPreferences( const PreferencesPageCallback& callback );
121 void PreferencesDialog_addDisplayPage( const PreferenceGroupCallback& callback );
122 void PreferencesDialog_addSettingsPreferences( const PreferencesPageCallback& callback );
123 void PreferencesDialog_addSettingsPage( const PreferenceGroupCallback& callback );
124
125 void PreferencesDialog_restartRequired( const char* staticName );
126
127 template<typename Value>
128 class LatchedValue
129 {
130 public:
131 Value m_value;
132 Value m_latched;
133 const char* m_description;
134
135 LatchedValue( Value value, const char* description ) : m_latched( value ), m_description( description ){
136 }
137 void useLatched(){
138         m_value = m_latched;
139 }
140 void import( Value value ){
141         m_latched = value;
142         if ( m_latched != m_value ) {
143                 PreferencesDialog_restartRequired( m_description );
144         }
145 }
146 };
147
148 typedef LatchedValue<bool> LatchedBool;
149 typedef MemberCaller1<LatchedBool, bool, &LatchedBool::import> LatchedBoolImportCaller;
150
151 typedef LatchedValue<int> LatchedInt;
152 typedef MemberCaller1<LatchedInt, int, &LatchedInt::import> LatchedIntImportCaller;
153
154 /*!
155    holds information for a given game
156    I'm a bit unclear on that still
157    it holds game specific configuration stuff
158    such as base names, engine names, some game specific features to activate in the various modules
159    it is not strictly a prefs thing since the user is not supposed to edit that (unless he is hacking
160    support for a new game)
161
162    what we do now is fully generate the information for this during the setup. We might want to
163    generate a piece that just says "the game pack is there", but put the rest of the config somwhere
164    else (i.e. not generated, copied over during setup .. for instance in the game tools directory)
165  */
166 class CGameDescription
167 {
168 typedef std::map<std::string, std::string> GameDescription;
169
170 public:
171 std::string mGameFile;   ///< the .game file that describes this game
172 GameDescription m_gameDescription;
173
174 std::string mGameToolsPath;   ///< the explicit path to the game-dependent modules
175 std::string mGameType;   ///< the type of the engine
176
177 const char* getKeyValue( const char* key ) const {
178         GameDescription::const_iterator i = m_gameDescription.find( key );
179         if ( i != m_gameDescription.end() ) {
180                 return ( *i ).second.c_str();
181         }
182         return "";
183 }
184 const char* getRequiredKeyValue( const char* key ) const {
185         GameDescription::const_iterator i = m_gameDescription.find( key );
186         if ( i != m_gameDescription.end() ) {
187                 return ( *i ).second.c_str();
188         }
189         ERROR_MESSAGE( "game attribute " << makeQuoted( key ) << " not found in " << makeQuoted( mGameFile.c_str() ) );
190         return "";
191 }
192
193 CGameDescription( xmlDocPtr pDoc, const std::string &GameFile );
194
195 void Dump();
196 };
197
198 extern CGameDescription *g_pGameDescription;
199
200 class PrefsDlg;
201
202 class PreferencesPage;
203
204 class StringOutputStream;
205
206 /*!
207    standalone dialog for games selection, and more generally global settings
208  */
209 class CGameDialog : public Dialog
210 {
211 protected:
212
213 mutable int m_nComboSelect;   ///< intermediate int value for combo in dialog box
214
215 public:
216
217 /*!
218    those settings are saved in the global prefs file
219    I'm too lazy to wrap behind protected access, not sure this needs to be public
220    NOTE: those are preference settings. if you change them it is likely that you would
221    have to restart the editor for them to take effect
222  */
223 /*@{*/
224 /*!
225    what game has been selected
226    this is the name of the .game file
227  */
228 std::string m_sGameFile;
229 /*!
230    prompt which game to load on startup
231  */
232 bool m_bGamePrompt;
233 /*!
234    log console to radiant.log
235    m_bForceLogConsole is an obscure forced latching situation
236  */
237 bool m_bForceLogConsole;
238 /*@}*/
239
240 /*!
241    the list of game descriptions we scanned from the game/ dir
242  */
243 std::list<CGameDescription*> mGames;
244
245 CGameDialog() :
246         m_sGameFile( "" ),
247         m_bGamePrompt( true ),
248         m_bForceLogConsole( false ){
249 }
250 virtual ~CGameDialog();
251
252 void AddPacksURL( StringOutputStream &s );
253
254 /*!
255    intialize the game dialog, called at CPrefsDlg::Init
256    will scan for games, load prefs, and do game selection dialog if needed
257  */
258 void Init();
259
260 /*!
261    reset the global settings by removing the file
262  */
263 void Reset();
264
265 /*!
266    run the dialog UI for the list of games
267  */
268 void DoGameDialog();
269
270 /*!
271    Dialog API
272    this is only called when the dialog is built at startup for main engine select
273  */
274 ui::Window BuildDialog();
275
276 void GameFileImport( int value );
277 void GameFileExport( const IntImportCallback& importCallback ) const;
278
279 /*!
280    construction of the dialog frame
281    this is the part to be re-used in prefs dialog
282    for the standalone dialog, we include this in a modal box
283    for prefs, we hook the frame in the main notebook
284    build the frame on-demand (only once)
285  */
286 void CreateGlobalFrame( PreferencesPage& page );
287
288 /*!
289    global preferences subsystem
290    XML-based this time, hopefully this will generalize to other prefs
291    LoadPrefs has hardcoded defaults
292    NOTE: it may not be strictly 'CGameDialog' to put the global prefs here
293    could have named the class differently I guess
294  */
295 /*@{*/
296 void LoadPrefs();   ///< load from file into variables
297 void SavePrefs();   ///< save pref variables to file
298 /*@}*/
299
300 private:
301 /*!
302    scan for .game files, load them
303  */
304 void ScanForGames();
305
306 /*!
307    inits g_Preferences.m_global_rc_path
308  */
309 void InitGlobalPrefPath();
310
311 /*!
312    uses m_nComboItem to find the right mGames
313  */
314 CGameDescription *GameDescriptionForComboItem();
315 };
316
317 /*!
318    this holds global level preferences
319  */
320 extern CGameDialog g_GamesDialog;
321
322
323 class texdef_t;
324
325 class PrefsDlg : public Dialog
326 {
327 public:
328 protected:
329 std::list<CGameDescription *> mGames;
330
331 public:
332
333 ui::Widget m_notebook;
334
335 virtual ~PrefsDlg(){
336         g_string_free( m_rc_path, true );
337         g_string_free( m_inipath, true );
338 }
339
340 /*!
341    path for global settings
342    win32: AppPath
343    linux: ~/.radiant/[version]/
344  */
345 GString *m_global_rc_path;
346
347 /*!
348    path to per-game settings
349    used for various game dependant storage
350    win32: GameToolsPath
351    linux: ~/.radiant/[version]/[gamename]/
352  */
353 GString *m_rc_path;
354
355 /*!
356    holds per-game settings
357    m_rc_path+"local.pref"
358    \todo FIXME at some point this should become XML property bag code too
359  */
360 GString *m_inipath;
361
362 // initialize the above paths
363 void Init();
364
365 /*! Utility function for swapping notebook pages for tree list selections */
366 void showPrefPage( ui::Widget prefpage );
367
368 protected:
369
370 /*! Dialog API */
371 ui::Window BuildDialog();
372 void PostModal( EMessageBoxReturn code );
373 };
374
375 extern PrefsDlg g_Preferences;
376
377 struct preferences_globals_t
378 {
379         // disabled all INI / registry read write .. used when shutting down after registry cleanup
380         bool disable_ini;
381         preferences_globals_t() : disable_ini( false ){
382         }
383 };
384 extern preferences_globals_t g_preferences_globals;
385
386 void PreferencesDialog_constructWindow( ui::Window main_window );
387 void PreferencesDialog_destroyWindow();
388
389 void PreferencesDialog_showDialog();
390
391 void GlobalPreferences_Init();
392 void Preferences_Init();
393
394 void Preferences_Load();
395 void Preferences_Save();
396
397 void Preferences_Reset();
398
399
400 #endif