diff --git a/ChangeLog-1999-07-09 b/ChangeLog-1999-07-09 index 7bfa5e2f48dffc41a72d8fb3e4caf770b20c9c48..0f27b1e7edb3010a319869e44bc0d4e2d19f9022 100644 --- a/ChangeLog-1999-07-09 +++ b/ChangeLog-1999-07-09 @@ -1,3 +1,9 @@ +1998-09-08 Miguel de Icaza + + * src/sheet-object.c (sheet_button_press): Lots of changes to + finish the editing facilities for objects: you can now resize the + objects and you can move them. + 1998-09-07 Miguel de Icaza * src/dialog-cell-format.c (apply_font_format): Optimization, walk diff --git a/ChangeLog-2000-02-23 b/ChangeLog-2000-02-23 index 7bfa5e2f48dffc41a72d8fb3e4caf770b20c9c48..0f27b1e7edb3010a319869e44bc0d4e2d19f9022 100644 --- a/ChangeLog-2000-02-23 +++ b/ChangeLog-2000-02-23 @@ -1,3 +1,9 @@ +1998-09-08 Miguel de Icaza + + * src/sheet-object.c (sheet_button_press): Lots of changes to + finish the editing facilities for objects: you can now resize the + objects and you can move them. + 1998-09-07 Miguel de Icaza * src/dialog-cell-format.c (apply_font_format): Optimization, walk diff --git a/OChangeLog-1999-07-09 b/OChangeLog-1999-07-09 index 7bfa5e2f48dffc41a72d8fb3e4caf770b20c9c48..0f27b1e7edb3010a319869e44bc0d4e2d19f9022 100644 --- a/OChangeLog-1999-07-09 +++ b/OChangeLog-1999-07-09 @@ -1,3 +1,9 @@ +1998-09-08 Miguel de Icaza + + * src/sheet-object.c (sheet_button_press): Lots of changes to + finish the editing facilities for objects: you can now resize the + objects and you can move them. + 1998-09-07 Miguel de Icaza * src/dialog-cell-format.c (apply_font_format): Optimization, walk diff --git a/OChangeLog-2000-02-23 b/OChangeLog-2000-02-23 index 7bfa5e2f48dffc41a72d8fb3e4caf770b20c9c48..0f27b1e7edb3010a319869e44bc0d4e2d19f9022 100644 --- a/OChangeLog-2000-02-23 +++ b/OChangeLog-2000-02-23 @@ -1,3 +1,9 @@ +1998-09-08 Miguel de Icaza + + * src/sheet-object.c (sheet_button_press): Lots of changes to + finish the editing facilities for objects: you can now resize the + objects and you can move them. + 1998-09-07 Miguel de Icaza * src/dialog-cell-format.c (apply_font_format): Optimization, walk diff --git a/src/pixmaps.h b/src/pixmaps.h index 11dc420ce21276a905da08252ef68e2b4dc930b4..48ff5091f15e8ed3523298496555faa365721b68 100644 --- a/src/pixmaps.h +++ b/src/pixmaps.h @@ -3,4 +3,5 @@ #include "pixmaps/align-right.xpm" #include "pixmaps/rect.xpm" #include "pixmaps/line.xpm" +#include "pixmaps/arrow.xpm" #include "pixmaps/oval.xpm" diff --git a/src/pixmaps/arrow.xpm b/src/pixmaps/arrow.xpm new file mode 100644 index 0000000000000000000000000000000000000000..3cced738dec404d34ea05700c68a0889421f3315 --- /dev/null +++ b/src/pixmaps/arrow.xpm @@ -0,0 +1,33 @@ +/* XPM */ +static char *arrow_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 24 24 2 1", +/* colors */ +". c #000000", +"# c None", +/* pixels */ +"########################", +"########################", +"##.#####################", +"##....##################", +"##......################", +"##....##################", +"##..##.#################", +"#######.################", +"########.###############", +"#########.##############", +"##########.#############", +"###########.############", +"############.###########", +"#############.##########", +"##############.#########", +"###############.########", +"################.#######", +"#################.######", +"##################.#####", +"###################.####", +"####################.###", +"#####################.##", +"########################", +"########################" +}; diff --git a/src/sheet-control-gui.h b/src/sheet-control-gui.h index 0ca7d9dbf4ae05eff449793ec975e584d7591096..120888f0e11ea06cb1a03c5965476c7bd45cd826 100644 --- a/src/sheet-control-gui.h +++ b/src/sheet-control-gui.h @@ -28,7 +28,7 @@ typedef struct { /* * Control points for the current item */ - GList *control_points; + GnomeCanvasItem *control_points [8]; /* Scrolling information */ GtkWidget *vs, *hs; /* The scrollbars */ diff --git a/src/sheet-object.c b/src/sheet-object.c index 0bbda4023f8b64244cb6e7d89090b026e51fec4d..548bf4db42cebcaad393b75c380a5c84a7755456 100644 --- a/src/sheet-object.c +++ b/src/sheet-object.c @@ -10,11 +10,27 @@ #define GNUMERIC_SHEET_VIEW(p) GNUMERIC_SHEET (SHEET_VIEW(p)->sheet_view); static void sheet_finish_object_creation (Sheet *sheet); +static void sheet_object_unrealize (Sheet *sheet, SheetObject *object); +static void sheet_object_realize (Sheet *sheet, SheetObject *object); +static void sheet_object_start_editing (SheetObject *object); +static int object_event (GnomeCanvasItem *item, + GdkEvent *event, + SheetObject *object); typedef struct { gdouble x, y; } ObjectCoords; +static void +window_to_world (GnomeCanvas *canvas, gdouble *x, gdouble *y) +{ +#define DISPLAY_X1(canvas) (GNOME_CANVAS (canvas)->layout.xoffset) +#define DISPLAY_Y1(canvas) (GNOME_CANVAS (canvas)->layout.yoffset) + + *x = canvas->scroll_x1 + (*x + DISPLAY_X1 (canvas) - canvas->zoom_xofs) / canvas->pixels_per_unit; + *y = canvas->scroll_y1 + (*y + DISPLAY_Y1 (canvas) - canvas->zoom_yofs) / canvas->pixels_per_unit; +} + static void sheet_release_coords (Sheet *sheet) { @@ -86,7 +102,7 @@ sheet_object_create_filled (Sheet *sheet, int type, } SheetObject * -sheet_object_create_line (Sheet *sheet, double x1, double y1, double x2, double y2, char *color, int w) +sheet_object_create_line (Sheet *sheet, int is_arrow, double x1, double y1, double x2, double y2, char *color, int w) { SheetObject *so; @@ -94,7 +110,8 @@ sheet_object_create_line (Sheet *sheet, double x1, double y1, double x2, double g_return_val_if_fail (IS_SHEET (sheet), NULL); so = sheet_object_new (sheet); - so->type = SHEET_OBJECT_LINE; + + so->type = is_arrow ? SHEET_OBJECT_ARROW : SHEET_OBJECT_LINE; so->points = gnome_canvas_points_new (2); so->points->coords [0] = (gdouble) x1; so->points->coords [1] = (gdouble) y1; @@ -171,9 +188,10 @@ sheet_view_object_realize (SheetView *sheet_view, SheetObject *object) "points", object->points, "fill_color", object->color->str, "width_pixels", object->width, - "arrow_shape_a", 1.0, - "arrow_shape_b", 1.0, - "arrow_shape_c", 1.0, + "arrow_shape_a", 8.0, + "arrow_shape_b", 10.0, + "arrow_shape_c", 3.0, + "last_arrowhead", TRUE, NULL); break; @@ -208,6 +226,9 @@ sheet_view_object_realize (SheetView *sheet_view, SheetObject *object) break; } + gtk_signal_connect (GTK_OBJECT (item), "event", + GTK_SIGNAL_FUNC (object_event), object); + if (item == NULL) g_warning ("We created an unsupported type\n"); @@ -252,6 +273,19 @@ sheet_object_realize (Sheet *sheet, SheetObject *object) } } +static void +sheet_object_unrealize (Sheet *sheet, SheetObject *object) +{ + GList *l; + + for (l = sheet->sheet_views; l; l = l->next){ + SheetView *sheet_view = l->data; + + sheet_view_object_unrealize (sheet_view, object); + sheet_view->temp_item = NULL; + } +} + static SheetObject * create_object (Sheet *sheet, gdouble to_x, gdouble to_y) { @@ -263,7 +297,15 @@ create_object (Sheet *sheet, gdouble to_x, gdouble to_y) switch (sheet->mode){ case SHEET_MODE_CREATE_LINE: o = sheet_object_create_line ( - sheet, + sheet, FALSE, + oc->x, oc->y, + to_x, to_y, + "black", 1); + break; + + case SHEET_MODE_CREATE_ARROW: + o = sheet_object_create_line ( + sheet, TRUE, oc->x, oc->y, to_x, to_y, "black", 1); @@ -303,7 +345,9 @@ sheet_motion_notify (GnumericSheet *gsheet, GdkEvent *event, Sheet *sheet) if (gsheet->sheet_view->temp_item) sheet_object_destroy (gsheet->sheet_view->temp_item); - create_object (sheet, event->motion.x, event->motion.y); + window_to_world (GNOME_CANVAS (gsheet), &event->button.x, &event->button.y); + + create_object (sheet, event->button.x, event->button.y); return 1; } @@ -318,7 +362,8 @@ sheet_button_release (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet if (gsheet->sheet_view->temp_item) sheet_object_destroy (gsheet->sheet_view->temp_item); - + + window_to_world (GNOME_CANVAS (gsheet), &event->x, &event->y); o = create_object (sheet, event->x, event->y); sheet_object_make_current (sheet, o); @@ -329,17 +374,19 @@ sheet_button_release (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet } static int -sheet_button_press (GnumericSheet *gsheet, GdkEvent *event, Sheet *sheet) +sheet_button_press (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet) { ObjectCoords *oc; /* Do not propagate this event further */ gtk_signal_emit_stop_by_name (GTK_OBJECT (gsheet), "button_press_event"); - + oc = g_new (ObjectCoords, 1); - oc->x = event->button.x; - oc->y = event->button.y; + oc->x = event->x; + oc->y = event->y; + window_to_world (GNOME_CANVAS (gsheet), &oc->x, &oc->y); + sheet->coords = g_list_append (sheet->coords, oc); gtk_signal_connect (GTK_OBJECT (gsheet), "button_release_event", @@ -399,86 +446,252 @@ sheet_set_mode_type (Sheet *sheet, SheetModeType mode) } static void -sheet_object_stop_editing (SheetObject *object) +sheet_object_destroy_control_points (Sheet *sheet) { - Sheet *sheet = object->sheet; GList *l; for (l = sheet->sheet_views; l; l = l->next){ - GList *items; SheetView *sheet_view = l->data; - - for (items = sheet_view->control_points; items; items = items->next){ - GnomeCanvasItem *item = items->data; - - gtk_object_destroy (GTK_OBJECT (item)); + int i; + + for (i = 0; i < 8; i++){ + gtk_object_destroy (GTK_OBJECT (sheet_view->control_points [i])); + sheet_view->control_points [i] = NULL; } - g_list_free (sheet_view->control_points); - sheet_view->control_points = NULL; } +} + +static void +sheet_object_stop_editing (SheetObject *object) +{ + Sheet *sheet = object->sheet; + + sheet_object_destroy_control_points (sheet); sheet->current_object = NULL; } +#define POINT(x) (1 << x) + +static void +set_item_x (SheetView *sheet_view, int idx, double x) +{ + gnome_canvas_item_set ( + sheet_view->control_points [idx], + "x1", x - 2, + "x2", x + 2, + NULL); +} + +static void +set_item_y (SheetView *sheet_view, int idx, double y) +{ + gnome_canvas_item_set ( + sheet_view->control_points [idx], + "y1", y - 2, + "y2", y + 2, + NULL); +} + /* * This hooks to the event for the handlebox */ static int -object_event (GnomeCanvasItem *item, GdkEvent *event, SheetObject *object) +object_handle_event (GnomeCanvasItem *item, GdkEvent *event, SheetObject *object) { int idx; - double *points = object->points->coords; - double x1, y1, x2, y2; - static int last_x, last_y, dx, dy; + GList *l; + static int last_x, last_y; + double dx, dy; switch (event->type){ case GDK_BUTTON_RELEASE: + if (!object->dragging) + return FALSE; + object->dragging = 0; + gnome_canvas_item_ungrab (item, event->button.time); break; case GDK_BUTTON_PRESS: object->dragging = 1; + gnome_canvas_item_grab (item, + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, event->button.time); last_x = event->button.x; last_y = event->button.y; break; - case GDK_MOTION_NOTIFY: + case GDK_MOTION_NOTIFY: { + double *coords = object->points->coords; + int change = 0; + if (!object->dragging) return FALSE; - idx = GPOINTER_TO_INT (gtk_object_get_user_data (item)); - printf ("HERE: %d\n", idx); + idx = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (item))); + gnome_canvas_c2w (item->canvas, + event->button.x - last_x, + event->button.y - last_y, + &dx, &dy); + + last_x = event->button.x; + last_y = event->button.y; + switch (idx){ case 0: - case 2: - case 5: - case 7: - /* borders */ - dx = event->button.x - last_x; - dy = event->button.y - last_y; + change = POINT (0) | POINT (1); break; case 1: - case 6: - dx = 0; - dy = event->button.y - last_y; + change = POINT (1); break; + case 2: + change = POINT (1) | POINT (2); + break; + case 3: + change = POINT (0); + break; + case 4: - dy = 0; - dx = event->button.x - last_x; + change = POINT (2); + break; + + case 5: + change = POINT (0) | POINT (3); + break; + + case 6: + change = POINT (3); break; + + case 7: + change = POINT (2) | POINT (3); + break; + + default: + g_warning ("Should not happen"); } + + for (l = object->sheet->sheet_views; l; l = l->next){ + SheetView *sheet_view = l->data; + GnomeCanvasItem *object_item = NULL; + GList *ll; + + /* Find the object in this sheet view */ + for (ll = object->realized_list; ll; ll = ll->next){ + GnomeCanvasItem *oi = ll->data; + + if (oi->canvas == GNOME_CANVAS (sheet_view->sheet_view)){ + object_item = oi; + break; + } + } + if (change & POINT (0)){ + set_item_x (sheet_view, 0, coords [0] + dx); + set_item_x (sheet_view, 3, coords [0] + dx); + set_item_x (sheet_view, 5, coords [0] + dx); + } else if (change & POINT (2)){ + set_item_x (sheet_view, 2, coords [2] + dx); + set_item_x (sheet_view, 4, coords [2] + dx); + set_item_x (sheet_view, 7, coords [2] + dx); + } + + if (change & POINT (1)){ + set_item_y (sheet_view, 0, coords [1] + dy); + set_item_y (sheet_view, 1, coords [1] + dy); + set_item_y (sheet_view, 2, coords [1] + dy); + } else if (change & POINT (3)){ + set_item_y (sheet_view, 5, coords [3] + dy); + set_item_y (sheet_view, 6, coords [3] + dy); + set_item_y (sheet_view, 7, coords [3] + dy); + } + + if (change & (POINT (0) | POINT (2))){ + set_item_x (sheet_view, 1, (coords [0] + dx + coords [2])/2); + set_item_x (sheet_view, 6, (coords [0] + dx + coords [2])/2); + } + + if (change & (POINT (1) | POINT (3))){ + set_item_y (sheet_view, 3, (coords [1] + dy + coords [3])/2); + set_item_y (sheet_view, 4, (coords [1] + dy + coords [3])/2); + } + + sheet_view_object_unrealize (sheet_view, object); + coords [0] += change & POINT (0) ? dx : 0; + coords [1] += change & POINT (1) ? dy : 0; + coords [2] += change & POINT (2) ? dx : 0; + coords [3] += change & POINT (3) ? dy : 0; + sheet_view_object_realize (sheet_view, object); + } + break; + } + + default: + return FALSE; + } + return TRUE; +} + +static int +object_event (GnomeCanvasItem *item, GdkEvent *event, SheetObject *object) +{ + static int last_x, last_y; + static int total_x, total_y; + int dx, dy; + + switch (event->type){ + case GDK_BUTTON_PRESS: + if (object->sheet->current_object) + sheet_object_stop_editing (object->sheet->current_object); + + object->dragging = 1; + gnome_canvas_item_grab (item, + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_RELEASE_MASK, + NULL, event->button.time); last_x = event->button.x; last_y = event->button.y; + total_x = 0; + total_y = 0; + break; + + case GDK_BUTTON_RELEASE: + if (!object->dragging) + return FALSE; - gnome_canvas_item_move (item, dx, dy); + object->dragging = 0; + gnome_canvas_item_ungrab (item, event->button.time); + + sheet_object_unrealize (object->sheet, object); + object->points->coords [0] += total_x; + object->points->coords [1] += total_y; + object->points->coords [2] += total_x; + object->points->coords [3] += total_y; + sheet_object_realize (object->sheet, object); + + sheet_object_make_current (object->sheet, object); break; + + case GDK_MOTION_NOTIFY: + if (!object->dragging) + return FALSE; + dx = event->button.x - last_x; + dy = event->button.y - last_y; + total_x += dx; + total_y += dy; + last_x = event->button.x; + last_y = event->button.y; + gnome_canvas_item_move (item, dx, dy); + break; + default: return FALSE; - } + } return TRUE; } @@ -499,7 +712,7 @@ new_control_point (GnomeCanvasGroup *group, SheetObject *object, int idx, double NULL); gtk_signal_connect (GTK_OBJECT (item), "event", - GTK_SIGNAL_FUNC (object_event), object); + GTK_SIGNAL_FUNC (object_handle_event), object); gtk_object_set_user_data (GTK_OBJECT (item), GINT_TO_POINTER (idx)); @@ -512,32 +725,23 @@ sheet_object_start_editing (SheetObject *object) Sheet *sheet = object->sheet; double *points = object->points->coords; GList *l; - int i; for (l = sheet->sheet_views; l; l = l->next){ SheetView *sheet_view = l->data; GnomeCanvasGroup *group = sheet_view->object_group; - GnomeCanvasItem *ul [8]; +#define ul(x) sheet_view->control_points [x] - ul [0] = new_control_point (group, object, 0, points [0], points [1]); - ul [1] = new_control_point (group, object, 1, (points [0] + points [2]) / 2, points [1]); - ul [2] = new_control_point (group, object, 2, points [2], points [1]); - ul [3] = new_control_point (group, object, 3, points [0], (points [1] + points [3]) / 2); - ul [4] = new_control_point (group, object, 4, points [2], (points [1] + points [3]) / 2); - ul [5] = new_control_point (group, object, 5, points [0], points [3]); - ul [6] = new_control_point (group, object, 6, (points [0] + points [2]) / 2, points [3]); - ul [7] = new_control_point (group, object, 7, points [2], points [3]); - - for (i = 0; i < 8; i++) - sheet_view->control_points = g_list_prepend (sheet_view->control_points, ul [i]); + ul (0) = new_control_point (group, object, 0, points [0], points [1]); + ul (1) = new_control_point (group, object, 1, (points [0] + points [2]) / 2, points [1]); + ul (2) = new_control_point (group, object, 2, points [2], points [1]); + ul (3) = new_control_point (group, object, 3, points [0], (points [1] + points [3]) / 2); + ul (4) = new_control_point (group, object, 4, points [2], (points [1] + points [3]) / 2); + ul (5) = new_control_point (group, object, 5, points [0], points [3]); + ul (6) = new_control_point (group, object, 6, (points [0] + points [2]) / 2, points [3]); + ul (7) = new_control_point (group, object, 7, points [2], points [3]); } } -void -sheet_object_make_draggable (SheetObject *object) -{ -} - void sheet_object_make_current (Sheet *sheet, SheetObject *object) { @@ -552,7 +756,6 @@ sheet_object_make_current (Sheet *sheet, SheetObject *object) if (sheet->current_object) sheet_object_stop_editing (sheet->current_object); - sheet_object_make_draggable (object); sheet_object_start_editing (object); sheet->current_object = object; diff --git a/src/sheet-object.h b/src/sheet-object.h index 77105c49ef378f8cffe286b335a42d464eead2f0..fc111cf4bc04b03566615592a0822e1eb67206e0 100644 --- a/src/sheet-object.h +++ b/src/sheet-object.h @@ -30,7 +30,7 @@ typedef struct { #define SHEET_OBJECT_SIGNATURE (('S' << 24) | ('O' << 16) | ('b' << 8) | 'e') #define IS_SHEET_OBJECT(x) (x->signature == SHEET_OBJECT_SIGNATURE) -SheetObject *sheet_object_create_line (Sheet *sheet, +SheetObject *sheet_object_create_line (Sheet *sheet, int is_arrow, double x1, double y1, double x2, double y2, char *color, int width); diff --git a/src/sheet-view.h b/src/sheet-view.h index 0ca7d9dbf4ae05eff449793ec975e584d7591096..120888f0e11ea06cb1a03c5965476c7bd45cd826 100644 --- a/src/sheet-view.h +++ b/src/sheet-view.h @@ -28,7 +28,7 @@ typedef struct { /* * Control points for the current item */ - GList *control_points; + GnomeCanvasItem *control_points [8]; /* Scrolling information */ GtkWidget *vs, *hs; /* The scrollbars */ diff --git a/src/sheet.h b/src/sheet.h index 81f5722f89d20d0bcddf80853152918f2447bf64..0fbe7f28ca67c9f2705b034da7613af29080a0dd 100644 --- a/src/sheet.h +++ b/src/sheet.h @@ -66,6 +66,7 @@ typedef enum { SHEET_MODE_CREATE_LINE, SHEET_MODE_CREATE_BOX, SHEET_MODE_CREATE_OVAL, + SHEET_MODE_CREATE_ARROW } SheetModeType; typedef struct { diff --git a/src/workbook.c b/src/workbook.c index 58ef0ffdc7c7946e25ed67bb381acab886ec31f0..e8f3ec843df6eab7dafc24f8132d1e4ae8e4a29b 100644 --- a/src/workbook.c +++ b/src/workbook.c @@ -102,6 +102,15 @@ create_line_cmd (GtkWidget *widget, Workbook *wb) sheet_set_mode_type (sheet, SHEET_MODE_CREATE_LINE); } +static void +create_arrow_cmd (GtkWidget *widget, Workbook *wb) +{ + Sheet *sheet; + + sheet = workbook_get_current_sheet (wb); + sheet_set_mode_type (sheet, SHEET_MODE_CREATE_ARROW); +} + static void create_rectangle_cmd (GtkWidget *widget, Workbook *wb) { @@ -358,6 +367,9 @@ static GnomeUIInfo workbook_toolbar [] = { GNOMEUIINFO_ITEM_DATA (N_("Line"), N_("Creates a line object"), create_line_cmd, NULL, line_xpm), + GNOMEUIINFO_ITEM_DATA (N_("Arrow"), + N_("Creates an arrow object"), + create_arrow_cmd, NULL, arrow_xpm), GNOMEUIINFO_ITEM_DATA (N_("Rectangle"), N_("Creates a rectangle object"), create_rectangle_cmd, NULL, rect_xpm),