X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fpreferences.cpp;h=fbd9815169fb935bc5bcea1b316638e47eab80ed;hb=9dfae1c9b270ee369c6362903a9205b30751b95f;hp=4209fdb35d6c5196fc1cae7e0c1909b2663d414b;hpb=7fc621fc78d0e040dc2c12f38dc53dd9048215dc;p=xonotic%2Fnetradiant.git diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index 4209fdb3..fbd98151 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -26,25 +26,13 @@ // #include "preferences.h" +#include "globaldefs.h" + +#include #include "environment.h" #include "debugging/debugging.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "generic/callback.h" #include "math/vector.h" #include "string/string.h" @@ -64,36 +52,42 @@ #include "gtkdlgs.h" - -void Global_constructPreferences( PreferencesPage& page ){ - page.appendCheckBox( "Console", "Enable Logging", g_Console_enableLogging ); +void Global_constructPreferences(PreferencesPage &page) +{ + page.appendCheckBox("Console", "Enable Logging", g_Console_enableLogging); } -void Interface_constructPreferences( PreferencesPage& page ){ -#ifdef WIN32 - page.appendCheckBox( "", "Default Text Editor", g_TextEditor_useWin32Editor ); +void Interface_constructPreferences(PreferencesPage &page) +{ +#if GDEF_OS_WINDOWS + page.appendCheckBox( "", "Default Text Editor", g_TextEditor_useWin32Editor ); #else - { - GtkWidget* use_custom = page.appendCheckBox( "Text Editor", "Custom", g_TextEditor_useCustomEditor ); - GtkWidget* custom_editor = page.appendPathEntry( "Text Editor Command", g_TextEditor_editorCommand, true ); - Widget_connectToggleDependency( custom_editor, use_custom ); - } + { + ui::CheckButton use_custom = page.appendCheckBox("Text Editor", "Custom", g_TextEditor_useCustomEditor); + ui::Widget custom_editor = page.appendPathEntry("Text Editor Command", g_TextEditor_editorCommand, true); + Widget_connectToggleDependency(custom_editor, use_custom); + } #endif } -void Mouse_constructPreferences( PreferencesPage& page ){ - { - const char* buttons[] = { "2 button", "3 button", }; - page.appendRadio( "Mouse Type", g_glwindow_globals.m_nMouseType, STRING_ARRAY_RANGE( buttons ) ); - } - page.appendCheckBox( "Right Button", "Activates Context Menu", g_xywindow_globals.m_bRightClick ); +void Mouse_constructPreferences(PreferencesPage &page) +{ + { + const char *buttons[] = {"2 button", "3 button",}; + page.appendRadio("Mouse Type", g_glwindow_globals.m_nMouseType, STRING_ARRAY_RANGE(buttons)); + } + page.appendCheckBox("Right Button", "Activates Context Menu", g_xywindow_globals.m_bRightClick); } -void Mouse_constructPage( PreferenceGroup& group ){ - PreferencesPage page( group.createPage( "Mouse", "Mouse Preferences" ) ); - Mouse_constructPreferences( page ); + +void Mouse_constructPage(PreferenceGroup &group) +{ + PreferencesPage page(group.createPage("Mouse", "Mouse Preferences")); + Mouse_constructPreferences(page); } -void Mouse_registerPreferencesPage(){ - PreferencesDialog_addInterfacePage( FreeCaller1() ); + +void Mouse_registerPreferencesPage() +{ + PreferencesDialog_addInterfacePage(makeCallbackF(Mouse_constructPage)); } @@ -104,62 +98,64 @@ void Mouse_registerPreferencesPage(){ */ #include +#include -inline const char* xmlAttr_getName( xmlAttrPtr attr ){ - return reinterpret_cast( attr->name ); -} - -inline const char* xmlAttr_getValue( xmlAttrPtr attr ){ - return reinterpret_cast( attr->children->content ); +inline const char *xmlAttr_getName(xmlAttrPtr attr) +{ + return reinterpret_cast( attr->name ); } -CGameDescription::CGameDescription( xmlDocPtr pDoc, const CopiedString& gameFile ){ - // read the user-friendly game name - xmlNodePtr pNode = pDoc->children; - - while ( strcmp( (const char*)pNode->name, "game" ) && pNode != 0 ) - { - pNode = pNode->next; - } - if ( !pNode ) { - Error( "Didn't find 'game' node in the game description file '%s'\n", pDoc->URL ); - } - - for ( xmlAttrPtr attr = pNode->properties; attr != 0; attr = attr->next ) - { - m_gameDescription.insert( GameDescription::value_type( xmlAttr_getName( attr ), xmlAttr_getValue( attr ) ) ); - } - - { - StringOutputStream path( 256 ); - path << AppPath_get() << gameFile.c_str() << "/"; - mGameToolsPath = path.c_str(); - } - - ASSERT_MESSAGE( file_exists( mGameToolsPath.c_str() ), "game directory not found: " << makeQuoted( mGameToolsPath.c_str() ) ); - - mGameFile = gameFile; - - { - GameDescription::iterator i = m_gameDescription.find( "type" ); - if ( i == m_gameDescription.end() ) { - globalErrorStream() << "Warning, 'type' attribute not found in '" << reinterpret_cast( pDoc->URL ) << "'\n"; - // default - mGameType = "q3"; - } - else - { - mGameType = ( *i ).second.c_str(); - } - } +inline const char *xmlAttr_getValue(xmlAttrPtr attr) +{ + return reinterpret_cast( attr->children->content ); } -void CGameDescription::Dump(){ - globalOutputStream() << "game description file: " << makeQuoted( mGameFile.c_str() ) << "\n"; - for ( GameDescription::iterator i = m_gameDescription.begin(); i != m_gameDescription.end(); ++i ) - { - globalOutputStream() << ( *i ).first.c_str() << " = " << makeQuoted( ( *i ).second.c_str() ) << "\n"; - } +CGameDescription::CGameDescription(xmlDocPtr pDoc, const CopiedString &gameFile) +{ + // read the user-friendly game name + xmlNodePtr pNode = pDoc->children; + + while (strcmp((const char *) pNode->name, "game") && pNode != 0) { + pNode = pNode->next; + } + if (!pNode) { + Error("Didn't find 'game' node in the game description file '%s'\n", pDoc->URL); + } + + for (xmlAttrPtr attr = pNode->properties; attr != 0; attr = attr->next) { + m_gameDescription.insert(GameDescription::value_type(xmlAttr_getName(attr), xmlAttr_getValue(attr))); + } + + { + StringOutputStream path(256); + path << AppPath_get() << gameFile.c_str() << "/"; + mGameToolsPath = path.c_str(); + } + + ASSERT_MESSAGE(file_exists(mGameToolsPath.c_str()), + "game directory not found: " << makeQuoted(mGameToolsPath.c_str())); + + mGameFile = gameFile; + + { + GameDescription::iterator i = m_gameDescription.find("type"); + if (i == m_gameDescription.end()) { + globalErrorStream() << "Warning, 'type' attribute not found in '" + << reinterpret_cast( pDoc->URL ) << "'\n"; + // default + mGameType = "q3"; + } else { + mGameType = (*i).second.c_str(); + } + } +} + +void CGameDescription::Dump() +{ + globalOutputStream() << "game description file: " << makeQuoted(mGameFile.c_str()) << "\n"; + for (GameDescription::iterator i = m_gameDescription.begin(); i != m_gameDescription.end(); ++i) { + globalOutputStream() << (*i).first.c_str() << " = " << makeQuoted((*i).second.c_str()) << "\n"; + } } CGameDescription *g_pGameDescription; ///< shortcut to g_GamesDialog.m_pCurrentDescription @@ -175,343 +171,341 @@ CGameDescription *g_pGameDescription; ///< shortcut to g_GamesDialog.m_pCurrentD #include "preferencedictionary.h" #include "stringio.h" -const char* const PREFERENCES_VERSION = "1.0"; - -bool Preferences_Load( PreferenceDictionary& preferences, const char* filename, const char *cmdline_prefix ){ - bool ret = false; - TextFileInputStream file( filename ); - if ( !file.failed() ) { - XMLStreamParser parser( file ); - XMLPreferenceDictionaryImporter importer( preferences, PREFERENCES_VERSION ); - parser.exportXML( importer ); - ret = true; - } - - int l = strlen( cmdline_prefix ); - for ( int i = 1; i < g_argc - 1; ++i ) - { - if ( g_argv[i][0] == '-' ) { - if ( !strncmp( g_argv[i] + 1, cmdline_prefix, l ) ) { - if ( g_argv[i][l + 1] == '-' ) { - preferences.importPref( g_argv[i] + l + 2, g_argv[i + 1] ); - } - } - ++i; - } - } +const char *const PREFERENCES_VERSION = "1.0"; - return ret; -} - -bool Preferences_Save( PreferenceDictionary& preferences, const char* filename ){ - TextFileOutputStream file( filename ); - if ( !file.failed() ) { - XMLStreamWriter writer( file ); - XMLPreferenceDictionaryExporter exporter( preferences, PREFERENCES_VERSION ); - exporter.exportXML( writer ); - return true; - } - return false; +bool Preferences_Load(PreferenceDictionary &preferences, const char *filename, const char *cmdline_prefix) +{ + bool ret = false; + TextFileInputStream file(filename); + if (!file.failed()) { + XMLStreamParser parser(file); + XMLPreferenceDictionaryImporter importer(preferences, PREFERENCES_VERSION); + parser.exportXML(importer); + ret = true; + } + + int l = strlen(cmdline_prefix); + for (int i = 1; i < g_argc - 1; ++i) { + if (g_argv[i][0] == '-') { + if (!strncmp(g_argv[i] + 1, cmdline_prefix, l)) { + if (g_argv[i][l + 1] == '-') { + preferences.importPref(g_argv[i] + l + 2, g_argv[i + 1]); + } + } + ++i; + } + } + + return ret; +} + +bool Preferences_Save(PreferenceDictionary &preferences, const char *filename) +{ + TextFileOutputStream file(filename); + if (!file.failed()) { + XMLStreamWriter writer(file); + XMLPreferenceDictionaryExporter exporter(preferences, PREFERENCES_VERSION); + exporter.exportXML(writer); + return true; + } + return false; } -bool Preferences_Save_Safe( PreferenceDictionary& preferences, const char* filename ){ - Array tmpName( filename, filename + strlen( filename ) + 1 + 3 ); - *( tmpName.end() - 4 ) = 'T'; - *( tmpName.end() - 3 ) = 'M'; - *( tmpName.end() - 2 ) = 'P'; - *( tmpName.end() - 1 ) = '\0'; +bool Preferences_Save_Safe(PreferenceDictionary &preferences, const char *filename) +{ + Array tmpName(filename, filename + strlen(filename) + 1 + 3); + *(tmpName.end() - 4) = 'T'; + *(tmpName.end() - 3) = 'M'; + *(tmpName.end() - 2) = 'P'; + *(tmpName.end() - 1) = '\0'; - return Preferences_Save( preferences, tmpName.data() ) - && ( !file_exists( filename ) || file_remove( filename ) ) - && file_move( tmpName.data(), filename ); + return Preferences_Save(preferences, tmpName.data()) + && (!file_exists(filename) || file_remove(filename)) + && file_move(tmpName.data(), filename); } +struct LogConsole { + static void Export(const Callback &returnz) + { + returnz(g_Console_enableLogging); + } -void LogConsole_importString( const char* string ){ - g_Console_enableLogging = string_equal( string, "true" ); - Sys_LogFile( g_Console_enableLogging ); -} -typedef FreeCaller1 LogConsoleImportStringCaller; + static void Import(bool value) + { + g_Console_enableLogging = value; + Sys_LogFile(g_Console_enableLogging); + } +}; -void RegisterGlobalPreferences( PreferenceSystem& preferences ){ - preferences.registerPreference( "gamefile", CopiedStringImportStringCaller( g_GamesDialog.m_sGameFile ), CopiedStringExportStringCaller( g_GamesDialog.m_sGameFile ) ); - preferences.registerPreference( "gamePrompt", BoolImportStringCaller( g_GamesDialog.m_bGamePrompt ), BoolExportStringCaller( g_GamesDialog.m_bGamePrompt ) ); - preferences.registerPreference( "log console", LogConsoleImportStringCaller(), BoolExportStringCaller( g_Console_enableLogging ) ); +void RegisterGlobalPreferences(PreferenceSystem &preferences) +{ + preferences.registerPreference("gamefile", make_property_string(g_GamesDialog.m_sGameFile)); + preferences.registerPreference("gamePrompt", make_property_string(g_GamesDialog.m_bGamePrompt)); + preferences.registerPreference("log console", make_property_string()); } PreferenceDictionary g_global_preferences; -void GlobalPreferences_Init(){ - RegisterGlobalPreferences( g_global_preferences ); +void GlobalPreferences_Init() +{ + RegisterGlobalPreferences(g_global_preferences); } -void CGameDialog::LoadPrefs(){ - // load global .pref file - StringOutputStream strGlobalPref( 256 ); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; +void CGameDialog::LoadPrefs() +{ + // load global .pref file + StringOutputStream strGlobalPref(256); + strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - globalOutputStream() << "loading global preferences from " << makeQuoted( strGlobalPref.c_str() ) << "\n"; + globalOutputStream() << "loading global preferences from " << makeQuoted(strGlobalPref.c_str()) << "\n"; - if ( !Preferences_Load( g_global_preferences, strGlobalPref.c_str(), "global" ) ) { - globalOutputStream() << "failed to load global preferences from " << strGlobalPref.c_str() << "\n"; - } + if (!Preferences_Load(g_global_preferences, strGlobalPref.c_str(), "global")) { + globalOutputStream() << "failed to load global preferences from " << strGlobalPref.c_str() << "\n"; + } } -void CGameDialog::SavePrefs(){ - StringOutputStream strGlobalPref( 256 ); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; +void CGameDialog::SavePrefs() +{ + StringOutputStream strGlobalPref(256); + strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - globalOutputStream() << "saving global preferences to " << strGlobalPref.c_str() << "\n"; + globalOutputStream() << "saving global preferences to " << strGlobalPref.c_str() << "\n"; - if ( !Preferences_Save_Safe( g_global_preferences, strGlobalPref.c_str() ) ) { - globalOutputStream() << "failed to save global preferences to " << strGlobalPref.c_str() << "\n"; - } + if (!Preferences_Save_Safe(g_global_preferences, strGlobalPref.c_str())) { + globalOutputStream() << "failed to save global preferences to " << strGlobalPref.c_str() << "\n"; + } } -void CGameDialog::DoGameDialog(){ - // show the UI - DoModal(); - - // we save the prefs file - SavePrefs(); -} +void CGameDialog::DoGameDialog() +{ + // show the UI + DoModal(); -void CGameDialog::GameFileImport( int value ){ - m_nComboSelect = value; - // use value to set m_sGameFile - std::list::iterator iGame = mGames.begin(); - int i; - for ( i = 0; i < value; i++ ) - { - ++iGame; - } - m_sGameFile = ( *iGame )->mGameFile; + // we save the prefs file + SavePrefs(); } -void CGameDialog::GameFileExport( const IntImportCallback& importCallback ) const { - // use m_sGameFile to set value - std::list::const_iterator iGame; - int i = 0; - for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame ) - { - if ( ( *iGame )->mGameFile == m_sGameFile ) { - m_nComboSelect = i; - break; - } - i++; - } - importCallback( m_nComboSelect ); +void CGameDialog::GameFileImport(int value) +{ + m_nComboSelect = value; + // use value to set m_sGameFile + std::list::iterator iGame = mGames.begin(); + int i; + for (i = 0; i < value; i++) { + ++iGame; + } + m_sGameFile = (*iGame)->mGameFile; } -void CGameDialog_GameFileImport( CGameDialog& self, int value ){ - self.GameFileImport( value ); -} +void CGameDialog::GameFileExport(const Callback &importCallback) const +{ + // use m_sGameFile to set value + std::list::const_iterator iGame; + int i = 0; + for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { + if ((*iGame)->mGameFile == m_sGameFile) { + m_nComboSelect = i; + break; + } + i++; + } + importCallback(m_nComboSelect); +} + +struct CGameDialog_GameFile { + static void Export(const CGameDialog &self, const Callback &returnz) + { + self.GameFileExport(returnz); + } + + static void Import(CGameDialog &self, int value) + { + self.GameFileImport(value); + } +}; -void CGameDialog_GameFileExport( CGameDialog& self, const IntImportCallback& importCallback ){ - self.GameFileExport( importCallback ); -} +void CGameDialog::CreateGlobalFrame(PreferencesPage &page) +{ + std::vector games; + games.reserve(mGames.size()); + for (std::list::iterator i = mGames.begin(); i != mGames.end(); ++i) { + games.push_back((*i)->getRequiredKeyValue("name")); + } + page.appendCombo( + "Select the game", + StringArrayRange(&(*games.begin()), &(*games.end())), + make_property(*this) + ); + page.appendCheckBox("Startup", "Show Global Preferences", m_bGamePrompt); +} + +ui::Window CGameDialog::BuildDialog() +{ + auto frame = create_dialog_frame("Game settings", ui::Shadow::ETCHED_IN); -void CGameDialog::CreateGlobalFrame( PreferencesPage& page ){ - std::vector games; - games.reserve( mGames.size() ); - for ( std::list::iterator i = mGames.begin(); i != mGames.end(); ++i ) - { - games.push_back( ( *i )->getRequiredKeyValue( "name" ) ); - } - page.appendCombo( - "Select the game", - StringArrayRange( &( *games.begin() ), &( *games.end() ) ), - ReferenceCaller1( *this ), - ReferenceCaller1( *this ) - ); - page.appendCheckBox( "Startup", "Show Global Preferences", m_bGamePrompt ); -} + auto vbox2 = create_dialog_vbox(0, 4); + frame.add(vbox2); -GtkWindow* CGameDialog::BuildDialog(){ - GtkFrame* frame = create_dialog_frame( "Game settings", GTK_SHADOW_ETCHED_IN ); + { + PreferencesPage preferencesPage(*this, vbox2); + Global_constructPreferences(preferencesPage); + CreateGlobalFrame(preferencesPage); + } - GtkVBox* vbox2 = create_dialog_vbox( 0, 4 ); - gtk_container_add( GTK_CONTAINER( frame ), GTK_WIDGET( vbox2 ) ); + return create_simple_modal_dialog_window("Global Preferences", m_modal, frame); +} - { - PreferencesPage preferencesPage( *this, GTK_WIDGET( vbox2 ) ); - Global_constructPreferences( preferencesPage ); - CreateGlobalFrame( preferencesPage ); - } +void CGameDialog::ScanForGames() +{ + StringOutputStream strGamesPath(256); + strGamesPath << AppPath_get() << "games/"; + const char *path = strGamesPath.c_str(); + + globalOutputStream() << "Scanning for game description files: " << path << '\n'; + + /*! + \todo FIXME LINUX: + do we put game description files below AppPath, or in ~/.radiant + i.e. read only or read/write? + my guess .. readonly cause it's an install + we will probably want to add ~/.radiant//games/ scanning on top of that for developers + (if that's really needed) + */ + + Directory_forEach(path, [&](const char *name) { + if (!extension_equal(path_get_extension(name), "game")) { + return; + } + StringOutputStream strPath(256); + strPath << path << name; + globalOutputStream() << strPath.c_str() << '\n'; + + xmlDocPtr pDoc = xmlParseFile(strPath.c_str()); + if (pDoc) { + mGames.push_front(new CGameDescription(pDoc, name)); + xmlFreeDoc(pDoc); + } else { + globalErrorStream() << "XML parser failed on '" << strPath.c_str() << "'\n"; + } + }); +} + +CGameDescription *CGameDialog::GameDescriptionForComboItem() +{ + std::list::iterator iGame; + int i = 0; + for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame, i++) { + if (i == m_nComboSelect) { + return (*iGame); + } + } + return 0; // not found +} - return create_simple_modal_dialog_window( "Global Preferences", m_modal, GTK_WIDGET( frame ) ); +void CGameDialog::InitGlobalPrefPath() +{ + g_Preferences.m_global_rc_path = g_string_new(SettingsPath_get()); } -class LoadGameFile +void CGameDialog::Reset() { -std::list& mGames; -const char* mPath; -public: -LoadGameFile( std::list& games, const char* path ) : mGames( games ), mPath( path ){ -} -void operator()( const char* name ) const { - if ( !extension_equal( path_get_extension( name ), "game" ) ) { - return; - } - StringOutputStream strPath( 256 ); - strPath << mPath << name; - globalOutputStream() << strPath.c_str() << '\n'; - - xmlDocPtr pDoc = xmlParseFile( strPath.c_str() ); - if ( pDoc ) { - mGames.push_front( new CGameDescription( pDoc, name ) ); - xmlFreeDoc( pDoc ); - } - else - { - globalErrorStream() << "XML parser failed on '" << strPath.c_str() << "'\n"; - } + if (!g_Preferences.m_global_rc_path) { + InitGlobalPrefPath(); + } + StringOutputStream strGlobalPref(256); + strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; + file_remove(strGlobalPref.c_str()); } -}; -void CGameDialog::ScanForGames(){ - StringOutputStream strGamesPath( 256 ); - strGamesPath << AppPath_get() << "games/"; - const char *path = strGamesPath.c_str(); - - globalOutputStream() << "Scanning for game description files: " << path << '\n'; - - /*! - \todo FIXME LINUX: - do we put game description files below AppPath, or in ~/.radiant - i.e. read only or read/write? - my guess .. readonly cause it's an install - we will probably want to add ~/.radiant//games/ scanning on top of that for developers - (if that's really needed) - */ - - Directory_forEach( path, LoadGameFile( mGames, path ) ); -} - -CGameDescription* CGameDialog::GameDescriptionForComboItem(){ - std::list::iterator iGame; - int i = 0; - for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame,i++ ) - { - if ( i == m_nComboSelect ) { - return ( *iGame ); - } - } - return 0; // not found -} - -void CGameDialog::InitGlobalPrefPath(){ - g_Preferences.m_global_rc_path = g_string_new( SettingsPath_get() ); -} - -void CGameDialog::Reset(){ - if ( !g_Preferences.m_global_rc_path ) { - InitGlobalPrefPath(); - } - StringOutputStream strGlobalPref( 256 ); - strGlobalPref << g_Preferences.m_global_rc_path->str << "global.pref"; - file_remove( strGlobalPref.c_str() ); -} - -void CGameDialog::Init(){ - InitGlobalPrefPath(); - LoadPrefs(); - ScanForGames(); - if ( mGames.empty() ) { - Error( "Didn't find any valid game file descriptions, aborting\n" ); - } - else - { - std::list::iterator iGame, iPrevGame; - for ( iGame = mGames.begin(), iPrevGame = mGames.end(); iGame != mGames.end(); iPrevGame = iGame, ++iGame ) - { - if ( iPrevGame != mGames.end() ) { - if ( strcmp( ( *iGame )->getRequiredKeyValue( "name" ), ( *iPrevGame )->getRequiredKeyValue( "name" ) ) < 0 ) { - CGameDescription *h = *iGame; - *iGame = *iPrevGame; - *iPrevGame = h; - } - } - } - } - - CGameDescription* currentGameDescription = 0; - - if ( !m_bGamePrompt ) { - // search by .game name - std::list::iterator iGame; - for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame ) - { - if ( ( *iGame )->mGameFile == m_sGameFile ) { - currentGameDescription = ( *iGame ); - break; - } - } - } - if ( m_bGamePrompt || !currentGameDescription ) { - Create(); - DoGameDialog(); - // use m_nComboSelect to identify the game to run as and set the globals - currentGameDescription = GameDescriptionForComboItem(); - ASSERT_NOTNULL( currentGameDescription ); - } - g_pGameDescription = currentGameDescription; - - g_pGameDescription->Dump(); -} - -CGameDialog::~CGameDialog(){ - // free all the game descriptions - std::list::iterator iGame; - for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame ) - { - delete ( *iGame ); - *iGame = 0; - } - if ( GetWidget() != 0 ) { - Destroy(); - } -} - -inline const char* GameDescription_getIdentifier( const CGameDescription& gameDescription ){ - const char* identifier = gameDescription.getKeyValue( "index" ); - if ( string_empty( identifier ) ) { - identifier = "1"; - } - return identifier; -} - -void CGameDialog::AddPacksURL( StringOutputStream &URL ){ - // add the URLs for the list of game packs installed - // FIXME: this is kinda hardcoded for now.. - std::list::iterator iGame; - for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame ) - { - URL << "&Games_dlup%5B%5D=" << GameDescription_getIdentifier( *( *iGame ) ); - } +void CGameDialog::Init() +{ + InitGlobalPrefPath(); + LoadPrefs(); + ScanForGames(); + if (mGames.empty()) { + Error("Didn't find any valid game file descriptions, aborting\n"); + } else { + std::list::iterator iGame, iPrevGame; + for (iGame = mGames.begin(), iPrevGame = mGames.end(); iGame != mGames.end(); iPrevGame = iGame, ++iGame) { + if (iPrevGame != mGames.end()) { + if (strcmp((*iGame)->getRequiredKeyValue("name"), (*iPrevGame)->getRequiredKeyValue("name")) < 0) { + CGameDescription *h = *iGame; + *iGame = *iPrevGame; + *iPrevGame = h; + } + } + } + } + + CGameDescription *currentGameDescription = 0; + + if (!m_bGamePrompt) { + // search by .game name + std::list::iterator iGame; + for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { + if ((*iGame)->mGameFile == m_sGameFile) { + currentGameDescription = (*iGame); + break; + } + } + } + if (m_bGamePrompt || !currentGameDescription) { + Create(); + DoGameDialog(); + // use m_nComboSelect to identify the game to run as and set the globals + currentGameDescription = GameDescriptionForComboItem(); + ASSERT_NOTNULL(currentGameDescription); + } + g_pGameDescription = currentGameDescription; + + g_pGameDescription->Dump(); +} + +CGameDialog::~CGameDialog() +{ + // free all the game descriptions + std::list::iterator iGame; + for (iGame = mGames.begin(); iGame != mGames.end(); ++iGame) { + delete (*iGame); + *iGame = 0; + } + if (GetWidget()) { + Destroy(); + } +} + +inline const char *GameDescription_getIdentifier(const CGameDescription &gameDescription) +{ + const char *identifier = gameDescription.getKeyValue("index"); + if (string_empty(identifier)) { + identifier = "1"; + } + return identifier; } + CGameDialog g_GamesDialog; // ============================================================================= // Widget callbacks for PrefsDlg -static void OnButtonClean( GtkWidget *widget, gpointer data ){ - // make sure this is what the user wants - if ( gtk_MessageBox( GTK_WIDGET( g_Preferences.GetWidget() ), "This will close Radiant and clean the corresponding registry entries.\n" - "Next time you start Radiant it will be good as new. Do you wish to continue?", - "Reset Registry", eMB_YESNO, eMB_ICONASTERISK ) == eIDYES ) { - PrefsDlg *dlg = (PrefsDlg*)data; - dlg->EndModal( eIDCANCEL ); +static void OnButtonClean(ui::Widget widget, gpointer data) +{ + // make sure this is what the user wants + if (ui::alert(g_Preferences.GetWidget(), "This will close Radiant and clean the corresponding registry entries.\n" + "Next time you start Radiant it will be good as new. Do you wish to continue?", + "Reset Registry", ui::alert_type::YESNO, ui::alert_icon::Asterisk) == ui::alert_response::YES) { + PrefsDlg *dlg = (PrefsDlg *) data; + dlg->EndModal(eIDCANCEL); - g_preferences_globals.disable_ini = true; - Preferences_Reset(); - gtk_main_quit(); - } + g_preferences_globals.disable_ini = true; + Preferences_Reset(); + gtk_main_quit(); + } } // ============================================================================= @@ -530,321 +524,355 @@ static void OnButtonClean( GtkWidget *widget, gpointer data ){ ======== */ -#define PREFS_LOCAL_FILENAME "local.pref" +const char *PREFS_LOCAL_FILENAME = "local.pref"; -void PrefsDlg::Init(){ - // m_global_rc_path has been set above - // m_rc_path is for game specific preferences - // takes the form: global-pref-path/gamename/prefs-file +void PrefsDlg::Init() +{ + // m_global_rc_path has been set above + // m_rc_path is for game specific preferences + // takes the form: global-pref-path/gamename/prefs-file - // this is common to win32 and Linux init now - m_rc_path = g_string_new( m_global_rc_path->str ); + // this is common to win32 and Linux init now + m_rc_path = g_string_new(m_global_rc_path->str); - // game sub-dir - g_string_append( m_rc_path, g_pGameDescription->mGameFile.c_str() ); - g_string_append( m_rc_path, "/" ); - Q_mkdir( m_rc_path->str ); + // game sub-dir + g_string_append(m_rc_path, g_pGameDescription->mGameFile.c_str()); + g_string_append(m_rc_path, "/"); + Q_mkdir(m_rc_path->str); - // then the ini file - m_inipath = g_string_new( m_rc_path->str ); - g_string_append( m_inipath, PREFS_LOCAL_FILENAME ); + // then the ini file + m_inipath = g_string_new(m_rc_path->str); + g_string_append(m_inipath, PREFS_LOCAL_FILENAME); } -void notebook_set_page( GtkWidget* notebook, GtkWidget* page ){ - int pagenum = gtk_notebook_page_num( GTK_NOTEBOOK( notebook ), page ); - if ( gtk_notebook_get_current_page( GTK_NOTEBOOK( notebook ) ) != pagenum ) { - gtk_notebook_set_current_page( GTK_NOTEBOOK( notebook ), pagenum ); - } +void notebook_set_page(ui::Widget notebook, ui::Widget page) +{ + int pagenum = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), page); + if (gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) != pagenum) { + gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), pagenum); + } } -void PrefsDlg::showPrefPage( GtkWidget* prefpage ){ - notebook_set_page( m_notebook, prefpage ); - return; +void PrefsDlg::showPrefPage(ui::Widget prefpage) +{ + notebook_set_page(m_notebook, prefpage); + return; } -static void treeSelection( GtkTreeSelection* selection, gpointer data ){ - PrefsDlg *dlg = (PrefsDlg*)data; +static void treeSelection(ui::TreeSelection selection, gpointer data) +{ + PrefsDlg *dlg = (PrefsDlg *) data; - GtkTreeModel* model; - GtkTreeIter selected; - if ( gtk_tree_selection_get_selected( selection, &model, &selected ) ) { - GtkWidget* prefpage; - gtk_tree_model_get( model, &selected, 1, (gpointer*)&prefpage, -1 ); - dlg->showPrefPage( prefpage ); - } + GtkTreeModel *model; + GtkTreeIter selected; + if (gtk_tree_selection_get_selected(selection, &model, &selected)) { + ui::Widget prefpage{ui::null}; + gtk_tree_model_get(model, &selected, 1, (gpointer *) &prefpage, -1); + dlg->showPrefPage(prefpage); + } } typedef std::list PreferenceGroupCallbacks; -inline void PreferenceGroupCallbacks_constructGroup( const PreferenceGroupCallbacks& callbacks, PreferenceGroup& group ){ - for ( PreferenceGroupCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i ) - { - ( *i )( group ); - } +inline void PreferenceGroupCallbacks_constructGroup(const PreferenceGroupCallbacks &callbacks, PreferenceGroup &group) +{ + for (PreferenceGroupCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i) { + (*i)(group); + } } -inline void PreferenceGroupCallbacks_pushBack( PreferenceGroupCallbacks& callbacks, const PreferenceGroupCallback& callback ){ - callbacks.push_back( callback ); +inline void +PreferenceGroupCallbacks_pushBack(PreferenceGroupCallbacks &callbacks, const PreferenceGroupCallback &callback) +{ + callbacks.push_back(callback); } typedef std::list PreferencesPageCallbacks; -inline void PreferencesPageCallbacks_constructPage( const PreferencesPageCallbacks& callbacks, PreferencesPage& page ){ - for ( PreferencesPageCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i ) - { - ( *i )( page ); - } +inline void PreferencesPageCallbacks_constructPage(const PreferencesPageCallbacks &callbacks, PreferencesPage &page) +{ + for (PreferencesPageCallbacks::const_iterator i = callbacks.begin(); i != callbacks.end(); ++i) { + (*i)(page); + } } -inline void PreferencesPageCallbacks_pushBack( PreferencesPageCallbacks& callbacks, const PreferencesPageCallback& callback ){ - callbacks.push_back( callback ); +inline void +PreferencesPageCallbacks_pushBack(PreferencesPageCallbacks &callbacks, const PreferencesPageCallback &callback) +{ + callbacks.push_back(callback); } PreferencesPageCallbacks g_interfacePreferences; -void PreferencesDialog_addInterfacePreferences( const PreferencesPageCallback& callback ){ - PreferencesPageCallbacks_pushBack( g_interfacePreferences, callback ); + +void PreferencesDialog_addInterfacePreferences(const PreferencesPageCallback &callback) +{ + PreferencesPageCallbacks_pushBack(g_interfacePreferences, callback); } + PreferenceGroupCallbacks g_interfaceCallbacks; -void PreferencesDialog_addInterfacePage( const PreferenceGroupCallback& callback ){ - PreferenceGroupCallbacks_pushBack( g_interfaceCallbacks, callback ); + +void PreferencesDialog_addInterfacePage(const PreferenceGroupCallback &callback) +{ + PreferenceGroupCallbacks_pushBack(g_interfaceCallbacks, callback); } PreferencesPageCallbacks g_displayPreferences; -void PreferencesDialog_addDisplayPreferences( const PreferencesPageCallback& callback ){ - PreferencesPageCallbacks_pushBack( g_displayPreferences, callback ); + +void PreferencesDialog_addDisplayPreferences(const PreferencesPageCallback &callback) +{ + PreferencesPageCallbacks_pushBack(g_displayPreferences, callback); } + PreferenceGroupCallbacks g_displayCallbacks; -void PreferencesDialog_addDisplayPage( const PreferenceGroupCallback& callback ){ - PreferenceGroupCallbacks_pushBack( g_displayCallbacks, callback ); + +void PreferencesDialog_addDisplayPage(const PreferenceGroupCallback &callback) +{ + PreferenceGroupCallbacks_pushBack(g_displayCallbacks, callback); } PreferencesPageCallbacks g_settingsPreferences; -void PreferencesDialog_addSettingsPreferences( const PreferencesPageCallback& callback ){ - PreferencesPageCallbacks_pushBack( g_settingsPreferences, callback ); + +void PreferencesDialog_addSettingsPreferences(const PreferencesPageCallback &callback) +{ + PreferencesPageCallbacks_pushBack(g_settingsPreferences, callback); } + PreferenceGroupCallbacks g_settingsCallbacks; -void PreferencesDialog_addSettingsPage( const PreferenceGroupCallback& callback ){ - PreferenceGroupCallbacks_pushBack( g_settingsCallbacks, callback ); + +void PreferencesDialog_addSettingsPage(const PreferenceGroupCallback &callback) +{ + PreferenceGroupCallbacks_pushBack(g_settingsCallbacks, callback); } -void Widget_updateDependency( GtkWidget* self, GtkWidget* toggleButton ){ - gtk_widget_set_sensitive( self, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( toggleButton ) ) && GTK_WIDGET_IS_SENSITIVE( toggleButton ) ); +void Widget_updateDependency(ui::Widget self, ui::Widget toggleButton) +{ + gtk_widget_set_sensitive(self, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggleButton)) && + gtk_widget_is_sensitive(toggleButton)); } -void ToggleButton_toggled_Widget_updateDependency( GtkWidget *toggleButton, GtkWidget* self ){ - Widget_updateDependency( self, toggleButton ); +void ToggleButton_toggled_Widget_updateDependency(ui::Widget toggleButton, ui::Widget self) +{ + Widget_updateDependency(self, toggleButton); } -void ToggleButton_state_changed_Widget_updateDependency( GtkWidget* toggleButton, GtkStateType state, GtkWidget* self ){ - if ( state == GTK_STATE_INSENSITIVE ) { - Widget_updateDependency( self, toggleButton ); - } +void ToggleButton_state_changed_Widget_updateDependency(ui::Widget toggleButton, GtkStateType state, ui::Widget self) +{ + if (state == GTK_STATE_INSENSITIVE) { + Widget_updateDependency(self, toggleButton); + } } -void Widget_connectToggleDependency( GtkWidget* self, GtkWidget* toggleButton ){ - g_signal_connect( G_OBJECT( toggleButton ), "state_changed", G_CALLBACK( ToggleButton_state_changed_Widget_updateDependency ), self ); - g_signal_connect( G_OBJECT( toggleButton ), "toggled", G_CALLBACK( ToggleButton_toggled_Widget_updateDependency ), self ); - Widget_updateDependency( self, toggleButton ); +void Widget_connectToggleDependency(ui::Widget self, ui::Widget toggleButton) +{ + toggleButton.connect("state_changed", G_CALLBACK(ToggleButton_state_changed_Widget_updateDependency), self); + toggleButton.connect("toggled", G_CALLBACK(ToggleButton_toggled_Widget_updateDependency), self); + Widget_updateDependency(self, toggleButton); } -inline GtkWidget* getVBox( GtkWidget* page ){ - return gtk_bin_get_child( GTK_BIN( page ) ); +inline ui::VBox getVBox(ui::Bin page) +{ + return ui::VBox::from(gtk_bin_get_child(page)); } -GtkTreeIter PreferenceTree_appendPage( GtkTreeStore* store, GtkTreeIter* parent, const char* name, GtkWidget* page ){ - GtkTreeIter group; - gtk_tree_store_append( store, &group, parent ); - gtk_tree_store_set( store, &group, 0, name, 1, page, -1 ); - return group; +GtkTreeIter PreferenceTree_appendPage(ui::TreeStore store, GtkTreeIter *parent, const char *name, ui::Widget page) +{ + GtkTreeIter group; + gtk_tree_store_append(store, &group, parent); + gtk_tree_store_set(store, &group, 0, name, 1, page, -1); + return group; } -GtkWidget* PreferencePages_addPage( GtkWidget* notebook, const char* name ){ - GtkWidget* preflabel = gtk_label_new( name ); - gtk_widget_show( preflabel ); +ui::Bin PreferencePages_addPage(ui::Widget notebook, const char *name) +{ + ui::Widget preflabel = ui::Label(name); + preflabel.show(); - GtkWidget* pageframe = gtk_frame_new( name ); - gtk_container_set_border_width( GTK_CONTAINER( pageframe ), 4 ); - gtk_widget_show( pageframe ); + auto pageframe = ui::Frame(name); + gtk_container_set_border_width(GTK_CONTAINER(pageframe), 4); + pageframe.show(); - GtkWidget* vbox = gtk_vbox_new( FALSE, 4 ); - gtk_widget_show( vbox ); - gtk_container_set_border_width( GTK_CONTAINER( vbox ), 4 ); - gtk_container_add( GTK_CONTAINER( pageframe ), vbox ); + ui::Widget vbox = ui::VBox(FALSE, 4); + vbox.show(); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 4); + pageframe.add(vbox); - // Add the page to the notebook - gtk_notebook_append_page( GTK_NOTEBOOK( notebook ), pageframe, preflabel ); + // Add the page to the notebook + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), pageframe, preflabel); - return pageframe; + return pageframe; } -class PreferenceTreeGroup : public PreferenceGroup -{ -Dialog& m_dialog; -GtkWidget* m_notebook; -GtkTreeStore* m_store; -GtkTreeIter m_group; +class PreferenceTreeGroup : public PreferenceGroup { + Dialog &m_dialog; + ui::Widget m_notebook; + ui::TreeStore m_store; + GtkTreeIter m_group; public: -PreferenceTreeGroup( Dialog& dialog, GtkWidget* notebook, GtkTreeStore* store, GtkTreeIter group ) : - m_dialog( dialog ), - m_notebook( notebook ), - m_store( store ), - m_group( group ){ -} -PreferencesPage createPage( const char* treeName, const char* frameName ){ - GtkWidget* page = PreferencePages_addPage( m_notebook, frameName ); - PreferenceTree_appendPage( m_store, &m_group, treeName, page ); - return PreferencesPage( m_dialog, getVBox( page ) ); -} + PreferenceTreeGroup(Dialog &dialog, ui::Widget notebook, ui::TreeStore store, GtkTreeIter group) : + m_dialog(dialog), + m_notebook(notebook), + m_store(store), + m_group(group) + { + } + + PreferencesPage createPage(const char *treeName, const char *frameName) + { + auto page = PreferencePages_addPage(m_notebook, frameName); + PreferenceTree_appendPage(m_store, &m_group, treeName, page); + return PreferencesPage(m_dialog, getVBox(page)); + } }; -GtkWindow* PrefsDlg::BuildDialog(){ - PreferencesDialog_addInterfacePreferences( FreeCaller1() ); - Mouse_registerPreferencesPage(); - - GtkWindow* dialog = create_floating_window( "NetRadiant Preferences", m_parent ); - - { - GtkWidget* mainvbox = gtk_vbox_new( FALSE, 5 ); - gtk_container_add( GTK_CONTAINER( dialog ), mainvbox ); - gtk_container_set_border_width( GTK_CONTAINER( mainvbox ), 5 ); - gtk_widget_show( mainvbox ); - - { - GtkWidget* hbox = gtk_hbox_new( FALSE, 5 ); - gtk_widget_show( hbox ); - gtk_box_pack_end( GTK_BOX( mainvbox ), hbox, FALSE, TRUE, 0 ); - - { - GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &m_modal ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &m_modal ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - { - GtkButton* button = create_dialog_button( "Clean", G_CALLBACK( OnButtonClean ), this ); - gtk_box_pack_end( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); - } - } - - { - GtkWidget* hbox = gtk_hbox_new( FALSE, 5 ); - gtk_box_pack_start( GTK_BOX( mainvbox ), hbox, TRUE, TRUE, 0 ); - gtk_widget_show( hbox ); - - { - GtkWidget* sc_win = gtk_scrolled_window_new( 0, 0 ); - gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( sc_win ), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); - gtk_box_pack_start( GTK_BOX( hbox ), sc_win, FALSE, FALSE, 0 ); - gtk_widget_show( sc_win ); - gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( sc_win ), GTK_SHADOW_IN ); - - // prefs pages notebook - m_notebook = gtk_notebook_new(); - // hide the notebook tabs since its not supposed to look like a notebook - gtk_notebook_set_show_tabs( GTK_NOTEBOOK( m_notebook ), FALSE ); - gtk_box_pack_start( GTK_BOX( hbox ), m_notebook, TRUE, TRUE, 0 ); - gtk_widget_show( m_notebook ); - - - { - GtkTreeStore* store = gtk_tree_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER ); - - GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); - gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Preferences", renderer, "text", 0, NULL ); - gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); - } - - { - GtkTreeSelection* selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) ); - g_signal_connect( G_OBJECT( selection ), "changed", G_CALLBACK( treeSelection ), this ); - } - - gtk_widget_show( view ); - - gtk_container_add( GTK_CONTAINER( sc_win ), view ); - - { - /********************************************************************/ - /* Add preference tree options */ - /********************************************************************/ - // Front page... - //GtkWidget* front = - PreferencePages_addPage( m_notebook, "Front Page" ); - - { - GtkWidget* global = PreferencePages_addPage( m_notebook, "Global Preferences" ); - { - PreferencesPage preferencesPage( *this, getVBox( global ) ); - Global_constructPreferences( preferencesPage ); - } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Global", global ); - { - GtkWidget* game = PreferencePages_addPage( m_notebook, "Game" ); - PreferencesPage preferencesPage( *this, getVBox( game ) ); - g_GamesDialog.CreateGlobalFrame( preferencesPage ); - - PreferenceTree_appendPage( store, &group, "Game", game ); - } - } - - { - GtkWidget* interfacePage = PreferencePages_addPage( m_notebook, "Interface Preferences" ); - { - PreferencesPage preferencesPage( *this, getVBox( interfacePage ) ); - PreferencesPageCallbacks_constructPage( g_interfacePreferences, preferencesPage ); - } - - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Interface", interfacePage ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); - - PreferenceGroupCallbacks_constructGroup( g_interfaceCallbacks, preferenceGroup ); - } - - { - GtkWidget* display = PreferencePages_addPage( m_notebook, "Display Preferences" ); - { - PreferencesPage preferencesPage( *this, getVBox( display ) ); - PreferencesPageCallbacks_constructPage( g_displayPreferences, preferencesPage ); - } - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Display", display ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); - - PreferenceGroupCallbacks_constructGroup( g_displayCallbacks, preferenceGroup ); - } - - { - GtkWidget* settings = PreferencePages_addPage( m_notebook, "General Settings" ); - { - PreferencesPage preferencesPage( *this, getVBox( settings ) ); - PreferencesPageCallbacks_constructPage( g_settingsPreferences, preferencesPage ); - } - - GtkTreeIter group = PreferenceTree_appendPage( store, 0, "Settings", settings ); - PreferenceTreeGroup preferenceGroup( *this, m_notebook, store, group ); - - PreferenceGroupCallbacks_constructGroup( g_settingsCallbacks, preferenceGroup ); - } - } - - gtk_tree_view_expand_all( GTK_TREE_VIEW( view ) ); - - g_object_unref( G_OBJECT( store ) ); - } - } - } - } - - gtk_notebook_set_page( GTK_NOTEBOOK( m_notebook ), 0 ); - - return dialog; +ui::Window PrefsDlg::BuildDialog() +{ + PreferencesDialog_addInterfacePreferences(makeCallbackF(Interface_constructPreferences)); + Mouse_registerPreferencesPage(); + + ui::Window dialog = ui::Window(create_floating_window("NetRadiant Preferences", m_parent)); + + { + auto mainvbox = ui::VBox(FALSE, 5); + dialog.add(mainvbox); + gtk_container_set_border_width(GTK_CONTAINER(mainvbox), 5); + mainvbox.show(); + + { + auto hbox = ui::HBox(FALSE, 5); + hbox.show(); + mainvbox.pack_end(hbox, FALSE, TRUE, 0); + + { + auto button = create_dialog_button("OK", G_CALLBACK(dialog_button_ok), &m_modal); + hbox.pack_end(button, FALSE, FALSE, 0); + } + { + auto button = create_dialog_button("Cancel", G_CALLBACK(dialog_button_cancel), &m_modal); + hbox.pack_end(button, FALSE, FALSE, 0); + } + { + auto button = create_dialog_button("Clean", G_CALLBACK(OnButtonClean), this); + hbox.pack_end(button, FALSE, FALSE, 0); + } + } + + { + auto hbox = ui::HBox(FALSE, 5); + mainvbox.pack_start(hbox, TRUE, TRUE, 0); + hbox.show(); + + { + auto sc_win = ui::ScrolledWindow(ui::New); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sc_win), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + hbox.pack_start(sc_win, FALSE, FALSE, 0); + sc_win.show(); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sc_win), GTK_SHADOW_IN); + + // prefs pages notebook + m_notebook = ui::Widget::from(gtk_notebook_new()); + // hide the notebook tabs since its not supposed to look like a notebook + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(m_notebook), FALSE); + hbox.pack_start(m_notebook, TRUE, TRUE, 0); + m_notebook.show(); + + + { + auto store = ui::TreeStore::from(gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER)); + + auto view = ui::TreeView(ui::TreeModel::from(store._handle)); + gtk_tree_view_set_headers_visible(view, FALSE); + + { + auto renderer = ui::CellRendererText(ui::New); + auto column = ui::TreeViewColumn("Preferences", renderer, {{"text", 0}}); + gtk_tree_view_append_column(view, column); + } + + { + auto selection = ui::TreeSelection::from(gtk_tree_view_get_selection(view)); + selection.connect("changed", G_CALLBACK(treeSelection), this); + } + + view.show(); + + sc_win.add(view); + + { + /********************************************************************/ + /* Add preference tree options */ + /********************************************************************/ + // Front page... + //GtkWidget* front = + PreferencePages_addPage(m_notebook, "Front Page"); + + { + auto global = PreferencePages_addPage(m_notebook, "Global Preferences"); + { + PreferencesPage preferencesPage(*this, getVBox(global)); + Global_constructPreferences(preferencesPage); + } + auto group = PreferenceTree_appendPage(store, 0, "Global", global); + { + auto game = PreferencePages_addPage(m_notebook, "Game"); + PreferencesPage preferencesPage(*this, getVBox(game)); + g_GamesDialog.CreateGlobalFrame(preferencesPage); + + PreferenceTree_appendPage(store, &group, "Game", game); + } + } + + { + auto interfacePage = PreferencePages_addPage(m_notebook, "Interface Preferences"); + { + PreferencesPage preferencesPage(*this, getVBox(interfacePage)); + PreferencesPageCallbacks_constructPage(g_interfacePreferences, preferencesPage); + } + + auto group = PreferenceTree_appendPage(store, 0, "Interface", interfacePage); + PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); + + PreferenceGroupCallbacks_constructGroup(g_interfaceCallbacks, preferenceGroup); + } + + { + auto display = PreferencePages_addPage(m_notebook, "Display Preferences"); + { + PreferencesPage preferencesPage(*this, getVBox(display)); + PreferencesPageCallbacks_constructPage(g_displayPreferences, preferencesPage); + } + auto group = PreferenceTree_appendPage(store, 0, "Display", display); + PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); + + PreferenceGroupCallbacks_constructGroup(g_displayCallbacks, preferenceGroup); + } + + { + auto settings = PreferencePages_addPage(m_notebook, "General Settings"); + { + PreferencesPage preferencesPage(*this, getVBox(settings)); + PreferencesPageCallbacks_constructPage(g_settingsPreferences, preferencesPage); + } + + auto group = PreferenceTree_appendPage(store, 0, "Settings", settings); + PreferenceTreeGroup preferenceGroup(*this, m_notebook, store, group); + + PreferenceGroupCallbacks_constructGroup(g_settingsCallbacks, preferenceGroup); + } + } + + gtk_tree_view_expand_all(view); + + g_object_unref(G_OBJECT(store)); + } + } + } + } + + gtk_notebook_set_current_page(GTK_NOTEBOOK(m_notebook), 0); + + return dialog; } preferences_globals_t g_preferences_globals; @@ -852,34 +880,41 @@ preferences_globals_t g_preferences_globals; PrefsDlg g_Preferences; // global prefs instance -void PreferencesDialog_constructWindow( GtkWindow* main_window ){ - g_Preferences.m_parent = main_window; - g_Preferences.Create(); +void PreferencesDialog_constructWindow(ui::Window main_window) +{ + g_Preferences.m_parent = main_window; + g_Preferences.Create(); } -void PreferencesDialog_destroyWindow(){ - g_Preferences.Destroy(); + +void PreferencesDialog_destroyWindow() +{ + g_Preferences.Destroy(); } PreferenceDictionary g_preferences; -PreferenceSystem& GetPreferenceSystem(){ - return g_preferences; +PreferenceSystem &GetPreferenceSystem() +{ + return g_preferences; } -class PreferenceSystemAPI -{ -PreferenceSystem* m_preferencesystem; +class PreferenceSystemAPI { + PreferenceSystem *m_preferencesystem; public: -typedef PreferenceSystem Type; -STRING_CONSTANT( Name, "*" ); + typedef PreferenceSystem Type; -PreferenceSystemAPI(){ - m_preferencesystem = &GetPreferenceSystem(); -} -PreferenceSystem* getTable(){ - return m_preferencesystem; -} + STRING_CONSTANT(Name, "*"); + + PreferenceSystemAPI() + { + m_preferencesystem = &GetPreferenceSystem(); + } + + PreferenceSystem *getTable() + { + return m_preferencesystem; + } }; #include "modulesystem/singletonmodule.h" @@ -887,100 +922,109 @@ PreferenceSystem* getTable(){ typedef SingletonModule PreferenceSystemModule; typedef Static StaticPreferenceSystemModule; -StaticRegisterModule staticRegisterPreferenceSystem( StaticPreferenceSystemModule::instance() ); +StaticRegisterModule staticRegisterPreferenceSystem(StaticPreferenceSystemModule::instance()); -void Preferences_Load(){ - g_GamesDialog.LoadPrefs(); +void Preferences_Load() +{ + g_GamesDialog.LoadPrefs(); - globalOutputStream() << "loading local preferences from " << g_Preferences.m_inipath->str << "\n"; + globalOutputStream() << "loading local preferences from " << g_Preferences.m_inipath->str << "\n"; - if ( !Preferences_Load( g_preferences, g_Preferences.m_inipath->str, g_GamesDialog.m_sGameFile.c_str() ) ) { - globalOutputStream() << "failed to load local preferences from " << g_Preferences.m_inipath->str << "\n"; - } + if (!Preferences_Load(g_preferences, g_Preferences.m_inipath->str, g_GamesDialog.m_sGameFile.c_str())) { + globalOutputStream() << "failed to load local preferences from " << g_Preferences.m_inipath->str << "\n"; + } } -void Preferences_Save(){ - if ( g_preferences_globals.disable_ini ) { - return; - } +void Preferences_Save() +{ + if (g_preferences_globals.disable_ini) { + return; + } - g_GamesDialog.SavePrefs(); + g_GamesDialog.SavePrefs(); - globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n"; + globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n"; - if ( !Preferences_Save_Safe( g_preferences, g_Preferences.m_inipath->str ) ) { - globalOutputStream() << "failed to save local preferences to " << g_Preferences.m_inipath->str << "\n"; - } + if (!Preferences_Save_Safe(g_preferences, g_Preferences.m_inipath->str)) { + globalOutputStream() << "failed to save local preferences to " << g_Preferences.m_inipath->str << "\n"; + } } -void Preferences_Reset(){ - file_remove( g_Preferences.m_inipath->str ); +void Preferences_Reset() +{ + file_remove(g_Preferences.m_inipath->str); } -void PrefsDlg::PostModal( EMessageBoxReturn code ){ - if ( code == eIDOK ) { - Preferences_Save(); - UpdateAllWindows(); - } +void PrefsDlg::PostModal(EMessageBoxReturn code) +{ + if (code == eIDOK) { + Preferences_Save(); + UpdateAllWindows(); + } } -std::vector g_restart_required; - -void PreferencesDialog_restartRequired( const char* staticName ){ - g_restart_required.push_back( staticName ); -} +std::vector g_restart_required; -void PreferencesDialog_showDialog(){ - if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) { - if ( !g_restart_required.empty() ) { - StringOutputStream message( 256 ); - message << "Preference changes require a restart:\n"; - for ( std::vector::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i ) - { - message << ( *i ) << '\n'; - } - gtk_MessageBox( GTK_WIDGET( MainFrame_getWindow() ), message.c_str() ); - g_restart_required.clear(); - } - } +void PreferencesDialog_restartRequired(const char *staticName) +{ + g_restart_required.push_back(staticName); } +void PreferencesDialog_showDialog() +{ + if (ConfirmModified("Edit Preferences") && g_Preferences.DoModal() == eIDOK) { + if (!g_restart_required.empty()) { + StringOutputStream message(256); + message << "Preference changes require a restart:\n"; + for (std::vector::iterator i = g_restart_required.begin(); + i != g_restart_required.end(); ++i) { + message << (*i) << '\n'; + } + ui::alert(MainFrame_getWindow(), message.c_str()); + g_restart_required.clear(); + } + } +} + +struct GameName { + static void Export(const Callback &returnz) + { + returnz(gamename_get()); + } + + static void Import(const char *value) + { + gamename_set(value); + } +}; +struct GameMode { + static void Export(const Callback &returnz) + { + returnz(gamemode_get()); + } + static void Import(const char *value) + { + gamemode_set(value); + } +}; - -void GameName_importString( const char* value ){ - gamename_set( value ); -} -typedef FreeCaller1 GameNameImportStringCaller; -void GameName_exportString( const StringImportCallback& importer ){ - importer( gamename_get() ); -} -typedef FreeCaller1 GameNameExportStringCaller; - -void GameMode_importString( const char* value ){ - gamemode_set( value ); -} -typedef FreeCaller1 GameModeImportStringCaller; -void GameMode_exportString( const StringImportCallback& importer ){ - importer( gamemode_get() ); -} -typedef FreeCaller1 GameModeExportStringCaller; - - -void RegisterPreferences( PreferenceSystem& preferences ){ -#ifdef WIN32 - preferences.registerPreference( "UseCustomShaderEditor", BoolImportStringCaller( g_TextEditor_useWin32Editor ), BoolExportStringCaller( g_TextEditor_useWin32Editor ) ); +void RegisterPreferences(PreferenceSystem &preferences) +{ +#if GDEF_OS_WINDOWS + preferences.registerPreference( "UseCustomShaderEditor", make_property_string( g_TextEditor_useWin32Editor ) ); #else - preferences.registerPreference( "UseCustomShaderEditor", BoolImportStringCaller( g_TextEditor_useCustomEditor ), BoolExportStringCaller( g_TextEditor_useCustomEditor ) ); - preferences.registerPreference( "CustomShaderEditorCommand", CopiedStringImportStringCaller( g_TextEditor_editorCommand ), CopiedStringExportStringCaller( g_TextEditor_editorCommand ) ); + preferences.registerPreference("UseCustomShaderEditor", make_property_string(g_TextEditor_useCustomEditor)); + preferences.registerPreference("CustomShaderEditorCommand", make_property_string(g_TextEditor_editorCommand)); #endif - preferences.registerPreference( "GameName", GameNameImportStringCaller(), GameNameExportStringCaller() ); - preferences.registerPreference( "GameMode", GameModeImportStringCaller(), GameModeExportStringCaller() ); + preferences.registerPreference("GameName", make_property()); + preferences.registerPreference("GameMode", make_property()); } -void Preferences_Init(){ - RegisterPreferences( GetPreferenceSystem() ); +void Preferences_Init() +{ + RegisterPreferences(GetPreferenceSystem()); }