summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-icon-canvas-item.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus-private/nautilus-icon-canvas-item.c')
-rw-r--r--libnautilus-private/nautilus-icon-canvas-item.c231
1 files changed, 189 insertions, 42 deletions
diff --git a/libnautilus-private/nautilus-icon-canvas-item.c b/libnautilus-private/nautilus-icon-canvas-item.c
index 2fa3496d8..e8ead663a 100644
--- a/libnautilus-private/nautilus-icon-canvas-item.c
+++ b/libnautilus-private/nautilus-icon-canvas-item.c
@@ -3,7 +3,6 @@
/* Nautilus - Icon canvas item class for icon container.
*
* Copyright (C) 2000 Eazel, Inc
- *
* Author: Andy Hertzfeld <andy@eazel.com>
*
* This library is free software; you can redistribute it and/or
@@ -78,6 +77,10 @@ struct NautilusIconCanvasItemDetails {
GdkFont *font;
NautilusEmblemAttachPoints *attach_points;
+ /* stuff for controls; if this gets too big, we've put it in a separate struct */
+ GtkWidget *control; /* optional Bonobo control*/
+ guint control_destroy_id;
+
/* Size of the text at current font. */
int text_width;
int text_height;
@@ -91,7 +94,7 @@ struct NautilusIconCanvasItemDetails {
guint is_highlighted_for_drop : 1;
guint show_stretch_handles : 1;
guint is_prelit : 1;
-
+ guint in_control_destroy : 1;
gboolean is_renaming;
/* Font stuff whilst in smooth mode */
@@ -105,7 +108,7 @@ enum {
ARG_EDITABLE_TEXT,
ARG_ADDITIONAL_TEXT,
ARG_FONT,
- ARG_HIGHLIGHTED_FOR_SELECTION,
+ ARG_HIGHLIGHTED_FOR_SELECTION,
ARG_HIGHLIGHTED_AS_KEYBOARD_FOCUS,
ARG_HIGHLIGHTED_FOR_DROP,
ARG_MODIFIER,
@@ -314,6 +317,11 @@ nautilus_icon_canvas_item_destroy (GtkObject *object)
gdk_font_unref (details->font);
}
+ if (details->control && !details->in_control_destroy) {
+ gtk_signal_disconnect (GTK_OBJECT (details->control), details->control_destroy_id);
+ gtk_widget_destroy (details->control);
+ }
+
gtk_object_unref (GTK_OBJECT (icon_item->details->smooth_font));
icon_item->details->smooth_font = NULL;
@@ -345,6 +353,43 @@ nautilus_icon_canvas_item_invalidate_label_size (NautilusIconCanvasItem *item)
item->details->text_height = -1;
}
+/* abstraction layer for icon width and height, to separate it from pixbuf with and height */
+static int
+nautilus_icon_canvas_item_get_icon_width (NautilusIconCanvasItem *item)
+{
+ GtkRequisition size_requisition;
+ double scale_factor = GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
+
+ if (item->details->control != NULL) {
+ gtk_widget_size_request (item->details->control, &size_requisition);
+ return size_requisition.width * scale_factor;
+ }
+
+ if (item->details->pixbuf == NULL) {
+ return NAUTILUS_ICON_SIZE_STANDARD;
+ }
+
+ return gdk_pixbuf_get_width (item->details->pixbuf);
+}
+
+static int
+nautilus_icon_canvas_item_get_icon_height (NautilusIconCanvasItem *item)
+{
+ GtkRequisition size_requisition;
+ double scale_factor = GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
+
+ if (item->details->control != NULL) {
+ gtk_widget_size_request (item->details->control, &size_requisition);
+ return size_requisition.height * scale_factor;
+ }
+ if (item->details->pixbuf == NULL) {
+ return NAUTILUS_ICON_SIZE_STANDARD;
+ }
+
+ return gdk_pixbuf_get_height (item->details->pixbuf);
+}
+
+
/* Set_arg handler for the icon item. */
static void
nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
@@ -427,8 +472,7 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_SMOOTH_FONT_SIZE:
nautilus_icon_canvas_item_set_smooth_font_size (NAUTILUS_ICON_CANVAS_ITEM (object),
GTK_VALUE_UINT (*arg));
- break;
-
+ break;
default:
g_warning ("nautilus_icons_view_item_item_set_arg on unknown argument");
return;
@@ -437,12 +481,27 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (object));
}
+/* handler for the control's destroy signal */
+static void
+do_control_destroy (GtkObject *object, gpointer data)
+{
+ NautilusIconCanvasItemDetails *details;
+
+ details = NAUTILUS_ICON_CANVAS_ITEM (data)->details;
+
+ details->in_control_destroy = TRUE;
+
+ gtk_object_destroy (GTK_OBJECT (data));
+}
+
/* Get_arg handler for the icon item */
static void
nautilus_icon_canvas_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
NautilusIconCanvasItemDetails *details;
+ GnomeCanvasItem *item;
+ item = GNOME_CANVAS_ITEM (object);
details = NAUTILUS_ICON_CANVAS_ITEM (object)->details;
switch (arg_id) {
@@ -490,12 +549,27 @@ GdkPixbuf *
nautilus_icon_canvas_item_get_image (NautilusIconCanvasItem *item)
{
NautilusIconCanvasItemDetails *details;
-
+ int width, height;
+ GdkPixbuf *pixbuf;
+
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), NULL);
details = item->details;
- return details->pixbuf;
+ if (details->control) {
+ width = details->control->allocation.width;
+ height = details->control->allocation.height;
+ pixbuf = nautilus_gdk_pixbuf_get_from_window_safe (details->control->window,
+ details->control->allocation.x,
+ details->control->allocation.y,
+ details->control->allocation.width,
+ details->control->allocation.height);
+ } else {
+ pixbuf = details->pixbuf;
+ gdk_pixbuf_ref (pixbuf);
+ }
+
+ return pixbuf;
}
void
@@ -597,13 +671,22 @@ recompute_bounding_box (NautilusIconCanvasItem *icon_item)
item->y1 = top_left.y;
item->x2 = bottom_right.x;
item->y2 = bottom_right.y;
+
+ if (icon_item->details->control)
+ gtk_layout_move (GTK_LAYOUT (item->canvas), icon_item->details->control,
+ item->x1 + item->canvas->zoom_xofs,
+ item->y1 + item->canvas->zoom_yofs);
+
}
+
void
nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item)
{
ArtIRect before, after;
-
+ GtkRequisition size_requisition;
+ int item_width, item_height;
+
/* Compute new bounds. */
nautilus_gnome_canvas_item_get_current_canvas_bounds
(GNOME_CANVAS_ITEM (item), &before);
@@ -616,6 +699,16 @@ nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item)
return;
}
+ /* if there is an embedded control, make a size request and size accordingly */
+ if (item->details->control) {
+ /* size the control appropriately */
+ gtk_widget_size_request (item->details->control, &size_requisition);
+ item_width = size_requisition.width * GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
+ item_height = size_requisition.height * GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
+
+ gtk_widget_set_usize (item->details->control, item_width, item_height);
+ }
+
/* Send out the bounds_changed signal and queue a redraw. */
nautilus_gnome_canvas_request_redraw_rectangle
(GNOME_CANVAS_ITEM (item)->canvas, &before);
@@ -757,7 +850,7 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item,
canvas_item = GNOME_CANVAS_ITEM (item);
if (drawable != NULL) {
- icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf);
+ icon_width = details->pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item);
gc = gdk_gc_new (canvas_item->canvas->layout.bin_window);
gdk_gc_get_values (gc, &save_gc);
}
@@ -1159,11 +1252,17 @@ emblem_layout_next (EmblemLayout *layout,
/* Return the rectangle and pixbuf. */
*emblem_pixbuf = pixbuf;
- emblem_rect->x0 = x - width / 2;
- emblem_rect->y0 = y - height / 2;
+ if (layout->icon_item->details->control) {
+ emblem_rect->x0 = x;
+ emblem_rect->y0 = y;
+ } else {
+ emblem_rect->x0 = x - width / 2;
+ emblem_rect->y0 = y - height / 2;
+ }
+
emblem_rect->x1 = emblem_rect->x0 + width;
emblem_rect->y1 = emblem_rect->y0 + height;
-
+
return TRUE;
}
@@ -1278,23 +1377,30 @@ nautilus_icon_canvas_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
icon_item = NAUTILUS_ICON_CANVAS_ITEM (item);
details = icon_item->details;
- /* Draw the pixbuf. */
- if (details->pixbuf == NULL) {
- return;
- }
- /* Compute icon rectangle in drawable coordinates. */
- get_icon_canvas_rectangle (icon_item, &icon_rect);
- icon_rect.x0 -= x;
- icon_rect.y0 -= y;
- icon_rect.x1 -= x;
- icon_rect.y1 -= y;
+ /* draw the icon or widget */
+ if (icon_item->details->control) {
+ gtk_widget_queue_draw (icon_item->details->control);
+ } else {
+ if (details->pixbuf != NULL) {
+
+ /* Compute icon rectangle in drawable coordinates. */
+ get_icon_canvas_rectangle (icon_item, &icon_rect);
+ icon_rect.x0 -= x;
+ icon_rect.y0 -= y;
+ icon_rect.x1 -= x;
+ icon_rect.y1 -= y;
+
+ /* if the pre-lit or selection flag is set, make a pre-lit or darkened pixbuf and draw that instead */
+ temp_pixbuf = map_pixbuf (icon_item);
+ draw_pixbuf (temp_pixbuf, drawable, icon_rect.x0, icon_rect.y0);
+
+ if (temp_pixbuf != details->pixbuf) {
+ gdk_pixbuf_unref (temp_pixbuf);
+ }
+
+ }
- /* if the pre-lit or selection flag is set, make a pre-lit or darkened pixbuf and draw that instead */
- temp_pixbuf = map_pixbuf (icon_item);
- draw_pixbuf (temp_pixbuf, drawable, icon_rect.x0, icon_rect.y0);
- if (temp_pixbuf != details->pixbuf) {
- gdk_pixbuf_unref (temp_pixbuf);
}
/* Draw the emblem pixbufs. */
@@ -1379,7 +1485,7 @@ draw_or_measure_label_text_aa (NautilusIconCanvasItem *item,
if (destination_pixbuf == NULL ) {
icon_width = 0;
} else {
- icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf);
+ icon_width = details->pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item);
}
max_text_width = floor (nautilus_icon_canvas_item_get_max_text_width (item));
@@ -1635,15 +1741,21 @@ nautilus_icon_canvas_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
gnome_canvas_buf_ensure_buf (buf);
buf->is_bg = FALSE;
}
-
- /* draw the icon */
- nautilus_gnome_canvas_draw_pixbuf (buf, temp_pixbuf, icon_rect.x0, icon_rect.y0);
-
- if (temp_pixbuf != icon_item->details->pixbuf) {
- gdk_pixbuf_unref (temp_pixbuf);
+
+ /* draw the icon or widget */
+ if (icon_item->details->control) {
+ gtk_widget_queue_draw (icon_item->details->control);
+ } else {
+ nautilus_gnome_canvas_draw_pixbuf (buf, temp_pixbuf, icon_rect.x0, icon_rect.y0);
+
+ if (temp_pixbuf != icon_item->details->pixbuf) {
+ gdk_pixbuf_unref (temp_pixbuf);
+ }
}
-
- /* draw the emblems */
+
+ /* draw the emblems */
+ get_icon_canvas_rectangle (icon_item, &icon_rect);
+
emblem_layout_reset (&emblem_layout, icon_item, &icon_rect);
while (emblem_layout_next (&emblem_layout, &emblem_pixbuf, &emblem_rect)) {
nautilus_gnome_canvas_draw_pixbuf (buf, emblem_pixbuf, emblem_rect.x0, emblem_rect.y0);
@@ -1875,8 +1987,8 @@ nautilus_icon_canvas_item_bounds (GnomeCanvasItem *item,
icon_rect.x1 = 0;
icon_rect.y1 = 0;
} else {
- icon_rect.x1 = gdk_pixbuf_get_width (details->pixbuf);
- icon_rect.y1 = gdk_pixbuf_get_height (details->pixbuf);
+ icon_rect.x1 = nautilus_icon_canvas_item_get_icon_width (icon_item);
+ icon_rect.y1 = nautilus_icon_canvas_item_get_icon_height (icon_item);
}
/* Compute text rectangle. */
@@ -1922,8 +2034,8 @@ nautilus_icon_canvas_item_get_icon_rectangle (NautilusIconCanvasItem *item,
pixbuf = item->details->pixbuf;
pixels_per_unit = GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit;
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit;
+ rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item)) / pixels_per_unit;
+ rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_height (item)) / pixels_per_unit;
}
/* Get the rectangle of the icon only, in canvas coordinates. */
@@ -1949,8 +2061,8 @@ get_icon_canvas_rectangle (NautilusIconCanvasItem *item,
pixbuf = item->details->pixbuf;
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf));
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf));
+ rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item));
+ rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_height (item));
}
void
@@ -2107,6 +2219,41 @@ nautilus_icon_canvas_item_set_smooth_font (NautilusIconCanvasItem *icon_item,
}
}
+GtkWidget *
+nautilus_icon_canvas_item_get_control (NautilusIconCanvasItem *icon_item)
+{
+ return icon_item->details->control;
+}
+
+void
+nautilus_icon_canvas_item_set_control (NautilusIconCanvasItem *icon_item, GtkWidget *control)
+{
+ GnomeCanvasItem *item;
+
+ if (icon_item->details->control == control) {
+ return;
+ }
+
+ item = GNOME_CANVAS_ITEM (icon_item);
+ if (icon_item->details->control) {
+ gtk_signal_disconnect (GTK_OBJECT (icon_item->details->control), icon_item->details->control_destroy_id);
+ gtk_container_remove (GTK_CONTAINER (item->canvas), icon_item->details->control);
+ icon_item->details->control = NULL;
+ }
+
+ if (control) {
+ icon_item->details->control = control;
+ icon_item->details->control_destroy_id = gtk_signal_connect (GTK_OBJECT (control),
+ "destroy",
+ (GtkSignalFunc) do_control_destroy,
+ item);
+ gtk_widget_show (control);
+ gtk_layout_put (GTK_LAYOUT (item->canvas), control,
+ item->x1 + item->canvas->zoom_xofs,
+ item->y1 + item->canvas->zoom_yofs);
+ }
+}
+
void
nautilus_icon_canvas_item_set_smooth_font_size (NautilusIconCanvasItem *icon_item,
guint font_size)