#undef DEBUG_ICON_VIEW
#define SCROLL_EDGE_SIZE 15
-#define ITEM_PADDING 6
#define GTK_ICON_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ICON_VIEW, GtkIconViewPrivate))
gint row_spacing;
gint column_spacing;
gint margin;
+ gint item_padding;
gint text_column;
gint markup_column;
gint tooltip_column;
- guint draw_focus : 1;
-
/* Drag-and-drop. */
GdkModifierType start_button_mask;
gint pressed_button;
guint empty_view_drop :1;
guint ctrl_pressed : 1;
- guint shift_pressed : 1;
+ guint shift_pressed : 1;
+
+ guint draw_focus : 1;
};
/* Signals */
PROP_COLUMN_SPACING,
PROP_MARGIN,
PROP_REORDERABLE,
- PROP_TOOLTIP_COLUMN
+ PROP_TOOLTIP_COLUMN,
+ PROP_ITEM_PADDING
};
/* GObject vfuncs */
0, G_MAXINT, 6,
GTK_PARAM_READWRITE));
-
/**
* GtkIconView:orientation:
*
-1,
GTK_PARAM_READWRITE));
+ /**
+ * GtkIconView:item-padding:
+ *
+ * The item-padding property specifies the padding around each
+ * of the icon view's item.
+ *
+ * Since: 2.18
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_ITEM_PADDING,
+ g_param_spec_int ("item-padding",
+ P_("Item Padding"),
+ P_("Padding around icon view items"),
+ 0, G_MAXINT, 6,
+ GTK_PARAM_READWRITE));
+
/* Style properties */
icon_view->priv->row_spacing = 6;
icon_view->priv->column_spacing = 6;
icon_view->priv->margin = 6;
+ icon_view->priv->item_padding = 6;
icon_view->priv->draw_focus = TRUE;
}
gtk_icon_view_set_tooltip_column (icon_view, g_value_get_int (value));
break;
+ case PROP_ITEM_PADDING:
+ gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
g_value_set_int (value, icon_view->priv->tooltip_column);
break;
+ case PROP_ITEM_PADDING:
+ g_value_set_int (value, icon_view->priv->item_padding);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
/* totally ignore our child's requisition */
if (child->cell < 0)
{
- allocation.x = child->item->x + ITEM_PADDING;
- allocation.y = child->item->y + ITEM_PADDING;
- allocation.width = child->item->width - ITEM_PADDING * 2;
- allocation.height = child->item->height - ITEM_PADDING * 2;
+ allocation.x = child->item->x + icon_view->priv->item_padding;
+ allocation.y = child->item->y + icon_view->priv->item_padding;
+ allocation.width = child->item->width - icon_view->priv->item_padding * 2;
+ allocation.height = child->item->height - icon_view->priv->item_padding * 2;
}
else
{
hadjustment->upper = MAX (allocation->width, icon_view->priv->width);
if (hadjustment->value > hadjustment->upper - hadjustment->page_size)
- gtk_adjustment_set_value (hadjustment, hadjustment->upper - hadjustment->page_size);
+ gtk_adjustment_set_value (hadjustment, MAX (0, hadjustment->upper - hadjustment->page_size));
vadjustment->page_size = allocation->height;
vadjustment->page_increment = allocation->height * 0.9;
vadjustment->upper = MAX (allocation->height, icon_view->priv->height);
if (vadjustment->value > vadjustment->upper - vadjustment->page_size)
- gtk_adjustment_set_value (vadjustment, vadjustment->upper - vadjustment->page_size);
+ gtk_adjustment_set_value (vadjustment, MAX (0, vadjustment->upper - vadjustment->page_size));
if (GTK_WIDGET_REALIZED (widget) &&
icon_view->priv->scroll_to_path)
if (expose->window != icon_view->priv->bin_window)
return FALSE;
+ /* If a layout has been scheduled, do it now so that all
+ * cell view items have valid sizes before we proceed. */
+ if (icon_view->priv->layout_idle_id != 0)
+ gtk_icon_view_layout (icon_view);
+
cr = gdk_cairo_create (icon_view->priv->bin_window);
cairo_set_line_width (cr, 1.);
static gboolean
rubberband_scroll_timeout (gpointer data)
{
- GtkIconView *icon_view = data;
+ GtkIconView *icon_view;
+ gdouble value;
+
+ icon_view = data;
+
+ value = MIN (icon_view->priv->vadjustment->value +
+ icon_view->priv->scroll_value_diff,
+ icon_view->priv->vadjustment->upper -
+ icon_view->priv->vadjustment->page_size);
- gtk_adjustment_set_value (icon_view->priv->vadjustment,
- icon_view->priv->vadjustment->value +
- icon_view->priv->scroll_value_diff);
+ gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
gtk_icon_view_update_rubberband (icon_view);
* gtk_icon_view_set_cursor:
* @icon_view: A #GtkIconView
* @path: A #GtkTreePath
- * @cell: One of the cell renderers of @icon_view, or %NULL
+ * @cell: (allow-none): One of the cell renderers of @icon_view, or %NULL
* @start_editing: %TRUE if the specified cell should start being edited.
*
* Sets the current keyboard focus to be at @path, and selects it. This is
- * useful when you want to focus the user's attention on a particular item.
+ * useful when you want to focus the user's attention on a particular item.
* If @cell is not %NULL, then focus is given to the cell specified by
* it. Additionally, if @start_editing is %TRUE, then editing should be
* started in the specified cell.
if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
cell_area->x = item->box[info->position].x - item->before[info->position];
- cell_area->y = item->y + ITEM_PADDING;
+ cell_area->y = item->y + icon_view->priv->item_padding;
cell_area->width = item->box[info->position].width +
item->before[info->position] + item->after[info->position];
- cell_area->height = item->height - ITEM_PADDING * 2;
+ cell_area->height = item->height - icon_view->priv->item_padding * 2;
}
else
{
- cell_area->x = item->x + ITEM_PADDING;
+ cell_area->x = item->x + icon_view->priv->item_padding;
cell_area->y = item->box[info->position].y - item->before[info->position];
- cell_area->width = item->width - ITEM_PADDING * 2;
+ cell_area->width = item->width - icon_view->priv->item_padding * 2;
cell_area->height = item->box[info->position].height +
item->before[info->position] + item->after[info->position];
}
else
item_width = item->width;
- if (item->width == -1)
- {
- if (item_width > 0)
- wrap_width = item_width - pixbuf_width - icon_view->priv->spacing;
- else
- wrap_width = MAX (2 * pixbuf_width, 50);
- }
- else if (icon_view->priv->orientation == GTK_ORIENTATION_VERTICAL)
- wrap_width = item_width;
- else
- wrap_width = item_width - pixbuf_width - icon_view->priv->spacing;
+ if (icon_view->priv->orientation == GTK_ORIENTATION_VERTICAL)
+ wrap_width = item_width;
+ else {
+ if (item->width == -1 && item_width <= 0)
+ wrap_width = MAX (2 * pixbuf_width, 50);
+ else
+ wrap_width = item_width - pixbuf_width - icon_view->priv->spacing;
+ }
- wrap_width -= ITEM_PADDING * 2;
+ wrap_width -= icon_view->priv->item_padding * 2;
g_object_set (text_info->cell, "wrap-width", wrap_width, NULL);
g_object_set (text_info->cell, "width", wrap_width, NULL);
}
}
- item->width += ITEM_PADDING * 2;
- item->height += ITEM_PADDING * 2;
+ item->width += icon_view->priv->item_padding * 2;
+ item->height += icon_view->priv->item_padding * 2;
}
static void
item->height += max_height[i] + (i > 0 ? spacing : 0);
}
- cell_area.x = item->x + ITEM_PADDING;
- cell_area.y = item->y + ITEM_PADDING;
+ cell_area.x = item->x + icon_view->priv->item_padding;
+ cell_area.y = item->y + icon_view->priv->item_padding;
for (k = 0; k < 2; k++)
for (l = icon_view->priv->cell_list, i = 0; l; l = l->next, i++)
if (icon_view->priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- /* We should not subtract ITEM_PADDING from item->height,
+ /* We should not subtract icon_view->priv->item_padding from item->height,
* because item->height is recalculated above using
* max_height which does not contain item padding.
*/
/* item->width is not recalculated and thus needs to be
* corrected for the padding.
*/
- cell_area.width = item->width - 2 * ITEM_PADDING;
+ cell_area.width = item->width - 2 * icon_view->priv->item_padding;
cell_area.height = max_height[i];
}
}
else
{
- if (item->box[info->position].width > item->width - ITEM_PADDING * 2)
+ if (item->box[info->position].width > item->width - icon_view->priv->item_padding * 2)
{
- item->width = item->box[info->position].width + ITEM_PADDING * 2;
+ item->width = item->box[info->position].width + icon_view->priv->item_padding * 2;
cell_area.width = item->width;
}
item->before[info->position] = item->box[info->position].y - cell_area.y;
}
}
- item->height += ITEM_PADDING * 2;
+ item->height += icon_view->priv->item_padding * 2;
}
static void
GList *items, *l;
GdkRectangle box;
+ if (cell_at_pos)
+ *cell_at_pos = NULL;
+
for (items = icon_view->priv->items; items; items = items->next)
{
GtkIconViewItem *item = items->data;
for (l = icon_view->priv->cell_list; l; l = l->next)
{
GtkIconViewCellInfo *info = (GtkIconViewCellInfo *)l->data;
-
+
if (!info->cell->visible)
continue;
-
+
gtk_icon_view_get_cell_box (icon_view, item, info, &box);
-
+
if ((x >= box.x && x <= box.x + box.width &&
y >= box.y && y <= box.y + box.height) ||
(x >= box.x &&
{
if (cell_at_pos)
*cell_at_pos = info;
-
+
return item;
}
}
if (only_in_cell)
return NULL;
-
- if (cell_at_pos)
- *cell_at_pos = NULL;
}
return item;
{
gint x, y;
gint focus_width;
- gfloat offset;
+ gfloat offset, value;
gtk_widget_style_get (GTK_WIDGET (icon_view),
"focus-line-width", &focus_width,
offset = y + item->y - focus_width -
row_align * (GTK_WIDGET (icon_view)->allocation.height - item->height);
-
- gtk_adjustment_set_value (icon_view->priv->vadjustment,
- icon_view->priv->vadjustment->value + offset);
+ value = CLAMP (icon_view->priv->vadjustment->value + offset,
+ icon_view->priv->vadjustment->lower,
+ icon_view->priv->vadjustment->upper - icon_view->priv->vadjustment->page_size);
+ gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
offset = x + item->x - focus_width -
col_align * (GTK_WIDGET (icon_view)->allocation.width - item->width);
-
- gtk_adjustment_set_value (icon_view->priv->hadjustment,
- icon_view->priv->hadjustment->value + offset);
+ value = CLAMP (icon_view->priv->hadjustment->value + offset,
+ icon_view->priv->hadjustment->lower,
+ icon_view->priv->hadjustment->upper - icon_view->priv->hadjustment->page_size);
+ gtk_adjustment_set_value (icon_view->priv->hadjustment, value);
gtk_adjustment_changed (icon_view->priv->hadjustment);
gtk_adjustment_changed (icon_view->priv->vadjustment);
/**
* gtk_icon_view_set_model:
* @icon_view: A #GtkIconView.
- * @model: The model.
+ * @model: (allow-none): The model.
*
- * Sets the model for a #GtkIconView.
- * If the @icon_view already has a model set, it will remove
+ * Sets the model for a #GtkIconView.
+ * If the @icon_view already has a model set, it will remove
* it before setting the new model. If @model is %NULL, then
* it will unset the old model.
*
*
* To free the return value, use:
* |[
- * g_list_foreach (list, gtk_tree_path_free, NULL);
+ * g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
* g_list_free (list);
* ]|
*
- * Return value: A #GList containing a #GtkTreePath for each selected row.
+ * Return value: (element-type GtkTreePath) (transfer full): A #GList containing a #GtkTreePath for each selected row.
*
* Since: 2.6
**/
return icon_view->priv->margin;
}
+/**
+ * gtk_icon_view_set_item_padding:
+ * @icon_view: a #GtkIconView
+ * @item_padding: the item padding
+ *
+ * Sets the #GtkIconView:item-padding property which specifies the padding
+ * around each of the icon view's items.
+ *
+ * Since: 2.18
+ */
+void
+gtk_icon_view_set_item_padding (GtkIconView *icon_view,
+ gint item_padding)
+{
+ g_return_if_fail (GTK_IS_ICON_VIEW (icon_view));
+
+ if (icon_view->priv->item_padding != item_padding)
+ {
+ icon_view->priv->item_padding = item_padding;
+
+ gtk_icon_view_stop_editing (icon_view, TRUE);
+ gtk_icon_view_invalidate_sizes (icon_view);
+ gtk_icon_view_queue_layout (icon_view);
+
+ g_object_notify (G_OBJECT (icon_view), "item-padding");
+ }
+}
+
+/**
+ * gtk_icon_view_get_item_padding:
+ * @icon_view: a #GtkIconView
+ *
+ * Returns the value of the ::item-padding property.
+ *
+ * Return value: the padding around items
+ *
+ * Since: 2.18
+ */
+gint
+gtk_icon_view_get_item_padding (GtkIconView *icon_view)
+{
+ g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), -1);
+
+ return icon_view->priv->item_padding;
+}
/* Get/set whether drag_motion requested the drag data and
* drag_data_received should thus not actually insert the data,
{
gint px, py, x, y, width, height;
gint hoffset, voffset;
+ gfloat value;
gdk_window_get_pointer (GTK_WIDGET (icon_view)->window, &px, &py, NULL);
gdk_window_get_geometry (GTK_WIDGET (icon_view)->window, &x, &y, &width, &height, NULL);
hoffset = MAX (px - (x + width - 2 * SCROLL_EDGE_SIZE), 0);
if (voffset != 0)
- gtk_adjustment_set_value (icon_view->priv->vadjustment,
- icon_view->priv->vadjustment->value + voffset);
-
+ {
+ value = CLAMP (icon_view->priv->vadjustment->value + voffset,
+ icon_view->priv->vadjustment->lower,
+ icon_view->priv->vadjustment->upper - icon_view->priv->vadjustment->page_size);
+ gtk_adjustment_set_value (icon_view->priv->vadjustment, value);
+ }
if (hoffset != 0)
- gtk_adjustment_set_value (icon_view->priv->hadjustment,
- icon_view->priv->hadjustment->value + hoffset);
+ {
+ value = CLAMP (icon_view->priv->hadjustment->value + hoffset,
+ icon_view->priv->hadjustment->lower,
+ icon_view->priv->hadjustment->upper - icon_view->priv->hadjustment->page_size);
+ gtk_adjustment_set_value (icon_view->priv->hadjustment, value);
+ }
}
/**
* gtk_icon_view_set_drag_dest_item:
* @icon_view: a #GtkIconView
- * @path: The path of the item to highlight, or %NULL.
+ * @path: (allow-none): The path of the item to highlight, or %NULL.
* @pos: Specifies where to drop, relative to the item
- *
+ *
* Sets the item that is highlighted for feedback.
*
* Since: 2.8
/* special case a drop on an empty model */
icon_view->priv->empty_view_drop = FALSE;
- if (pos == GTK_TREE_VIEW_DROP_BEFORE && path
+ if (pos == GTK_ICON_VIEW_DROP_ABOVE && path
&& gtk_tree_path_get_depth (path) == 1
&& gtk_tree_path_get_indices (path)[0] == 0)
{
gtk_widget_grab_focus (item->widget);
gtk_icon_view_set_cursor_item (GTK_ICON_VIEW (item->widget), item->item, -1);
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->widget));
- if (GTK_WIDGET_TOPLEVEL (toplevel))
+ if (gtk_widget_is_toplevel (toplevel))
gtk_window_present (GTK_WINDOW (toplevel));
return TRUE;
NULL /* value table */
};
- static const GInterfaceInfo atk_component_info =
+ const GInterfaceInfo atk_component_info =
{
(GInterfaceInitFunc) atk_component_item_interface_init,
(GInterfaceFinalizeFunc) NULL,
NULL
};
- static const GInterfaceInfo atk_action_info =
+ const GInterfaceInfo atk_action_info =
{
(GInterfaceInitFunc) atk_action_item_interface_init,
(GInterfaceFinalizeFunc) NULL,
NULL
};
- static const GInterfaceInfo atk_image_info =
+ const GInterfaceInfo atk_image_info =
{
(GInterfaceInitFunc) atk_image_item_interface_init,
(GInterfaceFinalizeFunc) NULL,
NULL
};
- static const GInterfaceInfo atk_text_info =
+ const GInterfaceInfo atk_text_info =
{
(GInterfaceInitFunc) atk_text_item_interface_init,
(GInterfaceFinalizeFunc) NULL,
GtkIconViewItem *item;
GtkIconViewAccessible *a11y_view;
GtkIconViewItemAccessible *a11y_item;
- gchar *name, *text;
+ const gchar *name;
+ gchar *text;
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
a11y_view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
index = gtk_tree_path_get_indices(path)[0];
- a11y_item = gtk_icon_view_accessible_find_child (atk_obj, index);
+ a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (
+ gtk_icon_view_accessible_find_child (atk_obj, index));
if (a11y_item)
{
if (!type)
{
- static GTypeInfo tinfo =
+ GTypeInfo tinfo =
{
0, /* class size */
(GBaseInitFunc) NULL, /* base init */
(GInstanceInitFunc) NULL, /* instance init */
NULL /* value table */
};
- static const GInterfaceInfo atk_component_info =
+ const GInterfaceInfo atk_component_info =
{
(GInterfaceInitFunc) atk_component_interface_init,
(GInterfaceFinalizeFunc) NULL,
NULL
};
- static const GInterfaceInfo atk_selection_info =
+ const GInterfaceInfo atk_selection_info =
{
(GInterfaceInitFunc) gtk_icon_view_accessible_selection_interface_init,
(GInterfaceFinalizeFunc) NULL,