/* dia-selection-tool.c * Copyright (C) 2001 Arjan Molenaar * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "dia-selection-tool.h" #include "dia-canvas-i18n.h" #include "dia-handle-layer.h" #include /* We need them to determine which handle we should grab: */ #include "dia-canvas-line.h" #include "dia-canvas-element.h" static void dia_selection_tool_class_init (DiaToolClass *class); static void dia_selection_tool_init (DiaSelectionTool *tool); static void dia_selection_tool_dispose (GObject *object); static gboolean dia_selection_tool_button_press (DiaTool *tool, DiaCanvasView *view, GdkEventButton *event); static gboolean dia_selection_tool_button_release (DiaTool *tool, DiaCanvasView *view, GdkEventButton *event); static gboolean dia_selection_tool_motion_notify (DiaTool *tool, DiaCanvasView *view, GdkEventMotion *event); static gboolean dia_selection_tool_key_press (DiaTool *tool, DiaCanvasView *view, GdkEventKey *event); static gboolean dia_selection_tool_key_release (DiaTool *tool, DiaCanvasView *view, GdkEventKey *event); static DiaToolClass *parent_class = NULL; GType dia_selection_tool_get_type (void) { static GtkType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (DiaSelectionToolClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dia_selection_tool_class_init, (GClassFinalizeFunc) NULL, (gconstpointer) NULL, /* class_data */ sizeof (DiaSelectionTool), (guint16) 0, /* n_preallocs */ (GInstanceInitFunc) dia_selection_tool_init, }; object_type = g_type_register_static (DIA_TYPE_TOOL, "DiaSelectionTool", &object_info, 0); } return object_type; } static void dia_selection_tool_class_init (DiaToolClass *klass) { GObjectClass *object_class = (GObjectClass*) klass; parent_class = g_type_class_peek_parent (klass); object_class->dispose = dia_selection_tool_dispose; klass->button_press_event = dia_selection_tool_button_press; klass->button_release_event = dia_selection_tool_button_release; klass->motion_notify_event = dia_selection_tool_motion_notify; klass->key_press_event = dia_selection_tool_key_press; klass->key_release_event = dia_selection_tool_key_release; } static void dia_selection_tool_init (DiaSelectionTool *tool) { tool->selector = NULL; } static void dispose_selector(DiaSelectionTool *tool) { if (tool->selector) { gtk_object_destroy (GTK_OBJECT (tool->selector)); g_object_unref (tool->selector); tool->selector = NULL; } } static void dia_selection_tool_dispose (GObject *object) { DiaSelectionTool *stool = (DiaSelectionTool*) object; if (stool->selector) { dispose_selector (stool); } G_OBJECT_CLASS (parent_class)->dispose (object); } static gboolean dia_selection_tool_button_press (DiaTool *tool, DiaCanvasView *view, GdkEventButton *event) { DiaSelectionTool *stool = DIA_SELECTION_TOOL (tool); gboolean retval = FALSE; gint cx, cy; if (stool->selector) { g_warning (G_STRLOC": Emergency cleanup for selection box"); dispose_selector (stool); } if (event->type == GDK_BUTTON_PRESS && event->button == 1) { if (!(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))) { dia_canvas_view_focus (view, NULL); dia_canvas_view_unselect_all (view); } gnome_canvas_w2c (GNOME_CANVAS (view), event->x, event->y, &cx, &cy); stool->selector = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (view)->root), dia_selector_get_type (), "x1", cx, "y1", cy, "x2", cx, "y2", cy, NULL); g_object_ref (stool->selector); retval = TRUE; } return retval; } static gboolean dia_selection_tool_button_release (DiaTool *tool, DiaCanvasView *view, GdkEventButton *event) { DiaSelectionTool *stool = DIA_SELECTION_TOOL (tool); gint x1, y1, x2, y2; gdouble wx1, wy1, wx2, wy2; DiaRectangle bb; if (!stool->selector) return FALSE; g_object_get (stool->selector, "x1", &x1, "y1", &y1, "x2", &x2, "y2", &y2, NULL); x2++; y2++; gnome_canvas_request_redraw (GNOME_CANVAS (view), x1, y1, x2, y2); dispose_selector (stool); if ((x1 != x2) && (y1 != y2)) { gnome_canvas_c2w (GNOME_CANVAS (view), x1, y1, &wx1, &wy1); gnome_canvas_c2w (GNOME_CANVAS (view), x2, y2, &wx2, &wy2); bb.left = MIN (wx1, wx2); bb.top = MIN (wy1, wy2); bb.right = MAX (wx1, wx2); bb.bottom = MAX (wy1, wy2); dia_canvas_view_select_rectangle (view, &bb); } return TRUE; } static gboolean dia_selection_tool_motion_notify (DiaTool *tool, DiaCanvasView *view, GdkEventMotion *event) { DiaSelectionTool *stool = DIA_SELECTION_TOOL (tool); gint cx, cy; if (stool->selector) { gnome_canvas_w2c (GNOME_CANVAS (view), event->x, event->y, &cx, &cy); g_object_set (stool->selector, "x2", (gint) cx, "y2", (gint) cy, NULL); gnome_canvas_item_request_update (stool->selector); return TRUE; } else return FALSE; } static gboolean dia_selection_tool_key_press (DiaTool *tool, DiaCanvasView *view, GdkEventKey *event) { return FALSE; } static gboolean dia_selection_tool_key_release (DiaTool *tool, DiaCanvasView *view, GdkEventKey *event) { return FALSE; } DiaTool* dia_selection_tool_new (void) { /* This is code lend from g_object_new_valist(). */ return g_object_new (DIA_TYPE_SELECTION_TOOL, NULL); }