]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/xywindow.cpp
Merge commit '54a2bda443aace9c00a1615af10cc1dc8b1f0cd1' into master-merge
[xonotic/netradiant.git] / radiant / xywindow.cpp
index d940d707c9716e6b87877b1701aecbab6e5e9c41..c7d1d6cbf1560f01c7637493c3e88c46eceb3bc0 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"
@@ -138,7 +139,9 @@ void ClipPoint::Draw( const char *label, float scale ){
 
        // draw label
        glRasterPos3f( m_ptClip[0] + offset, m_ptClip[1] + offset, m_ptClip[2] + offset );
-       glCallLists( GLsizei( strlen( label ) ), GL_UNSIGNED_BYTE, label );
+       //glCallLists( GLsizei( strlen( label ) ), GL_UNSIGNED_BYTE, label );   //fails with GCC
+       //glCallLists( GLsizei( strlen( label ) ), GL_UNSIGNED_BYTE, reinterpret_cast<const GLubyte*>( label ) );       //worx
+       GlobalOpenGL().drawString( label );
 }
 
 float fDiff( float f1, float f2 ){
@@ -544,7 +547,7 @@ void XYWnd::ZoomOut(){
 void XYWnd::ZoomInWithMouse( int pointx, int pointy ){
        float old_scale = Scale();
        ZoomIn();
-       if ( g_xywindow_globals.m_bImprovedWheelZoom ) {
+       if ( g_xywindow_globals.m_bZoomInToPointer ) {
                float scale_diff = 1.0 / old_scale - 1.0 / Scale();
                int nDim1 = ( m_viewType == YZ ) ? 1 : 0;
                int nDim2 = ( m_viewType == XY ) ? 1 : 2;
@@ -555,6 +558,19 @@ 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 );
+       }
+}
+
 VIEWTYPE GlobalXYWnd_getCurrentViewType(){
        ASSERT_NOTNULL( g_pParentWnd );
        ASSERT_NOTNULL( g_pParentWnd->ActiveXY() );
@@ -749,6 +765,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 );
                }
@@ -788,6 +806,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 );
        }
@@ -809,20 +832,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 );
@@ -838,6 +851,7 @@ XYWnd::XYWnd() :
        m_window_observer( NewWindowObserver() ),
        m_XORRectangle( m_gl_widget ),
        m_chasemouse_handler( 0 ){
+
        m_bActive = false;
        m_buttonstate = 0;
 
@@ -888,8 +902,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 ) );
@@ -987,18 +1004,40 @@ void XYWnd::Clipper_OnMouseMoved( int x, int y ){
        }
 }
 
+//#include "gtkutil/image.h"
+
+/* is called on every mouse move fraction; ain't good! */
 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;
+                       cursor = gdk_cursor_new( GDK_CROSSHAIR );
+                       //cursor = gdk_cursor_new( GDK_FLEUR );
+                       gdk_window_set_cursor( gtk_widget_get_window(m_gl_widget), cursor );
+                       gdk_cursor_unref( cursor );
+               }
+               else{
+                       GdkCursor *cursor;
+                       cursor = gdk_cursor_new( GDK_HAND2 );
+//                     GdkPixbuf* pixbuf = pixbuf_new_from_file_with_mask( "bitmaps/icon.png" );
+//                     cursor = gdk_cursor_new_from_pixbuf( gdk_display_get_default(), pixbuf, 0, 0 );
+//                     g_object_unref( pixbuf );
+                       gdk_window_set_cursor( gtk_widget_get_window(m_gl_widget), cursor );
+                       gdk_cursor_unref( cursor );
+
+               }
+       }
+#else
        if ( ClipMode() && GlobalClipPoints_Find( mousePosition, (VIEWTYPE)m_viewType, m_fScale ) != 0 ) {
-               GdkCursor *cursor;
-               cursor = gdk_cursor_new( GDK_CROSSHAIR );
-               gdk_window_set_cursor( gtk_widget_get_window(m_gl_widget), cursor );
-               gdk_cursor_unref( cursor );
+               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 );
        }
 }
 
@@ -1095,7 +1134,6 @@ void XYWnd::NewBrushDrag_Begin( int x, int y ){
        m_nNewBrushPressy = y;
 
        m_bNewBrushDrag = true;
-       GlobalUndoSystem().start();
 }
 
 void XYWnd::NewBrushDrag_End( int x, int y ){
@@ -1133,6 +1171,7 @@ void XYWnd::NewBrushDrag( int x, int y ){
        }
 
        if ( m_NewBrushDrag == 0 ) {
+               GlobalUndoSystem().start();
                NodeSmartReference node( GlobalBrushCreator().createBrush() );
                Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node );
 
@@ -1159,8 +1198,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 );
@@ -1275,13 +1314,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 );
 }
 
@@ -1290,6 +1333,8 @@ unsigned int Zoom_buttons(){
 }
 
 int g_dragZoom = 0;
+int g_zoom2x = 0;
+int g_zoom2y = 0;
 
 void XYWnd_zoomDelta( int x, int y, unsigned int state, void* data ){
        if ( y != 0 ) {
@@ -1302,7 +1347,12 @@ void XYWnd_zoomDelta( int x, int y, unsigned int state, void* data ){
                        }
                        else
                        {
+                               if ( g_xywindow_globals.m_bZoomInToPointer ) {
+                                       reinterpret_cast<XYWnd*>( data )->ZoomInWithMouse( g_zoom2x, g_zoom2y );
+                               }
+                               else{
                                reinterpret_cast<XYWnd*>( data )->ZoomIn();
+                               }
                                g_dragZoom += 8;
                        }
                }
@@ -1314,13 +1364,17 @@ gboolean XYWnd_Zoom_focusOut( ui::Widget widget, GdkEventFocus* event, XYWnd* xy
        return FALSE;
 }
 
-void XYWnd::Zoom_Begin(){
+void XYWnd::Zoom_Begin( int x, int y ){
        if ( m_zoom_started ) {
                Zoom_End();
        }
        m_zoom_started = true;
        g_dragZoom = 0;
-       g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_zoomDelta, this );
+       g_zoom2x = x;
+       g_zoom2y = y;
+       /* 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 );
 }
 
@@ -1366,7 +1420,7 @@ void XYWnd::XY_MouseDown( int x, int y, unsigned int buttons ){
                EntityCreate_MouseDown( x, y );
        }
        else if ( buttons == Zoom_buttons() ) {
-               Zoom_Begin();
+               Zoom_Begin( x, y );
        }
        else if ( ClipMode() && ( buttons == Clipper_buttons() || buttons == Clipper_quick_buttons() ) ) {
                Clipper_OnLButtonDown( x, y );
@@ -1592,17 +1646,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();
 }
 
 /*
@@ -2375,7 +2437,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 );
@@ -2398,11 +2460,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;
 
@@ -2458,7 +2522,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 );
+       }
 }
 
 /*
@@ -2846,7 +2912,6 @@ void unrealise(){
 EntityClassMenu g_EntityClassMenu;
 
 
-
 // Names
 void ShowNamesToggle(){
        GlobalEntityCreator().setShowNames( !GlobalEntityCreator().getShowNames() );
@@ -2861,6 +2926,20 @@ void ShowNamesExport( const Callback<void(bool)> & importer ){
 
 typedef FreeCaller<void(const Callback<void(bool)> &), ShowNamesExport> ShowNamesExportCaller;
 
+// TargetNames
+void ShowTargetNamesToggle(){
+       GlobalEntityCreator().setShowTargetNames( !GlobalEntityCreator().getShowTargetNames() );
+       XY_UpdateAllWindows();
+}
+
+typedef FreeCaller<void(), ShowTargetNamesToggle> ShowTargetNamesToggleCaller;
+
+void ShowTargetNamesExport( const Callback<void(bool)> & importer ){
+       importer( GlobalEntityCreator().getShowTargetNames() );
+}
+
+typedef FreeCaller<void(const Callback<void(bool)> &), ShowTargetNamesExport> ShowTargetNamesExportCaller;
+
 // Angles
 void ShowAnglesToggle(){
        GlobalEntityCreator().setShowAngles( !GlobalEntityCreator().getShowAngles() );
@@ -2990,6 +3069,10 @@ ShowNamesExportCaller g_show_names_caller;
 Callback<void(const Callback<void(bool)> &)> g_show_names_callback( g_show_names_caller );
 ToggleItem g_show_names( g_show_names_callback );
 
+ShowTargetNamesExportCaller g_show_targetnames_caller;
+Callback<void(const Callback<void(bool)> &)> g_show_targetnames_callback( g_show_targetnames_caller );
+ToggleItem g_show_targetnames( g_show_targetnames_callback );
+
 ShowAnglesExportCaller g_show_angles_caller;
 Callback<void(const Callback<void(bool)> &)> g_show_angles_callback( g_show_angles_caller );
 ToggleItem g_show_angles( g_show_angles_callback );
@@ -3034,6 +3117,7 @@ void XYShow_registerCommands(){
 
        GlobalToggles_insert( "ShowAngles", ShowAnglesToggleCaller(), ToggleItem::AddCallbackCaller( g_show_angles ) );
        GlobalToggles_insert( "ShowNames", ShowNamesToggleCaller(), ToggleItem::AddCallbackCaller( g_show_names ) );
+       GlobalToggles_insert( "ShowTargetNames", ShowTargetNamesToggleCaller(), ToggleItem::AddCallbackCaller( g_show_targetnames ) );
        GlobalToggles_insert( "ShowBlocks", ShowBlocksToggleCaller(), ToggleItem::AddCallbackCaller( g_show_blocks ) );
        GlobalToggles_insert( "ShowCoordinates", ShowCoordinatesToggleCaller(), ToggleItem::AddCallbackCaller( g_show_coordinates ) );
        GlobalToggles_insert( "ShowWindowOutline", ShowOutlineToggleCaller(), ToggleItem::AddCallbackCaller( g_show_outline ) );
@@ -3053,6 +3137,7 @@ void Orthographic_constructPreferences( PreferencesPage& page ){
        //page.appendCheckBox( "", "Display size info", g_xywindow_globals_private.m_bSizePaint );
        page.appendCheckBox( "", "Chase mouse during drags", g_xywindow_globals_private.m_bChaseMouse );
 //     page.appendCheckBox( "", "Update views on camera move", g_xywindow_globals_private.m_bCamXYUpdate );
+       page.appendCheckBox( "", "Zoom In to Mouse pointer", g_xywindow_globals.m_bZoomInToPointer );
 }
 void Orthographic_constructPage( PreferenceGroup& group ){
        PreferencesPage page( group.createPage( "Orthographic", "Orthographic View Preferences" ) );
@@ -3109,7 +3194,7 @@ void XYWindow_Construct(){
        GlobalPreferenceSystem().registerPreference( "ClipCaulk", make_property_string( g_clip_useCaulk ) );
 
 //     GlobalPreferenceSystem().registerPreference( "NewRightClick", make_property_string( g_xywindow_globals.m_bRightClick ) );
-       GlobalPreferenceSystem().registerPreference( "ImprovedWheelZoom", make_property_string( g_xywindow_globals.m_bImprovedWheelZoom ) );
+       GlobalPreferenceSystem().registerPreference( "2DZoomInToPointer", make_property_string( g_xywindow_globals.m_bZoomInToPointer ) );
        GlobalPreferenceSystem().registerPreference( "ChaseMouse", make_property_string( g_xywindow_globals_private.m_bChaseMouse ) );
        GlobalPreferenceSystem().registerPreference( "SizePainting", make_property_string( g_xywindow_globals_private.m_bSizePaint ) );
        GlobalPreferenceSystem().registerPreference( "ShowCrosshair", make_property_string( g_xywindow_globals_private.g_bCrossHairs ) );