2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
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.
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.
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
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.
29 #if !defined( INCLUDED_PREFERENCES_H )
30 #define INCLUDED_PREFERENCES_H
32 #include "libxml/parser.h"
37 void Widget_connectToggleDependency( GtkWidget* self, GtkWidget* toggleButton );
44 PreferencesPage( Dialog& dialog, GtkWidget* vbox ) : m_dialog( dialog ), m_vbox( vbox ){
46 GtkWidget* appendCheckBox( const char* name, const char* flag, bool& data ){
47 return m_dialog.addCheckBox( m_vbox, name, flag, data );
49 GtkWidget* appendCheckBox( const char* name, const char* flag, const BoolImportCallback& importCallback, const BoolExportCallback& exportCallback ){
50 return m_dialog.addCheckBox( m_vbox, name, flag, importCallback, exportCallback );
52 void appendCombo( const char* name, StringArrayRange values, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
53 m_dialog.addCombo( m_vbox, name, values, importCallback, exportCallback );
55 void appendCombo( const char* name, int& data, StringArrayRange values ){
56 m_dialog.addCombo( m_vbox, name, data, values );
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 );
61 void appendRadio( const char* name, StringArrayRange names, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
62 m_dialog.addRadio( m_vbox, name, names, importCallback, exportCallback );
64 void appendRadio( const char* name, int& data, StringArrayRange names ){
65 m_dialog.addRadio( m_vbox, name, data, names );
67 void appendRadioIcons( const char* name, StringArrayRange icons, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
68 m_dialog.addRadioIcons( m_vbox, name, icons, importCallback, exportCallback );
70 void appendRadioIcons( const char* name, int& data, StringArrayRange icons ){
71 m_dialog.addRadioIcons( m_vbox, name, data, icons );
73 GtkWidget* appendEntry( const char* name, const IntImportCallback& importCallback, const IntExportCallback& exportCallback ){
74 return m_dialog.addIntEntry( m_vbox, name, importCallback, exportCallback );
76 GtkWidget* appendEntry( const char* name, int& data ){
77 return m_dialog.addEntry( m_vbox, name, data );
79 GtkWidget* appendEntry( const char* name, const SizeImportCallback& importCallback, const SizeExportCallback& exportCallback ){
80 return m_dialog.addSizeEntry( m_vbox, name, importCallback, exportCallback );
82 GtkWidget* appendEntry( const char* name, std::size_t& data ){
83 return m_dialog.addEntry( m_vbox, name, data );
85 GtkWidget* appendEntry( const char* name, const FloatImportCallback& importCallback, const FloatExportCallback& exportCallback ){
86 return m_dialog.addFloatEntry( m_vbox, name, importCallback, exportCallback );
88 GtkWidget* appendEntry( const char* name, float& data ){
89 return m_dialog.addEntry( m_vbox, name, data );
91 GtkWidget* 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 );
94 GtkWidget* appendPathEntry( const char* name, CopiedString& data, bool directory ){
95 return m_dialog.addPathEntry( m_vbox, name, data, directory );
97 GtkWidget* appendSpinner( const char* name, int& data, double value, double lower, double upper ){
98 return m_dialog.addSpinner( m_vbox, name, data, value, lower, upper );
100 GtkWidget* 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 );
103 GtkWidget* 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 );
108 typedef Callback1<PreferencesPage&> PreferencesPageCallback;
110 class PreferenceGroup
113 virtual PreferencesPage createPage( const char* treeName, const char* frameName ) = 0;
116 typedef Callback1<PreferenceGroup&> PreferenceGroupCallback;
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 );
125 void PreferencesDialog_restartRequired( const char* staticName );
127 template<typename Value>
133 const char* m_description;
135 LatchedValue( Value value, const char* description ) : m_latched( value ), m_description( description ){
140 void import( Value value ){
142 if ( m_latched != m_value ) {
143 PreferencesDialog_restartRequired( m_description );
148 typedef LatchedValue<bool> LatchedBool;
149 typedef MemberCaller1<LatchedBool, bool, &LatchedBool::import> LatchedBoolImportCaller;
151 typedef LatchedValue<int> LatchedInt;
152 typedef MemberCaller1<LatchedInt, int, &LatchedInt::import> LatchedIntImportCaller;
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)
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)
166 class CGameDescription
168 typedef std::map<CopiedString, CopiedString> GameDescription;
171 CopiedString mGameFile; ///< the .game file that describes this game
172 GameDescription m_gameDescription;
174 CopiedString mGameToolsPath; ///< the explicit path to the game-dependent modules
175 CopiedString mGameType; ///< the type of the engine
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();
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();
189 ERROR_MESSAGE( "game attribute " << makeQuoted( key ) << " not found in " << makeQuoted( mGameFile.c_str() ) );
193 CGameDescription( xmlDocPtr pDoc, const CopiedString &GameFile );
198 extern CGameDescription *g_pGameDescription;
200 typedef struct _GtkWidget GtkWidget;
203 class PreferencesPage;
205 class StringOutputStream;
208 standalone dialog for games selection, and more generally global settings
210 class CGameDialog : public Dialog
214 mutable int m_nComboSelect; ///< intermediate int value for combo in dialog box
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
226 what game has been selected
227 this is the name of the .game file
229 CopiedString m_sGameFile;
231 prompt which game to load on startup
235 log console to radiant.log
236 m_bForceLogConsole is an obscure forced latching situation
238 bool m_bForceLogConsole;
242 the list of game descriptions we scanned from the game/ dir
244 std::list<CGameDescription*> mGames;
248 m_bGamePrompt( true ),
249 m_bForceLogConsole( false ){
251 virtual ~CGameDialog();
254 intialize the game dialog, called at CPrefsDlg::Init
255 will scan for games, load prefs, and do game selection dialog if needed
260 reset the global settings by removing the file
265 run the dialog UI for the list of games
271 this is only called when the dialog is built at startup for main engine select
273 GtkWindow* BuildDialog();
275 void GameFileImport( int value );
276 void GameFileExport( const IntImportCallback& importCallback ) const;
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)
285 void CreateGlobalFrame( PreferencesPage& page );
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
295 void LoadPrefs(); ///< load from file into variables
296 void SavePrefs(); ///< save pref variables to file
301 scan for .game files, load them
306 inits g_Preferences.m_global_rc_path
308 void InitGlobalPrefPath();
311 uses m_nComboItem to find the right mGames
313 CGameDescription *GameDescriptionForComboItem();
317 this holds global level preferences
319 extern CGameDialog g_GamesDialog;
324 class PrefsDlg : public Dialog
328 std::list<CGameDescription *> mGames;
332 GtkWidget *m_notebook;
335 g_string_free( m_rc_path, true );
336 g_string_free( m_inipath, true );
340 path for global settings
342 linux: ~/.radiant/[version]/
344 GString *m_global_rc_path;
347 path to per-game settings
348 used for various game dependant storage
350 linux: ~/.radiant/[version]/[gamename]/
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
361 // initialize the above paths
364 /*! Utility function for swapping notebook pages for tree list selections */
365 void showPrefPage( GtkWidget* prefpage );
370 GtkWindow* BuildDialog();
371 void PostModal( EMessageBoxReturn code );
374 extern PrefsDlg g_Preferences;
376 struct preferences_globals_t
378 // disabled all INI / registry read write .. used when shutting down after registry cleanup
380 preferences_globals_t() : disable_ini( false ){
383 extern preferences_globals_t g_preferences_globals;
385 typedef struct _GtkWindow GtkWindow;
386 void PreferencesDialog_constructWindow( GtkWindow* main_window );
387 void PreferencesDialog_destroyWindow();
389 void PreferencesDialog_showDialog();
391 void GlobalPreferences_Init();
392 void Preferences_Init();
394 void Preferences_Load();
395 void Preferences_Save();
397 void Preferences_Reset();