summaryrefslogtreecommitdiff
path: root/gtk/gtkoverlay.c
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimoc@gnome.org>2012-02-03 15:33:30 -0500
committerCosimo Cecchi <cosimoc@gnome.org>2012-02-29 12:28:24 -0500
commitd1aa797be306d27c91df8ea3b20c2b3eb773df61 (patch)
tree5fe92997e34d8646947ae87c2c4e91dad6c59009 /gtk/gtkoverlay.c
parent170e8712e9bfe792da29d6a3d1fb7a71fbe17336 (diff)
downloadgtk+-d1aa797be306d27c91df8ea3b20c2b3eb773df61.tar.gz
overlay: add left/right/top/bottom style classes to overlay children
When we're allocating children of GtkOverlay, compare their allocation with the overlay one, and set left/right/top/bottom style classes if the overlaid widget touches one or more of the overlay edges. https://bugzilla.gnome.org/show_bug.cgi?id=669342
Diffstat (limited to 'gtk/gtkoverlay.c')
-rw-r--r--gtk/gtkoverlay.c107
1 files changed, 92 insertions, 15 deletions
diff --git a/gtk/gtkoverlay.c b/gtk/gtkoverlay.c
index e27384916d..ff046e9852 100644
--- a/gtk/gtkoverlay.c
+++ b/gtk/gtkoverlay.c
@@ -113,6 +113,21 @@ gtk_overlay_create_child_window (GtkOverlay *overlay,
return window;
}
+static GtkAlign
+effective_align (GtkAlign align,
+ GtkTextDirection direction)
+{
+ switch (align)
+ {
+ case GTK_ALIGN_START:
+ return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
+ case GTK_ALIGN_END:
+ return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
+ default:
+ return align;
+ }
+}
+
static void
gtk_overlay_get_main_widget_allocation (GtkOverlay *overlay,
GtkAllocation *main_alloc_out)
@@ -159,6 +174,82 @@ gtk_overlay_get_main_widget_allocation (GtkOverlay *overlay,
}
static void
+gtk_overlay_child_update_style_classes (GtkOverlay *overlay,
+ GtkWidget *child,
+ GtkAllocation *child_allocation)
+{
+ GtkAllocation overlay_allocation, main_allocation;
+ GtkAlign valign, halign;
+ gboolean is_left, is_right, is_top, is_bottom;
+ gboolean has_left, has_right, has_top, has_bottom;
+ GtkStyleContext *context;
+ gint changed;
+
+ context = gtk_widget_get_style_context (child);
+ has_left = gtk_style_context_has_class (context, GTK_STYLE_CLASS_LEFT);
+ has_right = gtk_style_context_has_class (context, GTK_STYLE_CLASS_RIGHT);
+ has_top = gtk_style_context_has_class (context, GTK_STYLE_CLASS_TOP);
+ has_bottom = gtk_style_context_has_class (context, GTK_STYLE_CLASS_BOTTOM);
+
+ is_left = is_right = is_top = is_bottom = FALSE;
+ changed = 4;
+
+ gtk_overlay_get_main_widget_allocation (overlay, &main_allocation);
+ gtk_widget_get_allocation (GTK_WIDGET (overlay), &overlay_allocation);
+
+ main_allocation.x += overlay_allocation.x;
+ main_allocation.y += overlay_allocation.y;
+
+ halign = effective_align (gtk_widget_get_halign (child),
+ gtk_widget_get_direction (child));
+
+ if (halign == GTK_ALIGN_START)
+ is_left = (child_allocation->x == main_allocation.x);
+ else if (halign == GTK_ALIGN_END)
+ is_right = (child_allocation->x + child_allocation->width ==
+ main_allocation.x + main_allocation.width);
+
+ valign = gtk_widget_get_valign (child);
+
+ if (valign == GTK_ALIGN_START)
+ is_top = (child_allocation->y == main_allocation.y);
+ else if (valign == GTK_ALIGN_END)
+ is_bottom = (child_allocation->y + child_allocation->height ==
+ main_allocation.y + main_allocation.height);
+
+ if (has_left && !is_left)
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
+ else if (!has_left && is_left)
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
+ else
+ changed--;
+
+ if (has_right && !is_right)
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
+ else if (!has_right && is_right)
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
+ else
+ changed--;
+
+ if (has_top && !is_top)
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TOP);
+ else if (!has_top && is_top)
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
+ else
+ changed--;
+
+ if (has_bottom && !is_bottom)
+ gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BOTTOM);
+ else if (!has_bottom && is_bottom)
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
+ else
+ changed--;
+
+ if (changed > 0)
+ gtk_widget_reset_style (child);
+}
+
+static void
gtk_overlay_child_allocate (GtkOverlay *overlay,
GtkOverlayChild *child)
{
@@ -208,6 +299,7 @@ gtk_overlay_child_allocate (GtkOverlay *overlay,
allocation.x, allocation.y,
allocation.width, allocation.height);
+ gtk_overlay_child_update_style_classes (overlay, child->widget, &allocation);
gtk_widget_size_allocate (child->widget, &child_allocation);
}
@@ -272,21 +364,6 @@ gtk_overlay_size_allocate (GtkWidget *widget,
}
}
-static GtkAlign
-effective_align (GtkAlign align,
- GtkTextDirection direction)
-{
- switch (align)
- {
- case GTK_ALIGN_START:
- return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
- case GTK_ALIGN_END:
- return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
- default:
- return align;
- }
-}
-
static gboolean
gtk_overlay_get_child_position (GtkOverlay *overlay,
GtkWidget *widget,