X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fmainframe.cpp;h=4113072623c2d0dc0a6d5f224b38082040bbb3a1;hp=2eed7bff0c9f6a935cd146ee0410680b0f210a04;hb=a333eaee1c5b8b20ec59411f4878f8fc5bdfa584;hpb=cfc38f86f878d79656aba515838cb75cf5a371f6 diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 2eed7bff..41130726 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -101,6 +101,18 @@ #include "referencecache.h" #include "texwindow.h" +#if GDEF_OS_WINDOWS +#include +#else +#include +#endif + +#ifdef WORKAROUND_WINDOWS_GTK2_GLWIDGET +/* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ +#define WORKAROUND_GOBJECT_SET_GLWIDGET(window, widget) g_object_set_data( G_OBJECT( window ), "glwidget", G_OBJECT( widget ) ) +#else +#define WORKAROUND_GOBJECT_SET_GLWIDGET(window, widget) +#endif struct layout_globals_t { @@ -138,22 +150,25 @@ void VFS_Init(){ GlobalFileSystem().initialise(); g_vfsInitialized = true; } + void VFS_Shutdown(){ if ( !g_vfsInitialized ) return; GlobalFileSystem().shutdown(); g_vfsInitialized = false; } + void VFS_Refresh(){ if ( !g_vfsInitialized ) return; GlobalFileSystem().clear(); QE_InitVFS(); GlobalFileSystem().refresh(); g_vfsInitialized = true; - // also refresg models + // also refresh models RefreshReferences(); // also refresh texture browser TextureBrowser_RefreshShaders(); } + void VFS_Restart(){ VFS_Shutdown(); VFS_Init(); @@ -165,6 +180,7 @@ public: void realise(){ VFS_Init(); } + void unrealise(){ VFS_Shutdown(); } @@ -175,6 +191,7 @@ VFSModuleObserver g_VFSModuleObserver; void VFS_Construct(){ Radiant_attachHomePathsObserver( g_VFSModuleObserver ); } + void VFS_Destroy(){ Radiant_detachHomePathsObserver( g_VFSModuleObserver ); } @@ -191,6 +208,7 @@ const GUID qFOLDERID_SavedGames = {0x4C5C32FF, 0xBB9D, 0x43b0, {0xB5, 0xB4, 0x2D typedef HRESULT ( WINAPI qSHGetKnownFolderPath_t )( qREFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath ); static qSHGetKnownFolderPath_t *qSHGetKnownFolderPath; #endif + void HomePaths_Realise(){ do { @@ -207,9 +225,7 @@ void HomePaths_Realise(){ } path.clear(); path << DirectoryCleaned( g_get_home_dir() ) << prefix << "/"; -#endif - -#if GDEF_OS_WINDOWS +#elif GDEF_OS_WINDOWS TCHAR mydocsdir[MAX_PATH + 1]; wchar_t *mydocsdirw; HMODULE shfolder = LoadLibrary( "shfolder.dll" ); @@ -246,13 +262,19 @@ void HomePaths_Realise(){ break; } } -#endif - -#if GDEF_OS_POSIX +#elif GDEF_OS_XDG path.clear(); - path << DirectoryCleaned( g_get_home_dir() ) << prefix << "/"; - g_qeglobals.m_userEnginePath = path.c_str(); - break; + path << DirectoryCleaned( g_get_user_data_dir() ) << ( prefix + 1 ) << "/"; + if ( file_exists( path.c_str() ) && file_is_directory( path.c_str() ) ) { + g_qeglobals.m_userEnginePath = path.c_str(); + break; + } + else { + path.clear(); + path << DirectoryCleaned( g_get_home_dir() ) << prefix << "/"; + g_qeglobals.m_userEnginePath = path.c_str(); + break; + } #endif } @@ -287,12 +309,14 @@ std::size_t m_unrealised; public: HomePathsModuleObserver() : m_unrealised( 1 ){ } + void realise(){ if ( --m_unrealised == 0 ) { HomePaths_Realise(); g_homePathObservers.realise(); } } + void unrealise(){ if ( ++m_unrealised == 1 ) { g_homePathObservers.unrealise(); @@ -305,6 +329,7 @@ HomePathsModuleObserver g_HomePathsModuleObserver; void HomePaths_Construct(){ Radiant_attachEnginePathObserver( g_HomePathsModuleObserver ); } + void HomePaths_Destroy(){ Radiant_detachEnginePathObserver( g_HomePathsModuleObserver ); } @@ -425,14 +450,32 @@ void setPakPath( int num, const char* path ){ } -// App Path +// executable file path (full path) +CopiedString g_strAppFilePath; -CopiedString g_strAppPath; ///< holds the full path of the executable +// directory paths +CopiedString g_strAppPath; +CopiedString g_strLibPath; +CopiedString g_strDataPath; + +const char* AppFilePath_get(){ + return g_strAppFilePath.c_str(); +} const char* AppPath_get(){ return g_strAppPath.c_str(); } +const char *LibPath_get() +{ + return g_strLibPath.c_str(); +} + +const char *DataPath_get() +{ + return g_strDataPath.c_str(); +} + /// the path to the local rc-dir const char* LocalRcPath_get( void ){ static CopiedString rc_path; @@ -447,6 +490,7 @@ const char* LocalRcPath_get( void ){ /// directory for temp files /// NOTE: on *nix this is were we check for .pid CopiedString g_strSettingsPath; + const char* SettingsPath_get(){ return g_strSettingsPath.c_str(); } @@ -486,6 +530,7 @@ struct PakPath0 { setPakPath( 0, value ); } }; + struct PakPath1 { static void Export( const CopiedString &self, const Callback &returnz ) { returnz( self.c_str() ); @@ -495,6 +540,7 @@ struct PakPath1 { setPakPath( 1, value ); } }; + struct PakPath2 { static void Export( const CopiedString &self, const Callback &returnz ) { returnz( self.c_str() ); @@ -504,6 +550,7 @@ struct PakPath2 { setPakPath( 2, value ); } }; + struct PakPath3 { static void Export( const CopiedString &self, const Callback &returnz ) { returnz( self.c_str() ); @@ -513,6 +560,7 @@ struct PakPath3 { setPakPath( 3, value ); } }; + struct PakPath4 { static void Export( const CopiedString &self, const Callback &returnz ) { returnz( self.c_str() ); @@ -526,44 +574,35 @@ struct PakPath4 { bool g_disableEnginePath = false; bool g_disableHomePath = false; -void Paths_constructPreferences( PreferencesPage& page ){ +void Paths_constructBasicPreferences( PreferencesPage& page ) { page.appendPathEntry( "Engine Path", true, make_property(g_strEnginePath) ); +} - page.appendCheckBox( - "", "Do not use Engine Path", - g_disableEnginePath - ); +void Paths_constructPreferences( PreferencesPage& page ){ + Paths_constructBasicPreferences( page ); - page.appendCheckBox( - "", "Do not use Home Path", - g_disableHomePath - ); + page.appendSpacer( 4 ); + page.appendLabel( "", "Advanced options" ); + page.appendCheckBox( "", "Do not use Engine Path", g_disableEnginePath ); + page.appendCheckBox( "", "Do not use Home Path", g_disableHomePath ); - for ( int i = 0; i < g_pakPathCount; i++ ) { - std::string label = "Pak Path " + std::to_string(i); - switch (i) { - case 0: - page.appendPathEntry( label.c_str(), true, make_property( g_strPakPath[i] ) ); - break; - case 1: - page.appendPathEntry( label.c_str(), true, make_property( g_strPakPath[i] ) ); - break; - case 2: - page.appendPathEntry( label.c_str(), true, make_property( g_strPakPath[i] ) ); - break; - case 3: - page.appendPathEntry( label.c_str(), true, make_property( g_strPakPath[i] ) ); - break; - case 4: - page.appendPathEntry( label.c_str(), true, make_property( g_strPakPath[i] ) ); - break; - } - } + page.appendSpacer( 4 ); + page.appendLabel( "", "Only a very few games support Pak Paths," ); + page.appendLabel( "", "if you don't know what it is, leave this blank." ); + + const char *label = "Pak Path "; + page.appendPathEntry( label, true, make_property( g_strPakPath[0] ) ); + page.appendPathEntry( label, true, make_property( g_strPakPath[1] ) ); + page.appendPathEntry( label, true, make_property( g_strPakPath[2] ) ); + page.appendPathEntry( label, true, make_property( g_strPakPath[3] ) ); + page.appendPathEntry( label, true, make_property( g_strPakPath[4] ) ); } + void Paths_constructPage( PreferenceGroup& group ){ PreferencesPage page( group.createPage( "Paths", "Path Settings" ) ); Paths_constructPreferences( page ); } + void Paths_registerPreferencesPage(){ PreferencesDialog_addSettingsPage( makeCallbackF(Paths_constructPage) ); } @@ -573,14 +612,14 @@ class PathsDialog : public Dialog { public: ui::Window BuildDialog(){ - auto frame = create_dialog_frame( "Path settings", ui::Shadow::ETCHED_IN ); + auto frame = create_dialog_frame( "Path Settings", ui::Shadow::ETCHED_IN ); auto vbox2 = create_dialog_vbox( 0, 4 ); frame.add(vbox2); { - PreferencesPage preferencesPage( *this, vbox2 ); - Paths_constructPreferences( preferencesPage ); + PreferencesPage page( *this, vbox2 ); + Paths_constructBasicPreferences( page ); } return ui::Window(create_simple_modal_dialog_window( "Engine Path Not Found", m_modal, frame )); @@ -708,11 +747,13 @@ std::size_t m_unrealised; public: WorldspawnColourEntityClassObserver() : m_unrealised( 1 ){ } + void realise(){ if ( --m_unrealised == 0 ) { SetWorldspawnColour( g_xywindow_globals.color_brushes ); } } + void unrealise(){ if ( ++m_unrealised == 1 ) { } @@ -735,7 +776,7 @@ void Radiant_detachGameToolsPathObserver( ModuleObserver& observer ){ void Radiant_Initialise(){ GlobalModuleServer_Initialise(); - Radiant_loadModulesFromRoot( AppPath_get() ); + Radiant_loadModulesFromRoot( LibPath_get() ); Preferences_Load(); @@ -764,7 +805,7 @@ void Radiant_Shutdown(){ } void Exit(){ - if ( ConfirmModified( "Exit Radiant" ) ) { + if ( ConfirmModified( "Exit " RADIANT_NAME ) ) { gtk_main_quit(); } } @@ -925,6 +966,53 @@ void ColorScheme_Ydnar(){ XY_UpdateAllWindows(); } +/* color scheme to fit the GTK Adwaita Dark theme */ +void ColorScheme_AdwaitaDark() +{ + // SI_Colors0 + // GlobalTextureBrowser().color_textureback + TextureBrowser_setBackgroundColour(GlobalTextureBrowser(), Vector3(0.25f, 0.25f, 0.25f)); + + // SI_Colors4 + g_camwindow_globals.color_cameraback = Vector3(0.25f, 0.25f, 0.25f); + // SI_Colors12 + g_camwindow_globals.color_selbrushes3d = Vector3(1.0f, 0.0f, 0.0f); + CamWnd_Update(*g_pParentWnd->GetCamWnd()); + + // SI_Colors1 + g_xywindow_globals.color_gridback = Vector3(0.25f, 0.25f, 0.25f); + // SI_Colors2 + g_xywindow_globals.color_gridminor = Vector3(0.21f, 0.23f, 0.23f); + // SI_Colors3 + g_xywindow_globals.color_gridmajor = Vector3(0.14f, 0.15f, 0.15f); + // SI_Colors14 + g_xywindow_globals.color_gridmajor_alt = Vector3(1.0f, 0.0f, 0.0f); + // SI_Colors6 + g_xywindow_globals.color_gridblock = Vector3(1.0f, 1.0f, 1.0f); + // SI_Colors7 + g_xywindow_globals.color_gridtext = Vector3(0.0f, 0.0f, 0.0f); + // ?? + g_xywindow_globals.color_selbrushes = Vector3(1.0f, 0.0f, 0.0f); + // ?? + g_xywindow_globals.color_clipper = Vector3(0.0f, 0.0f, 1.0f); + // SI_Colors8 + g_xywindow_globals.color_brushes = Vector3(0.73f, 0.73f, 0.73f); + + // SI_AxisColors0 + g_xywindow_globals.AxisColorX = Vector3(1.0f, 0.0f, 0.0f); + // SI_AxisColors1 + g_xywindow_globals.AxisColorY = Vector3(0.0f, 1.0f, 0.0f); + // SI_AxisColors2 + g_xywindow_globals.AxisColorZ = Vector3(0.0f, 0.0f, 1.0f); + SetWorldspawnColour(g_xywindow_globals.color_brushes); + // ?? + g_xywindow_globals.color_viewname = Vector3(0.5f, 0.0f, 0.75f); + XY_UpdateAllWindows(); + + // SI_Colors5 + // g_entity_globals.color_entity = Vector3(0.0f, 0.0f, 0.0f); +} + typedef Callback GetColourCallback; typedef Callback SetColourCallback; @@ -936,6 +1024,7 @@ public: ChooseColour( const GetColourCallback& get, const SetColourCallback& set ) : m_get( get ), m_set( set ){ } + void operator()(){ Vector3 colour; m_get( colour ); @@ -945,16 +1034,17 @@ void operator()(){ }; - void Colour_get( const Vector3& colour, Vector3& other ){ other = colour; } + typedef ConstReferenceCaller ColourGetCaller; void Colour_set( Vector3& colour, const Vector3& other ){ colour = other; SceneChangeNotify(); } + typedef ReferenceCaller ColourSetCaller; void BrushColour_set( const Vector3& other ){ @@ -962,6 +1052,7 @@ void BrushColour_set( const Vector3& other ){ SetWorldspawnColour( g_xywindow_globals.color_brushes ); SceneChangeNotify(); } + typedef FreeCaller BrushColourSetCaller; void ClipperColour_set( const Vector3& other ){ @@ -969,16 +1060,19 @@ void ClipperColour_set( const Vector3& other ){ Brush_clipperColourChanged(); SceneChangeNotify(); } + typedef FreeCaller ClipperColourSetCaller; void TextureBrowserColour_get( Vector3& other ){ other = TextureBrowser_getBackgroundColour( GlobalTextureBrowser() ); } + typedef FreeCaller TextureBrowserColourGetCaller; void TextureBrowserColour_set( const Vector3& other ){ TextureBrowser_setBackgroundColour( GlobalTextureBrowser(), other ); } + typedef FreeCaller TextureBrowserColourSetCaller; @@ -1036,6 +1130,7 @@ ui::MenuItem create_colours_menu(){ create_menu_item_with_mnemonic( menu_3, "Q3Radiant Original", "ColorSchemeQER" ); create_menu_item_with_mnemonic( menu_3, "Black and Green", "ColorSchemeBlackAndGreen" ); create_menu_item_with_mnemonic( menu_3, "Maya/Max/Lightwave Emulation", "ColorSchemeYdnar" ); + create_menu_item_with_mnemonic(menu_3, "Adwaita Dark", "ColorSchemeAdwaitaDark"); menu_separator( menu_in_menu ); @@ -1097,17 +1192,17 @@ void EntityInspector_ToggleShow(){ } - void SetClipMode( bool enable ); + void ModeChangeNotify(); typedef void ( *ToolMode )(); + ToolMode g_currentToolMode = 0; bool g_currentToolModeSupportsComponentEditing = false; ToolMode g_defaultToolMode = 0; - void SelectionSystem_DefaultMode(){ GlobalSelectionSystem().SetMode( SelectionSystem::ePrimitive ); GlobalSelectionSystem().SetComponentMode( SelectionSystem::eDefault ); @@ -1248,6 +1343,7 @@ NodeSmartReference worldspawn; public: CloneSelected( bool d ) : doMakeUnique( d ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( path.size() == 1 ) { return true; @@ -1269,6 +1365,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const { return true; } + void post( const scene::Path& path, scene::Instance& instance ) const { if ( path.size() == 1 ) { return; @@ -1313,6 +1410,7 @@ struct AxisBase Vector3 x; Vector3 y; Vector3 z; + AxisBase( const Vector3& x_, const Vector3& y_, const Vector3& z_ ) : x( x_ ), y( y_ ), z( z_ ){ } @@ -1649,6 +1747,7 @@ public: SnappableSnapToGridSelected( float snap ) : m_snap( snap ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { Snappable* snappable = Node_getSnappable( path.top() ); @@ -1672,6 +1771,7 @@ public: ComponentSnappableSnapToGridSelected( float snap ) : m_snap( snap ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { ComponentSnappable* componentSnappable = Instance_getComponentSnappable( instance ); @@ -1704,9 +1804,11 @@ void Selection_SnapToGrid(){ static gint qe_every_second( gpointer data ){ - GdkModifierType mask; + if (g_pParentWnd == nullptr) + return TRUE; - gdk_window_get_pointer( 0, 0, 0, &mask ); + GdkModifierType mask; + gdk_window_get_pointer( gtk_widget_get_window(g_pParentWnd->m_window), nullptr, nullptr, &mask ); if ( ( mask & ( GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK ) ) == 0 ) { QE_CheckAutoSave(); @@ -1818,15 +1920,18 @@ void ScreenUpdates_Disable( const char* message, const char* title ){ bool isActiveApp = MainFrame_isActiveApp(); g_wait = create_wait_dialog( title, message ); - gtk_grab_add( g_wait.m_window ); if ( isActiveApp ) { g_wait.m_window.show(); + gtk_grab_add( g_wait.m_window ); ScreenUpdates_process(); } } else if ( g_wait.m_window.visible() ) { g_wait.m_label.text(message); + if ( GTK_IS_WINDOW(g_wait.m_window) ) { + gtk_grab_add(g_wait.m_window); + } ScreenUpdates_process(); } g_wait_stack.push_back( message ); @@ -1852,7 +1957,6 @@ void ScreenUpdates_Enable(){ } - void GlobalCamera_UpdateWindow(){ if ( g_pParentWnd != 0 ) { CamWnd_Update( *g_pParentWnd->GetCamWnd() ); @@ -1911,7 +2015,6 @@ LatchedValue g_Layout_enablePatchToolbar( true, "Patch Toolbar" ); LatchedValue g_Layout_enablePluginToolbar( true, "Plugin Toolbar" ); - ui::MenuItem create_file_menu(){ // File menu auto file_menu_item = new_sub_menu_item_with_mnemonic( "_File" ); @@ -2287,7 +2390,7 @@ ui::MenuItem create_help_menu(){ create_menu_item_with_mnemonic( menu, "Bug report", makeCallbackF(OpenBugReportURL) ); create_menu_item_with_mnemonic( menu, "Shortcuts list", makeCallbackF(DoCommandListDlg) ); - create_menu_item_with_mnemonic( menu, "_About", makeCallbackF(DoAbout) ); + create_menu_item_with_mnemonic( menu, "_About...", makeCallbackF(DoAbout) ); return help_menu_item; } @@ -2412,7 +2515,8 @@ void Select_constructToolbar( ui::Toolbar toolbar ){ void CSG_constructToolbar( ui::Toolbar toolbar ){ toolbar_append_button( toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.png", "CSGSubtract" ); toolbar_append_button( toolbar, "CSG Merge (CTRL + U)", "selection_csgmerge.png", "CSGMerge" ); - toolbar_append_button( toolbar, "Hollow", "selection_makehollow.png", "CSGHollow" ); + toolbar_append_button( toolbar, "Make Hollow", "selection_makehollow.png", "CSGMakeHollow" ); + toolbar_append_button( toolbar, "Make Room", "selection_makeroom.png", "CSGMakeRoom" ); } void ComponentModes_constructToolbar( ui::Toolbar toolbar ){ @@ -2602,6 +2706,7 @@ static gboolean notify( ui::Window window, gpointer dummy, MainWindowActive* sel return FALSE; } + public: void connect( ui::Window toplevel_window ){ toplevel_window.connect( "notify::is-active", G_CALLBACK( notify ), this ); @@ -2664,10 +2769,14 @@ MainFrame::~MainFrame(){ for ( std::vector::iterator i = g_floating_windows.begin(); i != g_floating_windows.end(); ++i ) { +#ifndef WORKAROUND_MACOS_GTK2_DESTROY i->destroy(); +#endif } +#ifndef WORKAROUND_MACOS_GTK2_DESTROY m_window.destroy(); +#endif } void MainFrame::SetActiveXY( XYWnd* p ){ @@ -2824,7 +2933,7 @@ WindowPositionTracker g_posXZWnd; WindowPositionTracker g_posYZWnd; static gint mainframe_delete( ui::Widget widget, GdkEvent *event, gpointer data ){ - if ( ConfirmModified( "Exit Radiant" ) ) { + if ( ConfirmModified( "Exit " RADIANT_NAME ) ) { gtk_main_quit(); } @@ -2998,6 +3107,8 @@ void MainFrame::Create(){ } CamWnd_setParent( *m_pCamWnd, window ); + WORKAROUND_GOBJECT_SET_GLWIDGET( window, CamWnd_getWidget( *m_pCamWnd ) ); + g_floating_windows.push_back( window ); } @@ -3017,6 +3128,8 @@ void MainFrame::Create(){ } XY_Top_Shown_Construct( window ); + WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pXYWnd->GetWidget() ); + g_floating_windows.push_back( window ); } @@ -3036,6 +3149,8 @@ void MainFrame::Create(){ XZ_Front_Shown_Construct( window ); + WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pXZWnd->GetWidget() ); + g_floating_windows.push_back( window ); } @@ -3055,12 +3170,16 @@ void MainFrame::Create(){ YZ_Side_Shown_Construct( window ); + WORKAROUND_GOBJECT_SET_GLWIDGET( window, m_pYZWnd->GetWidget() ); + g_floating_windows.push_back( window ); } { auto frame = create_framed_widget( TextureBrowser_constructWindow( GroupDialog_getWindow() ) ); g_page_textures = GroupDialog_addPage( "Textures", frame, TextureBrowserExportTitleCaller() ); + + WORKAROUND_GOBJECT_SET_GLWIDGET( GroupDialog_getWindow(), TextureBrowser_getGLWidget() ); } GroupDialog_show(); @@ -3094,6 +3213,8 @@ void MainFrame::Create(){ { auto frame = create_framed_widget( TextureBrowser_constructWindow( window ) ); g_page_textures = GroupDialog_addPage( "Textures", frame, TextureBrowserExportTitleCaller() ); + + WORKAROUND_GOBJECT_SET_GLWIDGET( window, TextureBrowser_getGLWidget() ); } } @@ -3183,7 +3304,7 @@ void MainFrame::SetStatusText( CopiedString& status_text, const char* pText ){ } void Sys_Status( const char* status ){ - if ( g_pParentWnd != 0 ) { + if ( g_pParentWnd != nullptr ) { g_pParentWnd->SetStatusText( g_pParentWnd->m_command_status, status ); } } @@ -3197,8 +3318,11 @@ int getFarClipDistance(){ } float ( *GridStatus_getGridSize )() = GetGridSize; + int ( *GridStatus_getRotateIncrement )() = getRotateIncrement; + int ( *GridStatus_getFarClipDistance )() = getFarClipDistance; + bool ( *GridStatus_getTextureLockEnabled )(); void MainFrame::SetGridStatus(){ @@ -3212,7 +3336,7 @@ void MainFrame::SetGridStatus(){ } void GridStatus_onTextureLockEnabledChanged(){ - if ( g_pParentWnd != 0 ) { + if ( g_pParentWnd != nullptr ) { g_pParentWnd->SetGridStatus(); } } @@ -3363,6 +3487,7 @@ void MainFrame_Construct(){ GlobalCommands_insert( "ColorSchemeQER", makeCallbackF(ColorScheme_QER) ); GlobalCommands_insert( "ColorSchemeBlackAndGreen", makeCallbackF(ColorScheme_Black) ); GlobalCommands_insert( "ColorSchemeYdnar", makeCallbackF(ColorScheme_Ydnar) ); + GlobalCommands_insert("ColorSchemeAdwaitaDark", makeCallbackF(ColorScheme_AdwaitaDark)); GlobalCommands_insert( "ChooseTextureBackgroundColor", makeCallback( g_ColoursMenu.m_textureback ) ); GlobalCommands_insert( "ChooseGridBackgroundColor", makeCallback( g_ColoursMenu.m_xyback ) ); GlobalCommands_insert( "ChooseGridMajorColor", makeCallback( g_ColoursMenu.m_gridmajor ) ); @@ -3380,8 +3505,9 @@ void MainFrame_Construct(){ GlobalCommands_insert( "CSGSubtract", makeCallbackF(CSG_Subtract), Accelerator( 'U', (GdkModifierType)GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "CSGMerge", makeCallbackF(CSG_Merge), Accelerator( 'U', (GdkModifierType)GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "CSGHollow", makeCallbackF(CSG_MakeHollow) ); + GlobalCommands_insert( "CSGMerge", makeCallbackF(CSG_Merge), Accelerator( 'U', (GdkModifierType) GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "CSGMakeHollow", makeCallbackF(CSG_MakeHollow) ); + GlobalCommands_insert( "CSGMakeRoom", makeCallbackF(CSG_MakeRoom) ); Grid_registerCommands(); @@ -3457,7 +3583,7 @@ void MainFrame_Construct(){ GlobalPreferenceSystem().registerPreference( "DisableHomePath", make_property_string( g_disableHomePath ) ); for ( int i = 0; i < g_pakPathCount; i++ ) { - std::string label = "PakPath" + std::to_string(i); + std::string label = "PakPath" + std::to_string( i ); GlobalPreferenceSystem().registerPreference( label.c_str(), make_property_string( g_strPakPath[i] ) ); } @@ -3473,8 +3599,7 @@ void MainFrame_Construct(){ g_entityCount.setCountChangedCallback( makeCallbackF(QE_entityCountChanged) ); GlobalEntityCreator().setCounter( &g_entityCount ); - GLWidget_sharedContextCreated = GlobalGL_sharedContextCreated; - GLWidget_sharedContextDestroyed = GlobalGL_sharedContextDestroyed; + glwidget_set_shared_context_constructors( GlobalGL_sharedContextCreated, GlobalGL_sharedContextDestroyed); GlobalEntityClassManager().attach( g_WorldspawnColourEntityClassObserver ); } @@ -3494,3 +3619,44 @@ void GLWindow_Construct(){ void GLWindow_Destroy(){ } + +void Radiant_Restart(){ + // preferences are expected to be already saved in any way + // this is just to be sure and be future proof + Preferences_Save(); + + // this asks user for saving if map is modified + // user can chose to not save, it's ok + ConfirmModified( "Restart " RADIANT_NAME ); + + int status; + + char *argv[ 3 ]; + char exe_file[ 256 ]; + char map_file[ 256 ]; + bool with_map = false; + + strncpy( exe_file, g_strAppFilePath.c_str(), 256 ); + + if ( !Map_Unnamed( g_map ) ) { + strncpy( map_file, Map_Name( g_map ), 256 ); + with_map = true; + } + + argv[ 0 ] = exe_file; + argv[ 1 ] = with_map ? map_file : NULL; + argv[ 2 ] = NULL; + +#if GDEF_OS_WINDOWS + status = !_spawnvpe( P_NOWAIT, exe_file, argv, environ ); +#else + pid_t pid; + + status = posix_spawn( &pid, exe_file, NULL, NULL, argv, environ ); +#endif + + // quit if radiant successfully started + if ( status == 0 ) { + gtk_main_quit(); + } +}