diff --git a/libs/gtkutil/widget.h b/libs/gtkutil/widget.h index f4bc3267..0ee5465e 100644 --- a/libs/gtkutil/widget.h +++ b/libs/gtkutil/widget.h @@ -28,8 +28,11 @@ #include "warnings.h" #include "debugging/debugging.h" +#include + inline bool widget_is_visible( GtkWidget* widget ){ - return GTK_WIDGET_VISIBLE( widget ) != FALSE; + //return GTK_WIDGET_VISIBLE( widget ) != FALSE; + return gtk_widget_get_visible( widget ) != FALSE; } inline void widget_set_visible( GtkWidget* widget, bool show ){ @@ -37,8 +40,6 @@ inline void widget_set_visible( GtkWidget* widget, bool show ){ /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ GtkWidget* glwidget = GTK_WIDGET( g_object_get_data( G_OBJECT( widget ), "glwidget" ) ); if ( glwidget ){ - //if ( widget_is_visible( glwidget ) ) - //globalOutputStream() << "glwidget have been already visible :0\n"; /* is not hidden aswell, according to this */ gtk_widget_hide( glwidget ); gtk_widget_show( glwidget ); } @@ -86,11 +87,17 @@ ToggleShown( const ToggleShown& other ); // NOT COPYABLE ToggleShown& operator=( const ToggleShown& other ); // NOT ASSIGNABLE static gboolean notify_visible( GtkWidget* widget, gpointer dummy, ToggleShown* self ){ + /* destroy = notify::visible with visible = 0, thus let's filter it out */ + if( gtk_main_level() > 0 ){ //== 0 at destroy time + self->m_shownDeferred = widget_is_visible( self->m_widget ); + } +//globalOutputStream() << "ToggleShown::notify_visible time " << gtk_get_current_event_time() << " visible " << self->m_shownDeferred << "\n"; self->update(); return FALSE; } static gboolean destroy( GtkWidget* widget, ToggleShown* self ){ - self->m_shownDeferred = GTK_WIDGET_VISIBLE( self->m_widget ) != FALSE; +//globalOutputStream() << "ToggleShown::destroy time " << gtk_get_current_event_time() << " visible " << self->m_shownDeferred << "\n"; + //self->m_shownDeferred = widget_is_visible( self->m_widget ); //always 0 at destroy time self->m_widget = 0; return FALSE; } @@ -102,22 +109,26 @@ ToggleShown( bool shown ) : m_shownDeferred( shown ), m_widget( 0 ), m_item( ActiveCaller( *this ) ){ } void update(){ +//globalOutputStream() << "ToggleShown::update\n"; m_item.update(); } bool active() const { +//globalOutputStream() << "ToggleShown::active\n"; if ( m_widget == 0 ) { return m_shownDeferred; } else { - return GTK_WIDGET_VISIBLE( m_widget ) != FALSE; + return widget_is_visible( m_widget ); } } void exportActive( const BoolImportCallback& importCallback ){ +//globalOutputStream() << "ToggleShown::exportActive\n"; importCallback( active() ); } typedef MemberCaller1 ActiveCaller; void set( bool shown ){ +//globalOutputStream() << "ToggleShown::set\n"; if ( m_widget == 0 ) { m_shownDeferred = shown; } @@ -127,10 +138,12 @@ void set( bool shown ){ } } void toggle(){ +//globalOutputStream() << "ToggleShown::toggle\n"; widget_toggle_visible( m_widget ); } typedef MemberCaller ToggleCaller; void connect( GtkWidget* widget ){ +//globalOutputStream() << "ToggleShown::connect\n"; m_widget = widget; widget_set_visible( m_widget, m_shownDeferred ); g_signal_connect( G_OBJECT( m_widget ), "notify::visible", G_CALLBACK( notify_visible ), this ); @@ -139,6 +152,18 @@ void connect( GtkWidget* widget ){ } }; +namespace{ + +void ToggleShown_importBool( ToggleShown& self, bool value ){ + self.set( value ); +} +typedef ReferenceCaller1 ToggleShownImportBoolCaller; +void ToggleShown_exportBool( const ToggleShown& self, const BoolImportCallback& importer ){ + importer( self.active() ); +} +typedef ConstReferenceCaller1 ToggleShownExportBoolCaller; + +} inline void widget_queue_draw( GtkWidget& widget ){ gtk_widget_queue_draw( &widget ); diff --git a/libs/gtkutil/window.h b/libs/gtkutil/window.h index 1a7161e6..cd597c86 100644 --- a/libs/gtkutil/window.h +++ b/libs/gtkutil/window.h @@ -108,32 +108,59 @@ typedef ConstReferenceCaller1m_position = WindowPosition( event->x, event->y, event->width, event->height ); return FALSE; } public: WindowPositionTracker() - : m_position( c_default_window_pos ){ + : m_position( c_default_window_pos ), m_window( 0 ){ } void sync( GtkWindow* window ){ +//globalOutputStream() << "WindowPositionTracker::sync\n"; window_set_position( window, m_position ); } +void sync(){ + if( m_window ) + sync( m_window ); +} + +/** need to reapply pos on every hiding to keep wnd pos after hide+show (flickering between two positions, if doing on showing) +this stuff is weird: some wnds, like entity list, keep pos on hide/show... untill you resize them -) +some, like floating xy/cam/groupdialog do not; if you remove glwidget from floating xy - it does xD +if you gtk_window_set_position( window, GTK_WIN_POS_CENTER_ALWAYS ), they do keep it, except of random centering after resizing (ms windows) +but this option doesn't sound healthy; +gtk_window_set_transient_for seems to do some gtk_window_set_position also +old questionable comment on this issue: +workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event */ +static gboolean notify_visible( GtkWidget* widget, gpointer dummy, WindowPositionTracker* self ){ + if( !widget_is_visible( GTK_WIDGET( self->m_window ) ) ) + self->sync(); + return FALSE; +} + void connect( GtkWindow* window ){ +//globalOutputStream() << "WindowPositionTracker::connect\n"; + m_window = window; sync( window ); g_signal_connect( G_OBJECT( window ), "configure_event", G_CALLBACK( configure ), this ); + g_signal_connect( G_OBJECT( window ), "notify::visible", G_CALLBACK( notify_visible ), this ); } const WindowPosition& getPosition() const { +//globalOutputStream() << "WindowPositionTracker::getPosition\n"; return m_position; } //hack void setPosition( const WindowPosition& position ){ +//globalOutputStream() << "WindowPositionTracker::setPosition\n"; m_position = position; } }; diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index 0beb2ed7..f6b6270a 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -2308,6 +2308,7 @@ void CamWnd_Construct(){ GlobalPreferenceSystem().registerPreference( "CameraFaceWire", BoolImportStringCaller( g_camwindow_globals_private.m_bFaceWire ), BoolExportStringCaller( g_camwindow_globals_private.m_bFaceWire ) ); GlobalPreferenceSystem().registerPreference( "3DZoomInToPointer", BoolImportStringCaller( g_camwindow_globals.m_bZoomInToPointer ), BoolExportStringCaller( g_camwindow_globals.m_bZoomInToPointer ) ); GlobalPreferenceSystem().registerPreference( "fieldOfView", FloatImportStringCaller( camera_t::fieldOfView ), FloatExportStringCaller( camera_t::fieldOfView ) ); + GlobalPreferenceSystem().registerPreference( "CamVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_camera_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_camera_shown ) ) ); CamWnd_constructStatic(); diff --git a/radiant/entityinspector.cpp b/radiant/entityinspector.cpp index 2040ffd7..9d3967f1 100644 --- a/radiant/entityinspector.cpp +++ b/radiant/entityinspector.cpp @@ -1429,6 +1429,10 @@ void EntityInspector_selectConnected( GtkButton *button, gpointer user_data ){ Select_ConnectedEntities( true, true, focus ); } +void EntityInspector_focusSelected( GtkButton *button, gpointer user_data ){ + FocusAllViews(); +} + GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){ GtkWidget* vbox = gtk_vbox_new( FALSE, 2 ); gtk_widget_show( vbox ); @@ -1690,6 +1694,7 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){ gtk_widget_set_tooltip_text( button, "AutoFocus on Selection" ); gtk_widget_show( button ); g_focusToggleButton = GTK_TOGGLE_BUTTON( button ); + g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_focusSelected ), 0 ); } } } diff --git a/radiant/entitylist.cpp b/radiant/entitylist.cpp index d08414e5..eca344f4 100644 --- a/radiant/entitylist.cpp +++ b/radiant/entitylist.cpp @@ -142,6 +142,10 @@ void entitylist_treeviewcolumn_celldatafunc( GtkTreeViewColumn* column, GtkCellR } } +void entitylist_focusSelected( GtkButton *button, gpointer user_data ){ + FocusAllViews(); +} + static gboolean entitylist_tree_select( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer data ){ GtkTreeIter iter; gtk_tree_model_get_iter( model, &iter, path ); @@ -339,6 +343,7 @@ void EntityList_constructWindow( GtkWindow* main_window ){ gtk_widget_show( check ); gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 ); getEntityList().m_check = check; + g_signal_connect( G_OBJECT( check ), "clicked", G_CALLBACK( entitylist_focusSelected ), 0 ); } } diff --git a/radiant/findtexturedialog.cpp b/radiant/findtexturedialog.cpp index 14998574..5bea3f7e 100644 --- a/radiant/findtexturedialog.cpp +++ b/radiant/findtexturedialog.cpp @@ -253,8 +253,6 @@ void FindTextureDialog::setReplaceStr( const char* name ){ } void FindTextureDialog::show(){ - // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event - g_FindTextureDialog.m_position_tracker.sync( g_FindTextureDialog.GetWidget() ); g_FindTextureDialog.ShowDlg(); gtk_window_present( g_FindTextureDialog.GetWidget() ); } diff --git a/radiant/groupdialog.cpp b/radiant/groupdialog.cpp index dc94603b..8eafa1df 100644 --- a/radiant/groupdialog.cpp +++ b/radiant/groupdialog.cpp @@ -59,13 +59,9 @@ GroupDlg(); void Create( GtkWindow* parent ); void Show(){ - // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event - m_position_tracker.sync( m_window ); /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ GtkWidget* glwidget = GTK_WIDGET( g_object_get_data( G_OBJECT( m_window ), "glwidget" ) ); if ( glwidget ){ - //if ( widget_is_visible( glwidget ) ) - //globalOutputStream() << "glwidget have been already visible :0\n"; /* is not hidden aswell, according to this */ gtk_widget_hide( glwidget ); gtk_widget_show( glwidget ); } diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index 80187727..2ad56036 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -1772,10 +1772,12 @@ bool MainFrame_isActiveApp(){ //globalOutputStream() << "toplevel.. "; if ( gtk_window_is_active( GTK_WINDOW( i->data ) ) ) { //globalOutputStream() << "is active\n"; + g_list_free( list ); return true; } //globalOutputStream() << "not active\n"; } + g_list_free( list ); return false; } @@ -2967,6 +2969,7 @@ gboolean toolbar_redirect_scroll( GtkWidget* widget, GdkEventScroll* event, gpoi return FALSE; } + void MainFrame::Create(){ GtkWindow* window = GTK_WINDOW( gtk_window_new( GTK_WINDOW_TOPLEVEL ) ); @@ -3157,8 +3160,6 @@ void MainFrame::Create(){ global_accel_connect_window( window ); g_posCamWnd.connect( window ); - gtk_widget_show( GTK_WIDGET( window ) ); - m_pCamWnd = NewCamWnd(); GlobalCamera_setCamWnd( *m_pCamWnd ); @@ -3166,6 +3167,7 @@ void MainFrame::Create(){ GtkFrame* frame = create_framed_widget( CamWnd_getWidget( *m_pCamWnd ) ); gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( frame ) ); } + CamWnd_setParent( *m_pCamWnd, window ); /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ g_object_set_data( G_OBJECT( window ), "glwidget", CamWnd_getWidget( *m_pCamWnd ) ); @@ -3182,11 +3184,11 @@ void MainFrame::Create(){ m_pXYWnd->m_parent = window; m_pXYWnd->SetViewType( XY ); - { GtkFrame* frame = create_framed_widget( m_pXYWnd->GetWidget() ); gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( frame ) ); } + XY_Top_Shown_Construct( window ); /* workaround for gtk 2.24 issue: not displayed glwidget after toggle */ g_object_set_data( G_OBJECT( window ), "glwidget", m_pXYWnd->GetWidget() ); diff --git a/radiant/patchdialog.cpp b/radiant/patchdialog.cpp index 7ce797e7..ef6728a3 100644 --- a/radiant/patchdialog.cpp +++ b/radiant/patchdialog.cpp @@ -301,8 +301,6 @@ void PatchInspector_queueDraw(){ void DoPatchInspector(){ g_PatchInspector.GetPatchInfo(); if ( !g_PatchInspector.visible() ) { - // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event - g_PatchInspector.m_position_tracker.sync( g_PatchInspector.GetWidget() ); g_PatchInspector.ShowDlg(); } } diff --git a/radiant/preferences.cpp b/radiant/preferences.cpp index e838ab8a..1c8b7e45 100644 --- a/radiant/preferences.cpp +++ b/radiant/preferences.cpp @@ -753,6 +753,7 @@ GtkWindow* PrefsDlg::BuildDialog(){ 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 ) ); + m_treeview = view; gtk_tree_view_set_headers_visible( GTK_TREE_VIEW( view ), FALSE ); { @@ -932,6 +933,8 @@ void PreferencesDialog_restartRequired( const char* staticName ){ void PreferencesDialog_showDialog(){ //if ( ConfirmModified( "Edit Preferences" ) && g_Preferences.DoModal() == eIDOK ) { + if( gtk_widget_get_realized( g_Preferences.m_treeview ) == TRUE ) + gtk_widget_grab_focus( g_Preferences.m_treeview ); if ( g_Preferences.DoModal() == eIDOK ) { if ( !g_restart_required.empty() ) { StringOutputStream message( 256 ); diff --git a/radiant/preferences.h b/radiant/preferences.h index 4b44f97f..e6d36898 100644 --- a/radiant/preferences.h +++ b/radiant/preferences.h @@ -321,8 +321,6 @@ CGameDescription *GameDescriptionForComboItem(); extern CGameDialog g_GamesDialog; -class texdef_t; - class PrefsDlg : public Dialog { public: @@ -332,6 +330,7 @@ std::list mGames; public: GtkWidget *m_notebook; +GtkWidget *m_treeview; virtual ~PrefsDlg(){ g_string_free( m_rc_path, true ); diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 0a0f412c..db1cef55 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -809,6 +809,8 @@ gboolean xywnd_button_release( GtkWidget* widget, GdkEventButton* event, XYWnd* xywnd->XY_MouseUp( static_cast( event->x ), static_cast( event->y ), buttons_for_event_button( event ) ); xywnd->ButtonState_onMouseUp( buttons_for_event_button( event ) ); + + xywnd->chaseMouseMotion( static_cast( event->x ), static_cast( event->y ) ); /* stop chaseMouseMotion this way */ } return FALSE; } @@ -3391,24 +3393,12 @@ void Clipper_registerPreferencesPage(){ #include "stringio.h" - - -void ToggleShown_importBool( ToggleShown& self, bool value ){ - self.set( value ); -} -typedef ReferenceCaller1 ToggleShownImportBoolCaller; -void ToggleShown_exportBool( const ToggleShown& self, const BoolImportCallback& importer ){ - importer( self.active() ); -} -typedef ConstReferenceCaller1 ToggleShownExportBoolCaller; - - void XYWindow_Construct(){ // GlobalCommands_insert( "ToggleCrosshairs", FreeCaller(), Accelerator( 'X', (GdkModifierType)GDK_SHIFT_MASK ) ); // GlobalCommands_insert( "ToggleSizePaint", FreeCaller(), Accelerator( 'J' ) ); // GlobalCommands_insert( "ToggleGrid", FreeCaller(), Accelerator( '0' ) ); - GlobalToggles_insert( "ToggleView", ToggleShown::ToggleCaller( g_xy_top_shown ), ToggleItem::AddCallbackCaller( g_xy_top_shown.m_item ), Accelerator( 'V', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + GlobalToggles_insert( "ToggleView", ToggleShown::ToggleCaller( g_xy_top_shown ), ToggleItem::AddCallbackCaller( g_xy_top_shown.m_item ) ); GlobalToggles_insert( "ToggleSideView", ToggleShown::ToggleCaller( g_yz_side_shown ), ToggleItem::AddCallbackCaller( g_yz_side_shown.m_item ) ); GlobalToggles_insert( "ToggleFrontView", ToggleShown::ToggleCaller( g_xz_front_shown ), ToggleItem::AddCallbackCaller( g_xz_front_shown.m_item ) ); GlobalCommands_insert( "NextView", FreeCaller(), Accelerator( GDK_Tab, (GdkModifierType)GDK_CONTROL_MASK ) ); @@ -3450,6 +3440,7 @@ void XYWindow_Construct(){ GlobalPreferenceSystem().registerPreference( "SI_Colors11", Vector3ImportStringCaller( g_xywindow_globals.color_selbrushes ), Vector3ExportStringCaller( g_xywindow_globals.color_selbrushes ) ); + GlobalPreferenceSystem().registerPreference( "XYVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_xy_top_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_xy_top_shown ) ) ); GlobalPreferenceSystem().registerPreference( "XZVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_xz_front_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_xz_front_shown ) ) ); GlobalPreferenceSystem().registerPreference( "YZVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_yz_side_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_yz_side_shown ) ) ); diff --git a/setup/data/tools-src/window1.png b/setup/data/tools-src/window1.png new file mode 100644 index 00000000..c880b89d Binary files /dev/null and b/setup/data/tools-src/window1.png differ diff --git a/setup/data/tools-src/window2.png b/setup/data/tools-src/window2.png new file mode 100644 index 00000000..94e936c5 Binary files /dev/null and b/setup/data/tools-src/window2.png differ diff --git a/setup/data/tools-src/window3.png b/setup/data/tools-src/window3.png new file mode 100644 index 00000000..e739968b Binary files /dev/null and b/setup/data/tools-src/window3.png differ diff --git a/setup/data/tools-src/window4.png b/setup/data/tools-src/window4.png new file mode 100644 index 00000000..891ca415 Binary files /dev/null and b/setup/data/tools-src/window4.png differ diff --git a/setup/data/tools/bitmaps/window1.png b/setup/data/tools/bitmaps/window1.png index c880b89d..8163ee74 100644 Binary files a/setup/data/tools/bitmaps/window1.png and b/setup/data/tools/bitmaps/window1.png differ diff --git a/setup/data/tools/bitmaps/window2.png b/setup/data/tools/bitmaps/window2.png index 94e936c5..67da22ab 100644 Binary files a/setup/data/tools/bitmaps/window2.png and b/setup/data/tools/bitmaps/window2.png differ diff --git a/setup/data/tools/bitmaps/window3.png b/setup/data/tools/bitmaps/window3.png index e739968b..8596ca88 100644 Binary files a/setup/data/tools/bitmaps/window3.png and b/setup/data/tools/bitmaps/window3.png differ diff --git a/setup/data/tools/bitmaps/window4.png b/setup/data/tools/bitmaps/window4.png index 891ca415..ac6df1c1 100644 Binary files a/setup/data/tools/bitmaps/window4.png and b/setup/data/tools/bitmaps/window4.png differ