]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/xywindow.cpp
radiant: fix windows build
[xonotic/netradiant.git] / radiant / xywindow.cpp
index 6da0a4b25fefd0907a712493a7da1f2906553915..c06994c4fa90df0765d4ef1fae205952bd124c4a 100644 (file)
@@ -58,6 +58,7 @@
 #include "gtkutil/widget.h"
 #include "gtkutil/glwidget.h"
 #include "gtkutil/filechooser.h"
+#include "gtkutil/cursor.h"
 #include "gtkmisc.h"
 #include "select.h"
 #include "csg.h"
@@ -557,6 +558,33 @@ void XYWnd::ZoomInWithMouse( int pointx, int pointy ){
        }
 }
 
+void XYWnd::Redraw() {
+       if ( glwidget_make_current( m_gl_widget ) != FALSE ) {
+               if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) {
+                       GlobalOpenGL_debugAssertNoErrors();
+                       XY_Draw();
+                       GlobalOpenGL_debugAssertNoErrors();
+
+                       m_XORRectangle.set( rectangle_t() );
+               }
+               glwidget_swap_buffers( m_gl_widget );
+       }
+}
+
+void XYWnd::FocusOnBounds( AABB& bounds ){
+       SetOrigin( bounds.origin );
+       int nDim1 = ( m_viewType == YZ ) ? 1 : 0;
+       int nDim2 = ( m_viewType == XY ) ? 1 : 2;
+       if( bounds.extents[ nDim1 ] < 128.f )
+               bounds.extents[ nDim1 ] = 128.f;
+       if( bounds.extents[ nDim2 ] < 128.f )
+               bounds.extents[ nDim2 ] = 128.f;
+       float scale1 = Width() / ( 3.f * bounds.extents[ nDim1 ] );
+       float scale2 = Height() / ( 3.f * bounds.extents[ nDim2 ] );
+       SetScale( MIN( scale1, scale2 ) );
+
+}
+
 VIEWTYPE GlobalXYWnd_getCurrentViewType(){
        ASSERT_NOTNULL( g_pParentWnd );
        ASSERT_NOTNULL( g_pParentWnd->ActiveXY() );
@@ -751,6 +779,8 @@ void xy_update_xor_rectangle( XYWnd& self, rect_t area ){
 
 gboolean xywnd_button_press( ui::Widget widget, GdkEventButton* event, XYWnd* xywnd ){
        if ( event->type == GDK_BUTTON_PRESS ) {
+               gtk_widget_grab_focus( xywnd->GetWidget() );
+
                if( !xywnd->Active() ){
                        g_pParentWnd->SetActiveXY( xywnd );
                }
@@ -790,6 +820,11 @@ void xywnd_motion( gdouble x, gdouble y, guint state, void* data ){
 }
 
 gboolean xywnd_wheel_scroll( ui::Widget widget, GdkEventScroll* event, XYWnd* xywnd ){
+       gtk_widget_grab_focus( xywnd->GetWidget() );
+       ui::Window window = xywnd->m_parent ? xywnd->m_parent : MainFrame_getWindow();
+       if( !gtk_window_is_active( window ) )
+               gtk_window_present( window );
+
        if( !xywnd->Active() ){
                g_pParentWnd->SetActiveXY( xywnd );
        }
@@ -811,20 +846,10 @@ gboolean xywnd_size_allocate( ui::Widget widget, GtkAllocation* allocation, XYWn
 }
 
 gboolean xywnd_expose( ui::Widget widget, GdkEventExpose* event, XYWnd* xywnd ){
-       if ( glwidget_make_current( xywnd->GetWidget() ) != FALSE ) {
-               if ( Map_Valid( g_map ) && ScreenUpdates_Enabled() ) {
-                       GlobalOpenGL_debugAssertNoErrors();
-                       xywnd->XY_Draw();
-                       GlobalOpenGL_debugAssertNoErrors();
-
-                       xywnd->m_XORRectangle.set( rectangle_t() );
-               }
-               glwidget_swap_buffers( xywnd->GetWidget() );
-       }
+       xywnd->Redraw();
        return FALSE;
 }
 
-
 void XYWnd_CameraMoved( XYWnd& xywnd ){
 //     if ( g_xywindow_globals_private.m_bCamXYUpdate ) {
                //XYWnd_Update( xywnd );
@@ -840,6 +865,7 @@ XYWnd::XYWnd() :
        m_window_observer( NewWindowObserver() ),
        m_XORRectangle( m_gl_widget ),
        m_chasemouse_handler( 0 ){
+
        m_bActive = false;
        m_buttonstate = 0;
 
@@ -890,8 +916,11 @@ XYWnd::XYWnd() :
 
        Map_addValidCallback( g_map, DeferredDrawOnMapValidChangedCaller( m_deferredDraw ) );
 
-       updateProjection();
-       updateModelview();
+       // This reconstruct=false argument is used to avoid a circular dependency
+       // between modelview and projection initialization and a valgrind complaint
+       updateProjection( false );
+       updateModelview( false );
+       m_view.Construct( m_projection, m_modelview, m_nWidth, m_nHeight );
 
        AddSceneChangeCallback( ReferenceCaller<XYWnd, void(), &XYWnd_Update>( *this ) );
        AddCameraMovedCallback( ReferenceCaller<XYWnd, void(), &XYWnd_CameraMoved>( *this ) );
@@ -995,6 +1024,7 @@ void XYWnd::Clipper_OnMouseMoved( int x, int y ){
 void XYWnd::Clipper_Crosshair_OnMouseMoved( int x, int y ){
        Vector3 mousePosition;
        XY_ToPoint( x, y, mousePosition );
+#if 0 // NetRadiantCustom
        if ( ClipMode() ) {
                if( GlobalClipPoints_Find( mousePosition, (VIEWTYPE)m_viewType, m_fScale ) != 0 ){
                        GdkCursor *cursor;
@@ -1014,9 +1044,14 @@ void XYWnd::Clipper_Crosshair_OnMouseMoved( int x, int y ){
 
                }
        }
+#else
+       if ( ClipMode() && GlobalClipPoints_Find( mousePosition, (VIEWTYPE)m_viewType, m_fScale ) != 0 ) {
+               set_cursor ( m_gl_widget, GDK_CROSSHAIR );
+       }
+#endif
        else
        {
-               gdk_window_set_cursor( gtk_widget_get_window(m_gl_widget), 0 );
+               default_cursor( m_gl_widget );
        }
 }
 
@@ -1177,8 +1212,8 @@ void entitycreate_activated( ui::Widget item ){
                g_pParentWnd->ActiveXY()->OnEntityCreate( entity_name );
        }
        else {
-               GlobalRadiant().m_pfnMessageBox( MainFrame_getWindow(), "There's already a worldspawn in your map!"
-                                                                                                                                                         "",
+               GlobalRadiant().m_pfnMessageBox( MainFrame_getWindow(),
+                       "There's already a worldspawn in your map!",
                                                                                 "Info",
                                                                                 eMB_OK,
                                                                                 eMB_ICONDEFAULT );
@@ -1293,13 +1328,17 @@ void XYWnd::Move_Begin(){
                Move_End();
        }
        m_move_started = true;
-       g_xywnd_freezePointer.freeze_pointer( m_parent  ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_moveDelta, this );
+       /* NetRadiantCustom did this instead:
+       g_xywnd_freezePointer.freeze_pointer( m_parent  ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_moveDelta, this ); */
+       g_xywnd_freezePointer.freeze_pointer( m_gl_widget, XYWnd_moveDelta, this );
        m_move_focusOut = m_gl_widget.connect( "focus_out_event", G_CALLBACK( XYWnd_Move_focusOut ), this );
 }
 
 void XYWnd::Move_End(){
        m_move_started = false;
-       g_xywnd_freezePointer.unfreeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), false );
+       /* NetRadiant did this instead:
+       g_xywnd_freezePointer.unfreeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), false ); */
+       g_xywnd_freezePointer.unfreeze_pointer( m_gl_widget, false );
        g_signal_handler_disconnect( G_OBJECT( m_gl_widget ), m_move_focusOut );
 }
 
@@ -1347,7 +1386,9 @@ void XYWnd::Zoom_Begin( int x, int y ){
        g_dragZoom = 0;
        g_zoom2x = x;
        g_zoom2y = y;
-       g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_zoomDelta, this );
+       /* NetRadiantCustom did this instead:
+       g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_zoomDelta, this ); */
+       g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), XYWnd_zoomDelta, this );
        m_zoom_focusOut = m_gl_widget.connect( "focus_out_event", G_CALLBACK( XYWnd_Zoom_focusOut ), this );
 }
 
@@ -1619,17 +1660,25 @@ void XYWnd::XY_DisableBackground( void ){
 
 void WXY_BackgroundSelect( void ){
        bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0;
+
+       ui::Window main_window = MainFrame_getWindow();
+
        if ( !brushesSelected ) {
-               ui::alert( ui::root, "You have to select some brushes to get the bounding box for.\n",
+               ui::alert( main_window, "You have to select some brushes to get the bounding box for.\n",
                                                "No selection", ui::alert_type::OK, ui::alert_icon::Error );
                return;
        }
 
-       const char *filename = MainFrame_getWindow().file_dialog( TRUE, "Background Image", NULL, NULL );
+       const char *filename = main_window.file_dialog( TRUE, "Background Image", NULL, NULL );
+
        g_pParentWnd->ActiveXY()->XY_DisableBackground();
+
        if ( filename ) {
                g_pParentWnd->ActiveXY()->XY_LoadBackgroundImage( filename );
        }
+
+       // Draw the background image immediately (do not wait for user input).
+       g_pParentWnd->ActiveXY()->Redraw();
 }
 
 /*
@@ -2402,7 +2451,7 @@ RenderStateFlags m_globalstate;
 Shader* m_state_selected;
 };
 
-void XYWnd::updateProjection(){
+void XYWnd::updateProjection( bool reconstruct ){
        m_projection[0] = 1.0f / static_cast<float>( m_nWidth / 2 );
        m_projection[5] = 1.0f / static_cast<float>( m_nHeight / 2 );
        m_projection[10] = 1.0f / ( g_MaxWorldCoord * m_fScale );
@@ -2425,11 +2474,13 @@ void XYWnd::updateProjection(){
 
        m_projection[15] = 1.0f;
 
+       if (reconstruct) {
        m_view.Construct( m_projection, m_modelview, m_nWidth, m_nHeight );
 }
+}
 
 // note: modelview matrix must have a uniform scale, otherwise strange things happen when rendering the rotation manipulator.
-void XYWnd::updateModelview(){
+void XYWnd::updateModelview( bool reconstruct ){
        int nDim1 = ( m_viewType == YZ ) ? 1 : 0;
        int nDim2 = ( m_viewType == XY ) ? 1 : 2;
 
@@ -2485,7 +2536,9 @@ void XYWnd::updateModelview(){
        m_modelview[3] = m_modelview[7] = m_modelview[11] = 0;
        m_modelview[15] = 1;
 
+       if (reconstruct) {
        m_view.Construct( m_projection, m_modelview, m_nWidth, m_nHeight );
+       }
 }
 
 /*
@@ -2701,7 +2754,7 @@ void XYWnd::OnEntityCreate( const char* item ){
 
 
 
-void GetFocusPosition( Vector3& position ){
+void GetCenterPosition( Vector3& position ){
        if ( GlobalSelectionSystem().countSelected() != 0 ) {
                Select_GetMid( position );
        }
@@ -2711,15 +2764,15 @@ void GetFocusPosition( Vector3& position ){
        }
 }
 
-void XYWnd_Focus( XYWnd* xywnd ){
+void XYWnd_Centralize( XYWnd* xywnd ){
        Vector3 position;
-       GetFocusPosition( position );
+       GetCenterPosition( position );
        xywnd->PositionView( position );
 }
 
-void XY_Split_Focus(){
+void XY_Split_Centralize(){
        Vector3 position;
-       GetFocusPosition( position );
+       GetCenterPosition( position );
        if ( g_pParentWnd->GetXYWnd() ) {
                g_pParentWnd->GetXYWnd()->PositionView( position );
        }
@@ -2731,10 +2784,52 @@ void XY_Split_Focus(){
        }
 }
 
+void XY_Centralize(){
+       if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit || g_pParentWnd->CurrentStyle() == MainFrame::eFloating ) {
+               // centralize all
+               XY_Split_Centralize();
+               return;
+       }
+
+       XYWnd* xywnd = g_pParentWnd->GetXYWnd();
+       XYWnd_Centralize( xywnd );
+}
+
+
+
+void GetSelectionBbox( AABB& bounds ){
+       if ( GlobalSelectionSystem().countSelected() != 0 ) {
+               Scene_BoundsSelected( GlobalSceneGraph(), bounds );
+       }
+       else
+       {
+               bounds = AABB( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ), Vector3( 128.f, 128.f, 128.f ) );
+       }
+}
+
+void XYWnd_Focus( XYWnd* xywnd ){
+       AABB bounds;
+       GetSelectionBbox( bounds );
+       xywnd->FocusOnBounds( bounds );
+}
+
+void XY_Split_Focus(){
+       AABB bounds;
+       GetSelectionBbox( bounds );
+       if ( g_pParentWnd->GetXYWnd() ) {
+               g_pParentWnd->GetXYWnd()->FocusOnBounds( bounds );
+       }
+       if ( g_pParentWnd->GetXZWnd() ) {
+               g_pParentWnd->GetXZWnd()->FocusOnBounds( bounds );
+       }
+       if ( g_pParentWnd->GetYZWnd() ) {
+               g_pParentWnd->GetYZWnd()->FocusOnBounds( bounds );
+       }
+}
+
 void XY_Focus(){
        if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit || g_pParentWnd->CurrentStyle() == MainFrame::eFloating ) {
-               // cannot do this in a split window
-               // do something else that the user may want here
+               // focus all
                XY_Split_Focus();
                return;
        }
@@ -2743,16 +2838,18 @@ void XY_Focus(){
        XYWnd_Focus( xywnd );
 }
 
+
+
 void XY_TopFrontSide( VIEWTYPE viewtype ){
        if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit ) {
                // cannot do this in a split window
                // do something else that the user may want here
-               XY_Split_Focus();
+               XY_Split_Centralize();
                return;
        }
        XYWnd* xywnd = g_pParentWnd->CurrentStyle() == MainFrame::eFloating ? g_pParentWnd->ActiveXY() : g_pParentWnd->GetXYWnd();
        xywnd->SetViewType( viewtype );
-       XYWnd_Focus( xywnd );
+       XYWnd_Centralize( xywnd );
 }
 
 void XY_Top(){
@@ -2777,14 +2874,14 @@ void XY_NextView( XYWnd* xywnd ){
        else{
                xywnd->SetViewType( XY );
        }
-       XYWnd_Focus( xywnd );
+       XYWnd_Centralize( xywnd );
 }
 
 void XY_Next(){
        if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit ) {
                // cannot do this in a split window
                // do something else that the user may want here
-               XY_Split_Focus();
+               XY_Split_Centralize();
                return;
        }
        XYWnd* xywnd = g_pParentWnd->CurrentStyle() == MainFrame::eFloating ? g_pParentWnd->ActiveXY() : g_pParentWnd->GetXYWnd();
@@ -3150,7 +3247,8 @@ void XYWindow_Construct(){
        GlobalCommands_insert( "ViewSide", makeCallbackF(XY_Side), Accelerator( GDK_KEY_KP_Page_Down ) );
        GlobalCommands_insert( "ViewFront", makeCallbackF(XY_Front), Accelerator( GDK_KEY_KP_End ) );
        GlobalCommands_insert( "Zoom100", makeCallbackF(XY_Zoom100) );
-       GlobalCommands_insert( "CenterXYView", makeCallbackF(XY_Focus), Accelerator( GDK_KEY_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
+       GlobalCommands_insert( "CenterXYView", makeCallbackF(XY_Centralize), Accelerator( GDK_KEY_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
+       GlobalCommands_insert( "XYFocusOnSelected", makeCallbackF(XY_Focus), Accelerator( GDK_KEY_grave ) );
 
        GlobalPreferenceSystem().registerPreference( "ClipCaulk", make_property_string( g_clip_useCaulk ) );
 
@@ -3180,8 +3278,6 @@ void XYWindow_Construct(){
        GlobalPreferenceSystem().registerPreference( "SI_Colors11", make_property_string( g_xywindow_globals.color_selbrushes ) );
 
 
-
-
        GlobalPreferenceSystem().registerPreference( "XZVIS", make_property_string<ToggleShown_Bool>( g_xz_front_shown ) );
        GlobalPreferenceSystem().registerPreference( "YZVIS", make_property_string<ToggleShown_Bool>( g_yz_side_shown ) );