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
This commit is contained in:
107
gtk/gtkoverlay.c
107
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)
|
||||
@@ -158,6 +173,82 @@ gtk_overlay_get_main_widget_allocation (GtkOverlay *overlay,
|
||||
*main_alloc_out = main_alloc;
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user