listview: Simplify a vfunc
authorBenjamin Otte <otte@redhat.com>
Fri, 3 Mar 2023 01:20:17 +0000 (02:20 +0100)
committerBenjamin Otte <otte.benjamin@googlemail.com>
Sun, 5 Mar 2023 15:23:20 +0000 (15:23 +0000)
Instead of making it 2 vfuncs for getting horizontal and vertical area,
make it one vfunc to get the area.

Also rewrite the implementations to use the tile's area instead of
trying to deduce things with fancy math.

gtk/gtkgridview.c
gtk/gtklistbase.c
gtk/gtklistbaseprivate.h
gtk/gtklistitemmanager.c
gtk/gtklistview.c

index 93d00a4537f130d9ab7ab4e126c39c9b5734a137..fa2b837af447aee2fdf701b978d895b409d488d3 100644 (file)
@@ -228,54 +228,37 @@ gtk_grid_view_split (GtkListBase *base,
 }
 
 static gboolean
-gtk_grid_view_get_allocation_along (GtkListBase *base,
-                                    guint        pos,
-                                    int         *offset,
-                                    int         *size)
+gtk_grid_view_get_allocation (GtkListBase  *base,
+                              guint         pos,
+                              GdkRectangle *area)
 {
   GtkGridView *self = GTK_GRID_VIEW (base);
   GtkListTile *tile;
-  guint remaining;
+  guint offset;
 
-  tile = gtk_list_item_manager_get_nth (self->item_manager, pos, &remaining);
-  if (tile->n_items <= self->n_columns)
+  tile = gtk_list_item_manager_get_nth (self->item_manager, pos, &offset);
+  if (tile == NULL || tile->area.width <= 0 || tile->area.height <= 0)
+    return FALSE;
+
+  *area = tile->area;
+
+  if (tile->n_items > self->n_columns)
     {
-      *offset = tile->area.y;
-      *size = tile->area.height;
+      area->height /= (tile->n_items / self->n_columns);
+      area->y += (offset / self->n_columns) * area->height;
+      offset %= self->n_columns;
     }
-  else
-    {
-      guint rows_in_tile = tile->n_items / self->n_columns;
-      guint row_height = tile->area.height / rows_in_tile;
-      guint row_index = remaining / self->n_columns;
 
-      *offset = tile->area.y  + row_index * row_height;
-      *size = row_height;
+  if (tile->n_items > 1)
+    {
+      guint col = area->x / self->column_width;
+      area->x = ceil ((col + offset) * self->column_width);
+      area->width = ceil ((col + offset + 1) * self->column_width) - area->x;
     }
 
   return TRUE;
 }
 
-static gboolean
-gtk_grid_view_get_allocation_across (GtkListBase *base,
-                                     guint        pos,
-                                     int         *offset,
-                                     int         *size)
-{
-  GtkGridView *self = GTK_GRID_VIEW (base);
-  guint start;
-
-  pos %= self->n_columns;
-  start = ceil (self->column_width * pos);
-
-  if (offset)
-    *offset = start;
-  if (size)
-    *size = ceil (self->column_width * (pos + 1)) - start;
-
-  return TRUE;
-}
-
 static gboolean
 gtk_grid_view_get_position_from_allocation (GtkListBase           *base,
                                             int                    x,
@@ -876,8 +859,7 @@ gtk_grid_view_class_init (GtkGridViewClass *klass)
   list_base_class->list_item_name = "child";
   list_base_class->list_item_role = GTK_ACCESSIBLE_ROLE_GRID_CELL;
   list_base_class->split = gtk_grid_view_split;
-  list_base_class->get_allocation_along = gtk_grid_view_get_allocation_along;
-  list_base_class->get_allocation_across = gtk_grid_view_get_allocation_across;
+  list_base_class->get_allocation = gtk_grid_view_get_allocation;
   list_base_class->get_items_in_rect = gtk_grid_view_get_items_in_rect;
   list_base_class->get_position_from_allocation = gtk_grid_view_get_position_from_allocation;
   list_base_class->move_focus_along = gtk_grid_view_move_focus_along;
index 2008f9a055e20d8555c338b0fc87517a5e45f212..1e4ee499a3cf62d1ee671183fb9818cb9a01d52e 100644 (file)
@@ -327,49 +327,22 @@ gtk_list_base_move_focus (GtkListBase    *self,
 }
 
 /*
- * gtk_list_base_get_allocation_along:
+ * gtk_list_base_get_allocation:
  * @self: a `GtkListBase`
- * @pos: item to get the size of
- * @offset: (out caller-allocates) (optional): set to the offset
- *   of the top/left of the item
- * @size: (out caller-allocates) (optional): set to the size of
- *   the item in the direction
+ * @pos: item to get the area of
+ * @area: (out caller-allocates): set to the area
+ *   occupied by the item
  *
- * Computes the allocation of the item in the direction along the sizing
- * axis.
+ * Computes the allocation of the item in the given position
  *
  * Returns: %TRUE if the item exists and has an allocation, %FALSE otherwise
  **/
 static gboolean
-gtk_list_base_get_allocation_along (GtkListBase *self,
-                                    guint        pos,
-                                    int         *offset,
-                                    int         *size)
+gtk_list_base_get_allocation (GtkListBase  *self,
+                              guint         pos,
+                              GdkRectangle *area)
 {
-  return GTK_LIST_BASE_GET_CLASS (self)->get_allocation_along (self, pos, offset, size);
-}
-
-/*
- * gtk_list_base_get_allocation_across:
- * @self: a `GtkListBase`
- * @pos: item to get the size of
- * @offset: (out caller-allocates) (optional): set to the offset
- *   of the top/left of the item
- * @size: (out caller-allocates) (optional): set to the size of
- *   the item in the direction
- *
- * Computes the allocation of the item in the direction across to the sizing
- * axis.
- *
- * Returns: %TRUE if the item exists and has an allocation, %FALSE otherwise
- **/
-static gboolean
-gtk_list_base_get_allocation_across (GtkListBase *self,
-                                     guint        pos,
-                                     int         *offset,
-                                     int         *size)
-{
-  return GTK_LIST_BASE_GET_CLASS (self)->get_allocation_across (self, pos, offset, size);
+  return GTK_LIST_BASE_GET_CLASS (self)->get_allocation (self, pos, area);
 }
 
 /*
@@ -807,29 +780,22 @@ gtk_list_base_scroll_to_item (GtkListBase *self,
                               guint        pos)
 {
   GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
-  int start, end;
   double align_along, align_across;
   GtkPackType side_along, side_across;
+  GdkRectangle area;
 
-  /* figure out primary orientation and if position is valid */
-  if (!gtk_list_base_get_allocation_along (GTK_LIST_BASE (self), pos, &start, &end))
+  if (!gtk_list_base_get_allocation (GTK_LIST_BASE (self), pos, &area))
     return;
 
-  end += start;
   gtk_list_base_compute_scroll_align (self,
                                       gtk_list_base_get_orientation (GTK_LIST_BASE (self)),
-                                      start, end,
+                                      area.y, area.y + area.height,
                                       priv->anchor_align_along, priv->anchor_side_along,
                                       &align_along, &side_along);
 
-  /* now do the same thing with the other orientation */
-  if (!gtk_list_base_get_allocation_across (GTK_LIST_BASE (self), pos, &start, &end))
-    return;
-
-  end += start;
   gtk_list_base_compute_scroll_align (self,
                                       gtk_list_base_get_opposite_orientation (GTK_LIST_BASE (self)),
-                                      start, end,
+                                      area.x, area.x + area.width,
                                       priv->anchor_align_across, priv->anchor_side_across,
                                       &align_across, &side_across);
 
@@ -959,8 +925,7 @@ gtk_list_base_move_cursor_page_up (GtkWidget *widget,
 
   pos = gtk_list_base_get_focus_position (self);
   page_size = gtk_adjustment_get_page_size (priv->adjustment[priv->orientation]);
-  if (!gtk_list_base_get_allocation_along (self, pos, &area.y, &area.height) ||
-      !gtk_list_base_get_allocation_across (self, pos, &area.x, &area.width))
+  if (!gtk_list_base_get_allocation (self, pos, &area))
     return TRUE;
   if (!gtk_list_base_get_position_from_allocation (self,
                                                    area.x + area.width / 2,
@@ -1005,8 +970,7 @@ gtk_list_base_move_cursor_page_down (GtkWidget *widget,
   if (end == 0)
     return TRUE;
 
-  if (!gtk_list_base_get_allocation_along (self, pos, &area.y, &area.height) ||
-      !gtk_list_base_get_allocation_across (self, pos, &area.x, &area.width))
+  if (!gtk_list_base_get_allocation (self, pos, &area))
     return TRUE;
 
   if (!gtk_list_base_get_position_from_allocation (self,
@@ -1510,13 +1474,13 @@ gtk_list_base_get_rubberband_coords (GtkListBase  *self,
     }
   else
     {
+      GdkRectangle area;
       guint pos = gtk_list_item_tracker_get_position (priv->item_manager, priv->rubberband->start_tracker);
 
-      if (gtk_list_base_get_allocation_along (self, pos, &y1, &y2) &&
-          gtk_list_base_get_allocation_across (self, pos, &x1, &x2))
+      if (gtk_list_base_get_allocation (self, pos, &area))
         {
-          x1 += x2 * priv->rubberband->start_align_across;
-          y1 += y2 * priv->rubberband->start_align_along;
+          x1 = area.x + area.width * priv->rubberband->start_align_across;
+          y1 = area.y + area.height * priv->rubberband->start_align_along;
         }
       else
         {
@@ -1947,7 +1911,7 @@ gtk_list_base_update_adjustments (GtkListBase *self)
 {
   GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
   GdkRectangle bounds;
-  int value_along, value_across, size;
+  int value_along, value_across;
   int page_along, page_across;
   guint pos;
 
@@ -1966,24 +1930,22 @@ gtk_list_base_update_adjustments (GtkListBase *self)
     }
   else
     {
-      if (gtk_list_base_get_allocation_across (self, pos, &value_across, &size))
+      GdkRectangle area;
+
+      if (gtk_list_base_get_allocation (self, pos, &area))
         {
+          value_across = area.x;
+          value_along = area.y;
           if (priv->anchor_side_across == GTK_PACK_END)
-            value_across += size;
-          value_across -= priv->anchor_align_across * page_across;
-        }
-      else
-        {
-          value_along = 0;
-        }
-      if (gtk_list_base_get_allocation_along (self, pos, &value_along, &size))
-        {
+            value_across += area.width;
           if (priv->anchor_side_along == GTK_PACK_END)
-            value_along += size;
+            value_along += area.height;
+          value_across -= priv->anchor_align_across * page_across;
           value_along -= priv->anchor_align_along * page_along;
         }
       else
         {
+          value_across = 0;
           value_along = 0;
         }
     }
index a418bec6cd3741c3ae5cf7b01ecec61bae63ef34..2915ec67fa0a04678a2f920c096a81362c48eac8 100644 (file)
@@ -43,14 +43,9 @@ struct _GtkListBaseClass
 
   void                 (* adjustment_value_changed)             (GtkListBase            *self,
                                                                  GtkOrientation          orientation);
-  gboolean             (* get_allocation_along)                 (GtkListBase            *self,
+  gboolean             (* get_allocation)                       (GtkListBase            *self,
                                                                  guint                   pos,
-                                                                 int                    *offset,
-                                                                 int                    *size);
-  gboolean             (* get_allocation_across)                (GtkListBase            *self,
-                                                                 guint                   pos,
-                                                                 int                    *offset,
-                                                                 int                    *size);
+                                                                 GdkRectangle           *area);
   gboolean             (* get_position_from_allocation)         (GtkListBase            *self,
                                                                  int                     across,
                                                                  int                     along,
index d2ba9aaa10a262f87d558fcba02420ac5f89cc0d..2b7ddaa9f1f95cdbc67079b14f871eba611a5b69 100644 (file)
@@ -170,7 +170,7 @@ gtk_list_item_manager_get_tile_bounds (GtkListItemManager *self,
   tile = gtk_rb_tree_get_root (self->items);
   if (tile == NULL)
     {
-      *out_bounds = &(GdkRectangle) { 0, 0, 0, 0 };
+      *out_bounds = (GdkRectangle) { 0, 0, 0, 0 };
       return;
     }
 
index 408870bccd8fe7ee4887da9599f858a4e740c6d9..9904bf1072b6faf13c05fcb6a9956a1737e016dc 100644 (file)
@@ -229,50 +229,25 @@ gtk_list_view_split (GtkListBase *base,
 }
 
 static gboolean
-gtk_list_view_get_allocation_along (GtkListBase *base,
-                                    guint        pos,
-                                    int         *offset,
-                                    int         *size)
+gtk_list_view_get_allocation (GtkListBase  *base,
+                              guint         pos,
+                              GdkRectangle *area)
 {
   GtkListView *self = GTK_LIST_VIEW (base);
   GtkListTile *tile;
-  guint skip;
-  int row_height;
+  guint offset;
 
-  tile = gtk_list_item_manager_get_nth (self->item_manager, pos, &skip);
+  tile = gtk_list_item_manager_get_nth (self->item_manager, pos, &offset);
   if (tile == NULL)
-    {
-      if (offset)
-        *offset = 0;
-      if (size)
-        *size = 0;
-      return FALSE;
-    }
-
-  row_height = tile->area.height / tile->n_items;
-
-  if (offset)
-    *offset = tile->area.y + skip * row_height;
-  if (size)
-    *size = row_height;
-
-  return TRUE;
-}
-
-static gboolean
-gtk_list_view_get_allocation_across (GtkListBase *base,
-                                     guint        pos,
-                                     int         *offset,
-                                     int         *size)
-{
-  GtkListView *self = GTK_LIST_VIEW (base);
+    return FALSE;
 
+  *area = tile->area;
+  if (tile->n_items)
+    area->height /= tile->n_items;
   if (offset)
-    *offset = 0;
-  if (size)
-    *size = self->list_width;
+    area->y += offset * area->height;
 
-  return TRUE;
+  return area->width > 0 && area->height > 0;
 }
 
 static GtkBitset *
@@ -683,8 +658,7 @@ gtk_list_view_class_init (GtkListViewClass *klass)
   list_base_class->list_item_name = "row";
   list_base_class->list_item_role = GTK_ACCESSIBLE_ROLE_LIST_ITEM;
   list_base_class->split = gtk_list_view_split;
-  list_base_class->get_allocation_along = gtk_list_view_get_allocation_along;
-  list_base_class->get_allocation_across = gtk_list_view_get_allocation_across;
+  list_base_class->get_allocation = gtk_list_view_get_allocation;
   list_base_class->get_items_in_rect = gtk_list_view_get_items_in_rect;
   list_base_class->get_position_from_allocation = gtk_list_view_get_position_from_allocation;
   list_base_class->move_focus_along = gtk_list_view_move_focus_along;