X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5b34e141062f3ea9ef676e4202dda7ca4065d1b3..1fe0a566bbf649efe7cadc21e8ded82458c8bdc6:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 1f6fb8ba13..e9ba04cdfe 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -27,15 +27,15 @@ #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" + #include "wx/math.h" #endif -#include "wx/layout.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" @@ -49,18 +49,12 @@ #include "wx/caret.h" #endif // wxUSE_CARET -#if wxUSE_TEXTCTRL - #include "wx/textctrl.h" -#endif - -#include "wx/statusbr.h" #include "wx/fontutil.h" #ifdef __WXDEBUG__ #include "wx/thread.h" #endif -#include "wx/math.h" #include // FIXME: Due to a hack we use GtkCombo in here, which is deprecated since gtk2.3.0 @@ -537,6 +531,18 @@ gtk_window_expose_callback( GtkWidget *widget, // "key_press_event" from any window //----------------------------------------------------------------------------- +// These are used when transforming Ctrl-alpha to ascii values 1-26 +inline bool wxIsLowerChar(int code) +{ + return (code >= 'a' && code <= 'z' ); +} + +inline bool wxIsUpperChar(int code) +{ + return (code >= 'A' && code <= 'Z' ); +} + + // set WXTRACE to this to see the key event codes on the console #define TRACE_KEYS _T("keyevent") @@ -1088,9 +1094,13 @@ gtk_window_key_press_callback( GtkWidget *widget, // To conform to the docs we need to translate Ctrl-alpha // characters to values in the range 1-26. - if (event.ControlDown() && key_code >= 'a' && key_code <= 'z' ) + if ( event.ControlDown() && + ( wxIsLowerChar(key_code) || wxIsUpperChar(key_code) )) { - event.m_keyCode = key_code - 'a' + 1; + if ( wxIsLowerChar(key_code) ) + event.m_keyCode = key_code - 'a' + 1; + if ( wxIsUpperChar(key_code) ) + event.m_keyCode = key_code - 'A' + 1; #if wxUSE_UNICODE event.m_uniChar = event.m_keyCode; #endif @@ -1229,8 +1239,14 @@ gtk_wxwindow_commit_cb (GtkIMContext *context, // To conform to the docs we need to translate Ctrl-alpha // characters to values in the range 1-26. - if (event.ControlDown() && *pstr >= 'a' && *pstr <= 'z' ) + if ( event.ControlDown() && + ( wxIsLowerChar(*pstr) || wxIsUpperChar(*pstr) )) { + if ( wxIsLowerChar(*pstr) ) + event.m_keyCode = *pstr - 'a' + 1; + if ( wxIsUpperChar(*pstr) ) + event.m_keyCode = *pstr - 'A' + 1; + event.m_keyCode = *pstr - 'a' + 1; #if wxUSE_UNICODE event.m_uniChar = event.m_keyCode; @@ -2107,9 +2123,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 +2153,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 +2189,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 +2501,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 +2609,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 @@ -2749,6 +2797,9 @@ void wxWindowGTK::PostCreation() #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 @@ -3846,7 +3897,7 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle(bool forceStyle) if ( m_foregroundColour.Ok() ) { - GdkColor *fg = m_foregroundColour.GetColor(); + const GdkColor *fg = m_foregroundColour.GetColor(); style->fg[GTK_STATE_NORMAL] = *fg; style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG; @@ -3860,7 +3911,7 @@ GtkRcStyle *wxWindowGTK::CreateWidgetStyle(bool forceStyle) if ( m_backgroundColour.Ok() ) { - GdkColor *bg = m_backgroundColour.GetColor(); + const GdkColor *bg = m_backgroundColour.GetColor(); style->bg[GTK_STATE_NORMAL] = *bg; style->base[GTK_STATE_NORMAL] = *bg; @@ -4082,18 +4133,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) ) @@ -4106,10 +4157,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); + } } } @@ -4166,7 +4226,7 @@ wxEventType wxWindowGTK::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; }