]> git.saurik.com Git - wxWidgets.git/commitdiff
fix setting background color in wxGTK3 with themes which use background images or...
authorPaul Cornett <paulcor@bullseye.com>
Sun, 4 Nov 2012 17:39:55 +0000 (17:39 +0000)
committerPaul Cornett <paulcor@bullseye.com>
Sun, 4 Nov 2012 17:39:55 +0000 (17:39 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72881 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/window.h
src/gtk/window.cpp

index baeb7041fb465ffec5e2ecdc0b3bb1eaf15c8059..4c9078e9895dd14843ca2552690e2256d0e66198 100644 (file)
@@ -14,6 +14,7 @@
 
 #ifdef __WXGTK3__
     typedef struct _cairo cairo_t;
+    typedef struct _GtkStyleProvider GtkStyleProvider;
     #define WXUNUSED_IN_GTK3(x)
 #else
     #define WXUNUSED_IN_GTK3(x) x
@@ -373,10 +374,8 @@ protected:
 #ifndef __WXGTK3__
     // Called by ApplyWidgetStyle (which is called by SetFont() and
     // SetXXXColour etc to apply style changed to native widgets) to create
-    // modified GTK style with non-standard attributes. If forceStyle=true,
-    // creates empty GtkRcStyle if there are no modifications, otherwise
-    // returns NULL in such case.
-    GtkRcStyle *GTKCreateWidgetStyle(bool forceStyle = false);
+    // modified GTK style with non-standard attributes.
+    GtkRcStyle* GTKCreateWidgetStyle();
 #endif
 
     void GTKApplyWidgetStyle(bool forceStyle = false);
@@ -414,6 +413,8 @@ private:
 #ifdef __WXGTK3__
     // paint context is stashed here so wxPaintDC can use it
     cairo_t* m_paintContext;
+    // style provider for "background-image"
+    GtkStyleProvider* m_styleProvider;
 
 public:
     cairo_t* GTKPaintContext() const
index 978f556ca75953261c85405458f5ccdaa05ae061..0543ea56e73c07b8c5a44686678d598bcb19a179 100644 (file)
@@ -2191,6 +2191,7 @@ void wxWindowGTK::Init()
     m_nativeSizeEvent = false;
 #ifdef __WXGTK3__
     m_paintContext = NULL;
+    m_styleProvider = NULL;
 #endif
 
     m_isScrolling = false;
@@ -2390,6 +2391,11 @@ wxWindowGTK::~wxWindowGTK()
     while (IsFrozen())
         Thaw();
 
+#ifdef __WXGTK3__
+    if (m_styleProvider)
+        g_object_unref(m_styleProvider);
+#endif
+
     if (m_widget)
     {
         // Note that gtk_widget_destroy() does not destroy the widget, it just
@@ -4011,16 +4017,8 @@ PangoContext *wxWindowGTK::GTKGetPangoDefaultContext()
 }
 
 #ifndef __WXGTK3__
-GtkRcStyle *wxWindowGTK::GTKCreateWidgetStyle(bool forceStyle)
+GtkRcStyle* wxWindowGTK::GTKCreateWidgetStyle()
 {
-    // do we need to apply any changes at all?
-    if ( !forceStyle &&
-         !m_font.IsOk() &&
-         !m_foregroundColour.IsOk() && !m_backgroundColour.IsOk() )
-    {
-        return NULL;
-    }
-
     GtkRcStyle *style = gtk_rc_style_new();
 
     if ( m_font.IsOk() )
@@ -4081,18 +4079,35 @@ GtkRcStyle *wxWindowGTK::GTKCreateWidgetStyle(bool forceStyle)
 }
 #endif // !__WXGTK3__
 
-void wxWindowGTK::GTKApplyWidgetStyle(bool WXUNUSED_IN_GTK3(forceStyle))
+void wxWindowGTK::GTKApplyWidgetStyle(bool forceStyle)
 {
+    if (forceStyle || m_font.IsOk() ||
+        m_foregroundColour.IsOk() || m_backgroundColour.IsOk())
+    {
 #ifdef __WXGTK3__
-    DoApplyWidgetStyle(NULL);
+        if (m_backgroundColour.IsOk())
+        {
+            // create a GtkStyleProvider to override "background-image"
+            if (m_styleProvider == NULL)
+                m_styleProvider = GTK_STYLE_PROVIDER(gtk_css_provider_new());
+            const char css[] =
+                "*{background-image:-gtk-gradient(linear,0 0,0 1,"
+                "from(rgba(%u,%u,%u,%g)),to(rgba(%u,%u,%u,%g)))}";
+            char buf[sizeof(css) + 20];
+            const unsigned r = m_backgroundColour.Red();
+            const unsigned g = m_backgroundColour.Green();
+            const unsigned b = m_backgroundColour.Blue();
+            const double a = m_backgroundColour.Alpha() / 255.0;
+            g_snprintf(buf, sizeof(buf), css, r, g, b, a, r, g, b, a);
+            gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(m_styleProvider), buf, -1, NULL);
+        }
+        DoApplyWidgetStyle(NULL);
 #else
-    GtkRcStyle *style = GTKCreateWidgetStyle(forceStyle);
-    if ( style )
-    {
+        GtkRcStyle* style = GTKCreateWidgetStyle();
         DoApplyWidgetStyle(style);
         g_object_unref(style);
-    }
 #endif
+    }
 
     // Style change may affect GTK+'s size calculation:
     InvalidateBestSize();
@@ -4130,6 +4145,25 @@ void wxWindowGTK::GTKApplyStyle(GtkWidget* widget, GtkRcStyle* WXUNUSED_IN_GTK3(
     gtk_widget_override_font(widget, pfd);
     gtk_widget_override_color(widget, GTK_STATE_FLAG_NORMAL, m_foregroundColour);
     gtk_widget_override_background_color(widget, GTK_STATE_FLAG_NORMAL, m_backgroundColour);
+
+    // setting background color has no effect with some themes when the widget style
+    // has a "background-image" property, so we need to override that as well
+
+    GtkStyleContext* context = gtk_widget_get_style_context(widget);
+    if (m_styleProvider)
+        gtk_style_context_remove_provider(context, m_styleProvider);
+    cairo_pattern_t* pattern = NULL;
+    if (m_backgroundColour.IsOk())
+    {
+        gtk_style_context_get(context,
+            GTK_STATE_FLAG_NORMAL, "background-image", &pattern, NULL);
+    }
+    if (pattern)
+    {
+        cairo_pattern_destroy(pattern);
+        gtk_style_context_add_provider(context,
+            m_styleProvider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+    }
 #else
     gtk_widget_modify_style(widget, style);
 #endif