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)
This commit is contained in:
Garux 2018-04-17 14:26:49 +03:00
parent 93aef246ea
commit 446ab50511
5 changed files with 42 additions and 42 deletions

View File

@ -80,8 +80,9 @@ class DeferredMotionDelta
{ {
int m_delta_x; int m_delta_x;
int m_delta_y; int m_delta_y;
unsigned int m_state;
guint m_motion_handler; 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; MotionDeltaFunction m_function;
void* m_data; void* m_data;
@ -89,6 +90,7 @@ static gboolean deferred_motion( gpointer data ){
reinterpret_cast<DeferredMotionDelta*>( data )->m_function( reinterpret_cast<DeferredMotionDelta*>( data )->m_function(
reinterpret_cast<DeferredMotionDelta*>( data )->m_delta_x, reinterpret_cast<DeferredMotionDelta*>( data )->m_delta_x,
reinterpret_cast<DeferredMotionDelta*>( data )->m_delta_y, reinterpret_cast<DeferredMotionDelta*>( data )->m_delta_y,
reinterpret_cast<DeferredMotionDelta*>( data )->m_state,
reinterpret_cast<DeferredMotionDelta*>( data )->m_data reinterpret_cast<DeferredMotionDelta*>( data )->m_data
); );
reinterpret_cast<DeferredMotionDelta*>( data )->m_motion_handler = 0; reinterpret_cast<DeferredMotionDelta*>( data )->m_motion_handler = 0;
@ -108,6 +110,7 @@ void flush(){
void motion_delta( int x, int y, unsigned int state ){ void motion_delta( int x, int y, unsigned int state ){
m_delta_x += x; m_delta_x += x;
m_delta_y += y; m_delta_y += y;
m_state = state;
if ( m_motion_handler == 0 ) { if ( m_motion_handler == 0 ) {
m_motion_handler = g_idle_add( deferred_motion, this ); m_motion_handler = g_idle_add( deferred_motion, this );
} }

View File

@ -117,7 +117,16 @@ const Matrix4 g_radiant2opengl(
); );
struct camera_t; 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 enum camera_draw_mode
{ {
@ -160,16 +169,18 @@ struct camera_t
DeferredMotionDelta m_mouseMove; DeferredMotionDelta m_mouseMove;
static void motionDelta( int x, int y, void* data ){ static void motionDelta( int x, int y, unsigned int state, void* data ){
Camera_mouseMove( *reinterpret_cast<camera_t*>( data ), x, y ); Camera_mouseMove( *reinterpret_cast<camera_t*>( data ), x, y, state );
} }
View* m_view; View* m_view;
Callback m_update; Callback m_update;
Callback1<const MotionDeltaValues&> m_update_motion_freemove;
static camera_draw_mode draw_mode; static camera_draw_mode draw_mode;
camera_t( View* view, const Callback& update ) camera_t( View* view, const Callback& update, const Callback1<const MotionDeltaValues&>& update_motion_freemove )
: width( 0 ), : width( 0 ),
height( 0 ), height( 0 ),
timing( false ), timing( false ),
@ -181,7 +192,8 @@ struct camera_t
m_keymove_handler( 0 ), m_keymove_handler( 0 ),
m_mouseMove( motionDelta, this ), m_mouseMove( motionDelta, this ),
m_view( view ), 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 #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... "; //globalOutputStream() << "mousemove... ";
Camera_FreeMove( camera, -x, -y ); Camera_FreeMove( camera, -x, -y );
camera.m_update_motion_freemove( MotionDeltaValues( x, y, state ) );
camera.m_update(); camera.m_update();
CameraMovedNotify(); CameraMovedNotify();
} }
@ -728,7 +741,6 @@ XORRectangle m_XORRectangle;
DeferredDraw m_deferredDraw; DeferredDraw m_deferredDraw;
DeferredMotion m_deferred_motion; DeferredMotion m_deferred_motion;
DeferredMotion m_deferred_motion_freemove;
guint m_selection_button_press_handler; guint m_selection_button_press_handler;
guint m_selection_button_release_handler; guint m_selection_button_release_handler;
@ -787,6 +799,8 @@ CameraView& getCameraView(){
Timer m_rightClickTimer; Timer m_rightClickTimer;
void selection_motion_freemove( const MotionDeltaValues& delta );
private: private:
void Cam_Draw(); 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 ){ gboolean selection_button_press( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){
if ( event->type == GDK_BUTTON_PRESS ) { if ( event->type == GDK_BUTTON_PRESS ) {
gtk_widget_grab_focus( widget ); 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; return FALSE;
} }
gboolean selection_button_release( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){ gboolean selection_button_release( GtkWidget* widget, GdkEventButton* event, WindowObserver* observer ){
if ( event->type == GDK_BUTTON_RELEASE ) { 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; return FALSE;
} }
void selection_motion( gdouble x, gdouble y, guint state, void* data ){ void selection_motion( gdouble x, gdouble y, guint state, void* data ){
//globalOutputStream() << "motion... "; //globalOutputStream() << "motion... ";
reinterpret_cast<WindowObserver*>( data )->onMouseMotion( WindowVector_forDouble( x, y ), modifiers_for_state( state ) ); reinterpret_cast<WindowObserver*>( data )->onMouseMotion( WindowVector( x, y ), modifiers_for_state( state ) );
} }
inline WindowVector windowvector_for_widget_centre( GtkWidget* widget ){ inline WindowVector windowvector_for_widget_centre( GtkWidget* widget ){
@ -1006,18 +1020,13 @@ gboolean selection_button_release_freemove( GtkWidget* widget, GdkEventButton* e
} }
return FALSE; return FALSE;
} }
#if 0
gboolean selection_motion_freemove( GtkWidget *widget, GdkEventMotion *event, WindowObserver* observer ){ void CamWnd::selection_motion_freemove( const MotionDeltaValues& delta ){
observer->onMouseMotion( windowvector_for_widget_centre( widget ), modifiers_for_state( event->state ) ); m_window_observer->incMouseMove( WindowVector( delta.x, delta.y ) );
return FALSE; m_window_observer->onMouseMotion( windowvector_for_widget_centre( m_gl_widget ), modifiers_for_state( delta.state ) );
}
#endif
void selection_motion_freemove( gdouble x, gdouble y, guint state, void* data ){
//globalOutputStream() << "motion... ";
CamWnd* camwnd = reinterpret_cast<CamWnd*>( 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 ) );
} }
typedef MemberCaller1<CamWnd, const MotionDeltaValues&, &CamWnd::selection_motion_freemove> CamWnd_selection_motion_freemove;
gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){ gboolean wheelmove_scroll( GtkWidget* widget, GdkEventScroll* event, CamWnd* camwnd ){
//gtk_window_set_focus( camwnd->m_parent, camwnd->m_gl_widget ); //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 ){ 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_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_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_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 ); 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_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_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_press_handler );
g_signal_handler_disconnect( G_OBJECT( camwnd.m_gl_widget ), camwnd.m_freelook_button_release_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() : CamWnd::CamWnd() :
m_view( true ), 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<CamWnd, CamWnd_Update>( *this ) ), m_cameraview( m_Camera, &m_view, ReferenceCaller<CamWnd, CamWnd_Update>( *this ) ),
m_fbo( 0 ),
m_gl_widget( glwidget_new( TRUE ) ), m_gl_widget( glwidget_new( TRUE ) ),
m_window_observer( NewWindowObserver() ), m_window_observer( NewWindowObserver() ),
m_deferredDraw( WidgetQueueDrawCaller( *m_gl_widget ) ), m_deferredDraw( WidgetQueueDrawCaller( *m_gl_widget ) ),
m_deferred_motion( selection_motion, m_window_observer ), 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_press_handler( 0 ),
m_selection_button_release_handler( 0 ), m_selection_button_release_handler( 0 ),
m_selection_motion_handler( 0 ), m_selection_motion_handler( 0 ),
m_freelook_button_press_handler( 0 ), m_freelook_button_press_handler( 0 ),
m_freelook_button_release_handler( 0 ), m_freelook_button_release_handler( 0 ),
m_drawing( false ), m_drawing( false )
m_fbo( 0 )
{ {
m_bFreeMove = false; m_bFreeMove = false;

View File

@ -5518,7 +5518,7 @@ bool mouse_moved_epsilon( const WindowVector& position, const DeviceVector& move
} }
/* support mouse_moved_epsilon with frozen pointer (camera freelook) */ /* support mouse_moved_epsilon with frozen pointer (camera freelook) */
void incMouseMove( const WindowVector& delta ){ 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; m_moveEnd -= normalized_delta;
if( m_mouse_down ) if( m_mouse_down )
m_moveStart -= normalized_delta; m_moveStart -= normalized_delta;

View File

@ -62,8 +62,4 @@ inline ModifierFlags modifiers_for_state( unsigned int state ){
return modifiers; return modifiers;
} }
inline WindowVector WindowVector_forDouble( double x, double y ){
return WindowVector( static_cast<float>( x ), static_cast<float>( y ) );
}
#endif #endif

View File

@ -1504,10 +1504,6 @@ void XYWnd::SetViewType( VIEWTYPE viewType ){
} }
inline WindowVector WindowVector_forInteger( int x, int y ){
return WindowVector( static_cast<float>( x ), static_cast<float>( y ) );
}
void XYWnd::mouseDown( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){ void XYWnd::mouseDown( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){
XY_MouseDown( static_cast<int>( position.x() ), static_cast<int>( position.y() ), buttons_for_button_and_modifiers( button, modifiers ) ); XY_MouseDown( static_cast<int>( position.x() ), static_cast<int>( 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 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 ); NewBrushDrag_End( x, y );
if ( m_NewBrushDrag == 0 ) { if ( m_NewBrushDrag == 0 ) {
//L button w/o created brush = tunnel selection //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 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 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; m_mousePosition[0] = m_mousePosition[1] = m_mousePosition[2] = 0.0;