]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcssenumvalue.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtkcssenumvalue.c
index 7e79fc7407fcea29e3250cd49f06a2ae13617dad..e1f1d1c478b0af6a149855af1455b623b2b8552d 100644 (file)
@@ -19,7 +19,9 @@
 
 #include "gtkcssenumvalueprivate.h"
 
-#include "gtkstylepropertyprivate.h"
+#include "gtkcsscomputedvaluesprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+#include "gtkstyleproviderprivate.h"
 
 /* repeated API */
 
@@ -35,6 +37,17 @@ gtk_css_value_enum_free (GtkCssValue *value)
   g_slice_free (GtkCssValue, value);
 }
 
+static GtkCssValue *
+gtk_css_value_enum_compute (GtkCssValue             *value,
+                            guint                    property_id,
+                            GtkStyleProviderPrivate *provider,
+                            GtkCssComputedValues    *values,
+                            GtkCssComputedValues    *parent_values,
+                            GtkCssDependencies      *dependencies)
+{
+  return _gtk_css_value_ref (value);
+}
+
 static gboolean
 gtk_css_value_enum_equal (const GtkCssValue *enum1,
                           const GtkCssValue *enum2)
@@ -42,6 +55,15 @@ gtk_css_value_enum_equal (const GtkCssValue *enum1,
   return enum1 == enum2;
 }
 
+static GtkCssValue *
+gtk_css_value_enum_transition (GtkCssValue *start,
+                               GtkCssValue *end,
+                               guint        property_id,
+                               double       progress)
+{
+  return NULL;
+}
+
 static void
 gtk_css_value_enum_print (const GtkCssValue *value,
                           GString           *string)
@@ -53,7 +75,9 @@ gtk_css_value_enum_print (const GtkCssValue *value,
 
 static const GtkCssValueClass GTK_CSS_VALUE_BORDER_STYLE = {
   gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
   gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
   gtk_css_value_enum_print
 };
 
@@ -102,11 +126,158 @@ _gtk_css_border_style_value_get (const GtkCssValue *value)
   return value->value;
 }
 
+/* GtkCssFontSize */
+
+/* XXX: Kinda bad to have that machinery here, nobody expects vital font
+ * size code to appear in gtkcssvalueenum.c.
+ */
+#define DEFAULT_FONT_SIZE 10
+
+double
+_gtk_css_font_size_get_default (GtkStyleProviderPrivate *provider)
+{
+  GtkSettings *settings;
+  PangoFontDescription *description;
+  char *font_name;
+  double font_size;
+
+  settings = _gtk_style_provider_private_get_settings (provider);
+  if (settings == NULL)
+    return DEFAULT_FONT_SIZE;
+  
+  g_object_get (settings, "gtk-font-name", &font_name, NULL);
+  description = pango_font_description_from_string (font_name);
+  g_free (font_name);
+  if (description == NULL)
+    return DEFAULT_FONT_SIZE;
+
+  if (pango_font_description_get_set_fields (description) & PANGO_FONT_MASK_SIZE)
+    font_size = (double) pango_font_description_get_size (description) / PANGO_SCALE;
+  else
+    font_size = DEFAULT_FONT_SIZE;
+
+  pango_font_description_free (description);
+  return font_size;
+}
+
+static GtkCssValue *
+gtk_css_value_font_size_compute (GtkCssValue             *value,
+                                 guint                    property_id,
+                                 GtkStyleProviderPrivate *provider,
+                                 GtkCssComputedValues    *values,
+                                 GtkCssComputedValues    *parent_values,
+                                 GtkCssDependencies      *dependencies)
+{
+  double font_size;
+
+  switch (value->value)
+    {
+    case GTK_CSS_FONT_SIZE_XX_SMALL:
+      font_size = _gtk_css_font_size_get_default (provider) * 3. / 5;
+      break;
+    case GTK_CSS_FONT_SIZE_X_SMALL:
+      font_size = _gtk_css_font_size_get_default (provider) * 3. / 4;
+      break;
+    case GTK_CSS_FONT_SIZE_SMALL:
+      font_size = _gtk_css_font_size_get_default (provider) * 8. / 9;
+      break;
+    default:
+      g_assert_not_reached ();
+      /* fall thru */
+    case GTK_CSS_FONT_SIZE_MEDIUM:
+      font_size = _gtk_css_font_size_get_default (provider);
+      break;
+    case GTK_CSS_FONT_SIZE_LARGE:
+      font_size = _gtk_css_font_size_get_default (provider) * 6. / 5;
+      break;
+    case GTK_CSS_FONT_SIZE_X_LARGE:
+      font_size = _gtk_css_font_size_get_default (provider) * 3. / 2;
+      break;
+    case GTK_CSS_FONT_SIZE_XX_LARGE:
+      font_size = _gtk_css_font_size_get_default (provider) * 2;
+      break;
+    case GTK_CSS_FONT_SIZE_SMALLER:
+      *dependencies = GTK_CSS_DEPENDS_ON_PARENT;
+      if (parent_values)
+        font_size = _gtk_css_number_value_get (_gtk_css_computed_values_get_value (parent_values, GTK_CSS_PROPERTY_FONT_SIZE), 100);
+      else
+        font_size = _gtk_css_font_size_get_default (provider);
+      /* XXX: This is what WebKit does... */
+      font_size /= 1.2;
+      break;
+    case GTK_CSS_FONT_SIZE_LARGER:
+      *dependencies = GTK_CSS_DEPENDS_ON_PARENT;
+      if (parent_values)
+        font_size = _gtk_css_number_value_get (_gtk_css_computed_values_get_value (parent_values, GTK_CSS_PROPERTY_FONT_SIZE), 100);
+      else
+        font_size = _gtk_css_font_size_get_default (provider);
+      /* XXX: This is what WebKit does... */
+      font_size *= 1.2;
+      break;
+  }
+
+  return _gtk_css_number_value_new (font_size, GTK_CSS_PX);
+}
+
+static const GtkCssValueClass GTK_CSS_VALUE_FONT_SIZE = {
+  gtk_css_value_enum_free,
+  gtk_css_value_font_size_compute,
+  gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
+  gtk_css_value_enum_print
+};
+
+static GtkCssValue font_size_values[] = {
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALLER, "smaller" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGER, "larger" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALL, "small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_MEDIUM, "medium" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGE, "large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" }
+};
+
+GtkCssValue *
+_gtk_css_font_size_value_new (GtkCssFontSize font_size)
+{
+  g_return_val_if_fail (font_size < G_N_ELEMENTS (font_size_values), NULL);
+
+  return _gtk_css_value_ref (&font_size_values[font_size]);
+}
+
+GtkCssValue *
+_gtk_css_font_size_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (font_size_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, font_size_values[i].name, TRUE))
+        return _gtk_css_value_ref (&font_size_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkCssFontSize
+_gtk_css_font_size_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_SIZE, GTK_CSS_FONT_SIZE_MEDIUM);
+
+  return value->value;
+}
+
 /* PangoStyle */
 
 static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
   gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
   gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
   gtk_css_value_enum_print
 };
 
@@ -152,7 +323,9 @@ _gtk_css_font_style_value_get (const GtkCssValue *value)
 
 static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIANT = {
   gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
   gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
   gtk_css_value_enum_print
 };
 
@@ -197,7 +370,9 @@ _gtk_css_font_variant_value_get (const GtkCssValue *value)
 
 static const GtkCssValueClass GTK_CSS_VALUE_FONT_WEIGHT = {
   gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
   gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
   gtk_css_value_enum_print
 };
 
@@ -217,10 +392,13 @@ GtkCssValue *
 _gtk_css_font_weight_value_new (PangoWeight font_weight)
 {
   guint i;
+  gint w;
+
+  w = ((font_weight + 50) / 100) * 100;
 
   for (i = 0; i < G_N_ELEMENTS (font_weight_values); i++)
     {
-      if (font_weight_values[i].value == font_weight)
+      if (font_weight_values[i].value == w)
         return _gtk_css_value_ref (&font_weight_values[i]);
     }
 
@@ -256,3 +434,220 @@ _gtk_css_font_weight_value_get (const GtkCssValue *value)
   return value->value;
 }
 
+/* GtkCssArea */
+
+static const GtkCssValueClass GTK_CSS_VALUE_AREA = {
+  gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
+  gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
+  gtk_css_value_enum_print
+};
+
+static GtkCssValue area_values[] = {
+  { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_BORDER_BOX, "border-box" },
+  { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_PADDING_BOX, "padding-box" },
+  { &GTK_CSS_VALUE_AREA, 1, GTK_CSS_AREA_CONTENT_BOX, "content-box" }
+};
+
+GtkCssValue *
+_gtk_css_area_value_new (GtkCssArea area)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (area_values); i++)
+    {
+      if (area_values[i].value == area)
+        return _gtk_css_value_ref (&area_values[i]);
+    }
+
+  g_return_val_if_reached (NULL);
+}
+
+GtkCssValue *
+_gtk_css_area_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (area_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, area_values[i].name, TRUE))
+        return _gtk_css_value_ref (&area_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkCssArea
+_gtk_css_area_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_AREA, GTK_CSS_AREA_BORDER_BOX);
+
+  return value->value;
+}
+
+/* GtkCssDirection */
+
+static const GtkCssValueClass GTK_CSS_VALUE_DIRECTION = {
+  gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
+  gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
+  gtk_css_value_enum_print
+};
+
+static GtkCssValue direction_values[] = {
+  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_NORMAL, "normal" },
+  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_REVERSE, "reverse" },
+  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE, "alternate" },
+  { &GTK_CSS_VALUE_DIRECTION, 1, GTK_CSS_DIRECTION_ALTERNATE_REVERSE, "alternate-reverse" }
+};
+
+GtkCssValue *
+_gtk_css_direction_value_new (GtkCssDirection direction)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (direction_values); i++)
+    {
+      if (direction_values[i].value == direction)
+        return _gtk_css_value_ref (&direction_values[i]);
+    }
+
+  g_return_val_if_reached (NULL);
+}
+
+GtkCssValue *
+_gtk_css_direction_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (direction_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, direction_values[i].name, TRUE))
+        return _gtk_css_value_ref (&direction_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkCssDirection
+_gtk_css_direction_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_DIRECTION, GTK_CSS_DIRECTION_NORMAL);
+
+  return value->value;
+}
+
+/* GtkCssPlayState */
+
+static const GtkCssValueClass GTK_CSS_VALUE_PLAY_STATE = {
+  gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
+  gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
+  gtk_css_value_enum_print
+};
+
+static GtkCssValue play_state_values[] = {
+  { &GTK_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_RUNNING, "running" },
+  { &GTK_CSS_VALUE_PLAY_STATE, 1, GTK_CSS_PLAY_STATE_PAUSED, "paused" }
+};
+
+GtkCssValue *
+_gtk_css_play_state_value_new (GtkCssPlayState play_state)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (play_state_values); i++)
+    {
+      if (play_state_values[i].value == play_state)
+        return _gtk_css_value_ref (&play_state_values[i]);
+    }
+
+  g_return_val_if_reached (NULL);
+}
+
+GtkCssValue *
+_gtk_css_play_state_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (play_state_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, play_state_values[i].name, TRUE))
+        return _gtk_css_value_ref (&play_state_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkCssPlayState
+_gtk_css_play_state_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_PLAY_STATE, GTK_CSS_PLAY_STATE_RUNNING);
+
+  return value->value;
+}
+
+/* GtkCssFillMode */
+
+static const GtkCssValueClass GTK_CSS_VALUE_FILL_MODE = {
+  gtk_css_value_enum_free,
+  gtk_css_value_enum_compute,
+  gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
+  gtk_css_value_enum_print
+};
+
+static GtkCssValue fill_mode_values[] = {
+  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_NONE, "none" },
+  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_FORWARDS, "forwards" },
+  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BACKWARDS, "backwards" },
+  { &GTK_CSS_VALUE_FILL_MODE, 1, GTK_CSS_FILL_BOTH, "both" }
+};
+
+GtkCssValue *
+_gtk_css_fill_mode_value_new (GtkCssFillMode fill_mode)
+{
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++)
+    {
+      if (fill_mode_values[i].value == fill_mode)
+        return _gtk_css_value_ref (&fill_mode_values[i]);
+    }
+
+  g_return_val_if_reached (NULL);
+}
+
+GtkCssValue *
+_gtk_css_fill_mode_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (fill_mode_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, fill_mode_values[i].name, TRUE))
+        return _gtk_css_value_ref (&fill_mode_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkCssFillMode
+_gtk_css_fill_mode_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FILL_MODE, GTK_CSS_FILL_NONE);
+
+  return value->value;
+}
+