diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 36a892127d..9ea245de1c 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -156,6 +156,7 @@ class WXDLLEXPORT wxCursor; class WXDLLEXPORT wxFont; class WXDLLEXPORT wxPalette; class WXDLLEXPORT wxPalette; +class WXDLLEXPORT wxRegion; /* * Bitmap flags @@ -302,6 +303,9 @@ WXDLLEXPORT_DATA(extern wxBrush) wxNullBrush; WXDLLEXPORT_DATA(extern wxPalette) wxNullPalette; WXDLLEXPORT_DATA(extern wxFont) wxNullFont; WXDLLEXPORT_DATA(extern wxColour) wxNullColour; +#ifdef __WXGTK__ +WXDLLEXPORT_DATA(extern wxRegion) wxNullRegion; +#endif // Stock cursors types WXDLLEXPORT_DATA(extern wxCursor*) wxSTANDARD_CURSOR; diff --git a/include/wx/gtk/region.h b/include/wx/gtk/region.h index 33af4087c3..b61066a208 100644 --- a/include/wx/gtk/region.h +++ b/include/wx/gtk/region.h @@ -63,6 +63,9 @@ class wxRegion : public wxGDIObject inline wxRegion& operator = ( const wxRegion& r ) { Ref(r); return (*this); } + bool operator == ( const wxRegion& region ); + bool operator != ( const wxRegion& region ); + void Clear(void); bool Union( long x, long y, long width, long height ); diff --git a/include/wx/gtk1/region.h b/include/wx/gtk1/region.h index 33af4087c3..b61066a208 100644 --- a/include/wx/gtk1/region.h +++ b/include/wx/gtk1/region.h @@ -63,6 +63,9 @@ class wxRegion : public wxGDIObject inline wxRegion& operator = ( const wxRegion& r ) { Ref(r); return (*this); } + bool operator == ( const wxRegion& region ); + bool operator != ( const wxRegion& region ); + void Clear(void); bool Union( long x, long y, long width, long height ); diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp index ee3811f915..290aeddf66 100644 --- a/src/common/prntbase.cpp +++ b/src/common/prntbase.cpp @@ -189,7 +189,7 @@ wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent, m_printPreview = preview; SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); - SetScrollbars(40, 40, 100, 100); + SetScrollbars(15, 18, 100, 100); } wxPreviewCanvas::~wxPreviewCanvas() @@ -705,13 +705,23 @@ bool wxPrintPreviewBase::DrawBlankPage(wxWindow *canvas, wxDC& dc) int shadowOffset = 4; dc.SetPen(*wxBLACK_PEN); dc.SetBrush(*wxBLACK_BRUSH); +/* dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2)); +*/ + dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight), (int)(actualWidth), shadowOffset); + dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight)); // Draw blank page allowing for 1-pixel border AROUND the actual page dc.SetPen(*wxBLACK_PEN); dc.SetBrush(*wxWHITE_BRUSH); - +/* + wxRegion update_region = canvas->GetUpdateRegion(); + wxRect r = update_region.GetBox(); + + printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height ); +*/ + dc.DrawRectangle((int)(x-1), (int)(y-1), (int)(actualWidth+2), (int)(actualHeight+2)); return TRUE; diff --git a/src/gtk/data.cpp b/src/gtk/data.cpp index 3d9ae3d037..42e8ea7018 100644 --- a/src/gtk/data.cpp +++ b/src/gtk/data.cpp @@ -46,6 +46,9 @@ wxCursor *g_globalCursor = (wxCursor *) NULL; // Don't allow event propagation during drag bool g_blockEventsOnDrag = FALSE; +// Don't allow mouse event propagation during scroll +bool g_blockEventsOnScroll = FALSE; + // Message Strings for Internationalization char **wx_msg_str = (char**)NULL; @@ -121,6 +124,7 @@ wxBrush wxNullBrush; wxFont wxNullFont; wxColour wxNullColour; wxPalette wxNullPalette; +wxRegion wxNullRegion; // Default window names const char *wxButtonNameStr = "button"; diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 854f5d07f5..58232ab959 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -115,6 +115,14 @@ wxPaintDC::wxPaintDC( wxWindow *window ) m_isMemDC = FALSE; SetUpDC(); + + wxRegion update = window->GetUpdateRegion(); + if (update == wxNullRegion) return; + + gdk_gc_set_clip_region( m_penGC, update.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, update.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, update.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, update.GetRegion() ); } wxPaintDC::~wxPaintDC(void) diff --git a/src/gtk/region.cpp b/src/gtk/region.cpp index 5e199e76a0..a01289855b 100644 --- a/src/gtk/region.cpp +++ b/src/gtk/region.cpp @@ -114,6 +114,16 @@ wxRegion::~wxRegion(void) { } +bool wxRegion::operator == ( const wxRegion& region ) +{ + return m_refData == region.m_refData; +} + +bool wxRegion::operator != ( const wxRegion& region ) +{ + return m_refData != region.m_refData; +} + void wxRegion::Clear(void) { UnRef(); diff --git a/src/gtk/scrolbar.cpp b/src/gtk/scrolbar.cpp index 312985e972..b0987af6b3 100644 --- a/src/gtk/scrolbar.cpp +++ b/src/gtk/scrolbar.cpp @@ -21,6 +21,7 @@ //----------------------------------------------------------------------------- extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; //----------------------------------------------------------------------------- // "value_changed" @@ -39,13 +40,20 @@ static void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *wi float line_step = win->m_adjust->step_increment; float page_step = win->m_adjust->page_increment; - if (fabs(win->m_adjust->value-win->m_adjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; - else if (fabs(win->m_adjust->value-win->m_adjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; - else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; - else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; - else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; - else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; - else command = wxEVT_SCROLL_THUMBTRACK; + if (win->m_isScrolling) + { + command = wxEVT_SCROLL_THUMBTRACK; + } + else + { + if (fabs(win->m_adjust->value-win->m_adjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; + else if (fabs(win->m_adjust->value-win->m_adjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; + else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; + else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; + else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; + else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; + else command = wxEVT_SCROLL_THUMBTRACK; + } int value = (int)(win->m_adjust->value+0.5); @@ -67,11 +75,12 @@ static void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *wi // "button_press_event" from slider //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButton *gdk_event, wxScrollBar *win ) +static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget), + GdkEventButton *WXUNUSED(gdk_event), + wxScrollBar *win ) { - if (gdk_event->window != widget->slider) return FALSE; - win->m_isScrolling = TRUE; + g_blockEventsOnScroll = TRUE; return FALSE; } @@ -80,14 +89,15 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButto // "button_release_event" from slider //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventButton *gdk_event, wxScrollBar *win ) +static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget), + GdkEventButton *WXUNUSED(gdk_event), + wxScrollBar *win ) { - if (gdk_event->window != widget->slider) return FALSE; - + win->m_isScrolling = FALSE; + g_blockEventsOnScroll = FALSE; + gtk_signal_emit_by_name( GTK_OBJECT(win->m_adjust), "value_changed" ); - win->m_isScrolling = FALSE; - return FALSE; } @@ -164,13 +174,14 @@ int wxScrollBar::GetRange() const void wxScrollBar::SetPosition( int viewStart ) { + if (m_isScrolling) return; + float fpos = (float)viewStart; m_oldPos = fpos; if (fabs(fpos-m_adjust->value) < 0.2) return; m_adjust->value = fpos; - - if (!m_isScrolling) - gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" ); + + gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" ); } void wxScrollBar::SetScrollbar( int position, int thumbSize, int range, int pageSize, diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index b2b8e025a8..e452bbd119 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -126,6 +126,7 @@ extern wxList wxPendingDelete; extern wxList wxTopLevelWindows; extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; static bool g_capturing = FALSE; // hack: we need something to pass to gtk_menu_popup, so we store the time of @@ -322,6 +323,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE; if (g_blockEventsOnDrag) return TRUE; + if (g_blockEventsOnScroll) return TRUE; if (win->m_wxwindow) { @@ -432,6 +434,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE; if (g_blockEventsOnDrag) return TRUE; + if (g_blockEventsOnScroll) return TRUE; if (!win->HasVMT()) return TRUE; @@ -502,7 +505,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE; if (g_blockEventsOnDrag) return TRUE; - + if (g_blockEventsOnScroll) return TRUE; + if (!win->HasVMT()) return TRUE; /* @@ -714,13 +718,20 @@ static void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow * float line_step = win->m_vAdjust->step_increment; float page_step = win->m_vAdjust->page_increment; - if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; - else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; - else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; - else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; - else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; - else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; - else command = wxEVT_SCROLL_THUMBTRACK; + if (win->m_isScrolling) + { + command = wxEVT_SCROLL_THUMBTRACK; + } + else + { + if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; + else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; + else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; + else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; + else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; + else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; + else command = wxEVT_SCROLL_THUMBTRACK; + } int value = (int)(win->m_vAdjust->value+0.5); @@ -754,13 +765,20 @@ static void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow * float line_step = win->m_hAdjust->step_increment; float page_step = win->m_hAdjust->page_increment; - if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; - else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; - else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; - else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; - else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; - else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; - else command = wxEVT_SCROLL_THUMBTRACK; + if (win->m_isScrolling) + { + command = wxEVT_SCROLL_THUMBTRACK; + } + else + { + if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; + else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; + else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; + else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; + else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; + else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; + else command = wxEVT_SCROLL_THUMBTRACK; + } int value = (int)(win->m_hAdjust->value+0.5); @@ -823,11 +841,14 @@ static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW // "button_press_event" from scrollbar //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButton *gdk_event, wxWindow *win ) +static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget), + GdkEventButton *WXUNUSED(gdk_event), + wxWindow *win ) { - if (gdk_event->window != widget->slider) return FALSE; - +// if (gdk_event->window != widget->slider) return FALSE; + win->m_isScrolling = TRUE; + g_blockEventsOnScroll = TRUE; return FALSE; } @@ -836,9 +857,15 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButto // "button_release_event" from scrollbar //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventButton *gdk_event, wxWindow *win ) +static gint gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindow *win ) { - if (gdk_event->window != widget->slider) return FALSE; + +// don't test here as we can reelase the mouse while being over +// a different window then the slider +// +// if (gdk_event->window != widget->slider) return FALSE; GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(win->m_widget); @@ -848,6 +875,7 @@ static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventBut gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" ); win->m_isScrolling = FALSE; + g_blockEventsOnScroll = FALSE; return FALSE; } @@ -970,18 +998,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget); - gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); scroll_class->scrollbar_spacing = 0; @@ -993,16 +1009,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) ); m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) ); - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", - (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); - gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", - (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed", - (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this ); - gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed", - (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this ); - m_wxwindow = gtk_myfixed_new(); #ifdef NEW_GTK_SCROLL_CODE @@ -1051,6 +1057,36 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_hAdjust->page_size = 5.0; gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + // 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(s_window->vscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + + // these handers het notified when screen updates are required either when + // scrolling or when the window size (and therefore scrollbar configuration) + // has changed + + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", + (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); + gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", + (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed", + (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this ); + gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed", + (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this ); + gtk_widget_show( m_wxwindow ); if (m_parent) m_parent->AddChild( this ); diff --git a/src/gtk1/data.cpp b/src/gtk1/data.cpp index 3d9ae3d037..42e8ea7018 100644 --- a/src/gtk1/data.cpp +++ b/src/gtk1/data.cpp @@ -46,6 +46,9 @@ wxCursor *g_globalCursor = (wxCursor *) NULL; // Don't allow event propagation during drag bool g_blockEventsOnDrag = FALSE; +// Don't allow mouse event propagation during scroll +bool g_blockEventsOnScroll = FALSE; + // Message Strings for Internationalization char **wx_msg_str = (char**)NULL; @@ -121,6 +124,7 @@ wxBrush wxNullBrush; wxFont wxNullFont; wxColour wxNullColour; wxPalette wxNullPalette; +wxRegion wxNullRegion; // Default window names const char *wxButtonNameStr = "button"; diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 854f5d07f5..58232ab959 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -115,6 +115,14 @@ wxPaintDC::wxPaintDC( wxWindow *window ) m_isMemDC = FALSE; SetUpDC(); + + wxRegion update = window->GetUpdateRegion(); + if (update == wxNullRegion) return; + + gdk_gc_set_clip_region( m_penGC, update.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, update.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, update.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, update.GetRegion() ); } wxPaintDC::~wxPaintDC(void) diff --git a/src/gtk1/region.cpp b/src/gtk1/region.cpp index 5e199e76a0..a01289855b 100644 --- a/src/gtk1/region.cpp +++ b/src/gtk1/region.cpp @@ -114,6 +114,16 @@ wxRegion::~wxRegion(void) { } +bool wxRegion::operator == ( const wxRegion& region ) +{ + return m_refData == region.m_refData; +} + +bool wxRegion::operator != ( const wxRegion& region ) +{ + return m_refData != region.m_refData; +} + void wxRegion::Clear(void) { UnRef(); diff --git a/src/gtk1/scrolbar.cpp b/src/gtk1/scrolbar.cpp index 312985e972..b0987af6b3 100644 --- a/src/gtk1/scrolbar.cpp +++ b/src/gtk1/scrolbar.cpp @@ -21,6 +21,7 @@ //----------------------------------------------------------------------------- extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; //----------------------------------------------------------------------------- // "value_changed" @@ -39,13 +40,20 @@ static void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *wi float line_step = win->m_adjust->step_increment; float page_step = win->m_adjust->page_increment; - if (fabs(win->m_adjust->value-win->m_adjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; - else if (fabs(win->m_adjust->value-win->m_adjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; - else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; - else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; - else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; - else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; - else command = wxEVT_SCROLL_THUMBTRACK; + if (win->m_isScrolling) + { + command = wxEVT_SCROLL_THUMBTRACK; + } + else + { + if (fabs(win->m_adjust->value-win->m_adjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; + else if (fabs(win->m_adjust->value-win->m_adjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; + else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; + else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; + else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; + else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; + else command = wxEVT_SCROLL_THUMBTRACK; + } int value = (int)(win->m_adjust->value+0.5); @@ -67,11 +75,12 @@ static void gtk_scrollbar_callback( GtkWidget *WXUNUSED(widget), wxScrollBar *wi // "button_press_event" from slider //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButton *gdk_event, wxScrollBar *win ) +static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget), + GdkEventButton *WXUNUSED(gdk_event), + wxScrollBar *win ) { - if (gdk_event->window != widget->slider) return FALSE; - win->m_isScrolling = TRUE; + g_blockEventsOnScroll = TRUE; return FALSE; } @@ -80,14 +89,15 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButto // "button_release_event" from slider //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventButton *gdk_event, wxScrollBar *win ) +static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget), + GdkEventButton *WXUNUSED(gdk_event), + wxScrollBar *win ) { - if (gdk_event->window != widget->slider) return FALSE; - + win->m_isScrolling = FALSE; + g_blockEventsOnScroll = FALSE; + gtk_signal_emit_by_name( GTK_OBJECT(win->m_adjust), "value_changed" ); - win->m_isScrolling = FALSE; - return FALSE; } @@ -164,13 +174,14 @@ int wxScrollBar::GetRange() const void wxScrollBar::SetPosition( int viewStart ) { + if (m_isScrolling) return; + float fpos = (float)viewStart; m_oldPos = fpos; if (fabs(fpos-m_adjust->value) < 0.2) return; m_adjust->value = fpos; - - if (!m_isScrolling) - gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" ); + + gtk_signal_emit_by_name( GTK_OBJECT(m_adjust), "value_changed" ); } void wxScrollBar::SetScrollbar( int position, int thumbSize, int range, int pageSize, diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index b2b8e025a8..e452bbd119 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -126,6 +126,7 @@ extern wxList wxPendingDelete; extern wxList wxTopLevelWindows; extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; static bool g_capturing = FALSE; // hack: we need something to pass to gtk_menu_popup, so we store the time of @@ -322,6 +323,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE; if (g_blockEventsOnDrag) return TRUE; + if (g_blockEventsOnScroll) return TRUE; if (win->m_wxwindow) { @@ -432,6 +434,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE; if (g_blockEventsOnDrag) return TRUE; + if (g_blockEventsOnScroll) return TRUE; if (!win->HasVMT()) return TRUE; @@ -502,7 +505,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE; if (g_blockEventsOnDrag) return TRUE; - + if (g_blockEventsOnScroll) return TRUE; + if (!win->HasVMT()) return TRUE; /* @@ -714,13 +718,20 @@ static void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow * float line_step = win->m_vAdjust->step_increment; float page_step = win->m_vAdjust->page_increment; - if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; - else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; - else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; - else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; - else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; - else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; - else command = wxEVT_SCROLL_THUMBTRACK; + if (win->m_isScrolling) + { + command = wxEVT_SCROLL_THUMBTRACK; + } + else + { + if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; + else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; + else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; + else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; + else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; + else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; + else command = wxEVT_SCROLL_THUMBTRACK; + } int value = (int)(win->m_vAdjust->value+0.5); @@ -754,13 +765,20 @@ static void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow * float line_step = win->m_hAdjust->step_increment; float page_step = win->m_hAdjust->page_increment; - if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; - else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; - else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; - else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; - else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; - else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; - else command = wxEVT_SCROLL_THUMBTRACK; + if (win->m_isScrolling) + { + command = wxEVT_SCROLL_THUMBTRACK; + } + else + { + if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM; + else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP; + else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN; + else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP; + else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN; + else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP; + else command = wxEVT_SCROLL_THUMBTRACK; + } int value = (int)(win->m_hAdjust->value+0.5); @@ -823,11 +841,14 @@ static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW // "button_press_event" from scrollbar //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButton *gdk_event, wxWindow *win ) +static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget), + GdkEventButton *WXUNUSED(gdk_event), + wxWindow *win ) { - if (gdk_event->window != widget->slider) return FALSE; - +// if (gdk_event->window != widget->slider) return FALSE; + win->m_isScrolling = TRUE; + g_blockEventsOnScroll = TRUE; return FALSE; } @@ -836,9 +857,15 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButto // "button_release_event" from scrollbar //----------------------------------------------------------------------------- -static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventButton *gdk_event, wxWindow *win ) +static gint gtk_scrollbar_button_release_callback( GtkRange *widget, + GdkEventButton *WXUNUSED(gdk_event), + wxWindow *win ) { - if (gdk_event->window != widget->slider) return FALSE; + +// don't test here as we can reelase the mouse while being over +// a different window then the slider +// +// if (gdk_event->window != widget->slider) return FALSE; GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(win->m_widget); @@ -848,6 +875,7 @@ static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventBut gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" ); win->m_isScrolling = FALSE; + g_blockEventsOnScroll = FALSE; return FALSE; } @@ -970,18 +998,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget); - gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event", - (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event", - (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); scroll_class->scrollbar_spacing = 0; @@ -993,16 +1009,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) ); m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) ); - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", - (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); - gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", - (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); - - gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed", - (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this ); - gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed", - (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this ); - m_wxwindow = gtk_myfixed_new(); #ifdef NEW_GTK_SCROLL_CODE @@ -1051,6 +1057,36 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_hAdjust->page_size = 5.0; gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" ); + // 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(s_window->vscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event", + (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event", + (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this ); + + // these handers het notified when screen updates are required either when + // scrolling or when the window size (and therefore scrollbar configuration) + // has changed + + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed", + (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this ); + gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed", + (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this ); + + gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed", + (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this ); + gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed", + (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this ); + gtk_widget_show( m_wxwindow ); if (m_parent) m_parent->AddChild( this );