ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
}
- // generate wxID_CANCEL if <esc> 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");
{
// 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;
}
}
}
{
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);
m_hasVMT = false;
m_needParent = true;
m_isBeingDeleted = false;
+
+ m_showOnIdle= false;
m_noExpose = false;
m_nativeSizeEvent = false;
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;
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();
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 );
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;
SetBackgroundStyle(GetBackgroundStyle());
m_needsStyleChange = false;
}
-
+
// Update invalidated regions.
GtkUpdate();
}
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;
}
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);
}
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)
if (m_wxwindow)
{
+ if (!GTK_PIZZA(m_wxwindow)->bin_window) return;
+
GdkRectangle gdk_rect,
*p;
if (rect)
{
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
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") );
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;
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") );
// 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
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
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