X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3b3dc8019a520ce5e166c8ae9098ba020f8b3f94..a9c11b71e345859fc8d44e0565c49e90ed3be668:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index ee7f1f9f46..b7ab6c34c8 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -24,16 +24,17 @@ #include "wx/frame.h" #include "wx/dcclient.h" #include "wx/menu.h" + #include "wx/dialog.h" + #include "wx/settings.h" + #include "wx/msgdlg.h" + #include "wx/textctrl.h" + #include "wx/toolbar.h" + #include "wx/combobox.h" + #include "wx/layout.h" + #include "wx/statusbr.h" #endif -#include "wx/layout.h" -#include "wx/dialog.h" -#include "wx/msgdlg.h" #include "wx/module.h" -#include "wx/combobox.h" -#if wxUSE_TOOLBAR_NATIVE -#include "wx/toolbar.h" -#endif #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -47,12 +48,6 @@ #include "wx/caret.h" #endif // wxUSE_CARET -#if wxUSE_TEXTCTRL - #include "wx/textctrl.h" -#endif - -#include "wx/statusbr.h" -#include "wx/settings.h" #include "wx/fontutil.h" #ifdef __WXDEBUG__ @@ -220,7 +215,6 @@ extern GtkContainerClass *pizza_parent_class; // data //----------------------------------------------------------------------------- -extern wxList wxPendingDelete; extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; @@ -2107,9 +2101,12 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win) // Convert scroll event type to scrollwin event type eventType += wxEVT_SCROLLWIN_TOP - wxEVT_SCROLL_TOP; const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL; + const int i = orient == wxVERTICAL; wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient); event.SetEventObject(win); + win->m_blockValueChanged[i] = true; win->GetEventHandler()->ProcessEvent(event); + win->m_blockValueChanged[i] = false; } } } @@ -2134,6 +2131,26 @@ gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win) } } +//----------------------------------------------------------------------------- +// "event_after" from scrollbar +//----------------------------------------------------------------------------- + +extern "C" { +static void +gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win) +{ + if (event->type == GDK_BUTTON_RELEASE) + { + g_signal_handlers_block_by_func(range, (void*)gtk_scrollbar_event_after, win); + + const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL; + wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient); + event.SetEventObject(win); + win->GetEventHandler()->ProcessEvent(event); + } +} +} + //----------------------------------------------------------------------------- // "button_release_event" from scrollbar //----------------------------------------------------------------------------- @@ -2150,10 +2167,10 @@ gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* w if (win->m_isScrolling) { win->m_isScrolling = false; - const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL; - wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient); - event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event); + // Hook up handler to send thumb release event after this emission is finished. + // To allow setting scroll position from event handler, sending event must + // be deferred until after the GtkRange handler for this signal has run + g_signal_handlers_unblock_by_func(range, (void*)gtk_scrollbar_event_after, win); } return false; @@ -2462,6 +2479,8 @@ void wxWindowGTK::Init() m_scrollBar[1] = NULL; m_scrollPos[0] = m_scrollPos[1] = 0; + m_blockValueChanged[0] = + m_blockValueChanged[1] = false; m_oldClientWidth = m_oldClientHeight = 0; @@ -2568,6 +2587,13 @@ bool wxWindowGTK::Create( wxWindow *parent, G_CALLBACK(gtk_scrollbar_button_release_event), this); g_signal_connect(m_scrollBar[1], "button_release_event", G_CALLBACK(gtk_scrollbar_button_release_event), this); + gulong handler_id; + handler_id = g_signal_connect( + m_scrollBar[0], "event_after", G_CALLBACK(gtk_scrollbar_event_after), this); + g_signal_handler_block(m_scrollBar[0], handler_id); + handler_id = g_signal_connect( + m_scrollBar[1], "event_after", G_CALLBACK(gtk_scrollbar_event_after), this); + g_signal_handler_block(m_scrollBar[1], handler_id); // these handlers get notified when scrollbar slider moves @@ -2746,6 +2772,15 @@ void wxWindowGTK::PostCreation() G_CALLBACK (wxgtk_combo_size_request_callback), this); } +#ifdef GTK_IS_FILE_CHOOSER_BUTTON + else if (GTK_IS_FILE_CHOOSER_BUTTON(m_widget)) + { + // If we connect to the "size_request" signal of a GtkFileChooserButton + // then that control won't be sized properly when placed inside sizers + // (this can be tested removing this elseif and running XRC or WIDGETS samples) + // FIXME: what should be done here ? + } +#endif else { // This is needed if we want to add our windows into native @@ -3743,6 +3778,14 @@ void wxWindowGTK::GtkSendPaintEvents() m_updateRegion.Clear(); } +void wxWindowGTK::SetDoubleBuffered( bool on ) +{ + wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); + + if ( m_wxwindow ) + gtk_widget_set_double_buffered( m_wxwindow, on ); +} + void wxWindowGTK::ClearBackground() { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); @@ -4068,18 +4111,18 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible, thumbVisible = 1; } + if (pos > range - thumbVisible) + pos = range - thumbVisible; + if (pos < 0) + pos = 0; const int i = orient == wxVERTICAL; GtkAdjustment* adj = m_scrollBar[i]->adjustment; - adj->value = pos; adj->step_increment = 1; adj->page_increment = adj->page_size = thumbVisible; - - BlockScrollEvent(); - // automatically clamps value to [0,range-page_size], and emits change events - gtk_range_set_range(m_scrollBar[i], 0, range); - UnblockScrollEvent(); - m_scrollPos[i] = adj->value; + adj->upper = range; + SetScrollPos(orient, pos); + gtk_adjustment_changed(adj); } void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) ) @@ -4092,10 +4135,19 @@ void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) ) if (GetScrollPos(orient) != pos) { const int i = orient == wxVERTICAL; - BlockScrollEvent(); - gtk_range_set_value(m_scrollBar[i], pos); - UnblockScrollEvent(); - m_scrollPos[i] = m_scrollBar[i]->adjustment->value; + GtkAdjustment* adj = m_scrollBar[i]->adjustment; + const int max = int(adj->upper - adj->page_size); + if (pos > max) + pos = max; + if (pos < 0) + pos = 0; + m_scrollPos[i] = + adj->value = pos; + // If a "value_changed" signal emission is not already in progress + if (!m_blockValueChanged[i]) + { + gtk_adjustment_value_changed(adj); + } } } @@ -4135,7 +4187,7 @@ static inline bool IsScrollIncrement(double increment, double x) return fabs(increment - fabs(x)) < tolerance; } -wxEventType wxWindow::GetScrollEventType(GtkRange* range) +wxEventType wxWindowGTK::GetScrollEventType(GtkRange* range) { DEBUG_MAIN_THREAD @@ -4152,7 +4204,7 @@ wxEventType wxWindow::GetScrollEventType(GtkRange* range) // update current position m_scrollPos[barIndex] = adj->value; // If event should be ignored, or integral position has not changed - if (!m_hasVMT || g_blockEventsOnDrag || m_blockScrollEvent || value == int(oldPos + 0.5)) + if (!m_hasVMT || g_blockEventsOnDrag || value == int(oldPos + 0.5)) { return wxEVT_NULL; }