]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
fixing dangling includes
[wxWidgets.git] / src / gtk / window.cpp
index 367f3aec8bf39ec285a26f1bad74dd4cb6083070..1df7e832647b7fde2d1e794502f303af45ef5af2 100644 (file)
@@ -295,30 +295,27 @@ gtk_window_expose_callback( GtkWidget* widget,
 }
 }
 
+#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))
     {
         gdk_draw_rectangle(gdk_event->window,
@@ -332,7 +329,7 @@ expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
 
         // 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
@@ -343,9 +340,28 @@ expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
            win->m_wxwindow->style, gdk_event->window, GTK_STATE_NORMAL,
            shadow, NULL, wxGTKPrivate::GetEntryWidget(), detail, x, y, w, h);
     }
+    return false;
+}
+}
 
-    // no further painting is needed for border-only GdkWindow
-    return win->m_wxwindow == win->m_widget;
+//-----------------------------------------------------------------------------
+// "parent_set" from m_wxwindow
+//-----------------------------------------------------------------------------
+
+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__
@@ -1531,6 +1547,38 @@ gtk_window_motion_notify_callback( GtkWidget * WXUNUSED(widget),
 // "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)
 {
@@ -1551,7 +1599,27 @@ 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;
 }
 
 //-----------------------------------------------------------------------------
@@ -2040,6 +2108,13 @@ bool wxWindowGTK::Create( wxWindow *parent,
 
 
     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
@@ -2215,15 +2290,6 @@ void wxWindowGTK::PostCreation()
 
         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
@@ -2342,8 +2408,16 @@ void wxWindowGTK::ConnectWidget( GtkWidget *widget )
                       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",
@@ -2570,17 +2644,43 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const
     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