}
}
+#ifndef __WXUNIVERSAL__
//-----------------------------------------------------------------------------
-// "expose_event" from m_widget, for drawing border
+// "expose_event" from m_wxwindow->parent, for drawing border
//-----------------------------------------------------------------------------
-#ifndef __WXUNIVERSAL__
-
extern "C" {
static gboolean
expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
{
- // if this event is not for the GdkWindow the border is drawn on
- if (win->m_wxwindow == win->m_widget && gdk_event->window == widget->window)
+ if (gdk_event->window != widget->window)
+ return false;
+
+ const GtkAllocation& alloc = win->m_wxwindow->allocation;
+ const int x = alloc.x;
+ const int y = alloc.y;
+ const int w = alloc.width;
+ const int h = alloc.height;
+
+ if (w <= 0 || h <= 0)
return false;
- int x = 0;
- int y = 0;
- // GtkScrolledWindow is GTK_NO_WINDOW
- if (GTK_WIDGET_NO_WINDOW(widget))
- {
- x = widget->allocation.x;
- y = widget->allocation.y;
- }
- int w = win->m_wxwindow->allocation.width;
- int h = win->m_wxwindow->allocation.height;
if (win->HasFlag(wxBORDER_SIMPLE))
{
- GdkGC* gc = gdk_gc_new(gdk_event->window);
- gdk_gc_set_foreground(gc, &widget->style->black);
- gdk_draw_rectangle(gdk_event->window, gc, false, x, y, w - 1, h - 1);
- g_object_unref(gc);
+ gdk_draw_rectangle(gdk_event->window,
+ widget->style->black_gc, false, x, y, w - 1, h - 1);
}
else
{
// Style detail to use
const char* detail;
- if (widget == win->m_wxwindow)
+ if (win->m_widget == win->m_wxwindow)
// for non-scrollable wxWindows
detail = "entry";
else
// for scrollable ones
detail = "viewport";
- GtkWidget* styleWidget = wxGTKPrivate::GetEntryWidget();
gtk_paint_shadow(
- styleWidget->style, gdk_event->window, GTK_STATE_NORMAL,
- shadow, NULL, styleWidget, detail, x, y, w, h);
+ win->m_wxwindow->style, gdk_event->window, GTK_STATE_NORMAL,
+ shadow, NULL, wxGTKPrivate::GetEntryWidget(), detail, x, y, w, h);
}
+ return false;
+}
+}
+
+//-----------------------------------------------------------------------------
+// "parent_set" from m_wxwindow
+//-----------------------------------------------------------------------------
- // no further painting is needed for border-only GdkWindow
- return win->m_wxwindow == win->m_widget;
+extern "C" {
+static void
+parent_set(GtkWidget* widget, GtkObject* old_parent, wxWindow* win)
+{
+ if (old_parent)
+ {
+ g_signal_handlers_disconnect_by_func(
+ old_parent, (void*)expose_event_border, win);
+ }
+ if (widget->parent)
+ {
+ g_signal_connect_after(widget->parent, "expose_event",
+ G_CALLBACK(expose_event_border), win);
+ }
}
}
#endif // !__WXUNIVERSAL__
// "scroll_event" (mouse wheel event)
//-----------------------------------------------------------------------------
+static gboolean
+window_scroll_event_hscrollbar(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
+{
+ if (gdk_event->direction != GDK_SCROLL_LEFT &&
+ gdk_event->direction != GDK_SCROLL_RIGHT)
+ {
+ return false;
+ }
+
+ wxMouseEvent event(wxEVT_MOUSEWHEEL);
+ InitMouseEvent(win, event, gdk_event);
+
+ GtkRange *range = win->m_scrollBar[wxWindow::ScrollDir_Horz];
+ if (!range) return FALSE;
+
+ if (range && GTK_WIDGET_VISIBLE (range))
+ {
+ GtkAdjustment *adj = range->adjustment;
+ gdouble delta = adj->step_increment * 3;
+ if (gdk_event->direction == GDK_SCROLL_LEFT)
+ delta = -delta;
+
+ gdouble new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
+
+ gtk_adjustment_set_value (adj, new_value);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static gboolean
window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
{
else
event.m_wheelRotation = -120;
- return win->GTKProcessEvent(event);
+ if (win->GTKProcessEvent(event))
+ return TRUE;
+
+ GtkRange *range = win->m_scrollBar[wxWindow::ScrollDir_Vert];
+ if (!range) return FALSE;
+
+ if (range && GTK_WIDGET_VISIBLE (range))
+ {
+ GtkAdjustment *adj = range->adjustment;
+ gdouble delta = adj->step_increment * 3;
+ if (gdk_event->direction == GDK_SCROLL_UP)
+ delta = -delta;
+
+ gdouble new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
+
+ gtk_adjustment_set_value (adj, new_value);
+
+ return TRUE;
+ }
+
+ return FALSE;
}
//-----------------------------------------------------------------------------
{
wxWindowGTK *focus = gs_pendingFocus ? gs_pendingFocus : gs_currentFocus;
// the cast is necessary when we compile in wxUniversal mode
- return wx_static_cast(wxWindow*, focus);
+ return static_cast<wxWindow*>(focus);
}
void wxWindowGTK::AddChildGTK(wxWindowGTK* child)
m_wxwindow = wxPizza::New(m_windowStyle);
+#ifndef __WXUNIVERSAL__
+ if (HasFlag(wxPizza::BORDER_STYLES))
+ {
+ g_signal_connect(m_wxwindow, "parent_set",
+ G_CALLBACK(parent_set), this);
+ }
+#endif
if (!HasFlag(wxHSCROLL) && !HasFlag(wxVSCROLL))
m_widget = m_wxwindow;
else
g_signal_connect (m_imData->context, "commit",
G_CALLBACK (gtk_wxwindow_commit_cb), this);
-
- // border drawing
-#ifndef __WXUNIVERSAL__
- if (HasFlag(wxPizza::BORDER_STYLES))
- {
- g_signal_connect(m_widget, "expose_event",
- G_CALLBACK(expose_event_border), this);
- }
-#endif
}
// focus handling
G_CALLBACK (gtk_window_button_release_callback), this);
g_signal_connect (widget, "motion_notify_event",
G_CALLBACK (gtk_window_motion_notify_callback), this);
+
g_signal_connect (widget, "scroll_event",
G_CALLBACK (window_scroll_event), this);
+ if (m_scrollBar[ScrollDir_Horz])
+ g_signal_connect (m_scrollBar[ScrollDir_Horz], "scroll_event",
+ G_CALLBACK (window_scroll_event_hscrollbar), this);
+ if (m_scrollBar[ScrollDir_Vert])
+ g_signal_connect (m_scrollBar[ScrollDir_Vert], "scroll_event",
+ G_CALLBACK (window_scroll_event), this);
+
g_signal_connect (widget, "popup_menu",
G_CALLBACK (wxgtk_window_popup_menu_callback), this);
g_signal_connect (widget, "enter_notify_event",
int w = m_width;
int h = m_height;
- if (m_wxwindow)
+ if ( m_wxwindow )
{
// if window is scrollable, account for scrollbars
- for (int i = 0; i < 2 && m_scrollBar[i]; i++)
+ if ( GTK_IS_SCROLLED_WINDOW(m_widget) )
{
- GtkRequisition req;
- GtkAdjustment* adj = gtk_range_get_adjustment(m_scrollBar[i]);
- // if scrollbar enabled
- if (adj->upper > adj->page_size)
+ GtkPolicyType policy[ScrollDir_Max];
+ gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(m_widget),
+ &policy[ScrollDir_Horz],
+ &policy[ScrollDir_Vert]);
+
+ for ( int i = 0; i < ScrollDir_Max; i++ )
{
- gtk_widget_size_request(GTK_WIDGET(m_scrollBar[i]), &req);
+ // don't account for the scrollbars we don't have
+ GtkRange * const range = m_scrollBar[i];
+ if ( !range )
+ continue;
+
+ // nor for the ones we have but don't current show
+ switch ( policy[i] )
+ {
+ case GTK_POLICY_NEVER:
+ // never shown so doesn't take any place
+ continue;
+
+ case GTK_POLICY_ALWAYS:
+ // no checks necessary
+ break;
+
+ case GTK_POLICY_AUTOMATIC:
+ // may be shown or not, check
+ GtkAdjustment *adj = gtk_range_get_adjustment(range);
+ if ( adj->upper <= adj->page_size )
+ continue;
+ }
+
+ GtkRequisition req;
+ gtk_widget_size_request(GTK_WIDGET(range), &req);
if (i == ScrollDir_Horz)
h -= req.height;
else
if (m_parent)
m_parent->ScreenToClient(&org_x, &org_y);
- wx_const_cast(wxWindowGTK*, this)->m_x = org_x;
- wx_const_cast(wxWindowGTK*, this)->m_y = org_y;
+ const_cast<wxWindowGTK*>(this)->m_x = org_x;
+ const_cast<wxWindowGTK*>(this)->m_y = org_y;
}
}
g_object_unref (layout);
}
+void wxWindowGTK::GTKDisableFocusOutEvent()
+{
+ g_signal_handlers_block_by_func( m_focusWidget,
+ (gpointer) gtk_window_focus_out_callback, this);
+}
+
+void wxWindowGTK::GTKEnableFocusOutEvent()
+{
+ g_signal_handlers_unblock_by_func( m_focusWidget,
+ (gpointer) gtk_window_focus_out_callback, this);
+}
bool wxWindowGTK::GTKHandleFocusIn()
{