X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b3d006af0fca9ba3679f092016cf149c9f6fd06c..b4ea182b39cf538d2ff2885b7b7406a221f44c3d:/src/gtk/window.cpp diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 424a219958..d94f9f2b0a 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1152,43 +1152,6 @@ gtk_window_key_press_callback( GtkWidget *widget, ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event ); } - // generate wxID_CANCEL if has been pressed (typically in dialogs) - if ( !ret && - (gdk_event->keyval == GDK_Escape) ) - { - // however only do it if we have a Cancel button in the dialog, - // otherwise the user code may get confused by the events from a - // nonexistent button and, worse, a wxButton might get button event - // from another button which is not really expected - wxWindow *winForCancel = win, - *btnCancel = NULL; - while ( winForCancel ) - { - btnCancel = winForCancel->FindWindow(wxID_CANCEL); - if ( btnCancel ) - { - // found a cancel button - break; - } - - if ( winForCancel->IsTopLevel() ) - { - // no need to look further - break; - } - - // maybe our parent has a cancel button? - winForCancel = winForCancel->GetParent(); - } - - if ( btnCancel ) - { - wxCommandEvent eventClick(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); - eventClick.SetEventObject(btnCancel); - ret = btnCancel->GetEventHandler()->ProcessEvent(eventClick); - } - } - if (ret) { g_signal_stop_emission_by_name (widget, "key_press_event"); @@ -2122,13 +2085,18 @@ 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; + + // find the scrollbar which generated the event + wxWindowGTK::ScrollDir dir = win->ScrollDirFromRange(range); + + // generate the corresponding wx event + const int orient = win->OrientFromScrollDir(dir); wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient); event.SetEventObject(win); - win->m_blockValueChanged[i] = true; + + win->m_blockValueChanged[dir] = true; win->GetEventHandler()->ProcessEvent(event); - win->m_blockValueChanged[i] = false; + win->m_blockValueChanged[dir] = false; } } } @@ -2165,7 +2133,8 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win) { g_signal_handlers_block_by_func(range, (void*)gtk_scrollbar_event_after, win); - const int orient = range == win->m_scrollBar[0] ? wxHORIZONTAL : wxVERTICAL; + const int orient = win->OrientFromScrollDir( + win->ScrollDirFromRange(range)); wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient); event.SetEventObject(win); win->GetEventHandler()->ProcessEvent(event); @@ -2488,6 +2457,8 @@ void wxWindowGTK::Init() m_hasVMT = false; m_needParent = true; m_isBeingDeleted = false; + + m_showOnIdle= false; m_noExpose = false; m_nativeSizeEvent = false; @@ -2497,12 +2468,13 @@ void wxWindowGTK::Init() m_mouseButtonDown = false; m_blockScrollEvent = false; - m_scrollBar[0] = - m_scrollBar[1] = NULL; - m_scrollPos[0] = - m_scrollPos[1] = 0; - m_blockValueChanged[0] = - m_blockValueChanged[1] = false; + // initialize scrolling stuff + for ( int dir = 0; dir < ScrollDir_Max; dir++ ) + { + m_scrollBar[dir] = NULL; + m_scrollPos[dir] = 0; + m_blockValueChanged[dir] = false; + } m_oldClientWidth = m_oldClientHeight = 0; @@ -2567,8 +2539,8 @@ bool wxWindowGTK::Create( wxWindow *parent, gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - m_scrollBar[0] = GTK_RANGE(scrolledWindow->hscrollbar); - m_scrollBar[1] = GTK_RANGE(scrolledWindow->vscrollbar); + m_scrollBar[ScrollDir_Horz] = GTK_RANGE(scrolledWindow->hscrollbar); + m_scrollBar[ScrollDir_Vert] = GTK_RANGE(scrolledWindow->vscrollbar); m_wxwindow = gtk_pizza_new(); @@ -2598,31 +2570,25 @@ bool wxWindowGTK::Create( wxWindow *parent, GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); m_acceptsFocus = true; - // these handlers block mouse events to any window during scrolling such as - // motion events and prevent GTK and wxWidgets from fighting over where the - // slider should be - g_signal_connect(m_scrollBar[0], "button_press_event", - G_CALLBACK(gtk_scrollbar_button_press_event), this); - g_signal_connect(m_scrollBar[1], "button_press_event", - G_CALLBACK(gtk_scrollbar_button_press_event), this); - g_signal_connect(m_scrollBar[0], "button_release_event", - 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 - - g_signal_connect(m_scrollBar[0], "value_changed", - G_CALLBACK(gtk_scrollbar_value_changed), this); - g_signal_connect(m_scrollBar[1], "value_changed", - G_CALLBACK(gtk_scrollbar_value_changed), this); + // connect various scroll-related events + for ( int dir = 0; dir < ScrollDir_Max; dir++ ) + { + // these handlers block mouse events to any window during scrolling + // such as motion events and prevent GTK and wxWidgets from fighting + // over where the slider should be + g_signal_connect(m_scrollBar[dir], "button_press_event", + G_CALLBACK(gtk_scrollbar_button_press_event), this); + g_signal_connect(m_scrollBar[dir], "button_release_event", + G_CALLBACK(gtk_scrollbar_button_release_event), this); + + gulong handler_id = g_signal_connect(m_scrollBar[dir], "event_after", + G_CALLBACK(gtk_scrollbar_event_after), this); + g_signal_handler_block(m_scrollBar[dir], handler_id); + + // these handlers get notified when scrollbar slider moves + g_signal_connect(m_scrollBar[dir], "value_changed", + G_CALLBACK(gtk_scrollbar_value_changed), this); + } gtk_widget_show( m_wxwindow ); @@ -2993,8 +2959,32 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags m_resizing = false; } +bool wxWindowGTK::GtkShowFromOnIdle() +{ + if (IsShown() && m_showOnIdle && !GTK_WIDGET_VISIBLE (m_widget)) + { + GtkAllocation alloc; + alloc.x = m_x; + alloc.y = m_y; + alloc.width = m_width; + alloc.height = m_height; + gtk_widget_size_allocate( m_widget, &alloc ); + gtk_widget_show( m_widget ); + wxShowEvent eventShow(GetId(), true); + eventShow.SetEventObject(this); + GetEventHandler()->ProcessEvent(eventShow); + m_showOnIdle = false; + return true; + } + + return false; +} + void wxWindowGTK::OnInternalIdle() { + // Check if we have to show window now + if (GtkShowFromOnIdle()) return; + if ( m_dirtyTabOrder ) { m_dirtyTabOrder = false; @@ -3008,7 +2998,7 @@ void wxWindowGTK::OnInternalIdle() SetBackgroundStyle(GetBackgroundStyle()); m_needsStyleChange = false; } - + // Update invalidated regions. GtkUpdate(); @@ -3218,14 +3208,22 @@ bool wxWindowGTK::Show( bool show ) } if (show) - gtk_widget_show( m_widget ); + { + if (!m_showOnIdle) + { + gtk_widget_show( m_widget ); + wxShowEvent eventShow(GetId(), show); + eventShow.SetEventObject(this); + GetEventHandler()->ProcessEvent(eventShow); + } + } else + { gtk_widget_hide( m_widget ); - - wxShowEvent eventShow(GetId(), show); - eventShow.SetEventObject(this); - - GetEventHandler()->ProcessEvent(eventShow); + wxShowEvent eventShow(GetId(), show); + eventShow.SetEventObject(this); + GetEventHandler()->ProcessEvent(eventShow); + } return true; } @@ -3463,6 +3461,12 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase ) if (newParent) { + if (GTK_WIDGET_VISIBLE (newParent->m_widget)) + { + m_showOnIdle = true; + gtk_widget_hide( m_widget ); + } + /* insert GTK representation */ (*(newParent->m_insertCallback))(newParent, this); } @@ -3645,34 +3649,49 @@ void wxWindowGTK::WarpPointer( int x, int y ) gdk_window_warp_pointer( window, x, y ); } -bool wxWindowGTK::ScrollLines(int lines) +wxWindowGTK::ScrollDir wxWindowGTK::ScrollDirFromRange(GtkRange *range) const { - bool changed = false; - GtkRange* range = m_scrollBar[1]; - if (range != NULL) + // find the scrollbar which generated the event + for ( int dir = 0; dir < ScrollDir_Max; dir++ ) { - GtkAdjustment* adj = range->adjustment; - const int pos = int(adj->value + 0.5); - gtk_range_set_value(range, pos + lines); - changed = pos != int(adj->value + 0.5); + if ( range == m_scrollBar[dir] ) + return (ScrollDir)dir; } - return changed; + + wxFAIL_MSG( _T("event from unknown scrollbar received") ); + + return ScrollDir_Max; } -bool wxWindowGTK::ScrollPages(int pages) +bool wxWindowGTK::DoScrollByUnits(ScrollDir dir, ScrollUnit unit, int units) { bool changed = false; - GtkRange* range = m_scrollBar[1]; - if (range != NULL) + GtkRange* range = m_scrollBar[dir]; + if ( range && units ) { GtkAdjustment* adj = range->adjustment; - const int pos = int(adj->value + 0.5); - gtk_range_set_value(range, pos + pages * adj->page_size); - changed = pos != int(adj->value + 0.5); + gdouble inc = unit == ScrollUnit_Line ? adj->step_increment + : adj->page_increment; + + const int posOld = int(adj->value + 0.5); + gtk_range_set_value(range, posOld + units*inc); + + changed = int(adj->value + 0.5) != posOld; } + return changed; } +bool wxWindowGTK::ScrollLines(int lines) +{ + return DoScrollByUnits(ScrollDir_Vert, ScrollUnit_Line, lines); +} + +bool wxWindowGTK::ScrollPages(int pages) +{ + return DoScrollByUnits(ScrollDir_Vert, ScrollUnit_Page, pages); +} + void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) { if (!m_widget) @@ -3682,6 +3701,8 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect ) if (m_wxwindow) { + if (!GTK_PIZZA(m_wxwindow)->bin_window) return; + GdkRectangle gdk_rect, *p; if (rect) @@ -3716,6 +3737,8 @@ void wxWindowGTK::GtkUpdate() { if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window) gdk_window_process_updates( GTK_PIZZA(m_wxwindow)->bin_window, FALSE ); + if (m_widget && m_widget->window) + gdk_window_process_updates( m_widget->window, FALSE ); // for consistency with other platforms (and also because it's convenient // to be able to update an entire TLW by calling Update() only once), we @@ -4114,8 +4137,11 @@ void wxWindowGTK::UnblockScrollEvent() m_blockScrollEvent = false; } -void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible, - int range, bool ) +void wxWindowGTK::SetScrollbar(int orient, + int pos, + int thumbVisible, + int range, + bool WXUNUSED(update)) { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") ); @@ -4135,8 +4161,7 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible, pos = range - thumbVisible; if (pos < 0) pos = 0; - const int i = orient == wxVERTICAL; - GtkAdjustment* adj = m_scrollBar[i]->adjustment; + GtkAdjustment* adj = m_scrollBar[ScrollDirFromOrient(orient)]->adjustment; adj->step_increment = 1; adj->page_increment = adj->page_size = thumbVisible; @@ -4145,7 +4170,7 @@ void wxWindowGTK::SetScrollbar( int orient, int pos, int thumbVisible, gtk_adjustment_changed(adj); } -void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) ) +void wxWindowGTK::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) { wxCHECK_RET( m_widget != NULL, wxT("invalid window") ); wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") ); @@ -4154,30 +4179,29 @@ void wxWindowGTK::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) ) // will not move smoothly while tracking when using wxScrollHelper. if (GetScrollPos(orient) != pos) { - const int i = orient == wxVERTICAL; - GtkAdjustment* adj = m_scrollBar[i]->adjustment; + const int dir = ScrollDirFromOrient(orient); + GtkAdjustment* adj = m_scrollBar[dir]->adjustment; const int max = int(adj->upper - adj->page_size); if (pos > max) pos = max; if (pos < 0) pos = 0; - m_scrollPos[i] = + m_scrollPos[dir] = adj->value = pos; // If a "value_changed" signal emission is not already in progress - if (!m_blockValueChanged[i]) + if (!m_blockValueChanged[dir]) { gtk_adjustment_value_changed(adj); } } } -int wxWindowGTK::GetScrollThumb( int orient ) const +int wxWindowGTK::GetScrollThumb(int orient) const { wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") ); wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") ); - const int i = orient == wxVERTICAL; - return int(m_scrollBar[i]->adjustment->page_size); + return int(m_scrollBar[ScrollDirFromOrient(orient)]->adjustment->page_size); } int wxWindowGTK::GetScrollPos( int orient ) const @@ -4185,8 +4209,7 @@ int wxWindowGTK::GetScrollPos( int orient ) const wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") ); wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") ); - const int i = orient == wxVERTICAL; - return int(m_scrollBar[i]->adjustment->value + 0.5); + return int(m_scrollBar[ScrollDirFromOrient(orient)]->adjustment->value + 0.5); } int wxWindowGTK::GetScrollRange( int orient ) const @@ -4194,8 +4217,7 @@ int wxWindowGTK::GetScrollRange( int orient ) const wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") ); wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") ); - const int i = orient == wxVERTICAL; - return int(m_scrollBar[i]->adjustment->upper); + return int(m_scrollBar[ScrollDirFromOrient(orient)]->adjustment->upper); } // Determine if increment is the same as +/-x, allowing for some small