From bbcecaf6b73f9dd315823ffbbd9aa9574b18aa7d Mon Sep 17 00:00:00 2001 From: Christopher James Lahey Date: Wed, 26 Jan 2000 11:26:07 +0000 Subject: Added an arrow cursor for the draggable columns. Made the clickable column 2000-01-27 Christopher James Lahey * widgets/e-reflow.h, widgets/e-reflow.c: Added an arrow cursor for the draggable columns. Made the clickable column area larger. * widgets/e-text.h, widgets/e-text.c: Added an I beam cursor for the text item when it is editable. * widgets/e-minicard-label.c: Forward enter and leave notifications to the contained editable text item. svn path=/trunk/; revision=1647 --- widgets/e-minicard-label.c | 28 +++-- widgets/e-minicard/e-minicard-label.c | 28 +++-- widgets/e-minicard/e-reflow.c | 192 +++++++++++++++++++++++++++------- widgets/e-minicard/e-reflow.h | 8 ++ widgets/e-reflow.c | 192 +++++++++++++++++++++++++++------- widgets/e-reflow.h | 8 ++ widgets/e-reflow/e-reflow.c | 192 +++++++++++++++++++++++++++------- widgets/e-reflow/e-reflow.h | 8 ++ widgets/e-text.c | 45 ++++++++ widgets/e-text.h | 6 ++ widgets/e-text/e-text.c | 45 ++++++++ widgets/e-text/e-text.h | 6 ++ widgets/misc/e-reflow.c | 192 +++++++++++++++++++++++++++------- widgets/misc/e-reflow.h | 8 ++ widgets/text/e-text.c | 45 ++++++++ widgets/text/e-text.h | 6 ++ 16 files changed, 853 insertions(+), 156 deletions(-) (limited to 'widgets') diff --git a/widgets/e-minicard-label.c b/widgets/e-minicard-label.c index 0c4078f69f..2b0fb3faf8 100644 --- a/widgets/e-minicard-label.c +++ b/widgets/e-minicard-label.c @@ -335,12 +335,14 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event) break; case GDK_BUTTON_PRESS: case GDK_BUTTON_RELEASE: - case GDK_MOTION_NOTIFY: { + case GDK_MOTION_NOTIFY: + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: { GnomeCanvasItem *field; ArtPoint p; double inv[6], affine[6]; gboolean return_val; - + field = e_minicard_label->field; art_affine_identity (affine); @@ -354,26 +356,40 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event) } art_affine_invert (inv, affine); - if (event->type == GDK_MOTION_NOTIFY) { + switch(event->type) { + case GDK_MOTION_NOTIFY: p.x = event->motion.x; p.y = event->motion.y; art_affine_point (&p, &p, inv); event->motion.x = p.x; event->motion.y = p.y; - } else { + break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: p.x = event->button.x; p.y = event->button.y; art_affine_point (&p, &p, inv); event->button.x = p.x; event->button.y = p.y; + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + p.x = event->crossing.x; + p.y = event->crossing.y; + art_affine_point (&p, &p, inv); + event->crossing.x = p.x; + event->crossing.y = p.y; + break; + default: + break; } gtk_signal_emit_by_name(GTK_OBJECT(e_minicard_label->field), "event", event, &return_val); return return_val; break; } - default: - break; + default: + break; } if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event) diff --git a/widgets/e-minicard/e-minicard-label.c b/widgets/e-minicard/e-minicard-label.c index 0c4078f69f..2b0fb3faf8 100644 --- a/widgets/e-minicard/e-minicard-label.c +++ b/widgets/e-minicard/e-minicard-label.c @@ -335,12 +335,14 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event) break; case GDK_BUTTON_PRESS: case GDK_BUTTON_RELEASE: - case GDK_MOTION_NOTIFY: { + case GDK_MOTION_NOTIFY: + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: { GnomeCanvasItem *field; ArtPoint p; double inv[6], affine[6]; gboolean return_val; - + field = e_minicard_label->field; art_affine_identity (affine); @@ -354,26 +356,40 @@ e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event) } art_affine_invert (inv, affine); - if (event->type == GDK_MOTION_NOTIFY) { + switch(event->type) { + case GDK_MOTION_NOTIFY: p.x = event->motion.x; p.y = event->motion.y; art_affine_point (&p, &p, inv); event->motion.x = p.x; event->motion.y = p.y; - } else { + break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: p.x = event->button.x; p.y = event->button.y; art_affine_point (&p, &p, inv); event->button.x = p.x; event->button.y = p.y; + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + p.x = event->crossing.x; + p.y = event->crossing.y; + art_affine_point (&p, &p, inv); + event->crossing.x = p.x; + event->crossing.y = p.y; + break; + default: + break; } gtk_signal_emit_by_name(GTK_OBJECT(e_minicard_label->field), "event", event, &return_val); return return_val; break; } - default: - break; + default: + break; } if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event) diff --git a/widgets/e-minicard/e-reflow.c b/widgets/e-minicard/e-reflow.c index 41be2ec533..96773a2445 100644 --- a/widgets/e-minicard/e-reflow.c +++ b/widgets/e-minicard/e-reflow.c @@ -21,6 +21,7 @@ */ #include +#include #include "e-reflow.h" #include "e-canvas-utils.h" static void e_reflow_init (EReflow *card); @@ -132,6 +133,13 @@ e_reflow_init (EReflow *reflow) reflow->idle = 0; reflow->column_drag = FALSE; + + reflow->need_height_update = FALSE; + reflow->need_column_resize = FALSE; + + reflow->default_cursor_shown = TRUE; + reflow->arrow_cursor = NULL; + reflow->default_cursor = NULL; } static void @@ -146,8 +154,7 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) switch (arg_id){ case ARG_HEIGHT: e_reflow->height = GTK_VALUE_DOUBLE (*arg); - _update_reflow(e_reflow); - gnome_canvas_item_request_update (item); + _queue_reflow(e_reflow); break; } } @@ -185,6 +192,9 @@ e_reflow_realize (GnomeCanvasItem *item) if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item); + e_reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + e_reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); + for(list = e_reflow->items; list; list = g_list_next(list)) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data); gtk_signal_connect(GTK_OBJECT(item), @@ -196,7 +206,7 @@ e_reflow_realize (GnomeCanvasItem *item) NULL); } - _update_reflow( e_reflow ); + _queue_reflow( e_reflow ); if (!item->canvas->aa) { } @@ -213,6 +223,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) { } + gdk_cursor_destroy (e_reflow->arrow_cursor); + gdk_cursor_destroy (e_reflow->default_cursor); + g_list_free (e_reflow->items); g_list_free (e_reflow->columns); @@ -221,9 +234,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) } static gint -e_reflow_pick_line (EReflow *e_reflow, gint x) +e_reflow_pick_line (EReflow *e_reflow, double x) { - x += 6; + x += 9; x /= e_reflow->column_width + 16; return x; } @@ -269,15 +282,23 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) case GDK_BUTTON_PRESS: { GdkEventButton *button = (GdkEventButton *) event; - int n_x; + double n_x; n_x = button->x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 4 ) { + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 16 ) { e_reflow->which_column_dragged = e_reflow_pick_line(e_reflow, button->x); - e_reflow->start_x = button->x; + e_reflow->start_x = e_reflow->which_column_dragged * (e_reflow->column_width + 16) - 1; e_reflow->temp_column_width = e_reflow->column_width; e_reflow->column_drag = TRUE; + + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + e_reflow->arrow_cursor, + button->time); + + e_reflow->previous_temp_column_width = -1; + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); return TRUE; } @@ -294,8 +315,8 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(e_reflow, adjustment->value) * (e_reflow->temp_column_width - e_reflow->column_width)); e_reflow->column_width = e_reflow->temp_column_width; e_reflow->column_drag = FALSE; - _update_reflow(e_reflow); - gnome_canvas_item_request_update(item); + _queue_reflow(e_reflow); + gnome_canvas_item_ungrab (item, button->time); return TRUE; } break; @@ -308,9 +329,58 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) (motion->x - e_reflow->start_x)/(e_reflow->which_column_dragged - e_reflow_pick_line(e_reflow, adjustment->value)); if (e_reflow->temp_column_width < 50) e_reflow->temp_column_width = 50; - if (old_width != e_reflow->temp_column_width) + if (old_width != e_reflow->temp_column_width) { + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); + } return TRUE; + } else { + GdkEventMotion *motion = (GdkEventMotion *) event; + double n_x; + n_x = motion->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( motion->y >= 7 && motion->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } else + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + + } + break; + case GDK_ENTER_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } + } + break; + case GDK_LEAVE_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( !( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) ) { + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + } } break; default: @@ -344,7 +414,7 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { int x_rect, y_rect, width_rect, height_rect; - gint running_width; + gdouble running_width; EReflow *e_reflow = E_REFLOW(item); int i; double column_width; @@ -417,25 +487,73 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) { + EReflow *e_reflow; double x0, x1, y0, y1; + e_reflow = E_REFLOW (item); + if (GNOME_CANVAS_ITEM_CLASS(parent_class)->update) GNOME_CANVAS_ITEM_CLASS(parent_class)->update (item, affine, clip_path, flags); - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if ( x0 > 0 ) - x0 = 0; - if ( y0 > 0 ) - y0 = 0; - if ( x1 < E_REFLOW(item)->width ) - x1 = E_REFLOW(item)->width; - if ( x1 < E_REFLOW(item)->height ) - x1 = E_REFLOW(item)->height; - - gnome_canvas_update_bbox(item, x0, y0, x1, y1); + if (e_reflow->need_height_update) { + x0 = item->x1; + y0 = item->y1; + x1 = item->x2; + y1 = item->y2; + if ( x0 > 0 ) + x0 = 0; + if ( y0 > 0 ) + y0 = 0; + if ( x1 < E_REFLOW(item)->width ) + x1 = E_REFLOW(item)->width; + if ( x1 < E_REFLOW(item)->height ) + x1 = E_REFLOW(item)->height; + + gnome_canvas_request_redraw(item->canvas, x0, y0, x1, y1); + e_reflow->need_height_update = FALSE; + } else if (e_reflow->need_column_resize) { + int x_rect, y_rect, width_rect, height_rect; + int start_line = e_reflow_pick_line(e_reflow, + gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))->value); + gdouble running_width; + int i; + double column_width; + + if ( e_reflow->previous_temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->previous_temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + if ( e_reflow->temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + e_reflow->previous_temp_column_width = e_reflow->temp_column_width; + e_reflow->need_column_resize = FALSE; + } } static double @@ -452,11 +570,11 @@ e_reflow_point (GnomeCanvasItem *item, return 0; if (y >= 7 && y <= e_reflow->height - 7) { - int n_x; + float n_x; n_x = x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if (n_x < 4) { + n_x += 9.0; + n_x = fmod(n_x, (e_reflow->column_width + 16)); + if (n_x < 16.0) { *actual_item = item; return 0; } @@ -467,7 +585,7 @@ e_reflow_point (GnomeCanvasItem *item, static void _reflow( EReflow *e_reflow ) { - int running_height; + gdouble running_height; GList *list; double item_height; @@ -514,8 +632,8 @@ _update_reflow( EReflow *e_reflow ) { if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) { - gint old_width; - gint running_width; + gdouble old_width; + gdouble running_width; _reflow (e_reflow); @@ -528,7 +646,7 @@ _update_reflow( EReflow *e_reflow ) GList *list; GList *next_column; gdouble item_height; - gint running_height; + gdouble running_height; running_height = 7; @@ -579,6 +697,8 @@ _idle_reflow(gpointer data) { EReflow *e_reflow = E_REFLOW(data); _update_reflow(e_reflow); + e_reflow->need_height_update = TRUE; + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow)); e_reflow->idle = 0; return FALSE; } diff --git a/widgets/e-minicard/e-reflow.h b/widgets/e-minicard/e-reflow.h index 27b96645f8..8506eda60b 100644 --- a/widgets/e-minicard/e-reflow.h +++ b/widgets/e-minicard/e-reflow.h @@ -71,6 +71,14 @@ struct _EReflow gdouble start_x; gint which_column_dragged; double temp_column_width; + double previous_temp_column_width; + + guint need_height_update : 1; + guint need_column_resize : 1; + + guint default_cursor_shown : 1; + GdkCursor *arrow_cursor; + GdkCursor *default_cursor; }; struct _EReflowClass diff --git a/widgets/e-reflow.c b/widgets/e-reflow.c index 41be2ec533..96773a2445 100644 --- a/widgets/e-reflow.c +++ b/widgets/e-reflow.c @@ -21,6 +21,7 @@ */ #include +#include #include "e-reflow.h" #include "e-canvas-utils.h" static void e_reflow_init (EReflow *card); @@ -132,6 +133,13 @@ e_reflow_init (EReflow *reflow) reflow->idle = 0; reflow->column_drag = FALSE; + + reflow->need_height_update = FALSE; + reflow->need_column_resize = FALSE; + + reflow->default_cursor_shown = TRUE; + reflow->arrow_cursor = NULL; + reflow->default_cursor = NULL; } static void @@ -146,8 +154,7 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) switch (arg_id){ case ARG_HEIGHT: e_reflow->height = GTK_VALUE_DOUBLE (*arg); - _update_reflow(e_reflow); - gnome_canvas_item_request_update (item); + _queue_reflow(e_reflow); break; } } @@ -185,6 +192,9 @@ e_reflow_realize (GnomeCanvasItem *item) if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item); + e_reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + e_reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); + for(list = e_reflow->items; list; list = g_list_next(list)) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data); gtk_signal_connect(GTK_OBJECT(item), @@ -196,7 +206,7 @@ e_reflow_realize (GnomeCanvasItem *item) NULL); } - _update_reflow( e_reflow ); + _queue_reflow( e_reflow ); if (!item->canvas->aa) { } @@ -213,6 +223,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) { } + gdk_cursor_destroy (e_reflow->arrow_cursor); + gdk_cursor_destroy (e_reflow->default_cursor); + g_list_free (e_reflow->items); g_list_free (e_reflow->columns); @@ -221,9 +234,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) } static gint -e_reflow_pick_line (EReflow *e_reflow, gint x) +e_reflow_pick_line (EReflow *e_reflow, double x) { - x += 6; + x += 9; x /= e_reflow->column_width + 16; return x; } @@ -269,15 +282,23 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) case GDK_BUTTON_PRESS: { GdkEventButton *button = (GdkEventButton *) event; - int n_x; + double n_x; n_x = button->x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 4 ) { + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 16 ) { e_reflow->which_column_dragged = e_reflow_pick_line(e_reflow, button->x); - e_reflow->start_x = button->x; + e_reflow->start_x = e_reflow->which_column_dragged * (e_reflow->column_width + 16) - 1; e_reflow->temp_column_width = e_reflow->column_width; e_reflow->column_drag = TRUE; + + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + e_reflow->arrow_cursor, + button->time); + + e_reflow->previous_temp_column_width = -1; + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); return TRUE; } @@ -294,8 +315,8 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(e_reflow, adjustment->value) * (e_reflow->temp_column_width - e_reflow->column_width)); e_reflow->column_width = e_reflow->temp_column_width; e_reflow->column_drag = FALSE; - _update_reflow(e_reflow); - gnome_canvas_item_request_update(item); + _queue_reflow(e_reflow); + gnome_canvas_item_ungrab (item, button->time); return TRUE; } break; @@ -308,9 +329,58 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) (motion->x - e_reflow->start_x)/(e_reflow->which_column_dragged - e_reflow_pick_line(e_reflow, adjustment->value)); if (e_reflow->temp_column_width < 50) e_reflow->temp_column_width = 50; - if (old_width != e_reflow->temp_column_width) + if (old_width != e_reflow->temp_column_width) { + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); + } return TRUE; + } else { + GdkEventMotion *motion = (GdkEventMotion *) event; + double n_x; + n_x = motion->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( motion->y >= 7 && motion->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } else + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + + } + break; + case GDK_ENTER_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } + } + break; + case GDK_LEAVE_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( !( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) ) { + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + } } break; default: @@ -344,7 +414,7 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { int x_rect, y_rect, width_rect, height_rect; - gint running_width; + gdouble running_width; EReflow *e_reflow = E_REFLOW(item); int i; double column_width; @@ -417,25 +487,73 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) { + EReflow *e_reflow; double x0, x1, y0, y1; + e_reflow = E_REFLOW (item); + if (GNOME_CANVAS_ITEM_CLASS(parent_class)->update) GNOME_CANVAS_ITEM_CLASS(parent_class)->update (item, affine, clip_path, flags); - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if ( x0 > 0 ) - x0 = 0; - if ( y0 > 0 ) - y0 = 0; - if ( x1 < E_REFLOW(item)->width ) - x1 = E_REFLOW(item)->width; - if ( x1 < E_REFLOW(item)->height ) - x1 = E_REFLOW(item)->height; - - gnome_canvas_update_bbox(item, x0, y0, x1, y1); + if (e_reflow->need_height_update) { + x0 = item->x1; + y0 = item->y1; + x1 = item->x2; + y1 = item->y2; + if ( x0 > 0 ) + x0 = 0; + if ( y0 > 0 ) + y0 = 0; + if ( x1 < E_REFLOW(item)->width ) + x1 = E_REFLOW(item)->width; + if ( x1 < E_REFLOW(item)->height ) + x1 = E_REFLOW(item)->height; + + gnome_canvas_request_redraw(item->canvas, x0, y0, x1, y1); + e_reflow->need_height_update = FALSE; + } else if (e_reflow->need_column_resize) { + int x_rect, y_rect, width_rect, height_rect; + int start_line = e_reflow_pick_line(e_reflow, + gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))->value); + gdouble running_width; + int i; + double column_width; + + if ( e_reflow->previous_temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->previous_temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + if ( e_reflow->temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + e_reflow->previous_temp_column_width = e_reflow->temp_column_width; + e_reflow->need_column_resize = FALSE; + } } static double @@ -452,11 +570,11 @@ e_reflow_point (GnomeCanvasItem *item, return 0; if (y >= 7 && y <= e_reflow->height - 7) { - int n_x; + float n_x; n_x = x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if (n_x < 4) { + n_x += 9.0; + n_x = fmod(n_x, (e_reflow->column_width + 16)); + if (n_x < 16.0) { *actual_item = item; return 0; } @@ -467,7 +585,7 @@ e_reflow_point (GnomeCanvasItem *item, static void _reflow( EReflow *e_reflow ) { - int running_height; + gdouble running_height; GList *list; double item_height; @@ -514,8 +632,8 @@ _update_reflow( EReflow *e_reflow ) { if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) { - gint old_width; - gint running_width; + gdouble old_width; + gdouble running_width; _reflow (e_reflow); @@ -528,7 +646,7 @@ _update_reflow( EReflow *e_reflow ) GList *list; GList *next_column; gdouble item_height; - gint running_height; + gdouble running_height; running_height = 7; @@ -579,6 +697,8 @@ _idle_reflow(gpointer data) { EReflow *e_reflow = E_REFLOW(data); _update_reflow(e_reflow); + e_reflow->need_height_update = TRUE; + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow)); e_reflow->idle = 0; return FALSE; } diff --git a/widgets/e-reflow.h b/widgets/e-reflow.h index 27b96645f8..8506eda60b 100644 --- a/widgets/e-reflow.h +++ b/widgets/e-reflow.h @@ -71,6 +71,14 @@ struct _EReflow gdouble start_x; gint which_column_dragged; double temp_column_width; + double previous_temp_column_width; + + guint need_height_update : 1; + guint need_column_resize : 1; + + guint default_cursor_shown : 1; + GdkCursor *arrow_cursor; + GdkCursor *default_cursor; }; struct _EReflowClass diff --git a/widgets/e-reflow/e-reflow.c b/widgets/e-reflow/e-reflow.c index 41be2ec533..96773a2445 100644 --- a/widgets/e-reflow/e-reflow.c +++ b/widgets/e-reflow/e-reflow.c @@ -21,6 +21,7 @@ */ #include +#include #include "e-reflow.h" #include "e-canvas-utils.h" static void e_reflow_init (EReflow *card); @@ -132,6 +133,13 @@ e_reflow_init (EReflow *reflow) reflow->idle = 0; reflow->column_drag = FALSE; + + reflow->need_height_update = FALSE; + reflow->need_column_resize = FALSE; + + reflow->default_cursor_shown = TRUE; + reflow->arrow_cursor = NULL; + reflow->default_cursor = NULL; } static void @@ -146,8 +154,7 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) switch (arg_id){ case ARG_HEIGHT: e_reflow->height = GTK_VALUE_DOUBLE (*arg); - _update_reflow(e_reflow); - gnome_canvas_item_request_update (item); + _queue_reflow(e_reflow); break; } } @@ -185,6 +192,9 @@ e_reflow_realize (GnomeCanvasItem *item) if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item); + e_reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + e_reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); + for(list = e_reflow->items; list; list = g_list_next(list)) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data); gtk_signal_connect(GTK_OBJECT(item), @@ -196,7 +206,7 @@ e_reflow_realize (GnomeCanvasItem *item) NULL); } - _update_reflow( e_reflow ); + _queue_reflow( e_reflow ); if (!item->canvas->aa) { } @@ -213,6 +223,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) { } + gdk_cursor_destroy (e_reflow->arrow_cursor); + gdk_cursor_destroy (e_reflow->default_cursor); + g_list_free (e_reflow->items); g_list_free (e_reflow->columns); @@ -221,9 +234,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) } static gint -e_reflow_pick_line (EReflow *e_reflow, gint x) +e_reflow_pick_line (EReflow *e_reflow, double x) { - x += 6; + x += 9; x /= e_reflow->column_width + 16; return x; } @@ -269,15 +282,23 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) case GDK_BUTTON_PRESS: { GdkEventButton *button = (GdkEventButton *) event; - int n_x; + double n_x; n_x = button->x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 4 ) { + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 16 ) { e_reflow->which_column_dragged = e_reflow_pick_line(e_reflow, button->x); - e_reflow->start_x = button->x; + e_reflow->start_x = e_reflow->which_column_dragged * (e_reflow->column_width + 16) - 1; e_reflow->temp_column_width = e_reflow->column_width; e_reflow->column_drag = TRUE; + + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + e_reflow->arrow_cursor, + button->time); + + e_reflow->previous_temp_column_width = -1; + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); return TRUE; } @@ -294,8 +315,8 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(e_reflow, adjustment->value) * (e_reflow->temp_column_width - e_reflow->column_width)); e_reflow->column_width = e_reflow->temp_column_width; e_reflow->column_drag = FALSE; - _update_reflow(e_reflow); - gnome_canvas_item_request_update(item); + _queue_reflow(e_reflow); + gnome_canvas_item_ungrab (item, button->time); return TRUE; } break; @@ -308,9 +329,58 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) (motion->x - e_reflow->start_x)/(e_reflow->which_column_dragged - e_reflow_pick_line(e_reflow, adjustment->value)); if (e_reflow->temp_column_width < 50) e_reflow->temp_column_width = 50; - if (old_width != e_reflow->temp_column_width) + if (old_width != e_reflow->temp_column_width) { + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); + } return TRUE; + } else { + GdkEventMotion *motion = (GdkEventMotion *) event; + double n_x; + n_x = motion->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( motion->y >= 7 && motion->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } else + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + + } + break; + case GDK_ENTER_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } + } + break; + case GDK_LEAVE_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( !( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) ) { + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + } } break; default: @@ -344,7 +414,7 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { int x_rect, y_rect, width_rect, height_rect; - gint running_width; + gdouble running_width; EReflow *e_reflow = E_REFLOW(item); int i; double column_width; @@ -417,25 +487,73 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) { + EReflow *e_reflow; double x0, x1, y0, y1; + e_reflow = E_REFLOW (item); + if (GNOME_CANVAS_ITEM_CLASS(parent_class)->update) GNOME_CANVAS_ITEM_CLASS(parent_class)->update (item, affine, clip_path, flags); - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if ( x0 > 0 ) - x0 = 0; - if ( y0 > 0 ) - y0 = 0; - if ( x1 < E_REFLOW(item)->width ) - x1 = E_REFLOW(item)->width; - if ( x1 < E_REFLOW(item)->height ) - x1 = E_REFLOW(item)->height; - - gnome_canvas_update_bbox(item, x0, y0, x1, y1); + if (e_reflow->need_height_update) { + x0 = item->x1; + y0 = item->y1; + x1 = item->x2; + y1 = item->y2; + if ( x0 > 0 ) + x0 = 0; + if ( y0 > 0 ) + y0 = 0; + if ( x1 < E_REFLOW(item)->width ) + x1 = E_REFLOW(item)->width; + if ( x1 < E_REFLOW(item)->height ) + x1 = E_REFLOW(item)->height; + + gnome_canvas_request_redraw(item->canvas, x0, y0, x1, y1); + e_reflow->need_height_update = FALSE; + } else if (e_reflow->need_column_resize) { + int x_rect, y_rect, width_rect, height_rect; + int start_line = e_reflow_pick_line(e_reflow, + gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))->value); + gdouble running_width; + int i; + double column_width; + + if ( e_reflow->previous_temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->previous_temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + if ( e_reflow->temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + e_reflow->previous_temp_column_width = e_reflow->temp_column_width; + e_reflow->need_column_resize = FALSE; + } } static double @@ -452,11 +570,11 @@ e_reflow_point (GnomeCanvasItem *item, return 0; if (y >= 7 && y <= e_reflow->height - 7) { - int n_x; + float n_x; n_x = x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if (n_x < 4) { + n_x += 9.0; + n_x = fmod(n_x, (e_reflow->column_width + 16)); + if (n_x < 16.0) { *actual_item = item; return 0; } @@ -467,7 +585,7 @@ e_reflow_point (GnomeCanvasItem *item, static void _reflow( EReflow *e_reflow ) { - int running_height; + gdouble running_height; GList *list; double item_height; @@ -514,8 +632,8 @@ _update_reflow( EReflow *e_reflow ) { if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) { - gint old_width; - gint running_width; + gdouble old_width; + gdouble running_width; _reflow (e_reflow); @@ -528,7 +646,7 @@ _update_reflow( EReflow *e_reflow ) GList *list; GList *next_column; gdouble item_height; - gint running_height; + gdouble running_height; running_height = 7; @@ -579,6 +697,8 @@ _idle_reflow(gpointer data) { EReflow *e_reflow = E_REFLOW(data); _update_reflow(e_reflow); + e_reflow->need_height_update = TRUE; + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow)); e_reflow->idle = 0; return FALSE; } diff --git a/widgets/e-reflow/e-reflow.h b/widgets/e-reflow/e-reflow.h index 27b96645f8..8506eda60b 100644 --- a/widgets/e-reflow/e-reflow.h +++ b/widgets/e-reflow/e-reflow.h @@ -71,6 +71,14 @@ struct _EReflow gdouble start_x; gint which_column_dragged; double temp_column_width; + double previous_temp_column_width; + + guint need_height_update : 1; + guint need_column_resize : 1; + + guint default_cursor_shown : 1; + GdkCursor *arrow_cursor; + GdkCursor *default_cursor; }; struct _EReflowClass diff --git a/widgets/e-text.c b/widgets/e-text.c index f4d6dddf55..1aef2ded6c 100644 --- a/widgets/e-text.c +++ b/widgets/e-text.c @@ -311,6 +311,9 @@ e_text_init (EText *text) text->primary_length = 0; text->clipboard_selection = NULL; text->clipboard_length = 0; + + text->pointer_in = FALSE; + text->default_cursor_shown = TRUE; } /* Destroy handler for the text item */ @@ -1031,6 +1034,9 @@ e_text_realize (GnomeCanvasItem *item) (* parent_class->realize) (item); text->gc = gdk_gc_new (item->canvas->layout.bin_window); + + text->i_cursor = gdk_cursor_new (GDK_XTERM); + text->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); } /* Unrealize handler for the text item */ @@ -1044,6 +1050,9 @@ e_text_unrealize (GnomeCanvasItem *item) gdk_gc_unref (text->gc); text->gc = NULL; + gdk_cursor_destroy (text->i_cursor); + gdk_cursor_destroy (text->default_cursor); + if (parent_class->unrealize) (* parent_class->unrealize) (item); } @@ -1700,6 +1709,12 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (focus_event->in) { if(!text->editing) { text->editing = TRUE; + if ( text->pointer_in ) { + if ( text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor); + text->default_cursor_shown = FALSE; + } + } text->selection_start = 0; text->selection_end = 0; text->select_by_word = FALSE; @@ -1712,6 +1727,10 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) } } else { text->editing = FALSE; + if ( ! text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor); + text->default_cursor_shown = TRUE; + } if (text->timeout_id) { g_source_remove(text->timeout_id); text->timeout_id = 0; @@ -1765,6 +1784,14 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (event->type == GDK_BUTTON_PRESS && text->timer) { g_timer_reset(text->timer); } + if (event->type == GDK_BUTTON_PRESS) { + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + text->i_cursor, + button.time); + } else { + gnome_canvas_item_ungrab (item, button.time); + } } else if (text->editable && event->type == GDK_BUTTON_RELEASE) { gnome_canvas_item_grab_focus (item); return 1; @@ -1784,6 +1811,24 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) text->last_state = motion.state; } break; + case GDK_ENTER_NOTIFY: + text->pointer_in = TRUE; + if (text->editing) { + if ( text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor); + text->default_cursor_shown = FALSE; + } + } + break; + case GDK_LEAVE_NOTIFY: + text->pointer_in = FALSE; + if (text->editing) { + if ( ! text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor); + text->default_cursor_shown = TRUE; + } + } + break; default: break; } diff --git a/widgets/e-text.h b/widgets/e-text.h index e1f250c678..f4f43a156b 100644 --- a/widgets/e-text.h +++ b/widgets/e-text.h @@ -167,6 +167,12 @@ struct _EText { gint primary_length; /* Primary selection text length */ gchar *clipboard_selection; /* Clipboard selection text */ gint clipboard_length; /* Clipboard selection text length*/ + + guint pointer_in : 1; + guint default_cursor_shown : 1; + + GdkCursor *default_cursor; + GdkCursor *i_cursor; }; struct _ETextClass { diff --git a/widgets/e-text/e-text.c b/widgets/e-text/e-text.c index f4d6dddf55..1aef2ded6c 100644 --- a/widgets/e-text/e-text.c +++ b/widgets/e-text/e-text.c @@ -311,6 +311,9 @@ e_text_init (EText *text) text->primary_length = 0; text->clipboard_selection = NULL; text->clipboard_length = 0; + + text->pointer_in = FALSE; + text->default_cursor_shown = TRUE; } /* Destroy handler for the text item */ @@ -1031,6 +1034,9 @@ e_text_realize (GnomeCanvasItem *item) (* parent_class->realize) (item); text->gc = gdk_gc_new (item->canvas->layout.bin_window); + + text->i_cursor = gdk_cursor_new (GDK_XTERM); + text->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); } /* Unrealize handler for the text item */ @@ -1044,6 +1050,9 @@ e_text_unrealize (GnomeCanvasItem *item) gdk_gc_unref (text->gc); text->gc = NULL; + gdk_cursor_destroy (text->i_cursor); + gdk_cursor_destroy (text->default_cursor); + if (parent_class->unrealize) (* parent_class->unrealize) (item); } @@ -1700,6 +1709,12 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (focus_event->in) { if(!text->editing) { text->editing = TRUE; + if ( text->pointer_in ) { + if ( text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor); + text->default_cursor_shown = FALSE; + } + } text->selection_start = 0; text->selection_end = 0; text->select_by_word = FALSE; @@ -1712,6 +1727,10 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) } } else { text->editing = FALSE; + if ( ! text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor); + text->default_cursor_shown = TRUE; + } if (text->timeout_id) { g_source_remove(text->timeout_id); text->timeout_id = 0; @@ -1765,6 +1784,14 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (event->type == GDK_BUTTON_PRESS && text->timer) { g_timer_reset(text->timer); } + if (event->type == GDK_BUTTON_PRESS) { + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + text->i_cursor, + button.time); + } else { + gnome_canvas_item_ungrab (item, button.time); + } } else if (text->editable && event->type == GDK_BUTTON_RELEASE) { gnome_canvas_item_grab_focus (item); return 1; @@ -1784,6 +1811,24 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) text->last_state = motion.state; } break; + case GDK_ENTER_NOTIFY: + text->pointer_in = TRUE; + if (text->editing) { + if ( text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor); + text->default_cursor_shown = FALSE; + } + } + break; + case GDK_LEAVE_NOTIFY: + text->pointer_in = FALSE; + if (text->editing) { + if ( ! text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor); + text->default_cursor_shown = TRUE; + } + } + break; default: break; } diff --git a/widgets/e-text/e-text.h b/widgets/e-text/e-text.h index e1f250c678..f4f43a156b 100644 --- a/widgets/e-text/e-text.h +++ b/widgets/e-text/e-text.h @@ -167,6 +167,12 @@ struct _EText { gint primary_length; /* Primary selection text length */ gchar *clipboard_selection; /* Clipboard selection text */ gint clipboard_length; /* Clipboard selection text length*/ + + guint pointer_in : 1; + guint default_cursor_shown : 1; + + GdkCursor *default_cursor; + GdkCursor *i_cursor; }; struct _ETextClass { diff --git a/widgets/misc/e-reflow.c b/widgets/misc/e-reflow.c index 41be2ec533..96773a2445 100644 --- a/widgets/misc/e-reflow.c +++ b/widgets/misc/e-reflow.c @@ -21,6 +21,7 @@ */ #include +#include #include "e-reflow.h" #include "e-canvas-utils.h" static void e_reflow_init (EReflow *card); @@ -132,6 +133,13 @@ e_reflow_init (EReflow *reflow) reflow->idle = 0; reflow->column_drag = FALSE; + + reflow->need_height_update = FALSE; + reflow->need_column_resize = FALSE; + + reflow->default_cursor_shown = TRUE; + reflow->arrow_cursor = NULL; + reflow->default_cursor = NULL; } static void @@ -146,8 +154,7 @@ e_reflow_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) switch (arg_id){ case ARG_HEIGHT: e_reflow->height = GTK_VALUE_DOUBLE (*arg); - _update_reflow(e_reflow); - gnome_canvas_item_request_update (item); + _queue_reflow(e_reflow); break; } } @@ -185,6 +192,9 @@ e_reflow_realize (GnomeCanvasItem *item) if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item); + e_reflow->arrow_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + e_reflow->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); + for(list = e_reflow->items; list; list = g_list_next(list)) { GnomeCanvasItem *item = GNOME_CANVAS_ITEM(list->data); gtk_signal_connect(GTK_OBJECT(item), @@ -196,7 +206,7 @@ e_reflow_realize (GnomeCanvasItem *item) NULL); } - _update_reflow( e_reflow ); + _queue_reflow( e_reflow ); if (!item->canvas->aa) { } @@ -213,6 +223,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) { } + gdk_cursor_destroy (e_reflow->arrow_cursor); + gdk_cursor_destroy (e_reflow->default_cursor); + g_list_free (e_reflow->items); g_list_free (e_reflow->columns); @@ -221,9 +234,9 @@ e_reflow_unrealize (GnomeCanvasItem *item) } static gint -e_reflow_pick_line (EReflow *e_reflow, gint x) +e_reflow_pick_line (EReflow *e_reflow, double x) { - x += 6; + x += 9; x /= e_reflow->column_width + 16; return x; } @@ -269,15 +282,23 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) case GDK_BUTTON_PRESS: { GdkEventButton *button = (GdkEventButton *) event; - int n_x; + double n_x; n_x = button->x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 4 ) { + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( button->y >= 7 && button->y <= e_reflow->height - 7 && n_x < 16 ) { e_reflow->which_column_dragged = e_reflow_pick_line(e_reflow, button->x); - e_reflow->start_x = button->x; + e_reflow->start_x = e_reflow->which_column_dragged * (e_reflow->column_width + 16) - 1; e_reflow->temp_column_width = e_reflow->column_width; e_reflow->column_drag = TRUE; + + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + e_reflow->arrow_cursor, + button->time); + + e_reflow->previous_temp_column_width = -1; + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); return TRUE; } @@ -294,8 +315,8 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(e_reflow, adjustment->value) * (e_reflow->temp_column_width - e_reflow->column_width)); e_reflow->column_width = e_reflow->temp_column_width; e_reflow->column_drag = FALSE; - _update_reflow(e_reflow); - gnome_canvas_item_request_update(item); + _queue_reflow(e_reflow); + gnome_canvas_item_ungrab (item, button->time); return TRUE; } break; @@ -308,9 +329,58 @@ e_reflow_event (GnomeCanvasItem *item, GdkEvent *event) (motion->x - e_reflow->start_x)/(e_reflow->which_column_dragged - e_reflow_pick_line(e_reflow, adjustment->value)); if (e_reflow->temp_column_width < 50) e_reflow->temp_column_width = 50; - if (old_width != e_reflow->temp_column_width) + if (old_width != e_reflow->temp_column_width) { + e_reflow->need_column_resize = TRUE; gnome_canvas_item_request_update(item); + } return TRUE; + } else { + GdkEventMotion *motion = (GdkEventMotion *) event; + double n_x; + n_x = motion->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( motion->y >= 7 && motion->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } else + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + + } + break; + case GDK_ENTER_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) { + if ( e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->arrow_cursor); + e_reflow->default_cursor_shown = FALSE; + } + } + } + break; + case GDK_LEAVE_NOTIFY: + if (!e_reflow->column_drag) { + GdkEventCrossing *crossing = (GdkEventCrossing *) event; + double n_x; + n_x = crossing->x; + n_x += 9; + n_x = fmod(n_x,(e_reflow->column_width + 16)); + if ( !( crossing->y >= 7 && crossing->y <= e_reflow->height - 7 && n_x < 16 ) ) { + if ( ! e_reflow->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, e_reflow->default_cursor); + e_reflow->default_cursor_shown = TRUE; + } + } } break; default: @@ -344,7 +414,7 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { int x_rect, y_rect, width_rect, height_rect; - gint running_width; + gdouble running_width; EReflow *e_reflow = E_REFLOW(item); int i; double column_width; @@ -417,25 +487,73 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable, static void e_reflow_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) { + EReflow *e_reflow; double x0, x1, y0, y1; + e_reflow = E_REFLOW (item); + if (GNOME_CANVAS_ITEM_CLASS(parent_class)->update) GNOME_CANVAS_ITEM_CLASS(parent_class)->update (item, affine, clip_path, flags); - x0 = item->x1; - y0 = item->y1; - x1 = item->x2; - y1 = item->y2; - if ( x0 > 0 ) - x0 = 0; - if ( y0 > 0 ) - y0 = 0; - if ( x1 < E_REFLOW(item)->width ) - x1 = E_REFLOW(item)->width; - if ( x1 < E_REFLOW(item)->height ) - x1 = E_REFLOW(item)->height; - - gnome_canvas_update_bbox(item, x0, y0, x1, y1); + if (e_reflow->need_height_update) { + x0 = item->x1; + y0 = item->y1; + x1 = item->x2; + y1 = item->y2; + if ( x0 > 0 ) + x0 = 0; + if ( y0 > 0 ) + y0 = 0; + if ( x1 < E_REFLOW(item)->width ) + x1 = E_REFLOW(item)->width; + if ( x1 < E_REFLOW(item)->height ) + x1 = E_REFLOW(item)->height; + + gnome_canvas_request_redraw(item->canvas, x0, y0, x1, y1); + e_reflow->need_height_update = FALSE; + } else if (e_reflow->need_column_resize) { + int x_rect, y_rect, width_rect, height_rect; + int start_line = e_reflow_pick_line(e_reflow, + gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas))->value); + gdouble running_width; + int i; + double column_width; + + if ( e_reflow->previous_temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->previous_temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + if ( e_reflow->temp_column_width != -1 ) { + running_width = start_line * (e_reflow->column_width + 16); + column_width = e_reflow->temp_column_width; + running_width -= start_line * (column_width + 16); + running_width += 7 + column_width + 7; + y_rect = 7; + width_rect = 2; + height_rect = e_reflow->height - 14; + + for ( i = 0; i < e_reflow->column_count - 1; i++) { + x_rect = running_width; + gnome_canvas_request_redraw(item->canvas, x_rect, y_rect, x_rect + width_rect, y_rect + height_rect); + running_width += 2 + 7 + column_width + 7; + } + } + + e_reflow->previous_temp_column_width = e_reflow->temp_column_width; + e_reflow->need_column_resize = FALSE; + } } static double @@ -452,11 +570,11 @@ e_reflow_point (GnomeCanvasItem *item, return 0; if (y >= 7 && y <= e_reflow->height - 7) { - int n_x; + float n_x; n_x = x; - n_x += 3; - n_x %= (int)(e_reflow->column_width + 16); - if (n_x < 4) { + n_x += 9.0; + n_x = fmod(n_x, (e_reflow->column_width + 16)); + if (n_x < 16.0) { *actual_item = item; return 0; } @@ -467,7 +585,7 @@ e_reflow_point (GnomeCanvasItem *item, static void _reflow( EReflow *e_reflow ) { - int running_height; + gdouble running_height; GList *list; double item_height; @@ -514,8 +632,8 @@ _update_reflow( EReflow *e_reflow ) { if ( GTK_OBJECT_FLAGS( e_reflow ) & GNOME_CANVAS_ITEM_REALIZED ) { - gint old_width; - gint running_width; + gdouble old_width; + gdouble running_width; _reflow (e_reflow); @@ -528,7 +646,7 @@ _update_reflow( EReflow *e_reflow ) GList *list; GList *next_column; gdouble item_height; - gint running_height; + gdouble running_height; running_height = 7; @@ -579,6 +697,8 @@ _idle_reflow(gpointer data) { EReflow *e_reflow = E_REFLOW(data); _update_reflow(e_reflow); + e_reflow->need_height_update = TRUE; + gnome_canvas_item_request_update(GNOME_CANVAS_ITEM(e_reflow)); e_reflow->idle = 0; return FALSE; } diff --git a/widgets/misc/e-reflow.h b/widgets/misc/e-reflow.h index 27b96645f8..8506eda60b 100644 --- a/widgets/misc/e-reflow.h +++ b/widgets/misc/e-reflow.h @@ -71,6 +71,14 @@ struct _EReflow gdouble start_x; gint which_column_dragged; double temp_column_width; + double previous_temp_column_width; + + guint need_height_update : 1; + guint need_column_resize : 1; + + guint default_cursor_shown : 1; + GdkCursor *arrow_cursor; + GdkCursor *default_cursor; }; struct _EReflowClass diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index f4d6dddf55..1aef2ded6c 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -311,6 +311,9 @@ e_text_init (EText *text) text->primary_length = 0; text->clipboard_selection = NULL; text->clipboard_length = 0; + + text->pointer_in = FALSE; + text->default_cursor_shown = TRUE; } /* Destroy handler for the text item */ @@ -1031,6 +1034,9 @@ e_text_realize (GnomeCanvasItem *item) (* parent_class->realize) (item); text->gc = gdk_gc_new (item->canvas->layout.bin_window); + + text->i_cursor = gdk_cursor_new (GDK_XTERM); + text->default_cursor = gdk_cursor_new (GDK_LEFT_PTR); } /* Unrealize handler for the text item */ @@ -1044,6 +1050,9 @@ e_text_unrealize (GnomeCanvasItem *item) gdk_gc_unref (text->gc); text->gc = NULL; + gdk_cursor_destroy (text->i_cursor); + gdk_cursor_destroy (text->default_cursor); + if (parent_class->unrealize) (* parent_class->unrealize) (item); } @@ -1700,6 +1709,12 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (focus_event->in) { if(!text->editing) { text->editing = TRUE; + if ( text->pointer_in ) { + if ( text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor); + text->default_cursor_shown = FALSE; + } + } text->selection_start = 0; text->selection_end = 0; text->select_by_word = FALSE; @@ -1712,6 +1727,10 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) } } else { text->editing = FALSE; + if ( ! text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor); + text->default_cursor_shown = TRUE; + } if (text->timeout_id) { g_source_remove(text->timeout_id); text->timeout_id = 0; @@ -1765,6 +1784,14 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (event->type == GDK_BUTTON_PRESS && text->timer) { g_timer_reset(text->timer); } + if (event->type == GDK_BUTTON_PRESS) { + gnome_canvas_item_grab (item, + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK, + text->i_cursor, + button.time); + } else { + gnome_canvas_item_ungrab (item, button.time); + } } else if (text->editable && event->type == GDK_BUTTON_RELEASE) { gnome_canvas_item_grab_focus (item); return 1; @@ -1784,6 +1811,24 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) text->last_state = motion.state; } break; + case GDK_ENTER_NOTIFY: + text->pointer_in = TRUE; + if (text->editing) { + if ( text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->i_cursor); + text->default_cursor_shown = FALSE; + } + } + break; + case GDK_LEAVE_NOTIFY: + text->pointer_in = FALSE; + if (text->editing) { + if ( ! text->default_cursor_shown ) { + gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, text->default_cursor); + text->default_cursor_shown = TRUE; + } + } + break; default: break; } diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h index e1f250c678..f4f43a156b 100644 --- a/widgets/text/e-text.h +++ b/widgets/text/e-text.h @@ -167,6 +167,12 @@ struct _EText { gint primary_length; /* Primary selection text length */ gchar *clipboard_selection; /* Clipboard selection text */ gint clipboard_length; /* Clipboard selection text length*/ + + guint pointer_in : 1; + guint default_cursor_shown : 1; + + GdkCursor *default_cursor; + GdkCursor *i_cursor; }; struct _ETextClass { -- cgit v1.2.3