From 446ab50511b19aad050d3b07dc0adc8bc8ef9a7c Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 17 Apr 2018 14:26:49 +0300 Subject: [PATCH] really support mouse_moved_epsilon system in camera freelook use FreezePointer chain for freelook selections/manipulaions instead of extra gtk motion handler (fixes one step latency in window observer aswell) --- libs/gtkutil/cursor.h | 5 +++- radiant/camwindow.cpp | 61 +++++++++++++++++++++------------------ radiant/selection.cpp | 2 +- radiant/windowobservers.h | 4 --- radiant/xywindow.cpp | 12 +++----- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/libs/gtkutil/cursor.h b/libs/gtkutil/cursor.h index 70dcfec9..fd8330e8 100644 --- a/libs/gtkutil/cursor.h +++ b/libs/gtkutil/cursor.h @@ -80,8 +80,9 @@ class DeferredMotionDelta { int m_delta_x; int m_delta_y; +unsigned int m_state; guint m_motion_handler; -typedef void ( *MotionDeltaFunction )( int x, int y, void* data ); +typedef void ( *MotionDeltaFunction )( int x, int y, unsigned int state, void* data ); MotionDeltaFunction m_function; void* m_data; @@ -89,6 +90,7 @@ static gboolean deferred_motion( gpointer data ){ reinterpret_cast( data )->m_function( reinterpret_cast( data )->m_delta_x, reinterpret_cast( data )->m_delta_y, + reinterpret_cast( data )->m_state, reinterpret_cast( data )->m_data ); reinterpret_cast( data )->m_motion_handler = 0; @@ -108,6 +110,7 @@ void flush(){ void motion_delta( int x, int y, unsigned int state ){ m_delta_x += x; m_delta_y += y; + m_state = state; if ( m_motion_handler == 0 ) { m_motion_handler = g_idle_add( deferred_motion, this ); } diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index ed38cf22..cc762a03 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -117,7 +117,16 @@ const Matrix4 g_radiant2opengl( ); struct camera_t; -void Camera_mouseMove( camera_t& camera, int x, int y ); +void Camera_mouseMove( camera_t& camera, int x, int y, unsigned int state ); + +struct MotionDeltaValues { + int x; + int y; + unsigned int state; + MotionDeltaValues( int x_, int y_, unsigned int state_ ): + x( x_ ), y( y_ ), state( state_ ) { + } +}; enum camera_draw_mode { @@ -160,16 +169,18 @@ struct camera_t DeferredMotionDelta m_mouseMove; - static void motionDelta( int x, int y, void* data ){ - Camera_mouseMove( *reinterpret_cast( data ), x, y ); + static void motionDelta( int x, int y, unsigned int state, void* data ){ + Camera_mouseMove( *reinterpret_cast( data ), x, y, state ); } View* m_view; Callback m_update; + Callback1 m_update_motion_freemove; + static camera_draw_mode draw_mode; - camera_t( View* view, const Callback& update ) + camera_t( View* view, const Callback& update, const Callback1& update_motion_freemove ) : width( 0 ), height( 0 ), timing( false ), @@ -181,7 +192,8 @@ struct camera_t m_keymove_handler( 0 ), m_mouseMove( motionDelta, this ), m_view( view ), - m_update( update ){ + m_update( update ), + m_update_motion_freemove( update_motion_freemove ){ } }; @@ -365,9 +377,10 @@ void Cam_MouseControl( camera_t& camera, int x, int y ){ } #endif // 0 -void Camera_mouseMove( camera_t& camera, int x, int y ){ +void Camera_mouseMove( camera_t& camera, int x, int y, unsigned int state ){ //globalOutputStream() << "mousemove... "; Camera_FreeMove( camera, -x, -y ); + camera.m_update_motion_freemove( MotionDeltaValues( x, y, state ) ); camera.m_update(); CameraMovedNotify(); } @@ -728,7 +741,6 @@ XORRectangle m_XORRectangle; DeferredDraw m_deferredDraw; DeferredMotion m_deferred_motion; -DeferredMotion m_deferred_motion_freemove; guint m_selection_button_press_handler; guint m_selection_button_release_handler; @@ -787,6 +799,8 @@ CameraView& getCameraView(){ Timer m_rightClickTimer; +void selection_motion_freemove( const MotionDeltaValues& delta ); + private: void Cam_Draw(); }; @@ -972,21 +986,21 @@ void camwnd_update_xor_rectangle( CamWnd& self, rect_t area ){ gboolean selection_button_press( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ if ( event->type == GDK_BUTTON_PRESS ) { gtk_widget_grab_focus( widget ); - observer->onMouseDown( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); + observer->onMouseDown( WindowVector( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); } return FALSE; } gboolean selection_button_release( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ if ( event->type == GDK_BUTTON_RELEASE ) { - observer->onMouseUp( WindowVector_forDouble( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); + observer->onMouseUp( WindowVector( event->x, event->y ), button_for_button( event->button ), modifiers_for_state( event->state ) ); } return FALSE; } void selection_motion( gdouble x, gdouble y, guint state, void* data ){ //globalOutputStream() << "motion... "; - reinterpret_cast( data )->onMouseMotion( WindowVector_forDouble( x, y ), modifiers_for_state( state ) ); + reinterpret_cast( data )->onMouseMotion( WindowVector( x, y ), modifiers_for_state( state ) ); } inline WindowVector windowvector_for_widget_centre( GtkWidget* widget ){ @@ -1006,18 +1020,13 @@ gboolean selection_button_release_freemove( GtkWidget* widget, GdkEventButton* e } return FALSE; } -#if 0 -gboolean selection_motion_freemove( GtkWidget *widget, GdkEventMotion *event, WindowObserver* observer ){ - observer->onMouseMotion( windowvector_for_widget_centre( widget ), modifiers_for_state( event->state ) ); - return FALSE; -} -#endif -void selection_motion_freemove( gdouble x, gdouble y, guint state, void* data ){ - //globalOutputStream() << "motion... "; - CamWnd* camwnd = reinterpret_cast( data ); - camwnd->m_window_observer->incMouseMove( WindowVector_forDouble( x, y ) ); - camwnd->m_window_observer->onMouseMotion( windowvector_for_widget_centre( camwnd->m_gl_widget ), modifiers_for_state( state ) ); + +void CamWnd::selection_motion_freemove( const MotionDeltaValues& delta ){ + m_window_observer->incMouseMove( WindowVector( delta.x, delta.y ) ); + m_window_observer->onMouseMotion( windowvector_for_widget_centre( m_gl_widget ), modifiers_for_state( delta.state ) ); } +typedef MemberCaller1 CamWnd_selection_motion_freemove; + gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){ //gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget ); @@ -1321,8 +1330,6 @@ void CamWnd_Remove_Handlers_Move( CamWnd& camwnd ){ void CamWnd_Add_Handlers_FreeMove( CamWnd& camwnd ){ camwnd.m_selection_button_press_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_press_event", G_CALLBACK( selection_button_press_freemove ), camwnd.m_window_observer ); camwnd.m_selection_button_release_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_release_event", G_CALLBACK( selection_button_release_freemove ), camwnd.m_window_observer ); - //camwnd.m_selection_motion_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "motion_notify_event", G_CALLBACK( selection_motion_freemove ), camwnd.m_window_observer ); - camwnd.m_selection_motion_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "motion_notify_event", G_CALLBACK( DeferredMotion::gtk_motion ), &camwnd.m_deferred_motion_freemove ); camwnd.m_freelook_button_press_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_press_event", G_CALLBACK( disable_freelook_button_press ), &camwnd ); camwnd.m_freelook_button_release_handler = g_signal_connect( G_OBJECT( camwnd.m_gl_widget ), "button_release_event", G_CALLBACK( disable_freelook_button_release ), &camwnd ); @@ -1361,7 +1368,6 @@ void CamWnd_Remove_Handlers_FreeMove( CamWnd& camwnd ){ g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_press_handler ); g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_button_release_handler ); - g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_selection_motion_handler ); g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_press_handler ); g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_release_handler ); @@ -1369,20 +1375,19 @@ void CamWnd_Remove_Handlers_FreeMove( CamWnd& camwnd ){ CamWnd::CamWnd() : m_view( true ), - m_Camera( &m_view, CamWndQueueDraw( *this ) ), + m_Camera( &m_view, CamWndQueueDraw( *this ), CamWnd_selection_motion_freemove( *this ) ), m_cameraview( m_Camera, &m_view, ReferenceCaller( *this ) ), + m_fbo( 0 ), m_gl_widget( glwidget_new( TRUE ) ), m_window_observer( NewWindowObserver() ), m_deferredDraw( WidgetQueueDrawCaller( *m_gl_widget ) ), m_deferred_motion( selection_motion, m_window_observer ), - m_deferred_motion_freemove( selection_motion_freemove, this ), m_selection_button_press_handler( 0 ), m_selection_button_release_handler( 0 ), m_selection_motion_handler( 0 ), m_freelook_button_press_handler( 0 ), m_freelook_button_release_handler( 0 ), - m_drawing( false ), - m_fbo( 0 ) + m_drawing( false ) { m_bFreeMove = false; diff --git a/radiant/selection.cpp b/radiant/selection.cpp index b6f68565..67b897ad 100644 --- a/radiant/selection.cpp +++ b/radiant/selection.cpp @@ -5518,7 +5518,7 @@ bool mouse_moved_epsilon( const WindowVector& position, const DeviceVector& move } /* support mouse_moved_epsilon with frozen pointer (camera freelook) */ void incMouseMove( const WindowVector& delta ){ - const WindowVector normalized_delta = device( delta ); + const WindowVector normalized_delta( delta.x() * 2.f / m_width, delta.y() * 2.f / m_height ); m_moveEnd -= normalized_delta; if( m_mouse_down ) m_moveStart -= normalized_delta; diff --git a/radiant/windowobservers.h b/radiant/windowobservers.h index eab5fe59..af80136c 100644 --- a/radiant/windowobservers.h +++ b/radiant/windowobservers.h @@ -62,8 +62,4 @@ inline ModifierFlags modifiers_for_state( unsigned int state ){ return modifiers; } -inline WindowVector WindowVector_forDouble( double x, double y ){ - return WindowVector( static_cast( x ), static_cast( y ) ); -} - #endif diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index 1ec52e36..9bc90c6c 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -1504,10 +1504,6 @@ void XYWnd::SetViewType( VIEWTYPE viewType ){ } -inline WindowVector WindowVector_forInteger( int x, int y ){ - return WindowVector( static_cast( x ), static_cast( y ) ); -} - void XYWnd::mouseDown( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){ XY_MouseDown( static_cast( position.x() ), static_cast( position.y() ), buttons_for_button_and_modifiers( button, modifiers ) ); } @@ -1543,7 +1539,7 @@ void XYWnd::XY_MouseDown( int x, int y, unsigned int buttons ){ } else { - m_window_observer->onMouseDown( WindowVector_forInteger( x, y ), button_for_flags( buttons ), modifiers_for_flags( buttons ) ); + m_window_observer->onMouseDown( WindowVector( x, y ), button_for_flags( buttons ), modifiers_for_flags( buttons ) ); } } @@ -1565,12 +1561,12 @@ void XYWnd::XY_MouseUp( int x, int y, unsigned int buttons ){ NewBrushDrag_End( x, y ); if ( m_NewBrushDrag == 0 ) { //L button w/o created brush = tunnel selection - m_window_observer->onMouseUp( WindowVector_forInteger( x, y ), button_for_flags( buttons ), modifiers_for_flags( buttons ) ); + m_window_observer->onMouseUp( WindowVector( x, y ), button_for_flags( buttons ), modifiers_for_flags( buttons ) ); } } else { - m_window_observer->onMouseUp( WindowVector_forInteger( x, y ), button_for_flags( buttons ), modifiers_for_flags( buttons ) ); + m_window_observer->onMouseUp( WindowVector( x, y ), button_for_flags( buttons ), modifiers_for_flags( buttons ) ); } } @@ -1606,7 +1602,7 @@ void XYWnd::XY_MouseMoved( int x, int y, unsigned int buttons ){ else { - m_window_observer->onMouseMotion( WindowVector_forInteger( x, y ), modifiers_for_flags( buttons ) ); + m_window_observer->onMouseMotion( WindowVector( x, y ), modifiers_for_flags( buttons ) ); { m_mousePosition[0] = m_mousePosition[1] = m_mousePosition[2] = 0.0;