[gtk+/popovers: 37/45] popover: Flip popovers positioning on left/right on RTL.



commit 7a4655c87515a1886f9b8542da6cdb425cc183f0
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Jan 14 12:31:25 2014 +0100

    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.

 gtk/gtkpopover.c |   54 ++++++++++++++++++++++++++++++++++++------------------
 gtk/gtkwindow.c  |    3 ++-
 2 files changed, 38 insertions(+), 19 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 6420881..2370bef 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -296,6 +296,21 @@ gtk_popover_get_pointed_to_coords (GtkPopover            *popover,
   *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
 gtk_popover_get_gap_coords (GtkPopover      *popover,
                             gint            *initial_x_out,
@@ -313,7 +328,7 @@ gtk_popover_get_gap_coords (GtkPopover      *popover,
   gint initial_x, initial_y;
   gint tip_x, tip_y;
   gint final_x, final_y;
-  GtkPositionType gap_side;
+  GtkPositionType gap_side, pos;
   GtkAllocation allocation;
   gint border_radius;
 
@@ -333,21 +348,21 @@ gtk_popover_get_gap_coords (GtkPopover      *popover,
                          gtk_widget_get_state_flags (GTK_WIDGET (popover)),
                          GTK_STYLE_PROPERTY_BORDER_RADIUS, &border_radius,
                          NULL);
+  pos = get_effective_position (popover, priv->final_position);
 
-  if (priv->final_position == GTK_POS_BOTTOM ||
-      priv->final_position == GTK_POS_RIGHT)
+  if (pos == GTK_POS_BOTTOM || pos == GTK_POS_RIGHT)
     {
       base = TAIL_HEIGHT;
       tip = 0;
       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;
       tip = allocation.height;
       gap_side = GTK_POS_BOTTOM;
     }
-  else if (priv->final_position == GTK_POS_LEFT)
+  else if (pos == GTK_POS_LEFT)
     {
       base = allocation.width - TAIL_HEIGHT;
       tip = allocation.width;
@@ -356,7 +371,7 @@ gtk_popover_get_gap_coords (GtkPopover      *popover,
   else
     g_assert_not_reached ();
 
-  if (POS_IS_VERTICAL (priv->final_position))
+  if (POS_IS_VERTICAL (pos))
     {
       tip_pos = rect.x + (rect.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);
   GtkPopoverPrivate *priv = popover->priv;
   GtkAllocation allocation;
+  GtkPositionType pos;
   gint x1, x2, y1, y2;
 
   gtk_widget_get_allocation (widget, &allocation);
@@ -430,13 +446,15 @@ gtk_popover_get_rect_coords (GtkPopover *popover,
   y2 = allocation.height -
     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;
-  else if (priv->final_position == GTK_POS_BOTTOM)
+  else if (pos == GTK_POS_BOTTOM)
     y1 += TAIL_HEIGHT;
-  else if (priv->final_position == GTK_POS_LEFT)
+  else if (pos == GTK_POS_LEFT)
     x2 -= TAIL_HEIGHT;
-  else if (priv->final_position == GTK_POS_RIGHT)
+  else if (pos == GTK_POS_RIGHT)
     x1 += TAIL_HEIGHT;
 
   if (x1_out)
@@ -547,6 +565,7 @@ gtk_popover_update_position (GtkPopover *popover)
   GtkAllocation window_alloc;
   cairo_rectangle_int_t rect;
   GtkPopoverPrivate *priv;
+  GtkPositionType pos;
   GtkRequisition req;
 
   priv = popover->priv;
@@ -559,20 +578,19 @@ gtk_popover_update_position (GtkPopover *popover)
   priv->final_position = priv->preferred_position;
 
   gtk_popover_get_pointed_to_coords (popover, &rect);
+  pos = get_effective_position (popover, priv->preferred_position);
 
   /* Check whether there's enough room on the
    * 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;
-  else if (priv->preferred_position == GTK_POS_BOTTOM &&
-           rect.y > window_alloc.height - req.height)
+  else if (pos == GTK_POS_BOTTOM && rect.y > window_alloc.height - req.height)
     priv->final_position = GTK_POS_TOP;
-  else if (priv->preferred_position == GTK_POS_LEFT && rect.x < req.width)
-    priv->final_position = GTK_POS_RIGHT;
-  else if (priv->preferred_position == GTK_POS_RIGHT &&
-           rect.x > window_alloc.width - req.width)
-    priv->final_position = GTK_POS_LEFT;
+  else if (pos == GTK_POS_LEFT && rect.x < req.width)
+    priv->final_position = get_effective_position (popover, GTK_POS_RIGHT);
+  else if (pos == GTK_POS_RIGHT && rect.x > window_alloc.width - req.width)
+    priv->final_position = get_effective_position (popover, GTK_POS_LEFT);
 
   gtk_window_set_popover_position (priv->window, GTK_WIDGET (popover),
                                    priv->final_position, &rect);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 2921fd2..77101dc 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -5769,7 +5769,8 @@ popover_get_rect (GtkWindowPopover      *popover,
         rect->y = CLAMP (popover->rect.y + (popover->rect.height / 2) -
                          (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;
 


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