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