#include "gtkcellrenderer.h"
#include "gtkcellrenderertext.h"
#include "gtkcellrendererpixbuf.h"
-#include "gtkcellsizerequest.h"
#include "gtkmarshalers.h"
#include "gtkbindings.h"
#include "gtkdnd.h"
#include "gtkentry.h"
#include "gtkcombobox.h"
#include "gtktextbuffer.h"
+#include "gtkscrollable.h"
#include "gtksizerequest.h"
#include "gtktreednd.h"
#include "gtkprivate.h"
* @title: GtkIconView
* @short_description: A widget which displays a list of icons in a grid
*
- * #GtkIconView provides an alternative view on a list model.
+ * #GtkIconView provides an alternative view on a #GtkTreeModel.
* It displays the model as a grid of icons with labels. Like
* #GtkTreeView, it allows to select one or multiple items
* (depending on the selection mode, see gtk_icon_view_set_selection_mode()).
* In addition to selection with the arrow keys, #GtkIconView supports
* rubberband selection, which is controlled by dragging the pointer.
+ *
+ * Note that if the tree model is backed by an actual tree store (as
+ * opposed to a flat list where the mapping to icons is obvious),
+ * #GtkIconView will only display the first level of the tree and
+ * ignore the tree's branches.
*/
#define SCROLL_EDGE_SIZE 15
+#define GTK_ICON_VIEW_PRIORITY_LAYOUT (GDK_PRIORITY_REDRAW + 5)
+
typedef struct _GtkIconViewItem GtkIconViewItem;
struct _GtkIconViewItem
{
guint shift_pressed : 1;
guint draw_focus : 1;
+
+ /* GtkScrollablePolicy needs to be checked when
+ * driving the scrollable adjustment values */
+ guint hscroll_policy : 1;
+ guint vscroll_policy : 1;
};
/* Signals */
PROP_MARGIN,
PROP_REORDERABLE,
PROP_TOOLTIP_COLUMN,
- PROP_ITEM_PADDING
+ PROP_ITEM_PADDING,
+
+ /* For scrollable interface */
+ PROP_HADJUSTMENT,
+ PROP_VADJUSTMENT,
+ PROP_HSCROLL_POLICY,
+ PROP_VSCROLL_POLICY
};
/* GObject vfuncs */
guint prop_id,
GValue *value,
GParamSpec *pspec);
-
-/* GtkObject vfuncs */
-static void gtk_icon_view_destroy (GtkObject *object);
-
/* GtkWidget vfuncs */
+static void gtk_icon_view_destroy (GtkWidget *widget);
static void gtk_icon_view_realize (GtkWidget *widget);
static void gtk_icon_view_unrealize (GtkWidget *widget);
static void gtk_icon_view_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_icon_view_state_changed (GtkWidget *widget,
GtkStateType previous_state);
-static void gtk_icon_view_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
+static void gtk_icon_view_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void gtk_icon_view_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
static void gtk_icon_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean gtk_icon_view_draw (GtkWidget *widget,
gpointer callback_data);
/* GtkIconView vfuncs */
-static void gtk_icon_view_set_adjustments (GtkIconView *icon_view,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj);
static void gtk_icon_view_real_select_all (GtkIconView *icon_view);
static void gtk_icon_view_real_unselect_all (GtkIconView *icon_view);
static void gtk_icon_view_real_select_cursor_item (GtkIconView *icon_view);
static gboolean gtk_icon_view_real_activate_cursor_item (GtkIconView *icon_view);
/* Internal functions */
+static void gtk_icon_view_set_hadjustment_values (GtkIconView *icon_view);
+static void gtk_icon_view_set_vadjustment_values (GtkIconView *icon_view);
+static void gtk_icon_view_set_hadjustment (GtkIconView *icon_view,
+ GtkAdjustment *adjustment);
+static void gtk_icon_view_set_vadjustment (GtkIconView *icon_view,
+ GtkAdjustment *adjustment);
+static void gtk_icon_view_accessible_set_adjustment (AtkObject *accessible,
+ GtkOrientation orientation,
+ GtkAdjustment *adjustment);
static void gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
GtkIconView *icon_view);
static void gtk_icon_view_layout (GtkIconView *icon_view);
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
gtk_icon_view_cell_layout_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
- gtk_icon_view_buildable_init))
+ gtk_icon_view_buildable_init)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
static void
gtk_icon_view_class_init (GtkIconViewClass *klass)
{
GObjectClass *gobject_class;
- GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
GtkBindingSet *binding_set;
g_type_class_add_private (klass, sizeof (GtkIconViewPrivate));
gobject_class = (GObjectClass *) klass;
- object_class = (GtkObjectClass *) klass;
widget_class = (GtkWidgetClass *) klass;
container_class = (GtkContainerClass *) klass;
gobject_class->set_property = gtk_icon_view_set_property;
gobject_class->get_property = gtk_icon_view_get_property;
- object_class->destroy = gtk_icon_view_destroy;
-
+ widget_class->destroy = gtk_icon_view_destroy;
widget_class->realize = gtk_icon_view_realize;
widget_class->unrealize = gtk_icon_view_unrealize;
widget_class->style_set = gtk_icon_view_style_set;
widget_class->get_accessible = gtk_icon_view_get_accessible;
- widget_class->size_request = gtk_icon_view_size_request;
+ widget_class->get_preferred_width = gtk_icon_view_get_preferred_width;
+ widget_class->get_preferred_height = gtk_icon_view_get_preferred_height;
widget_class->size_allocate = gtk_icon_view_size_allocate;
widget_class->draw = gtk_icon_view_draw;
widget_class->motion_notify_event = gtk_icon_view_motion;
container_class->remove = gtk_icon_view_remove;
container_class->forall = gtk_icon_view_forall;
- klass->set_scroll_adjustments = gtk_icon_view_set_adjustments;
klass->select_all = gtk_icon_view_real_select_all;
klass->unselect_all = gtk_icon_view_real_unselect_all;
klass->select_cursor_item = gtk_icon_view_real_select_cursor_item;
0, G_MAXINT, 6,
GTK_PARAM_READWRITE));
-
+ /* Scrollable interface properties */
+ g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
+ g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+ g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
/* Style properties */
gtk_widget_class_install_style_property (widget_class,
GTK_PARAM_READABLE));
/* Signals */
- /**
- * GtkIconView::set-scroll-adjustments
- * @horizontal: the horizontal #GtkAdjustment
- * @vertical: the vertical #GtkAdjustment
- *
- * Set the scroll adjustments for the icon view. Usually scrolled containers
- * like #GtkScrolledWindow will emit this signal to connect two instances
- * of #GtkScrollbar to the scroll directions of the #GtkIconView.
- */
- widget_class->set_scroll_adjustments_signal =
- g_signal_new (I_("set-scroll-adjustments"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkIconViewClass, set_scroll_adjustments),
- NULL, NULL,
- _gtk_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE, 2,
- GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
-
/**
* GtkIconView::item-activated:
* @iconview: the object on which the signal is emitted
gtk_widget_set_can_focus (GTK_WIDGET (icon_view), TRUE);
- gtk_icon_view_set_adjustments (icon_view, NULL, NULL);
-
icon_view->priv->cell_list = NULL;
icon_view->priv->n_cells = 0;
icon_view->priv->cursor_cell = -1;
icon_view->priv->draw_focus = TRUE;
}
-static void
-gtk_icon_view_destroy (GtkObject *object)
-{
- GtkIconView *icon_view;
-
- icon_view = GTK_ICON_VIEW (object);
-
- gtk_icon_view_stop_editing (icon_view, TRUE);
-
- gtk_icon_view_set_model (icon_view, NULL);
-
- if (icon_view->priv->layout_idle_id != 0)
- {
- g_source_remove (icon_view->priv->layout_idle_id);
- icon_view->priv->layout_idle_id = 0;
- }
-
- if (icon_view->priv->scroll_to_path != NULL)
- {
- gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
- icon_view->priv->scroll_to_path = NULL;
- }
-
- remove_scroll_timeout (icon_view);
-
- if (icon_view->priv->hadjustment != NULL)
- {
- g_object_unref (icon_view->priv->hadjustment);
- icon_view->priv->hadjustment = NULL;
- }
-
- if (icon_view->priv->vadjustment != NULL)
- {
- g_object_unref (icon_view->priv->vadjustment);
- icon_view->priv->vadjustment = NULL;
- }
-
- GTK_OBJECT_CLASS (gtk_icon_view_parent_class)->destroy (object);
-}
-
/* GObject methods */
static void
gtk_icon_view_finalize (GObject *object)
gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value));
break;
+ case PROP_HADJUSTMENT:
+ gtk_icon_view_set_hadjustment (icon_view, g_value_get_object (value));
+ break;
+ case PROP_VADJUSTMENT:
+ gtk_icon_view_set_vadjustment (icon_view, g_value_get_object (value));
+ break;
+ case PROP_HSCROLL_POLICY:
+ icon_view->priv->hscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (icon_view));
+ break;
+ case PROP_VSCROLL_POLICY:
+ icon_view->priv->vscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (icon_view));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
g_value_set_int (value, icon_view->priv->item_padding);
break;
+ case PROP_HADJUSTMENT:
+ g_value_set_object (value, icon_view->priv->hadjustment);
+ break;
+ case PROP_VADJUSTMENT:
+ g_value_set_object (value, icon_view->priv->vadjustment);
+ break;
+ case PROP_HSCROLL_POLICY:
+ g_value_set_enum (value, icon_view->priv->hscroll_policy);
+ break;
+ case PROP_VSCROLL_POLICY:
+ g_value_set_enum (value, icon_view->priv->vscroll_policy);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-/* GtkWidget signals */
+/* GtkWidget methods */
+static void
+gtk_icon_view_destroy (GtkWidget *widget)
+{
+ GtkIconView *icon_view = GTK_ICON_VIEW (widget);
+
+ gtk_icon_view_stop_editing (icon_view, TRUE);
+
+ gtk_icon_view_set_model (icon_view, NULL);
+
+ if (icon_view->priv->layout_idle_id != 0)
+ {
+ g_source_remove (icon_view->priv->layout_idle_id);
+ icon_view->priv->layout_idle_id = 0;
+ }
+
+ if (icon_view->priv->scroll_to_path != NULL)
+ {
+ gtk_tree_row_reference_free (icon_view->priv->scroll_to_path);
+ icon_view->priv->scroll_to_path = NULL;
+ }
+
+ remove_scroll_timeout (icon_view);
+
+ if (icon_view->priv->hadjustment != NULL)
+ {
+ g_object_unref (icon_view->priv->hadjustment);
+ icon_view->priv->hadjustment = NULL;
+ }
+
+ if (icon_view->priv->vadjustment != NULL)
+ {
+ g_object_unref (icon_view->priv->vadjustment);
+ icon_view->priv->vadjustment = NULL;
+ }
+
+ GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->destroy (widget);
+}
+
static void
gtk_icon_view_realize (GtkWidget *widget)
{
}
static void
-gtk_icon_view_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
+gtk_icon_view_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
{
- GtkIconView *icon_view = GTK_ICON_VIEW (widget);
- GList *tmp_list;
-
- requisition->width = icon_view->priv->width;
- requisition->height = icon_view->priv->height;
-
- tmp_list = icon_view->priv->children;
-
- while (tmp_list)
- {
- GtkIconViewChild *child = tmp_list->data;
- GtkRequisition child_requisition;
-
- tmp_list = tmp_list->next;
+ *minimum = *natural = GTK_ICON_VIEW (widget)->priv->width;
+}
- if (gtk_widget_get_visible (child->widget))
- gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
- &child_requisition, NULL);
- }
+static void
+gtk_icon_view_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ *minimum = *natural = GTK_ICON_VIEW (widget)->priv->height;
}
static void
{
GtkIconView *icon_view = GTK_ICON_VIEW (widget);
- GtkAdjustment *hadjustment, *vadjustment;
-
gtk_widget_set_allocation (widget, allocation);
if (gtk_widget_get_realized (widget))
gtk_icon_view_allocate_children (icon_view);
- hadjustment = icon_view->priv->hadjustment;
- vadjustment = icon_view->priv->vadjustment;
-
- hadjustment->page_size = allocation->width;
- hadjustment->page_increment = allocation->width * 0.9;
- hadjustment->step_increment = allocation->width * 0.1;
- hadjustment->lower = 0;
- 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);
+ /* Delay signal emission */
+ g_object_freeze_notify (G_OBJECT (icon_view->priv->hadjustment));
+ g_object_freeze_notify (G_OBJECT (icon_view->priv->vadjustment));
- vadjustment->page_size = allocation->height;
- vadjustment->page_increment = allocation->height * 0.9;
- vadjustment->step_increment = allocation->height * 0.1;
- vadjustment->lower = 0;
- 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_icon_view_set_hadjustment_values (icon_view);
+ gtk_icon_view_set_vadjustment_values (icon_view);
if (gtk_widget_get_realized (widget) &&
icon_view->priv->scroll_to_path)
icon_view->priv->scroll_to_col_align);
gtk_tree_path_free (path);
}
- else
- {
- gtk_adjustment_changed (hadjustment);
- gtk_adjustment_changed (vadjustment);
- }
+
+ /* Emit any pending signals now */
+ g_object_thaw_notify (G_OBJECT (icon_view->priv->hadjustment));
+ g_object_thaw_notify (G_OBJECT (icon_view->priv->vadjustment));
}
static gboolean
gint dest_index;
GtkIconViewDropPosition dest_pos;
GtkIconViewItem *dest_item = NULL;
- int x, y;
icon_view = GTK_ICON_VIEW (widget);
cairo_save (cr);
- gdk_window_get_position (icon_view->priv->bin_window, &x, &y);
- cairo_translate (cr, x, y);
+ gtk_cairo_transform_to_window (cr, widget, icon_view->priv->bin_window);
- /* 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);
-
cairo_set_line_width (cr, 1.);
gtk_icon_view_get_drag_dest_item (icon_view, &path, &dest_pos);
/* GtkIconView signals */
-static void
-gtk_icon_view_set_adjustments (GtkIconView *icon_view,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj)
-{
- gboolean need_adjust = FALSE;
-
- if (hadj)
- g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
- else
- hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
- if (vadj)
- g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
- else
- vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-
- if (icon_view->priv->hadjustment && (icon_view->priv->hadjustment != hadj))
- {
- g_signal_handlers_disconnect_matched (icon_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, icon_view);
- g_object_unref (icon_view->priv->hadjustment);
- }
-
- if (icon_view->priv->vadjustment && (icon_view->priv->vadjustment != vadj))
- {
- g_signal_handlers_disconnect_matched (icon_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, icon_view);
- g_object_unref (icon_view->priv->vadjustment);
- }
-
- if (icon_view->priv->hadjustment != hadj)
- {
- icon_view->priv->hadjustment = hadj;
- g_object_ref_sink (icon_view->priv->hadjustment);
-
- g_signal_connect (icon_view->priv->hadjustment, "value-changed",
- G_CALLBACK (gtk_icon_view_adjustment_changed),
- icon_view);
- need_adjust = TRUE;
- }
-
- if (icon_view->priv->vadjustment != vadj)
- {
- icon_view->priv->vadjustment = vadj;
- g_object_ref_sink (icon_view->priv->vadjustment);
-
- g_signal_connect (icon_view->priv->vadjustment, "value-changed",
- G_CALLBACK (gtk_icon_view_adjustment_changed),
- icon_view);
- need_adjust = TRUE;
- }
-
- if (need_adjust)
- gtk_icon_view_adjustment_changed (NULL, icon_view);
-}
-
static void
gtk_icon_view_real_select_all (GtkIconView *icon_view)
{
}
/* Internal functions */
+static void
+gtk_icon_view_process_updates (GtkIconView *icon_view)
+{
+ /* Prior to drawing, we check if a layout has been scheduled. If so,
+ * do it now that all cell view items have valid sizes before we proceeed
+ * (and resize the bin_window if required).
+ */
+ if (icon_view->priv->layout_idle_id != 0)
+ gtk_icon_view_layout (icon_view);
+
+ gdk_window_process_updates (icon_view->priv->bin_window, TRUE);
+}
+
+static void
+gtk_icon_view_set_hadjustment_values (GtkIconView *icon_view)
+{
+ GtkAllocation allocation;
+ GtkAdjustment *adj = icon_view->priv->hadjustment;
+ gdouble old_page_size;
+ gdouble old_upper;
+ gdouble old_value;
+ gdouble new_value;
+ gdouble new_upper;
+
+ gtk_widget_get_allocation (GTK_WIDGET (icon_view), &allocation);
+
+ old_value = gtk_adjustment_get_value (adj);
+ old_upper = gtk_adjustment_get_upper (adj);
+ old_page_size = gtk_adjustment_get_page_size (adj);
+ new_upper = MAX (allocation.width, icon_view->priv->width);
+
+ g_object_set (adj,
+ "lower", 0.0,
+ "upper", new_upper,
+ "page-size", (gdouble)allocation.width,
+ "step-increment", allocation.width * 0.1,
+ "page-increment", allocation.width * 0.9,
+ NULL);
+
+ if (gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL)
+ {
+ /* Make sure no scrolling occurs for RTL locales also (if possible) */
+ /* Quick explanation:
+ * In LTR locales, leftmost portion of visible rectangle should stay
+ * fixed, which means left edge of scrollbar thumb should remain fixed
+ * and thus adjustment's value should stay the same.
+ *
+ * In RTL locales, we want to keep rightmost portion of visible
+ * rectangle fixed. This means right edge of thumb should remain fixed.
+ * In this case, upper - value - page_size should remain constant.
+ */
+ new_value = (new_upper - allocation.width) -
+ (old_upper - old_value - old_page_size);
+ new_value = CLAMP (new_value, 0, new_upper - allocation.width);
+ }
+ else
+ new_value = CLAMP (old_value, 0, new_upper - allocation.width);
+
+ if (new_value != old_value)
+ gtk_adjustment_set_value (adj, new_value);
+}
+
+static void
+gtk_icon_view_set_vadjustment_values (GtkIconView *icon_view)
+{
+ GtkAllocation allocation;
+ GtkAdjustment *adj = icon_view->priv->vadjustment;
+ gdouble old_value;
+ gdouble new_value;
+ gdouble new_upper;
+
+ gtk_widget_get_allocation (GTK_WIDGET (icon_view), &allocation);
+
+ old_value = gtk_adjustment_get_value (adj);
+ new_upper = MAX (allocation.height, icon_view->priv->height);
+
+ g_object_set (adj,
+ "lower", 0.0,
+ "upper", new_upper,
+ "page-size", (gdouble)allocation.height,
+ "step-increment", allocation.height * 0.1,
+ "page-increment", allocation.height * 0.9,
+ NULL);
+
+ new_value = CLAMP (old_value, 0, new_upper - allocation.height);
+ if (new_value != old_value)
+ gtk_adjustment_set_value (adj, new_value);
+}
+
+static void
+gtk_icon_view_set_hadjustment (GtkIconView *icon_view,
+ GtkAdjustment *adjustment)
+{
+ GtkIconViewPrivate *priv = icon_view->priv;
+ AtkObject *atk_obj;
+
+ if (adjustment && priv->hadjustment == adjustment)
+ return;
+
+ if (priv->hadjustment != NULL)
+ {
+ g_signal_handlers_disconnect_matched (priv->hadjustment,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, icon_view);
+ g_object_unref (priv->hadjustment);
+ }
+
+ if (!adjustment)
+ adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (gtk_icon_view_adjustment_changed), icon_view);
+ priv->hadjustment = g_object_ref_sink (adjustment);
+ gtk_icon_view_set_hadjustment_values (icon_view);
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
+ gtk_icon_view_accessible_set_adjustment (atk_obj,
+ GTK_ORIENTATION_HORIZONTAL,
+ adjustment);
+
+ g_object_notify (G_OBJECT (icon_view), "hadjustment");
+}
+
+static void
+gtk_icon_view_set_vadjustment (GtkIconView *icon_view,
+ GtkAdjustment *adjustment)
+{
+ GtkIconViewPrivate *priv = icon_view->priv;
+ AtkObject *atk_obj;
+
+ if (adjustment && priv->vadjustment == adjustment)
+ return;
+
+ if (priv->vadjustment != NULL)
+ {
+ g_signal_handlers_disconnect_matched (priv->vadjustment,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, icon_view);
+ g_object_unref (priv->vadjustment);
+ }
+
+ if (!adjustment)
+ adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (gtk_icon_view_adjustment_changed), icon_view);
+ priv->vadjustment = g_object_ref_sink (adjustment);
+ gtk_icon_view_set_vadjustment_values (icon_view);
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
+ gtk_icon_view_accessible_set_adjustment (atk_obj,
+ GTK_ORIENTATION_VERTICAL,
+ adjustment);
+
+ g_object_notify (G_OBJECT (icon_view), "vadjustment");
+}
+
static void
gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
- GtkIconView *icon_view)
+ GtkIconView *icon_view)
{
+ GtkIconViewPrivate *priv = icon_view->priv;
+
if (gtk_widget_get_realized (GTK_WIDGET (icon_view)))
{
- gdk_window_move (icon_view->priv->bin_window,
- - icon_view->priv->hadjustment->value,
- - icon_view->priv->vadjustment->value);
+ gdk_window_move (priv->bin_window,
+ - priv->hadjustment->value,
+ - priv->vadjustment->value);
if (icon_view->priv->doing_rubberband)
- gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
+ gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
- gdk_window_process_updates (icon_view->priv->bin_window, TRUE);
+ gtk_icon_view_process_updates (icon_view);
}
}
pixbuf_info = g_list_nth_data (icon_view->priv->cell_list,
icon_view->priv->pixbuf_cell);
- gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (pixbuf_info->cell),
- GTK_WIDGET (icon_view),
- &min_size, NULL);
+ gtk_cell_renderer_get_preferred_size (pixbuf_info->cell,
+ GTK_WIDGET (icon_view),
+ &min_size, NULL);
if (icon_view->priv->item_width > 0)
item_width = icon_view->priv->item_width;
if (!gtk_cell_renderer_get_visible (info->cell))
continue;
- gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
- GTK_WIDGET (icon_view),
- &min_size, NULL);
+ gtk_cell_renderer_get_preferred_size (info->cell,
+ GTK_WIDGET (icon_view),
+ &min_size, NULL);
item->box[info->position].width = min_size.width;
item->box[info->position].height = min_size.height;
cell_area.height = max_height[i];
}
- gtk_cell_size_request_get_size (GTK_CELL_SIZE_REQUEST (info->cell),
- GTK_WIDGET (icon_view),
- &min_size, NULL);
+ gtk_cell_renderer_get_preferred_size (info->cell,
+ GTK_WIDGET (icon_view),
+ &min_size, NULL);
item->box[info->position].width = min_size.width;
item->box[info->position].height = min_size.height;
if (icon_view->priv->layout_idle_id != 0)
return;
- icon_view->priv->layout_idle_id = gdk_threads_add_idle (layout_callback, icon_view);
+ icon_view->priv->layout_idle_id =
+ gdk_threads_add_idle_full (GTK_ICON_VIEW_PRIORITY_LAYOUT,
+ layout_callback, icon_view, NULL);
}
static void
GtkTreeIter *iter,
gpointer data)
{
+ GtkIconView *icon_view = GTK_ICON_VIEW (data);
GtkIconViewItem *item;
gint index;
- GtkIconView *icon_view;
- icon_view = GTK_ICON_VIEW (data);
+ /* ignore changes in branches */
+ if (gtk_tree_path_get_depth (path) > 1)
+ return;
gtk_icon_view_stop_editing (icon_view, TRUE);
GtkTreeIter *iter,
gpointer data)
{
+ GtkIconView *icon_view = GTK_ICON_VIEW (data);
gint index;
GtkIconViewItem *item;
gboolean iters_persist;
- GtkIconView *icon_view;
GList *list;
-
- icon_view = GTK_ICON_VIEW (data);
+
+ /* ignore changes in branches */
+ if (gtk_tree_path_get_depth (path) > 1)
+ return;
iters_persist = gtk_tree_model_get_flags (icon_view->priv->model) & GTK_TREE_MODEL_ITERS_PERSIST;
GtkTreePath *path,
gpointer data)
{
+ GtkIconView *icon_view = GTK_ICON_VIEW (data);
gint index;
- GtkIconView *icon_view;
GtkIconViewItem *item;
GList *list, *next;
gboolean emit = FALSE;
-
- icon_view = GTK_ICON_VIEW (data);
+
+ /* ignore changes in branches */
+ if (gtk_tree_path_get_depth (path) > 1)
+ return;
index = gtk_tree_path_get_indices(path)[0];
gint *new_order,
gpointer data)
{
+ GtkIconView *icon_view = GTK_ICON_VIEW (data);
int i;
int length;
- GtkIconView *icon_view;
GList *items = NULL, *list;
GtkIconViewItem **item_array;
gint *order;
-
- icon_view = GTK_ICON_VIEW (data);
+
+ /* ignore changes in branches */
+ if (iter != NULL)
+ return;
gtk_icon_view_stop_editing (icon_view, TRUE);
* When enabled, #GtkWidget::has-tooltip will be set to %TRUE and
* @icon_view will connect a #GtkWidget::query-tooltip signal handler.
*
+ * Note that the signal handler sets the text with gtk_tooltip_set_markup(),
+ * so &, <, etc have to be escaped in the text.
+ *
* Since: 2.12
*/
void
if (model)
{
GType column_type;
-
- g_return_if_fail (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_LIST_ONLY);
if (icon_view->priv->pixbuf_column != -1)
{
g_object_set (info->cell,
"alignment", PANGO_ALIGN_CENTER,
"wrap-mode", PANGO_WRAP_WORD_CHAR,
- "xalign", 0.0,
+ "xalign", 0.5,
"yalign", 0.0,
NULL);
else
"alignment", PANGO_ALIGN_LEFT,
"wrap-mode", PANGO_WRAP_WORD_CHAR,
"xalign", 0.0,
- "yalign", 0.0,
+ "yalign", 0.5,
NULL);
}
}
window = gtk_widget_get_window (GTK_WIDGET (icon_view));
gdk_window_get_pointer (window, &px, &py, NULL);
- gdk_window_get_geometry (window, &x, &y, &width, &height, NULL);
+ gdk_window_get_geometry (window, &x, &y, &width, &height);
/* see if we are near the edge. */
voffset = py - (y + 2 * SCROLL_EDGE_SIZE);
}
static void
-gtk_icon_view_accessible_adjustment_changed (GtkAdjustment *adjustment,
- GtkIconView *icon_view)
+gtk_icon_view_accessible_adjustment_changed (GtkAdjustment *adjustment,
+ GtkIconViewAccessible *view)
{
- AtkObject *obj;
- GtkIconViewAccessible *view;
-
- /*
- * The scrollbars have changed
- */
- obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
- view = GTK_ICON_VIEW_ACCESSIBLE (obj);
-
gtk_icon_view_accessible_traverse_items (view, NULL);
}
static void
-gtk_icon_view_accessible_set_scroll_adjustments (GtkWidget *widget,
- GtkAdjustment *hadj,
- GtkAdjustment *vadj)
+gtk_icon_view_accessible_set_adjustment (AtkObject *accessible,
+ GtkOrientation orientation,
+ GtkAdjustment *adjustment)
{
- AtkObject *atk_obj;
GtkIconViewAccessiblePrivate *priv;
+ GtkAdjustment **old_adj_ptr;
- atk_obj = gtk_widget_get_accessible (widget);
- priv = gtk_icon_view_accessible_get_priv (atk_obj);
+ priv = gtk_icon_view_accessible_get_priv (accessible);
- if (priv->old_hadj != hadj)
+ /* Adjustments are set for the first time in constructor and priv is not
+ * initialized at that time, so skip this first setting. */
+ if (!priv)
+ return;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
- if (priv->old_hadj)
- {
- g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
- (gpointer *)&priv->old_hadj);
-
- g_signal_handlers_disconnect_by_func (priv->old_hadj,
- (gpointer) gtk_icon_view_accessible_adjustment_changed,
- widget);
- }
- priv->old_hadj = hadj;
- if (priv->old_hadj)
- {
- g_object_add_weak_pointer (G_OBJECT (priv->old_hadj),
- (gpointer *)&priv->old_hadj);
- g_signal_connect (hadj,
- "value-changed",
- G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
- widget);
- }
+ if (priv->old_hadj == adjustment)
+ return;
+
+ old_adj_ptr = &priv->old_hadj;
}
- if (priv->old_vadj != vadj)
+ else
{
- if (priv->old_vadj)
- {
- g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
- (gpointer *)&priv->old_vadj);
-
- g_signal_handlers_disconnect_by_func (priv->old_vadj,
- (gpointer) gtk_icon_view_accessible_adjustment_changed,
- widget);
- }
- priv->old_vadj = vadj;
- if (priv->old_vadj)
- {
- g_object_add_weak_pointer (G_OBJECT (priv->old_vadj),
- (gpointer *)&priv->old_vadj);
- g_signal_connect (vadj,
- "value-changed",
- G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
- widget);
- }
+ if (priv->old_vadj == adjustment)
+ return;
+
+ old_adj_ptr = &priv->old_vadj;
}
+
+ /* Disconnect signal handlers */
+ if (*old_adj_ptr)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (*old_adj_ptr),
+ (gpointer *)&priv->old_hadj);
+ g_signal_handlers_disconnect_by_func (*old_adj_ptr,
+ gtk_icon_view_accessible_adjustment_changed,
+ accessible);
+ }
+
+ /* Connect signal */
+ *old_adj_ptr = adjustment;
+ g_object_add_weak_pointer (G_OBJECT (adjustment), (gpointer *)old_adj_ptr);
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
+ accessible);
}
static void
icon_view = GTK_ICON_VIEW (data);
if (icon_view->priv->hadjustment)
- {
- priv->old_hadj = icon_view->priv->hadjustment;
- g_object_add_weak_pointer (G_OBJECT (priv->old_hadj), (gpointer *)&priv->old_hadj);
- g_signal_connect (icon_view->priv->hadjustment,
- "value-changed",
- G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
- icon_view);
- }
+ gtk_icon_view_accessible_set_adjustment (accessible,
+ GTK_ORIENTATION_HORIZONTAL,
+ icon_view->priv->hadjustment);
if (icon_view->priv->vadjustment)
- {
- priv->old_vadj = icon_view->priv->vadjustment;
- g_object_add_weak_pointer (G_OBJECT (priv->old_vadj), (gpointer *)&priv->old_vadj);
- g_signal_connect (icon_view->priv->vadjustment,
- "value-changed",
- G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
- icon_view);
- }
- g_signal_connect_after (data,
- "set-scroll-adjustments",
- G_CALLBACK (gtk_icon_view_accessible_set_scroll_adjustments),
- NULL);
+ gtk_icon_view_accessible_set_adjustment (accessible,
+ GTK_ORIENTATION_VERTICAL,
+ icon_view->priv->vadjustment);
g_signal_connect (data,
"notify",
G_CALLBACK (gtk_icon_view_accessible_notify_gtk),
g_signal_handlers_disconnect_by_func (priv->old_hadj,
(gpointer) gtk_icon_view_accessible_adjustment_changed,
- widget);
+ accessible);
priv->old_hadj = NULL;
}
if (priv->old_vadj)
g_signal_handlers_disconnect_by_func (priv->old_vadj,
(gpointer) gtk_icon_view_accessible_adjustment_changed,
- widget);
+ accessible);
priv->old_vadj = NULL;
}
}