diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2012-02-03 15:33:30 -0500 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2012-02-29 12:28:24 -0500 |
commit | d1aa797be306d27c91df8ea3b20c2b3eb773df61 (patch) | |
tree | 5fe92997e34d8646947ae87c2c4e91dad6c59009 | |
parent | 170e8712e9bfe792da29d6a3d1fb7a71fbe17336 (diff) | |
download | gtk+-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
-rw-r--r-- | gtk/gtkoverlay.c | 107 |
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, |