summaryrefslogtreecommitdiffstats
path: root/src/display/control/canvas-item.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/display/control/canvas-item.h175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/display/control/canvas-item.h b/src/display/control/canvas-item.h
new file mode 100644
index 0000000..37d5ec7
--- /dev/null
+++ b/src/display/control/canvas-item.h
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_CANVAS_ITEM_H
+#define SEEN_CANVAS_ITEM_H
+
+/**
+ * Abstract base class for on-canvas control items.
+ */
+
+/*
+ * Author:
+ * Tavmjong Bah
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * Rewrite of SPCanvasItem
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ *
+ * A note about coordinates:
+ *
+ * 1. Canvas items are constructed using document (SVG) coordinates.
+ * 2. Calculations are made in canvas units, which is equivalent of SVG units multiplied by zoom factor.
+ * This is true for bounds and closest distance calculations.
+ * 3 Drawing is done in screen units which is the same as canvas units but translated.
+ * The document and canvas origins overlap.
+ * The affine contains only scaling and rotating components.
+ */
+
+//#define CANVAS_ITEM_DEBUG
+
+#include <gdk/gdk.h> // GdkEvent
+#include <gdkmm/device.h> // Gdk::EventMask
+#include <glib.h> // guint32
+#include <sigc++/sigc++.h>
+
+#include <2geom/rect.h>
+
+#include <boost/intrusive/list.hpp>
+
+#include "canvas-item-buffer.h"
+#include "canvas-item-enums.h"
+
+class SPItem;
+
+namespace Inkscape {
+
+static guint32 CANVAS_ITEM_COLORS[] = { 0x0000ff7f, 0xff00007f, 0xffff007f };
+
+namespace UI::Widget {
+class Canvas;
+}
+
+class CanvasItemGroup; // A canvas control that contains other canvas controls.
+
+class CanvasItem {
+
+public:
+ CanvasItem(CanvasItemGroup* group);
+ virtual ~CanvasItem();
+
+ // Structure
+ void set_canvas(UI::Widget::Canvas *canvas) { _canvas = canvas; }
+ UI::Widget::Canvas* get_canvas() { return _canvas; }
+
+ void set_parent(CanvasItemGroup *parent) { _parent = parent; }
+ CanvasItemGroup* get_parent() { return _parent; }
+
+ void set_item(SPItem *item) { _item = item; }
+ SPItem* get_item() { return _item; }
+
+ // Z Position
+ bool is_descendant_of(CanvasItem *ancestor);
+ void set_z_position(unsigned int n);
+ int get_z_position(); // z position in group.
+ // void raise_by(unsigned int n);
+ void raise_to_top(); // Move to top of group (last entry).
+ // void lower_by(unsigned int n);
+ void lower_to_bottom(); // Move to bottom of group (first entry).
+
+ // Geometry
+ void request_update();
+ virtual void update(Geom::Affine const &affine) = 0;
+ Geom::Affine get_affine() { return _affine; }
+ Geom::Rect get_bounds() { return _bounds; }
+
+ // Selection
+ virtual bool contains(Geom::Point const &p, double tolerance = 0) { return _bounds.interiorContains(p); }
+ int grab(Gdk::EventMask event_mask, GdkCursor *cursor = nullptr);
+ int grab(Gdk::EventMask event_mask, Glib::RefPtr<Gdk::Cursor> cursor);
+ void ungrab();
+
+ // Display
+ virtual void render(Inkscape::CanvasItemBuffer *buf) = 0;
+ bool is_visible() { return _visible; }
+ virtual void hide();
+ virtual void show();
+ void request_redraw(); // queue redraw request
+
+ // Properties
+ virtual void set_fill(guint32 rgba);
+ void set_fill(CanvasItemColor color) { set_fill(CANVAS_ITEM_COLORS[color]); }
+ virtual void set_stroke(guint32 rgba);
+ void set_stroke(CanvasItemColor color) { set_stroke(CANVAS_ITEM_COLORS[color]); }
+ void set_name(std::string const &name) { _name = name; }
+ std::string get_name() { return _name; }
+
+ // Events
+ void set_pickable(bool pickable) { _pickable = pickable; }
+ bool is_pickable() { return _pickable; }
+ sigc::connection connect_event(sigc::slot<bool, GdkEvent*> slot) {
+ return _event_signal.connect(slot);
+ }
+ virtual bool handle_event(GdkEvent *event) {
+ return _event_signal.emit(event); // Default just emit event.
+ }
+
+ // Boost linked list member hook, speeds deletion.
+ boost::intrusive::list_member_hook<> member_hook;
+
+protected:
+
+ // Structure
+ CanvasItemGroup *_parent = nullptr;
+ Inkscape::UI::Widget::Canvas *_canvas = nullptr;
+ SPItem *_item; // The object this canvas item is linked to in some sense. Can be nullptr.
+
+ // Geometry
+ Geom::Rect _bounds;
+ Geom::Affine _affine;
+ bool _need_update = true; // Need update after creation!
+
+ // Display
+ bool _visible = true;
+ bool _align_to_drawing = false; // Rotate if drawing is rotated. TODO: Implement!
+
+ // Selection
+ bool _pickable = false; // Most items are just for display and are not pickable!
+
+ // Properties
+ guint32 _fill = CANVAS_ITEM_COLORS[CANVAS_ITEM_SECONDARY];
+ guint32 _stroke = CANVAS_ITEM_COLORS[CANVAS_ITEM_PRIMARY];
+ std::string _name; // For debugging
+
+ // Events
+ sigc::signal<bool, GdkEvent*> _event_signal;
+};
+
+
+} // namespace Inkscape
+
+/** Type for linked list storing CanvasItem's.
+ *
+ * Used to speed deletion when a group contains a large number of item's (as in nodes for a
+ * complex path).
+ */
+typedef boost::intrusive::list<
+ Inkscape::CanvasItem,
+ boost::intrusive::member_hook<Inkscape::CanvasItem, boost::intrusive::list_member_hook<>,
+ &Inkscape::CanvasItem::member_hook> > CanvasItemList;
+
+// Recursively print CanvasItem tree.
+void canvas_item_print_tree(Inkscape::CanvasItem *item);
+
+#endif // SEEN_CANVAS_ITEM_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :