mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-29 10:37:39 +00:00
popover: Flip popovers positioning on left/right on RTL.
If widgets have GTK_TEXT_DIRECTION_RTL, popovers being positioned on GTK_POS_LEFT/RIGHT will default to appearing on the other side too.
This commit is contained in:
parent
a3b3b4621c
commit
69182c03fb
@ -296,6 +296,21 @@ gtk_popover_get_pointed_to_coords (GtkPopover *popover,
|
|||||||
*rect_out = rect;
|
*rect_out = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkPositionType
|
||||||
|
get_effective_position (GtkPopover *popover,
|
||||||
|
GtkPositionType pos)
|
||||||
|
{
|
||||||
|
if (gtk_widget_get_direction (GTK_WIDGET (popover)) == GTK_TEXT_DIR_RTL)
|
||||||
|
{
|
||||||
|
if (pos == GTK_POS_LEFT)
|
||||||
|
pos = GTK_POS_RIGHT;
|
||||||
|
else if (pos == GTK_POS_RIGHT)
|
||||||
|
pos = GTK_POS_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_popover_get_gap_coords (GtkPopover *popover,
|
gtk_popover_get_gap_coords (GtkPopover *popover,
|
||||||
gint *initial_x_out,
|
gint *initial_x_out,
|
||||||
@ -313,7 +328,7 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
|
|||||||
gint initial_x, initial_y;
|
gint initial_x, initial_y;
|
||||||
gint tip_x, tip_y;
|
gint tip_x, tip_y;
|
||||||
gint final_x, final_y;
|
gint final_x, final_y;
|
||||||
GtkPositionType gap_side;
|
GtkPositionType gap_side, pos;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
gint border_radius;
|
gint border_radius;
|
||||||
|
|
||||||
@ -333,21 +348,21 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
|
|||||||
gtk_widget_get_state_flags (GTK_WIDGET (popover)),
|
gtk_widget_get_state_flags (GTK_WIDGET (popover)),
|
||||||
GTK_STYLE_PROPERTY_BORDER_RADIUS, &border_radius,
|
GTK_STYLE_PROPERTY_BORDER_RADIUS, &border_radius,
|
||||||
NULL);
|
NULL);
|
||||||
|
pos = get_effective_position (popover, priv->final_position);
|
||||||
|
|
||||||
if (priv->final_position == GTK_POS_BOTTOM ||
|
if (pos == GTK_POS_BOTTOM || pos == GTK_POS_RIGHT)
|
||||||
priv->final_position == GTK_POS_RIGHT)
|
|
||||||
{
|
{
|
||||||
base = TAIL_HEIGHT;
|
base = TAIL_HEIGHT;
|
||||||
tip = 0;
|
tip = 0;
|
||||||
gap_side = (priv->final_position == GTK_POS_BOTTOM) ? GTK_POS_TOP : GTK_POS_LEFT;
|
gap_side = (priv->final_position == GTK_POS_BOTTOM) ? GTK_POS_TOP : GTK_POS_LEFT;
|
||||||
}
|
}
|
||||||
else if (priv->final_position == GTK_POS_TOP)
|
else if (pos == GTK_POS_TOP)
|
||||||
{
|
{
|
||||||
base = allocation.height - TAIL_HEIGHT;
|
base = allocation.height - TAIL_HEIGHT;
|
||||||
tip = allocation.height;
|
tip = allocation.height;
|
||||||
gap_side = GTK_POS_BOTTOM;
|
gap_side = GTK_POS_BOTTOM;
|
||||||
}
|
}
|
||||||
else if (priv->final_position == GTK_POS_LEFT)
|
else if (pos == GTK_POS_LEFT)
|
||||||
{
|
{
|
||||||
base = allocation.width - TAIL_HEIGHT;
|
base = allocation.width - TAIL_HEIGHT;
|
||||||
tip = allocation.width;
|
tip = allocation.width;
|
||||||
@ -356,7 +371,7 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
|
|||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
|
||||||
if (POS_IS_VERTICAL (priv->final_position))
|
if (POS_IS_VERTICAL (pos))
|
||||||
{
|
{
|
||||||
tip_pos = rect.x + (rect.width / 2);
|
tip_pos = rect.x + (rect.width / 2);
|
||||||
initial_x = CLAMP (tip_pos - TAIL_GAP_WIDTH / 2,
|
initial_x = CLAMP (tip_pos - TAIL_GAP_WIDTH / 2,
|
||||||
@ -415,6 +430,7 @@ gtk_popover_get_rect_coords (GtkPopover *popover,
|
|||||||
GtkWidget *widget = GTK_WIDGET (popover);
|
GtkWidget *widget = GTK_WIDGET (popover);
|
||||||
GtkPopoverPrivate *priv = popover->priv;
|
GtkPopoverPrivate *priv = popover->priv;
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
|
GtkPositionType pos;
|
||||||
gint x1, x2, y1, y2;
|
gint x1, x2, y1, y2;
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
@ -430,13 +446,15 @@ gtk_popover_get_rect_coords (GtkPopover *popover,
|
|||||||
y2 = allocation.height -
|
y2 = allocation.height -
|
||||||
gtk_widget_get_margin_bottom (widget) + y1;
|
gtk_widget_get_margin_bottom (widget) + y1;
|
||||||
|
|
||||||
if (priv->final_position == GTK_POS_TOP)
|
pos = get_effective_position (popover, priv->final_position);
|
||||||
|
|
||||||
|
if (pos == GTK_POS_TOP)
|
||||||
y2 -= TAIL_HEIGHT;
|
y2 -= TAIL_HEIGHT;
|
||||||
else if (priv->final_position == GTK_POS_BOTTOM)
|
else if (pos == GTK_POS_BOTTOM)
|
||||||
y1 += TAIL_HEIGHT;
|
y1 += TAIL_HEIGHT;
|
||||||
else if (priv->final_position == GTK_POS_LEFT)
|
else if (pos == GTK_POS_LEFT)
|
||||||
x2 -= TAIL_HEIGHT;
|
x2 -= TAIL_HEIGHT;
|
||||||
else if (priv->final_position == GTK_POS_RIGHT)
|
else if (pos == GTK_POS_RIGHT)
|
||||||
x1 += TAIL_HEIGHT;
|
x1 += TAIL_HEIGHT;
|
||||||
|
|
||||||
if (x1_out)
|
if (x1_out)
|
||||||
@ -547,6 +565,7 @@ gtk_popover_update_position (GtkPopover *popover)
|
|||||||
GtkAllocation window_alloc;
|
GtkAllocation window_alloc;
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
GtkPopoverPrivate *priv;
|
GtkPopoverPrivate *priv;
|
||||||
|
GtkPositionType pos;
|
||||||
GtkRequisition req;
|
GtkRequisition req;
|
||||||
|
|
||||||
priv = popover->priv;
|
priv = popover->priv;
|
||||||
@ -559,20 +578,19 @@ gtk_popover_update_position (GtkPopover *popover)
|
|||||||
priv->final_position = priv->preferred_position;
|
priv->final_position = priv->preferred_position;
|
||||||
|
|
||||||
gtk_popover_get_pointed_to_coords (popover, &rect);
|
gtk_popover_get_pointed_to_coords (popover, &rect);
|
||||||
|
pos = get_effective_position (popover, priv->preferred_position);
|
||||||
|
|
||||||
/* Check whether there's enough room on the
|
/* Check whether there's enough room on the
|
||||||
* preferred side, move to the opposite one if not.
|
* preferred side, move to the opposite one if not.
|
||||||
*/
|
*/
|
||||||
if (priv->preferred_position == GTK_POS_TOP && rect.y < req.height)
|
if (pos == GTK_POS_TOP && rect.y < req.height)
|
||||||
priv->final_position = GTK_POS_BOTTOM;
|
priv->final_position = GTK_POS_BOTTOM;
|
||||||
else if (priv->preferred_position == GTK_POS_BOTTOM &&
|
else if (pos == GTK_POS_BOTTOM && rect.y > window_alloc.height - req.height)
|
||||||
rect.y > window_alloc.height - req.height)
|
|
||||||
priv->final_position = GTK_POS_TOP;
|
priv->final_position = GTK_POS_TOP;
|
||||||
else if (priv->preferred_position == GTK_POS_LEFT && rect.x < req.width)
|
else if (pos == GTK_POS_LEFT && rect.x < req.width)
|
||||||
priv->final_position = GTK_POS_RIGHT;
|
priv->final_position = get_effective_position (popover, GTK_POS_RIGHT);
|
||||||
else if (priv->preferred_position == GTK_POS_RIGHT &&
|
else if (pos == GTK_POS_RIGHT && rect.x > window_alloc.width - req.width)
|
||||||
rect.x > window_alloc.width - req.width)
|
priv->final_position = get_effective_position (popover, GTK_POS_LEFT);
|
||||||
priv->final_position = GTK_POS_LEFT;
|
|
||||||
|
|
||||||
gtk_window_set_popover_position (priv->window, GTK_WIDGET (popover),
|
gtk_window_set_popover_position (priv->window, GTK_WIDGET (popover),
|
||||||
priv->final_position, &rect);
|
priv->final_position, &rect);
|
||||||
|
@ -5776,7 +5776,8 @@ popover_get_rect (GtkWindowPopover *popover,
|
|||||||
rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) -
|
rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) -
|
||||||
(req.height / 2), 0, win_alloc.height - req.height);
|
(req.height / 2), 0, win_alloc.height - req.height);
|
||||||
|
|
||||||
if (popover->pos == GTK_POS_LEFT)
|
if ((popover->pos == GTK_POS_LEFT) ==
|
||||||
|
(gtk_widget_get_direction (popover->widget) == GTK_TEXT_DIR_LTR))
|
||||||
{
|
{
|
||||||
rect->x = popover->rect.x - req.width;
|
rect->x = popover->rect.x - req.width;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user