Re: Polishing the icon stretching code
- From: Matthias Clasen <mclasen redhat com>
- To: Alexander Larsson <alexl redhat com>
- Cc: nautilus-list gnome org
- Subject: Re: Polishing the icon stretching code
- Date: Thu, 27 Oct 2005 14:51:10 -0400
On Mon, 2005-10-24 at 13:21 -0400, Matthias Clasen wrote:
> On Mon, 2005-10-24 at 09:27 +0200, Alexander Larsson wrote:
> > On Sat, 2005-10-22 at 01:33 -0400, Matthias Clasen wrote:
> > > I have attached a patch to
> > > http://bugzilla.gnome.org/show_bug.cgi?id=157271
> > > which makes nautilus use the resize cursors when stretching
> > > an icon. It also makes the knob image themable.
> > >
> > > There are some more things which could be improved here:
> > >
> > > - Add keynav for stretching icons (proposal: use Ctrl-+/- to
> > > stretch the icon while the stretch handles are displayed)
> > > - Don't hardcode a line width of 1 for the focus-like rectangle
> > > drawn with the stretch handles, but use a value derived from
> > > focus-width.
> > >
> > > I also note that "note-indicator.png" is another icon that should
> > > probably be made themable.
> >
> > Looks good to commit to HEAD.
>
> I attched another iteration of the patch, which adds keynav
> (C-+/C--/C-0 for growing, shrinking, or resetting) the icon which
> is currently stretched. I also changed the drawing code to draw the
> outline as black/white instead of black-over-background, since the
> latter tends to be poorly visible on a dark background image.
Alex pointed out that Ctrl-0 did not actually work for unstretching.
It took me a little while to figure out that it is because the
zoom_to_normal action is made invisible, but not insensitive like
the other zoom controls. Here is a patch which fixes this, and also
makes C-= works in the same way as C-+ (nautilus also does this for the
zoom controls).
Matthias
--- nautilus-2.12.1/src/nautilus-window-manage-views.c.stretch 2005-07-11 04:37:43.000000000 -0400
+++ nautilus-2.12.1/src/nautilus-window-manage-views.c 2005-10-27 14:35:29.000000000 -0400
@@ -1532,10 +1532,7 @@
action = gtk_action_group_get_action (window->details->main_action_group,
NAUTILUS_ACTION_ZOOM_NORMAL);
gtk_action_set_visible (action, supports_zooming);
- gtk_action_set_sensitive (action,
- TRUE);
-
- /* FIXME bugzilla.gnome.org 43442: Desensitize "Zoom Normal"? */
+ gtk_action_set_sensitive (action, supports_zooming);
}
static void
--- nautilus-2.12.1/libnautilus-private/nautilus-icon-canvas-item.h.stretch 2005-06-22 12:25:45.000000000 -0400
+++ nautilus-2.12.1/libnautilus-private/nautilus-icon-canvas-item.h 2005-10-27 14:35:29.000000000 -0400
@@ -84,7 +84,8 @@
gboolean nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item,
ArtIRect canvas_rect);
gboolean nautilus_icon_canvas_item_hit_test_stretch_handles (NautilusIconCanvasItem *item,
- ArtPoint world_point);
+ ArtPoint world_point,
+ GtkCornerType *corner);
void nautilus_icon_canvas_item_invalidate_label_size (NautilusIconCanvasItem *item);
ArtDRect nautilus_icon_canvas_item_get_icon_rectangle (const NautilusIconCanvasItem *item);
ArtDRect nautilus_icon_canvas_item_get_text_rectangle (const NautilusIconCanvasItem *item);
--- nautilus-2.12.1/libnautilus-private/nautilus-icon-container.c.stretch 2005-10-03 04:00:26.000000000 -0400
+++ nautilus-2.12.1/libnautilus-private/nautilus-icon-container.c 2005-10-27 14:45:53.000000000 -0400
@@ -3367,6 +3367,8 @@
NautilusIcon *icon;
ArtPoint world_point;
GtkWidget *toplevel;
+ GtkCornerType corner;
+ GdkCursor *cursor;
details = container->details;
icon = details->stretch_icon;
@@ -3374,11 +3376,27 @@
/* Check if we hit the stretch handles. */
world_point.x = details->drag_x;
world_point.y = details->drag_y;
- if (!nautilus_icon_canvas_item_hit_test_stretch_handles
- (icon->item, world_point)) {
+ if (!nautilus_icon_canvas_item_hit_test_stretch_handles (icon->item, world_point, &corner)) {
return FALSE;
}
+ switch (corner) {
+ case GTK_CORNER_TOP_LEFT:
+ cursor = gdk_cursor_new (GDK_TOP_LEFT_CORNER);
+ break;
+ case GTK_CORNER_BOTTOM_LEFT:
+ cursor = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
+ break;
+ case GTK_CORNER_TOP_RIGHT:
+ cursor = gdk_cursor_new (GDK_TOP_RIGHT_CORNER);
+ break;
+ case GTK_CORNER_BOTTOM_RIGHT:
+ cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
+ break;
+ default:
+ cursor = NULL;
+ break;
+ }
/* Set up the dragging. */
details->drag_state = DRAG_STATE_STRETCH;
eel_canvas_w2c (EEL_CANVAS (container),
@@ -3396,8 +3414,10 @@
eel_canvas_item_grab (EEL_CANVAS_ITEM (icon->item),
(GDK_POINTER_MOTION_MASK
| GDK_BUTTON_RELEASE_MASK),
- NULL,
+ cursor,
GDK_CURRENT_TIME);
+ if (cursor)
+ gdk_cursor_unref (cursor);
/* Ensure the window itself is focused.. */
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (container));
@@ -3458,6 +3478,43 @@
}
}
+static gboolean
+keyboard_stretching (NautilusIconContainer *container,
+ GdkEventKey *event)
+{
+ NautilusIcon *icon;
+ guint size;
+
+ icon = container->details->stretch_icon;
+
+ if (icon == NULL || !icon->is_selected) {
+ return FALSE;
+ }
+
+ icon_get_size (container, icon, &size);
+
+ switch (event->keyval) {
+ case GDK_equal:
+ case GDK_plus:
+ case GDK_KP_Add:
+ icon_set_size (container, icon, size + 5, FALSE, FALSE);
+ break;
+ case GDK_minus:
+ case GDK_KP_Subtract:
+ icon_set_size (container, icon, size - 5, FALSE, FALSE);
+ break;
+ case GDK_0:
+ case GDK_KP_0:
+ nautilus_icon_container_move_icon (container, icon,
+ icon->x, icon->y,
+ 1.0, 1.0,
+ FALSE, TRUE, TRUE);
+ break;
+ }
+
+ return TRUE;
+}
+
static void
ungrab_stretch_icon (NautilusIconContainer *container)
{
@@ -3489,7 +3546,7 @@
redo_layout (container);
}
-static void
+static gboolean
undo_stretching (NautilusIconContainer *container)
{
NautilusIcon *stretched_icon;
@@ -3497,7 +3554,7 @@
stretched_icon = container->details->stretch_icon;
if (stretched_icon == NULL) {
- return;
+ return FALSE;
}
if (container->details->drag_state == DRAG_STATE_STRETCH) {
@@ -3519,6 +3576,8 @@
container->details->stretch_icon = NULL;
emit_stretch_ended (container, stretched_icon);
redo_layout (container);
+
+ return TRUE;
}
static gboolean
@@ -3857,9 +3916,19 @@
handled = TRUE;
break;
- case GDK_Escape:
- undo_stretching (container);
- handled = TRUE;
+ case GDK_Escape:
+ handled = undo_stretching (container);
+ break;
+ case GDK_plus:
+ case GDK_minus:
+ case GDK_equal:
+ case GDK_KP_Add:
+ case GDK_KP_Subtract:
+ case GDK_0:
+ case GDK_KP_0:
+ if (event->state & GDK_CONTROL_MASK) {
+ handled = keyboard_stretching (container, event);
+ }
break;
case GDK_F10:
/* handle Ctrl+F10 because we want to display the
--- nautilus-2.12.1/libnautilus-private/nautilus-icon-canvas-item.c.stretch 2005-09-26 11:30:05.000000000 -0400
+++ nautilus-2.12.1/libnautilus-private/nautilus-icon-canvas-item.c 2005-10-27 14:35:29.000000000 -0400
@@ -44,6 +44,7 @@
#include <eel/eel-accessibility.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtksignal.h>
+#include <gdk/gdk.h>
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rgb_affine.h>
#include <libart_lgpl/art_rgb_rgba_affine.h>
@@ -209,7 +210,8 @@
GdkGC *gc);
static gboolean hit_test_stretch_handle (NautilusIconCanvasItem *item,
- ArtIRect canvas_rect);
+ ArtIRect canvas_rect,
+ GtkCornerType *corner);
static void clear_rounded_corners (GdkPixbuf *destination_pixbuf,
GdkPixbuf *corner_pixbuf,
int corner_size);
@@ -1152,12 +1154,30 @@
draw_or_measure_label_text (item, drawable, create_mask, icon_rect);
}
+static GdkPixbuf *
+get_knob_pixbuf (void)
+{
+ GdkPixbuf *knob_pixbuf;
+ char *knob_filename;
+
+ knob_pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+ "stock-nautilus-knob",
+ 8, 0, NULL);
+ if (!knob_pixbuf) {
+ knob_filename = nautilus_pixmap_file ("knob.png");
+ knob_pixbuf = gdk_pixbuf_new_from_file (knob_filename, NULL);
+ g_free (knob_filename);
+ }
+
+ return knob_pixbuf;
+}
+
static void
draw_stretch_handles (NautilusIconCanvasItem *item, GdkDrawable *drawable,
const ArtIRect *rect)
{
+ GtkWidget *widget;
GdkGC *gc;
- char *knob_filename;
GdkPixbuf *knob_pixbuf;
GdkBitmap *stipple;
int knob_width, knob_height;
@@ -1166,17 +1186,27 @@
return;
}
+ widget = GTK_WIDGET (EEL_CANVAS_ITEM (item)->canvas);
+
gc = gdk_gc_new (drawable);
- knob_filename = nautilus_pixmap_file ("knob.png");
- knob_pixbuf = gdk_pixbuf_new_from_file (knob_filename, NULL);
+ knob_pixbuf = get_knob_pixbuf ();
knob_width = gdk_pixbuf_get_width (knob_pixbuf);
knob_height = gdk_pixbuf_get_height (knob_pixbuf);
stipple = eel_stipple_bitmap_for_screen (
gdk_drawable_get_screen (GDK_DRAWABLE (drawable)));
- /* first draw the box */
+ /* first draw the box */
+ gdk_gc_set_rgb_fg_color (gc, &widget->style->white);
+ gdk_draw_rectangle
+ (drawable, gc, FALSE,
+ rect->x0,
+ rect->y0,
+ rect->x1 - rect->x0 - 1,
+ rect->y1 - rect->y0 - 1);
+
+ gdk_gc_set_rgb_fg_color (gc, &widget->style->black);
gdk_gc_set_stipple (gc, stipple);
gdk_gc_set_fill (gc, GDK_STIPPLED);
gdk_draw_rectangle
@@ -1192,8 +1222,6 @@
draw_pixbuf (knob_pixbuf, drawable, rect->x0, rect->y1 - knob_height);
draw_pixbuf (knob_pixbuf, drawable, rect->x1 - knob_width, rect->y0);
draw_pixbuf (knob_pixbuf, drawable, rect->x1 - knob_width, rect->y1 - knob_height);
-
- g_free (knob_filename);
g_object_unref (knob_pixbuf);
g_object_unref (gc);
@@ -1828,7 +1856,7 @@
}
/* Check for hits in the stretch handles. */
- if (hit_test_stretch_handle (icon_item, canvas_rect)) {
+ if (hit_test_stretch_handle (icon_item, canvas_rect, NULL)) {
return TRUE;
}
@@ -2055,12 +2083,13 @@
/* Check if one of the stretch handles was hit. */
static gboolean
hit_test_stretch_handle (NautilusIconCanvasItem *item,
- ArtIRect probe_canvas_rect)
+ ArtIRect probe_canvas_rect,
+ GtkCornerType *corner)
{
ArtIRect icon_rect;
- char *knob_filename;
GdkPixbuf *knob_pixbuf;
int knob_width, knob_height;
+ int hit_corner;
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), FALSE);
@@ -2075,24 +2104,36 @@
return FALSE;
}
- knob_filename = nautilus_pixmap_file ("knob.png");
- knob_pixbuf = gdk_pixbuf_new_from_file (knob_filename, NULL);
+
+ knob_pixbuf = get_knob_pixbuf ();
knob_width = gdk_pixbuf_get_width (knob_pixbuf);
knob_height = gdk_pixbuf_get_height (knob_pixbuf);
+ g_object_unref (knob_pixbuf);
- g_free (knob_filename);
- g_object_unref (knob_pixbuf);
-
/* Check for hits in the stretch handles. */
- return (probe_canvas_rect.x0 < icon_rect.x0 + knob_width
- || probe_canvas_rect.x1 >= icon_rect.x1 - knob_width)
- && (probe_canvas_rect.y0 < icon_rect.y0 + knob_height
- || probe_canvas_rect.y1 >= icon_rect.y1 - knob_height);
+ hit_corner = -1;
+ if (probe_canvas_rect.x0 < icon_rect.x0 + knob_width) {
+ if (probe_canvas_rect.y0 < icon_rect.y0 + knob_height)
+ hit_corner = GTK_CORNER_TOP_LEFT;
+ else if (probe_canvas_rect.y1 >= icon_rect.y1 - knob_height)
+ hit_corner = GTK_CORNER_BOTTOM_LEFT;
+ }
+ else if (probe_canvas_rect.x1 >= icon_rect.x1 - knob_width) {
+ if (probe_canvas_rect.y0 < icon_rect.y0 + knob_height)
+ hit_corner = GTK_CORNER_TOP_RIGHT;
+ else if (probe_canvas_rect.y1 >= icon_rect.y1 - knob_height)
+ hit_corner = GTK_CORNER_BOTTOM_RIGHT;
+ }
+ if (corner)
+ *corner = hit_corner;
+
+ return hit_corner != -1;
}
gboolean
nautilus_icon_canvas_item_hit_test_stretch_handles (NautilusIconCanvasItem *item,
- ArtPoint world_point)
+ ArtPoint world_point,
+ GtkCornerType *corner)
{
ArtIRect canvas_rect;
@@ -2105,7 +2146,7 @@
&canvas_rect.y0);
canvas_rect.x1 = canvas_rect.x0 + 1;
canvas_rect.y1 = canvas_rect.y0 + 1;
- return hit_test_stretch_handle (item, canvas_rect);
+ return hit_test_stretch_handle (item, canvas_rect, corner);
}
/* nautilus_icon_canvas_item_hit_test_rectangle
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]