Commit 5837f657 authored by Arturo Espinosa's avatar Arturo Espinosa

Ok, finally objects are fully editable.



Ok, finally objects are fully editable.

We need support for saving the graphical objects.  It should be
pretty simple, as things are kept nicely on a list of SheetObjects
which can be dumped and restored from disk easily.

Miguel.
parent 33f5a8c3
1998-09-08 Miguel de Icaza <miguel@nuclecu.unam.mx>
* 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 <miguel@nuclecu.unam.mx> 1998-09-07 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_font_format): Optimization, walk * src/dialog-cell-format.c (apply_font_format): Optimization, walk
......
1998-09-08 Miguel de Icaza <miguel@nuclecu.unam.mx>
* 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 <miguel@nuclecu.unam.mx> 1998-09-07 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_font_format): Optimization, walk * src/dialog-cell-format.c (apply_font_format): Optimization, walk
......
1998-09-08 Miguel de Icaza <miguel@nuclecu.unam.mx>
* 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 <miguel@nuclecu.unam.mx> 1998-09-07 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_font_format): Optimization, walk * src/dialog-cell-format.c (apply_font_format): Optimization, walk
......
1998-09-08 Miguel de Icaza <miguel@nuclecu.unam.mx>
* 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 <miguel@nuclecu.unam.mx> 1998-09-07 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/dialog-cell-format.c (apply_font_format): Optimization, walk * src/dialog-cell-format.c (apply_font_format): Optimization, walk
......
...@@ -3,4 +3,5 @@ ...@@ -3,4 +3,5 @@
#include "pixmaps/align-right.xpm" #include "pixmaps/align-right.xpm"
#include "pixmaps/rect.xpm" #include "pixmaps/rect.xpm"
#include "pixmaps/line.xpm" #include "pixmaps/line.xpm"
#include "pixmaps/arrow.xpm"
#include "pixmaps/oval.xpm" #include "pixmaps/oval.xpm"
/* XPM */
static char *arrow_xpm[] = {
/* width height num_colors chars_per_pixel */
" 24 24 2 1",
/* colors */
". c #000000",
"# c None",
/* pixels */
"########################",
"########################",
"##.#####################",
"##....##################",
"##......################",
"##....##################",
"##..##.#################",
"#######.################",
"########.###############",
"#########.##############",
"##########.#############",
"###########.############",
"############.###########",
"#############.##########",
"##############.#########",
"###############.########",
"################.#######",
"#################.######",
"##################.#####",
"###################.####",
"####################.###",
"#####################.##",
"########################",
"########################"
};
...@@ -28,7 +28,7 @@ typedef struct { ...@@ -28,7 +28,7 @@ typedef struct {
/* /*
* Control points for the current item * Control points for the current item
*/ */
GList *control_points; GnomeCanvasItem *control_points [8];
/* Scrolling information */ /* Scrolling information */
GtkWidget *vs, *hs; /* The scrollbars */ GtkWidget *vs, *hs; /* The scrollbars */
......
...@@ -10,11 +10,27 @@ ...@@ -10,11 +10,27 @@
#define GNUMERIC_SHEET_VIEW(p) GNUMERIC_SHEET (SHEET_VIEW(p)->sheet_view); #define GNUMERIC_SHEET_VIEW(p) GNUMERIC_SHEET (SHEET_VIEW(p)->sheet_view);
static void sheet_finish_object_creation (Sheet *sheet); 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 { typedef struct {
gdouble x, y; gdouble x, y;
} ObjectCoords; } 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 static void
sheet_release_coords (Sheet *sheet) sheet_release_coords (Sheet *sheet)
{ {
...@@ -86,7 +102,7 @@ sheet_object_create_filled (Sheet *sheet, int type, ...@@ -86,7 +102,7 @@ sheet_object_create_filled (Sheet *sheet, int type,
} }
SheetObject * 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; SheetObject *so;
...@@ -94,7 +110,8 @@ sheet_object_create_line (Sheet *sheet, double x1, double y1, double x2, double ...@@ -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); g_return_val_if_fail (IS_SHEET (sheet), NULL);
so = sheet_object_new (sheet); 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 = gnome_canvas_points_new (2);
so->points->coords [0] = (gdouble) x1; so->points->coords [0] = (gdouble) x1;
so->points->coords [1] = (gdouble) y1; so->points->coords [1] = (gdouble) y1;
...@@ -171,9 +188,10 @@ sheet_view_object_realize (SheetView *sheet_view, SheetObject *object) ...@@ -171,9 +188,10 @@ sheet_view_object_realize (SheetView *sheet_view, SheetObject *object)
"points", object->points, "points", object->points,
"fill_color", object->color->str, "fill_color", object->color->str,
"width_pixels", object->width, "width_pixels", object->width,
"arrow_shape_a", 1.0, "arrow_shape_a", 8.0,
"arrow_shape_b", 1.0, "arrow_shape_b", 10.0,
"arrow_shape_c", 1.0, "arrow_shape_c", 3.0,
"last_arrowhead", TRUE,
NULL); NULL);
break; break;
...@@ -208,6 +226,9 @@ sheet_view_object_realize (SheetView *sheet_view, SheetObject *object) ...@@ -208,6 +226,9 @@ sheet_view_object_realize (SheetView *sheet_view, SheetObject *object)
break; break;
} }
gtk_signal_connect (GTK_OBJECT (item), "event",
GTK_SIGNAL_FUNC (object_event), object);
if (item == NULL) if (item == NULL)
g_warning ("We created an unsupported type\n"); g_warning ("We created an unsupported type\n");
...@@ -252,6 +273,19 @@ sheet_object_realize (Sheet *sheet, SheetObject *object) ...@@ -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 * static SheetObject *
create_object (Sheet *sheet, gdouble to_x, gdouble to_y) create_object (Sheet *sheet, gdouble to_x, gdouble to_y)
{ {
...@@ -263,7 +297,15 @@ 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){ switch (sheet->mode){
case SHEET_MODE_CREATE_LINE: case SHEET_MODE_CREATE_LINE:
o = sheet_object_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, oc->x, oc->y,
to_x, to_y, to_x, to_y,
"black", 1); "black", 1);
...@@ -303,7 +345,9 @@ sheet_motion_notify (GnumericSheet *gsheet, GdkEvent *event, Sheet *sheet) ...@@ -303,7 +345,9 @@ sheet_motion_notify (GnumericSheet *gsheet, GdkEvent *event, Sheet *sheet)
if (gsheet->sheet_view->temp_item) if (gsheet->sheet_view->temp_item)
sheet_object_destroy (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; return 1;
} }
...@@ -318,7 +362,8 @@ sheet_button_release (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet ...@@ -318,7 +362,8 @@ sheet_button_release (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet
if (gsheet->sheet_view->temp_item) if (gsheet->sheet_view->temp_item)
sheet_object_destroy (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); o = create_object (sheet, event->x, event->y);
sheet_object_make_current (sheet, o); sheet_object_make_current (sheet, o);
...@@ -329,17 +374,19 @@ sheet_button_release (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet ...@@ -329,17 +374,19 @@ sheet_button_release (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet
} }
static int static int
sheet_button_press (GnumericSheet *gsheet, GdkEvent *event, Sheet *sheet) sheet_button_press (GnumericSheet *gsheet, GdkEventButton *event, Sheet *sheet)
{ {
ObjectCoords *oc; ObjectCoords *oc;
/* Do not propagate this event further */ /* Do not propagate this event further */
gtk_signal_emit_stop_by_name (GTK_OBJECT (gsheet), "button_press_event"); gtk_signal_emit_stop_by_name (GTK_OBJECT (gsheet), "button_press_event");
oc = g_new (ObjectCoords, 1); 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); sheet->coords = g_list_append (sheet->coords, oc);
gtk_signal_connect (GTK_OBJECT (gsheet), "button_release_event", gtk_signal_connect (GTK_OBJECT (gsheet), "button_release_event",
...@@ -399,86 +446,252 @@ sheet_set_mode_type (Sheet *sheet, SheetModeType mode) ...@@ -399,86 +446,252 @@ sheet_set_mode_type (Sheet *sheet, SheetModeType mode)
} }
static void static void
sheet_object_stop_editing (SheetObject *object) sheet_object_destroy_control_points (Sheet *sheet)
{ {
Sheet *sheet = object->sheet;
GList *l; GList *l;
for (l = sheet->sheet_views; l; l = l->next){ for (l = sheet->sheet_views; l; l = l->next){
GList *items;
SheetView *sheet_view = l->data; SheetView *sheet_view = l->data;
int i;
for (items = sheet_view->control_points; items; items = items->next){
GnomeCanvasItem *item = items->data; for (i = 0; i < 8; i++){
gtk_object_destroy (GTK_OBJECT (sheet_view->control_points [i]));
gtk_object_destroy (GTK_OBJECT (item)); 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; 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 * This hooks to the event for the handlebox
*/ */
static int static int
object_event (GnomeCanvasItem *item, GdkEvent *event, SheetObject *object) object_handle_event (GnomeCanvasItem *item, GdkEvent *event, SheetObject *object)
{ {
int idx; int idx;
double *points = object->points->coords; GList *l;
double x1, y1, x2, y2; static int last_x, last_y;
static int last_x, last_y, dx, dy; double dx, dy;
switch (event->type){ switch (event->type){
case GDK_BUTTON_RELEASE: case GDK_BUTTON_RELEASE:
if (!object->dragging)
return FALSE;
object->dragging = 0; object->dragging = 0;
gnome_canvas_item_ungrab (item, event->button.time);
break; break;
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
object->dragging = 1; 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_x = event->button.x;
last_y = event->button.y; last_y = event->button.y;
break; break;
case GDK_MOTION_NOTIFY: case GDK_MOTION_NOTIFY: {
double *coords = object->points->coords;
int change = 0;
if (!object->dragging) if (!object->dragging)
return FALSE; return FALSE;
idx = GPOINTER_TO_INT (gtk_object_get_user_data (item)); idx = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (item)));
printf ("HERE: %d\n", idx); 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){ switch (idx){
case 0: case 0:
case 2: change = POINT (0) | POINT (1);
case 5:
case 7:
/* borders */
dx = event->button.x - last_x;
dy = event->button.y - last_y;
break; break;
case 1: case 1:
case 6: change = POINT (1);
dx = 0;
dy = event->button.y - last_y;
break; break;
case 2:
change = POINT (1) | POINT (2);
break;
case 3: case 3:
change = POINT (0);
break;
case 4: case 4:
dy = 0; change = POINT (2);
dx = event->button.x - last_x; break;
case 5:
change = POINT (0) | POINT (3);
break;
case 6:
change = POINT (3);
break; 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_x = event->button.x;
last_y = event->button.y; 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; 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);