From cf19b0bd2567b4c3b2a6f9b60587909a7c784a98 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 5 Aug 2001 21:40:30 +0000 Subject: [PATCH] Patch that should prevent problem with interference between dragging the scrollbat thumb and normal mouse events. Also, thumb-release event are now sent from wxScrollWindow. Neither has been tested, but the same code works in wxWindow. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11287 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/scrolwin.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++ src/gtk1/scrolwin.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) diff --git a/src/gtk/scrolwin.cpp b/src/gtk/scrolwin.cpp index 4a5737f0ba..46cefd3e0f 100644 --- a/src/gtk/scrolwin.cpp +++ b/src/gtk/scrolwin.cpp @@ -59,6 +59,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel) //----------------------------------------------------------------------------- extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; //----------------------------------------------------------------------------- // idle system @@ -98,6 +99,66 @@ static void gtk_scrolled_window_hscroll_callback( GtkAdjustment *adjust, wxScrol win->GtkHScroll( adjust->value ); } +//----------------------------------------------------------------------------- +// "button_press_event" from scrollbar +//----------------------------------------------------------------------------- + +static gint gtk_scrollbar_button_press_callback( GtkRange *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + g_blockEventsOnScroll = TRUE; + win->m_isScrolling = (gdk_event->window == widget->slider); + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "button_release_event" from scrollbar +//----------------------------------------------------------------------------- + +static gint gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindowGTK *win) +{ +// don't test here as we can release the mouse while being over +// a different window than the slider +// +// if (gdk_event->window != widget->slider) return FALSE; + + g_blockEventsOnScroll = FALSE; + + if (win->m_isScrolling) + { + wxEventType command = wxEVT_SCROLLWIN_THUMBRELEASE; + int value = -1; + int dir = -1; + + GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget); + if (widget == GTK_RANGE(scrolledWindow->hscrollbar)) + { + value = (int)(win->m_hAdjust->value+0.5); + dir = wxHORIZONTAL; + } + if (widget == GTK_RANGE(scrolledWindow->vscrollbar)) + { + value = (int)(win->m_vAdjust->value+0.5); + dir = wxVERTICAL; + } + + wxScrollWinEvent event( command, value, dir ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + } + + win->m_isScrolling = FALSE; + + return FALSE; +} + //----------------------------------------------------------------------------- // InsertChild for wxScrolledWindow //----------------------------------------------------------------------------- @@ -217,6 +278,22 @@ bool wxScrolledWindow::Create(wxWindow *parent, GtkVConnectEvent(); GtkHConnectEvent(); + // these handlers block mouse events to any window during scrolling such as + // motion events and prevent GTK and wxWindows from fighting over where the + // slider should be + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + gtk_widget_show( m_wxwindow ); if (m_parent) diff --git a/src/gtk1/scrolwin.cpp b/src/gtk1/scrolwin.cpp index 4a5737f0ba..46cefd3e0f 100644 --- a/src/gtk1/scrolwin.cpp +++ b/src/gtk1/scrolwin.cpp @@ -59,6 +59,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel) //----------------------------------------------------------------------------- extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; //----------------------------------------------------------------------------- // idle system @@ -98,6 +99,66 @@ static void gtk_scrolled_window_hscroll_callback( GtkAdjustment *adjust, wxScrol win->GtkHScroll( adjust->value ); } +//----------------------------------------------------------------------------- +// "button_press_event" from scrollbar +//----------------------------------------------------------------------------- + +static gint gtk_scrollbar_button_press_callback( GtkRange *widget, + GdkEventButton *gdk_event, + wxWindowGTK *win) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + g_blockEventsOnScroll = TRUE; + win->m_isScrolling = (gdk_event->window == widget->slider); + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "button_release_event" from scrollbar +//----------------------------------------------------------------------------- + +static gint gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindowGTK *win) +{ +// don't test here as we can release the mouse while being over +// a different window than the slider +// +// if (gdk_event->window != widget->slider) return FALSE; + + g_blockEventsOnScroll = FALSE; + + if (win->m_isScrolling) + { + wxEventType command = wxEVT_SCROLLWIN_THUMBRELEASE; + int value = -1; + int dir = -1; + + GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget); + if (widget == GTK_RANGE(scrolledWindow->hscrollbar)) + { + value = (int)(win->m_hAdjust->value+0.5); + dir = wxHORIZONTAL; + } + if (widget == GTK_RANGE(scrolledWindow->vscrollbar)) + { + value = (int)(win->m_vAdjust->value+0.5); + dir = wxVERTICAL; + } + + wxScrollWinEvent event( command, value, dir ); + event.SetEventObject( win ); + win->GetEventHandler()->ProcessEvent( event ); + } + + win->m_isScrolling = FALSE; + + return FALSE; +} + //----------------------------------------------------------------------------- // InsertChild for wxScrolledWindow //----------------------------------------------------------------------------- @@ -217,6 +278,22 @@ bool wxScrolledWindow::Create(wxWindow *parent, GtkVConnectEvent(); GtkHConnectEvent(); + // these handlers block mouse events to any window during scrolling such as + // motion events and prevent GTK and wxWindows from fighting over where the + // slider should be + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + gtk_widget_show( m_wxwindow ); if (m_parent) -- 2.45.2