}
void Interface_constructPreferences( PreferencesPage& page ){
-#if GDEF_OS_WINDOWS
- page.appendCheckBox( "", "External Shader Editor", g_TextEditor_useWin32Editor );
-#else
- {
- 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
+ page.appendPathEntry( "Shader Editor Command", g_TextEditor_editorCommand, false );
}
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 );
- page.appendCheckBox( "", "Improved mousewheel zoom", g_xywindow_globals.m_bImprovedWheelZoom );
+// {
+// 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 );
+ page.appendCheckBox( "", "Zoom to mouse pointer", g_xywindow_globals.m_bZoomInToPointer );
}
void Mouse_constructPage( PreferenceGroup& group ){
PreferencesPage page( group.createPage( "Mouse", "Mouse Preferences" ) );
{
StringOutputStream path( 256 );
- path << AppPath_get() << gameFile.c_str() << "/";
+ path << DataPath_get() << "gamepacks/" << gameFile.c_str() << "/";
mGameToolsPath = path.c_str();
}
}
bool Preferences_Save_Safe( PreferenceDictionary& preferences, const char* filename ){
- Array<char> tmpName( filename, filename + strlen( filename ) + 1 + 3 );
- *( tmpName.end() - 4 ) = 'T';
- *( tmpName.end() - 3 ) = 'M';
- *( tmpName.end() - 2 ) = 'P';
- *( tmpName.end() - 1 ) = '\0';
+ std::string tmpName( filename );
+ tmpName += "TMP";
- return Preferences_Save( preferences, tmpName.data() )
+ return Preferences_Save( preferences, tmpName.c_str() )
&& ( !file_exists( filename ) || file_remove( filename ) )
&& file_move( tmpName.data(), filename );
}
static void Import(bool value) {
g_Console_enableLogging = value;
- Sys_LogFile(g_Console_enableLogging);
+ Sys_EnableLogFile(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( "skipGamePromptOnce", make_property_string( g_GamesDialog.m_bSkipGamePromptOnce ) );
preferences.registerPreference( "log console", make_property_string<LogConsole>() );
}
{
++iGame;
}
+
+ if ( ( *iGame )->mGameFile != m_sGameFile ) {
m_sGameFile = ( *iGame )->mGameFile;
+
+ // do not trigger radiant restart when switching game on startup using Global Preferences dialog
+ if ( !onStartup ) {
+ PreferencesDialog_restartRequired( "Selected Game" );
+ }
+ }
+
+ // onStartup can only be true once, when Global Preferences are displayed at startup
+ onStartup = false;
}
void CGameDialog::GameFileExport( const Callback<void(int)> & importCallback ) const {
return create_simple_modal_dialog_window( "Global Preferences", m_modal, frame );
}
+static void StringReplace( std::string& input, const std::string& first, const std::string& second )
+{
+ size_t found = 0;
+ while ( ( found = input.find(first, found) ) != std::string::npos )
+ {
+ input.replace( found, first.length(), second );
+ }
+}
+
+// FIXME, for some unknown reason it sorts “Quake 3” after “Quake 4”.
+static bool CompareGameName( CGameDescription *first, CGameDescription *second )
+{
+ std::string string1( first->getRequiredKeyValue( "name" ) );
+ std::string string2( second->getRequiredKeyValue( "name" ) );
+
+ // HACK: Replace some roman numerals.
+ StringReplace( string1, " III", " 3" );
+ StringReplace( string2, " III", " 3" );
+ StringReplace( string1, " II", " 2" );
+ StringReplace( string2, " II", " 2" );
+
+ return string1 < string2;
+}
+
void CGameDialog::ScanForGames(){
StringOutputStream strGamesPath( 256 );
- strGamesPath << AppPath_get() << "games/";
+ strGamesPath << DataPath_get() << "gamepacks/games/";
const char *path = strGamesPath.c_str();
globalOutputStream() << "Scanning for game description files: " << path << '\n';
} else {
globalErrorStream() << "XML parser failed on '" << strPath.c_str() << "'\n";
}
+
+ mGames.sort(CompareGameName);
});
}
}
void CGameDialog::Init(){
+ bool gamePrompt = false;
+
InitGlobalPrefPath();
LoadPrefs();
ScanForGames();
+
if ( mGames.empty() ) {
Error( "Didn't find any valid game file descriptions, aborting\n" );
}
CGameDescription* currentGameDescription = 0;
- if ( !m_bGamePrompt ) {
+ // m_bSkipGamePromptOnce is used to not prompt for game on restart, only on fresh startup
+ if ( m_bGamePrompt && !m_bSkipGamePromptOnce ) {
+ gamePrompt = true;
+ }
+
+ m_bSkipGamePromptOnce = false;
+ g_GamesDialog.SavePrefs();
+
+ if ( !gamePrompt ) {
// search by .game name
std::list<CGameDescription *>::iterator iGame;
for ( iGame = mGames.begin(); iGame != mGames.end(); ++iGame )
}
}
}
- if ( m_bGamePrompt || !currentGameDescription ) {
+
+ if ( gamePrompt || !currentGameDescription ) {
+ onStartup = true;
Create();
DoGameDialog();
// use m_nComboSelect to identify the game to run as and set the globals
currentGameDescription = GameDescriptionForComboItem();
ASSERT_NOTNULL( currentGameDescription );
}
+ else {
+ onStartup = false;
+ }
+
g_pGameDescription = currentGameDescription;
g_pGameDescription->Dump();
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?",
+ if ( ui::alert( g_Preferences.GetWidget(), "This will close " RADIANT_NAME " and clean the corresponding registry entries.\n"
+ "Next time you start " RADIANT_NAME " 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 );
ui::Window PrefsDlg::BuildDialog(){
PreferencesDialog_addInterfacePreferences( makeCallbackF(Interface_constructPreferences) );
- Mouse_registerPreferencesPage();
+ //Mouse_registerPreferencesPage();
+
+ ui::Window dialog = ui::Window(create_floating_window( RADIANT_NAME " Preferences", m_parent ));
- ui::Window dialog = ui::Window(create_floating_window( "NetRadiant Preferences", m_parent ));
+ gtk_window_set_transient_for( dialog, m_parent );
+ gtk_window_set_position( dialog, GTK_WIN_POS_CENTER_ON_PARENT );
{
auto mainvbox = ui::VBox( FALSE, 5 );
return;
}
+ // save global preferences
g_GamesDialog.SavePrefs();
globalOutputStream() << "saving local preferences to " << g_Preferences.m_inipath->str << "\n";
g_restart_required.push_back( staticName );
}
-void PreferencesDialog_showDialog(){
- //if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) {
- if ( g_Preferences.DoModal() == eIDOK ) {
+bool PreferencesDialog_isRestartRequired(){
+ return !g_restart_required.empty();
+}
+
+void PreferencesDialog_restartIfRequired(){
if ( !g_restart_required.empty() ) {
StringOutputStream message( 256 );
- message << "Preference changes require a restart:\n";
+ message << "Preference changes require a restart:\n\n";
+
for ( std::vector<const char*>::iterator i = g_restart_required.begin(); i != g_restart_required.end(); ++i )
{
message << ( *i ) << '\n';
}
- ui::alert( MainFrame_getWindow(), message.c_str() );
+
+ message << "\nRestart now?";
+
+ auto ret = ui::alert( MainFrame_getWindow(), message.c_str(), "Restart " RADIANT_NAME "?", ui::alert_type::YESNO, ui::alert_icon::Question );
+
g_restart_required.clear();
+
+ if ( ret == ui::alert_response::YES ) {
+ g_GamesDialog.m_bSkipGamePromptOnce = true;
+ Radiant_Restart();
}
}
}
+void PreferencesDialog_showDialog(){
+ if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) {
+ PreferencesDialog_restartIfRequired();
+ }
+}
+
struct GameName {
static void Export(const Callback<void(const char *)> &returnz) {
returnz(gamename_get());
};
void RegisterPreferences( PreferenceSystem& preferences ){
-#if GDEF_OS_WINDOWS
- preferences.registerPreference( "UseCustomShaderEditor", make_property_string( g_TextEditor_useWin32Editor ) );
-#else
- preferences.registerPreference( "UseCustomShaderEditor", make_property_string( g_TextEditor_useCustomEditor ) );
preferences.registerPreference( "CustomShaderEditorCommand", make_property_string( g_TextEditor_editorCommand ) );
-#endif
preferences.registerPreference( "GameName", make_property<GameName>() );
preferences.registerPreference( "GameMode", make_property<GameMode>() );