* make the shape export work again
[dia.git] / app / create_object.c
blob6e3a0bfb1d001fd4a922eb196f59cde72de54f75
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #include "create_object.h"
19 #include "connectionpoint_ops.h"
20 #include "handle_ops.h"
21 #include "object_ops.h"
22 #include "preferences.h"
23 #include "undo.h"
25 static void create_object_button_press(CreateObjectTool *tool, GdkEventButton *event,
26 DDisplay *ddisp);
27 static void create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
28 DDisplay *ddisp);
29 static void create_object_motion(CreateObjectTool *tool, GdkEventMotion *event,
30 DDisplay *ddisp);
31 static void create_object_double_click(CreateObjectTool *tool, GdkEventMotion *event,
32 DDisplay *ddisp);
35 static void
36 create_object_button_press(CreateObjectTool *tool, GdkEventButton *event,
37 DDisplay *ddisp)
39 Point clickedpoint, origpoint;
40 Handle *handle1;
41 Handle *handle2;
42 Object *obj;
44 ddisplay_untransform_coords(ddisp,
45 (int)event->x, (int)event->y,
46 &clickedpoint.x, &clickedpoint.y);
48 origpoint = clickedpoint;
50 snap_to_grid(ddisp, &clickedpoint.x, &clickedpoint.y);
52 obj = tool->objtype->ops->create(&clickedpoint, tool->user_data,
53 &handle1, &handle2);
54 diagram_add_object(ddisp->diagram, obj);
56 /* Try a connect */
57 if (handle1 != NULL &&
58 handle1->connect_type != HANDLE_NONCONNECTABLE) {
59 ConnectionPoint *connectionpoint;
60 connectionpoint =
61 object_find_connectpoint_display(ddisp, &origpoint);
62 if (connectionpoint != NULL) {
63 (obj->ops->move)(obj, &origpoint);
67 if (!(event->state & GDK_SHIFT_MASK)) {
68 /* Not Multi-select => remove current selection */
69 diagram_remove_all_selected(ddisp->diagram, TRUE);
71 diagram_select(ddisp->diagram, obj);
73 obj->ops->selectf(obj, &clickedpoint,
74 (Renderer *)ddisp->renderer);
76 tool->obj = obj;
78 /* Connect first handle if possible: */
79 if ((handle1!= NULL) &&
80 (handle1->connect_type != HANDLE_NONCONNECTABLE)) {
81 object_connect_display(ddisp, obj, handle1);
84 object_add_updates(obj, ddisp->diagram);
85 diagram_flush(ddisp->diagram);
87 if (handle2 != NULL) {
88 tool->handle = handle2;
89 tool->moving = TRUE;
90 tool->last_to = handle2->pos;
92 gdk_pointer_grab (ddisp->canvas->window, FALSE,
93 GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
94 NULL, NULL, event->time);
95 } else {
96 diagram_update_extents(ddisp->diagram);
97 tool->moving = FALSE;
101 static void
102 create_object_double_click(CreateObjectTool *tool, GdkEventMotion *event,
103 DDisplay *ddisp)
107 static void
108 create_object_button_release(CreateObjectTool *tool, GdkEventButton *event,
109 DDisplay *ddisp)
111 GList *list = NULL;
112 if (tool->moving) {
113 gdk_pointer_ungrab (event->time);
115 object_add_updates(tool->obj, ddisp->diagram);
116 tool->obj->ops->move_handle(tool->obj, tool->handle, &tool->last_to,
117 HANDLE_MOVE_CREATE_FINAL,0);
118 object_add_updates(tool->obj, ddisp->diagram);
122 list = g_list_prepend(list, tool->obj);
124 undo_insert_objects(ddisp->diagram, list, 1);
126 if (tool->moving) {
127 if (tool->handle->connect_type != HANDLE_NONCONNECTABLE) {
128 object_connect_display(ddisp, tool->obj, tool->handle);
129 diagram_update_connections_selection(ddisp->diagram);
130 diagram_flush(ddisp->diagram);
132 tool->moving = FALSE;
133 tool->handle = NULL;
134 tool->obj = NULL;
137 diagram_update_extents(ddisp->diagram);
138 diagram_modified(ddisp->diagram);
140 undo_set_transactionpoint(ddisp->diagram->undo);
142 if (prefs.reset_tools_after_create)
143 tool_reset();
145 static void
146 create_object_motion(CreateObjectTool *tool, GdkEventMotion *event,
147 DDisplay *ddisp)
149 Point to;
150 ConnectionPoint *connectionpoint;
152 if (!tool->moving)
153 return;
155 ddisplay_untransform_coords(ddisp, event->x, event->y, &to.x, &to.y);
157 /* Move to ConnectionPoint if near: */
158 if ((tool->handle != NULL &&
159 tool->handle->connect_type != HANDLE_NONCONNECTABLE) &&
160 ((connectionpoint =
161 object_find_connectpoint_display(ddisp, &to)) != NULL)) {
162 to = connectionpoint->pos;
163 } else {
164 /* No connectionopoint near, then snap to grid (if enabled) */
165 snap_to_grid(ddisp, &to.x, &to.y);
168 object_add_updates(tool->obj, ddisp->diagram);
169 tool->obj->ops->move_handle(tool->obj, tool->handle, &to,
170 HANDLE_MOVE_CREATE, 0);
171 object_add_updates(tool->obj, ddisp->diagram);
173 diagram_flush(ddisp->diagram);
175 tool->last_to = to;
177 return;
182 Tool *create_create_object_tool(ObjectType *objtype, void *user_data)
184 CreateObjectTool *tool;
186 tool = g_new(CreateObjectTool, 1);
187 tool->tool.type = CREATE_OBJECT_TOOL;
188 tool->tool.button_press_func = (ButtonPressFunc) &create_object_button_press;
189 tool->tool.button_release_func = (ButtonReleaseFunc) &create_object_button_release;
190 tool->tool.motion_func = (MotionFunc) &create_object_motion;
191 tool->tool.double_click_func = (DoubleClickFunc) &create_object_double_click;
193 tool->objtype = objtype;
194 tool->user_data = user_data;
195 tool->moving = FALSE;
197 return (Tool *) tool;
200 void free_create_object_tool(Tool *tool)
202 g_free(tool);