[gtk+] win32 theme: Add a way to query border of theme parts



commit 67b893c5f8be66c316189ed73692093accfb1e9a
Author: Benjamin Otte <otte gnome org>
Date:   Mon Feb 15 06:50:22 2016 +0100

    win32 theme: Add a way to query border of theme parts

 gtk/gtkcssnumbervalue.c    |   12 +++++++++-
 gtk/gtkcsswin32sizevalue.c |   41 ++++++++++++++++++++++++++++++++++++++-
 gtk/gtkwin32draw.c         |   27 +++++++++++++++++++++++--
 gtk/gtkwin32drawprivate.h  |    6 +++++
 gtk/gtkwin32theme.c        |   45 ++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwin32themeprivate.h |    4 +++
 6 files changed, 128 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c
index e8256c0..54e1d1c 100644
--- a/gtk/gtkcssnumbervalue.c
+++ b/gtk/gtkcssnumbervalue.c
@@ -133,7 +133,11 @@ gtk_css_number_value_can_parse (GtkCssParser *parser)
       || _gtk_css_parser_has_prefix (parser, "calc")
       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-size")
       || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width")
-      || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height");
+      || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height")
+      || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-top")
+      || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-left")
+      || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-bottom")
+      || _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-right");
 }
 
 GtkCssValue *
@@ -144,7 +148,11 @@ _gtk_css_number_value_parse (GtkCssParser           *parser,
     return gtk_css_calc_value_parse (parser, flags);
   if (_gtk_css_parser_has_prefix (parser, "-gtk-win32-size") ||
       _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-width") ||
-      _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height"))
+      _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-height") ||
+      _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-top") ||
+      _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-left") ||
+      _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-bottom") ||
+      _gtk_css_parser_has_prefix (parser, "-gtk-win32-part-border-right"))
     return gtk_css_win32_size_value_parse (parser, flags);
 
   return gtk_css_dimension_value_parse (parser, flags);
diff --git a/gtk/gtkcsswin32sizevalue.c b/gtk/gtkcsswin32sizevalue.c
index 7c35d37..9497c9c 100644
--- a/gtk/gtkcsswin32sizevalue.c
+++ b/gtk/gtkcsswin32sizevalue.c
@@ -24,13 +24,21 @@
 typedef enum {
   GTK_WIN32_SIZE,
   GTK_WIN32_PART_WIDTH,
-  GTK_WIN32_PART_HEIGHT
+  GTK_WIN32_PART_HEIGHT,
+  GTK_WIN32_PART_BORDER_TOP,
+  GTK_WIN32_PART_BORDER_RIGHT,
+  GTK_WIN32_PART_BORDER_BOTTOM,
+  GTK_WIN32_PART_BORDER_LEFT
 } GtkWin32SizeType;
 
 static const char *css_value_names[] = {
   "-gtk-win32-size(",
   "-gtk-win32-part-width(",
-  "-gtk-win32-part-height("
+  "-gtk-win32-part-height(",
+  "-gtk-win32-part-border-top(",
+  "-gtk-win32-part-border-right(",
+  "-gtk-win32-part-border-bottom(",
+  "-gtk-win32-part-border-left("
 };
 
 struct _GtkCssValue {
@@ -63,6 +71,7 @@ gtk_css_value_win32_size_free (GtkCssValue *value)
 static int
 gtk_css_value_win32_compute_size (const GtkCssValue *value)
 {
+  GtkBorder border;
   int size;
 
   switch (value->type)
@@ -78,6 +87,26 @@ gtk_css_value_win32_compute_size (const GtkCssValue *value)
       gtk_win32_theme_get_part_size (value->theme, value->val.part.part, value->val.part.state, NULL, &size);
       break;
 
+    case GTK_WIN32_PART_BORDER_TOP:
+      gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
+      size = border.top;
+      break;
+
+    case GTK_WIN32_PART_BORDER_RIGHT:
+      gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
+      size = border.right;
+      break;
+
+    case GTK_WIN32_PART_BORDER_BOTTOM:
+      gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
+      size = border.bottom;
+      break;
+
+    case GTK_WIN32_PART_BORDER_LEFT:
+      gtk_win32_theme_get_part_border (value->theme, value->val.part.part, value->val.part.state, &border);
+      size = border.left;
+      break;
+
     default:
       g_assert_not_reached ();
       return 0;
@@ -139,6 +168,10 @@ gtk_css_value_win32_size_print (const GtkCssValue *value,
 
     case GTK_WIN32_PART_WIDTH:
     case GTK_WIN32_PART_HEIGHT:
+    case GTK_WIN32_PART_BORDER_TOP:
+    case GTK_WIN32_PART_BORDER_RIGHT:
+    case GTK_WIN32_PART_BORDER_BOTTOM:
+    case GTK_WIN32_PART_BORDER_LEFT:
       g_string_append_printf (string, ", %d, %d", value->val.part.part, value->val.part.state);
       break;
 
@@ -317,6 +350,10 @@ gtk_css_win32_size_value_parse (GtkCssParser           *parser,
 
     case GTK_WIN32_PART_WIDTH:
     case GTK_WIN32_PART_HEIGHT:
+    case GTK_WIN32_PART_BORDER_TOP:
+    case GTK_WIN32_PART_BORDER_RIGHT:
+    case GTK_WIN32_PART_BORDER_BOTTOM:
+    case GTK_WIN32_PART_BORDER_LEFT:
       result = gtk_css_win32_size_value_parse_part_size (result, parser);
       break;
 
diff --git a/gtk/gtkwin32draw.c b/gtk/gtkwin32draw.c
index 1c761f2..4a28f11 100644
--- a/gtk/gtkwin32draw.c
+++ b/gtk/gtkwin32draw.c
@@ -86,6 +86,7 @@ struct _GtkWin32ThemePart {
   const char *class_name;
   gint        part;
   gint        size;
+  GtkBorder   margins;
   void        (* draw_func)             (cairo_t        *cr,
                                          int             part,
                                          int             state,
@@ -94,9 +95,9 @@ struct _GtkWin32ThemePart {
 };
 
 static GtkWin32ThemePart theme_parts[] = {
-  { "button", 1,  0, draw_button },
-  { "button", 2, 13, draw_radio },
-  { "button", 3, 13, draw_check }
+  { "button", 1,  0, { 3, 3, 3, 3 }, draw_button },
+  { "button", 2, 13, { 0, 0, 0, 0 }, draw_radio },
+  { "button", 3, 13, { 0, 0, 0, 0 }, draw_check }
 };
 
 static const GtkWin32ThemePart *
@@ -158,6 +159,26 @@ gtk_win32_get_theme_part_size (const char *class_name,
     }
 }
 
+void
+gtk_win32_get_theme_margins (const char     *class_name,
+                             int             part,
+                             int             state,
+                             GtkBorder      *out_margins)
+{
+  const GtkWin32ThemePart *theme_part;
+
+  theme_part = get_theme_part (class_name, part);
+
+  if (theme_part)
+    {
+      *out_margins = theme_part->margins;
+    }
+  else
+    {
+      out_margins->top = out_margins->bottom = out_margins->left = out_margins->right = 0;
+    }
+}
+
 struct {
   const char *name;
   GdkRGBA rgba;
diff --git a/gtk/gtkwin32drawprivate.h b/gtk/gtkwin32drawprivate.h
index f8a11ca..b2f339a 100644
--- a/gtk/gtkwin32drawprivate.h
+++ b/gtk/gtkwin32drawprivate.h
@@ -21,6 +21,8 @@
 #include <gdk/gdk.h>
 #include <cairo.h>
 
+#include <gtk/gtkborder.h>
+
 G_BEGIN_DECLS
 
 enum {
@@ -68,6 +70,10 @@ void                    gtk_win32_get_theme_part_size           (const char
                                                                  int             state,
                                                                  int            *width,
                                                                  int            *height);
+void                    gtk_win32_get_theme_margins             (const char     *class_name,
+                                                                 int             part,
+                                                                 int             state,
+                                                                 GtkBorder      *out_margins);
 
 void                    gtk_win32_get_sys_color                 (gint            id,
                                                                  GdkRGBA        *color);
diff --git a/gtk/gtkwin32theme.c b/gtk/gtkwin32theme.c
index dced7c7..dadc910 100644
--- a/gtk/gtkwin32theme.c
+++ b/gtk/gtkwin32theme.c
@@ -64,6 +64,12 @@ typedef HRESULT (FAR PASCAL *GetThemePartSizeFunc)          (HTHEME hTheme,
                                                             RECT *prc,
                                                             int eSize,
                                                             SIZE *psz);
+typedef HRESULT (FAR PASCAL *GetThemeBackgroundExtentFunc)  (HTHEME hTheme,
+                                                            HDC hdc,
+                                                            int iPartId,
+                                                            int iStateId,
+                                                             const RECT *pContentRect,
+                                                             RECT *pExtentRect);
 
 static GetThemeSysFontFunc get_theme_sys_font = NULL;
 static GetThemeSysColorFunc GetThemeSysColor = NULL;
@@ -77,6 +83,7 @@ static IsAppThemedFunc is_app_themed = NULL;
 static IsThemeBackgroundPartiallyTransparentFunc is_theme_partially_transparent = NULL;
 static DrawThemeParentBackgroundFunc draw_theme_parent_background = NULL;
 static GetThemePartSizeFunc GetThemePartSize = NULL;
+static GetThemeBackgroundExtentFunc GetThemeBackgroundExtent = NULL;
 
 #endif
 
@@ -212,6 +219,7 @@ gtk_win32_theme_init (void)
       is_theme_partially_transparent = (IsThemeBackgroundPartiallyTransparentFunc) GetProcAddress 
(uxtheme_dll, "IsThemeBackgroundPartiallyTransparent");
       draw_theme_parent_background = (DrawThemeParentBackgroundFunc) GetProcAddress (uxtheme_dll, 
"DrawThemeParentBackground");
       GetThemePartSize = (GetThemePartSizeFunc) GetProcAddress (uxtheme_dll, "GetThemePartSize");
+      GetThemeBackgroundExtent = (GetThemeBackgroundExtentFunc) GetProcAddress (uxtheme_dll, 
"GetThemeBackgroundExtent");
     }
 
   if (is_app_themed && is_theme_active)
@@ -388,6 +396,43 @@ gtk_win32_theme_create_surface (GtkWin32Theme *theme,
 }
 
 void
+gtk_win32_theme_get_part_border (GtkWin32Theme  *theme,
+                                 int             part,
+                                 int             state,
+                                 GtkBorder      *out_border)
+{
+#ifdef G_OS_WIN32
+  HTHEME htheme = gtk_win32_theme_get_htheme (theme);
+  RECT content, extent;
+  HDC hdc;
+  HRESULT res;
+
+  if (use_xp_theme && GetThemeBackgroundExtent != NULL && htheme != NULL)
+    {
+      /* According to Wine source code, these values don't matter
+       * because uxtheme.dll deals with margins internally. */
+      content.left = content.top = 0;
+      content.right = content.bottom = 100;
+
+      hdc = GetDC (NULL);
+      res = GetThemeBackgroundExtent (htheme, hdc, part, state, &content, &extent);
+      ReleaseDC (NULL, hdc);
+
+      if (SUCCEEDED (res))
+        {
+          out_border->top = content.top - extent.top;
+          out_border->left = content.left - extent.left;
+          out_border->bottom = extent.bottom - content.bottom;
+          out_border->right = extent.right - content.right;
+          return;
+        }
+    }
+#endif
+
+  gtk_win32_get_theme_margins (theme->class_name, part, state, out_border);
+}
+
+void
 gtk_win32_theme_get_part_size (GtkWin32Theme  *theme,
                                int             part,
                                int             state,
diff --git a/gtk/gtkwin32themeprivate.h b/gtk/gtkwin32themeprivate.h
index b03bea8..9ea7777 100644
--- a/gtk/gtkwin32themeprivate.h
+++ b/gtk/gtkwin32themeprivate.h
@@ -49,6 +49,10 @@ cairo_surface_t *       gtk_win32_theme_create_surface  (GtkWin32Theme *theme,
                                                         int           *x_offs_out,
                                                         int           *y_offs_out);
 
+void                    gtk_win32_theme_get_part_border (GtkWin32Theme  *theme,
+                                                         int             part,
+                                                         int             state,
+                                                         GtkBorder      *out_border);
 void                    gtk_win32_theme_get_part_size   (GtkWin32Theme  *theme,
                                                          int             part,
                                                          int             state,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]