[gtk+/wip/css-is-awesome: 1/3] widget: Add new helper methods for implementing CSS box model semantics



commit d055d0af8ba150d72f2284f19e156ee5125fbf7f
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Nov 1 14:08:54 2013 -0400

    widget: Add new helper methods for implementing CSS box model semantics
    
    Based on the approach used in gnome-shell's "St", we add a few new
    helper methods so that widgets can upgrade to a CSS box model at
    their own leisure, without a bunch of copy/paste code as had been
    carried out in a bunch of other widgets.

 gtk/gtkwidget.c        |  155 ++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwidgetprivate.h |   14 ++++
 2 files changed, 169 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 21d02f3..f6494ad 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -16011,3 +16011,158 @@ gtk_widget_get_template_child (GtkWidget   *widget,
 
   return ret;
 }
+
+static int
+get_width_inc (GtkStyleContext *context)
+{
+  return (_gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_PADDING_LEFT), 0) +
+          _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_PADDING_RIGHT), 0) +
+          _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 0) +
+          _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH), 0));
+}
+
+static int
+get_height_inc (GtkStyleContext *context)
+{
+  return (_gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_PADDING_TOP), 0) +
+          _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_PADDING_BOTTOM), 0) +
+          _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 0) +
+          _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH), 0));
+}
+
+/**
+ * _gtk_widget_get_context_box:
+ * @context: A #GtkWidget
+ * @box: The input allocation
+ * @content_box: (out): The content box for the widget
+ *
+ * Given an input allocation, @box, this calculates the "context box"
+ * in CSS box model terms. Currently this simply subtracts padding
+ * and border from the input allocation, but in the future could be
+ * expanded to reflect the addition of a 'box-sizing' property in CSS.
+ *
+ * This is meant as a helper method for widgets to use in their
+ * size_allocate() implementation.
+ *
+ * Since: 3.12
+ */
+void
+_gtk_widget_get_content_box (GtkWidget     *widget,
+                             GtkAllocation *box,
+                             GtkAllocation *content_box)
+{
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+
+  content_box->x = (_gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_PADDING_LEFT), 0) +
+                    _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH), 0));
+  content_box->y = (_gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_PADDING_TOP), 0) +
+                    _gtk_css_number_value_get (_gtk_style_context_peek_property (context, 
GTK_CSS_PROPERTY_BORDER_TOP_WIDTH), 0));
+
+  content_box->width = MAX (box->width - get_width_inc (context), 0);
+  content_box->height = MAX (box->height - get_height_inc (context), 0);
+}
+
+/**
+ * _gtk_widget_adjust_for_width:
+ * @widget: A #GtkWidget
+ * @for_width: (inout): The width request
+ *
+ * Adjusts @for_width to remove elements outside the content box,
+ * such as padding and border.
+ *
+ * This is meant as a helper method for widgets to use at the top
+ * of their get_preferred_height_for_width() implementation.
+ *
+ * Since: 3.12
+ */
+void
+_gtk_widget_adjust_for_width (GtkWidget *widget,
+                              int       *for_width)
+{
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+  if (*for_width >= 0)
+    *for_width = MAX (0, *for_width - get_width_inc (context));
+}
+
+/**
+ * _gtk_widget_adjust_preferred_width:
+ * @widget: A #GtkWidget
+ * @minimum_width: (inout): The minimum width
+ * @natural_width: (inout): The natural width
+ *
+ * Adjusts @minimum_width and @natural_width to include elements
+ * outside the content box, such as padding and border.
+ *
+ * This is meant as a helper method for widgets to use at the bottom
+ * of their get_preferred_width() and get_preferred_width_for_height()
+ * implementations: simply calculate the width required for the
+ * content, and adjust it with this method to make sure you've
+ * calculated everything correctly.
+ *
+ * Since: 3.12
+ */
+void
+_gtk_widget_adjust_preferred_width (GtkWidget *widget,
+                                    int       *minimum_width,
+                                    int       *natural_width)
+{
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+  int width_inc = get_width_inc (context);
+
+  if (minimum_width)
+    *minimum_width += width_inc;
+  if (natural_width)
+    *natural_width += width_inc;
+}
+
+/**
+ * _gtk_widget_adjust_for_height:
+ * @widget: A #GtkWidget
+ * @for_height: (inout): The height request
+ *
+ * Adjusts @for_height to remove elements outside the content box.
+ *
+ * This is meant as a helper method for widgets to use at the top
+ * of their get_preferred_width_for_height() implementation.
+ *
+ * Since: 3.12
+ */
+void
+_gtk_widget_adjust_for_height (GtkWidget *widget,
+                               int       *for_height)
+{
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+  if (*for_height >= 0)
+    *for_height = MAX (0, *for_height - get_height_inc (context));
+}
+
+/**
+ * _gtk_widget_adjust_preferred_height:
+ * @widget: A #GtkWidget
+ * @minimum_height: (inout): The minimum height
+ * @natural_height: (inout): The natural height
+ *
+ * Adjusts @minimum_height and @natural_height to include elements
+ * outside the content box, such as padding and border.
+ *
+ * This is meant as a helper method for widgets to use at the bottom
+ * of their get_preferred_height() and get_preferred_height_for_width()
+ * implementations: simply calculate the height required for the
+ * content, and adjust it with this method to make sure you've
+ * calculated everything correctly.
+ *
+ * Since: 3.12
+ */
+void
+_gtk_widget_adjust_preferred_height (GtkWidget *widget,
+                                     int       *minimum_height,
+                                     int       *natural_height)
+{
+  GtkStyleContext *context = gtk_widget_get_style_context (widget);
+  int height_inc = get_height_inc (context);
+
+  if (minimum_height)
+    *minimum_height += height_inc;
+  if (natural_height)
+    *natural_height += height_inc;
+}
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 7cf15f8..b553f86 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -149,6 +149,20 @@ void              _gtk_widget_style_context_invalidated    (GtkWidget    *widget
 void              _gtk_widget_update_parent_muxer          (GtkWidget    *widget);
 GtkActionMuxer *  _gtk_widget_get_action_muxer             (GtkWidget    *widget);
 
+void              _gtk_widget_get_content_box              (GtkWidget     *widget,
+                                                            GtkAllocation *box,
+                                                            GtkAllocation *content_box);
+void              _gtk_widget_adjust_for_width             (GtkWidget     *widget,
+                                                            int           *for_width);
+void              _gtk_widget_adjust_preferred_width       (GtkWidget     *widget,
+                                                            int           *minimum_width,
+                                                            int           *natural_width);
+void              _gtk_widget_adjust_for_height            (GtkWidget     *widget,
+                                                            int           *for_height);
+void              _gtk_widget_adjust_preferred_height      (GtkWidget     *widget,
+                                                            int           *minimum_height,
+                                                            int           *natural_height);
+
 G_END_DECLS
 
 #endif /* __GTK_WIDGET_PRIVATE_H__ */


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