1 // SPDX-License-Identifier: GPL-2.0-or-later 2 #ifndef SEEN_CANVAS_ITEM_H 3 #define SEEN_CANVAS_ITEM_H 4 5 /** 6 * Abstract base class for on-canvas control items. 7 */ 8 9 /* 10 * Author: 11 * Tavmjong Bah 12 * 13 * Copyright (C) 2020 Tavmjong Bah 14 * 15 * Rewrite of SPCanvasItem 16 * 17 * Released under GNU GPL v2+, read the file 'COPYING' for more information. 18 * 19 * A note about coordinates: 20 * 21 * 1. Canvas items are constructed using document (SVG) coordinates. 22 * 2. Calculations are made in canvas units, which is equivalent of SVG units multiplied by zoom factor. 23 * This is true for bounds and closest distance calculations. 24 * 3 Drawing is done in screen units which is the same as canvas units but translated. 25 * The document and canvas origins overlap. 26 * The affine contains only scaling and rotating components. 27 */ 28 29 //#define CANVAS_ITEM_DEBUG 30 31 #include <gdk/gdk.h> // GdkEvent 32 #include <gdkmm/device.h> // Gdk::EventMask 33 #include <glib.h> // guint32 34 #include <sigc++/sigc++.h> 35 36 #include <2geom/rect.h> 37 38 #include <boost/intrusive/list.hpp> 39 40 #include "canvas-item-buffer.h" 41 #include "canvas-item-enums.h" 42 43 class SPItem; 44 45 namespace Inkscape { 46 47 static guint32 CANVAS_ITEM_COLORS[] = { 0x0000ff7f, 0xff00007f, 0xffff007f }; 48 49 namespace UI::Widget { 50 class Canvas; 51 } 52 53 class CanvasItemGroup; // A canvas control that contains other canvas controls. 54 55 class CanvasItem { 56 57 public: 58 CanvasItem(CanvasItemGroup* group); 59 virtual ~CanvasItem(); 60 61 // Structure set_canvas(UI::Widget::Canvas * canvas)62 void set_canvas(UI::Widget::Canvas *canvas) { _canvas = canvas; } get_canvas()63 UI::Widget::Canvas* get_canvas() { return _canvas; } 64 set_parent(CanvasItemGroup * parent)65 void set_parent(CanvasItemGroup *parent) { _parent = parent; } get_parent()66 CanvasItemGroup* get_parent() { return _parent; } 67 set_item(SPItem * item)68 void set_item(SPItem *item) { _item = item; } get_item()69 SPItem* get_item() { return _item; } 70 71 // Z Position 72 bool is_descendant_of(CanvasItem *ancestor); 73 void set_z_position(unsigned int n); 74 int get_z_position(); // z position in group. 75 // void raise_by(unsigned int n); 76 void raise_to_top(); // Move to top of group (last entry). 77 // void lower_by(unsigned int n); 78 void lower_to_bottom(); // Move to bottom of group (first entry). 79 80 // Geometry 81 void request_update(); 82 virtual void update(Geom::Affine const &affine) = 0; get_affine()83 Geom::Affine get_affine() { return _affine; } get_bounds()84 Geom::Rect get_bounds() { return _bounds; } 85 86 // Selection 87 virtual bool contains(Geom::Point const &p, double tolerance = 0) { return _bounds.interiorContains(p); } 88 int grab(Gdk::EventMask event_mask, GdkCursor *cursor = nullptr); 89 void ungrab(); 90 91 // Display 92 virtual void render(Inkscape::CanvasItemBuffer *buf) = 0; is_visible()93 bool is_visible() { return _visible; } 94 virtual void hide(); 95 virtual void show(); 96 97 // Properties 98 virtual void set_fill(guint32 rgba); set_fill(CanvasItemColor color)99 void set_fill(CanvasItemColor color) { set_fill(CANVAS_ITEM_COLORS[color]); } 100 virtual void set_stroke(guint32 rgba); set_stroke(CanvasItemColor color)101 void set_stroke(CanvasItemColor color) { set_stroke(CANVAS_ITEM_COLORS[color]); } set_name(std::string const & name)102 void set_name(std::string const &name) { _name = name; } get_name()103 std::string get_name() { return _name; } 104 105 // Events set_pickable(bool pickable)106 void set_pickable(bool pickable) { _pickable = pickable; } is_pickable()107 bool is_pickable() { return _pickable; } connect_event(sigc::slot<bool,GdkEvent * > slot)108 sigc::connection connect_event(sigc::slot<bool, GdkEvent*> slot) { 109 return _event_signal.connect(slot); 110 } handle_event(GdkEvent * event)111 virtual bool handle_event(GdkEvent *event) { 112 return _event_signal.emit(event); // Default just emit event. 113 } 114 115 // Boost linked list member hook, speeds deletion. 116 boost::intrusive::list_member_hook<> member_hook; 117 118 protected: 119 120 // Structure 121 CanvasItemGroup *_parent = nullptr; 122 Inkscape::UI::Widget::Canvas *_canvas = nullptr; 123 SPItem *_item; // The object this canvas item is linked to in some sense. Can be nullptr. 124 125 // Geometry 126 Geom::Rect _bounds; 127 Geom::Affine _affine; 128 bool _need_update = true; // Need update after creation! 129 130 // Display 131 bool _visible = true; 132 bool _align_to_drawing = false; // Rotate if drawing is rotated. TODO: Implement! 133 134 // Selection 135 bool _pickable = false; // Most items are just for display and are not pickable! 136 137 // Properties 138 guint32 _fill = CANVAS_ITEM_COLORS[CANVAS_ITEM_SECONDARY]; 139 guint32 _stroke = CANVAS_ITEM_COLORS[CANVAS_ITEM_PRIMARY]; 140 std::string _name; // For debugging 141 142 // Events 143 sigc::signal<bool, GdkEvent*> _event_signal; 144 }; 145 146 147 } // namespace Inkscape 148 149 /** Type for linked list storing CanvasItem's. 150 * 151 * Used to speed deletion when a group containes a large number of item's (as in nodes for a 152 * complex path). 153 */ 154 typedef boost::intrusive::list< 155 Inkscape::CanvasItem, 156 boost::intrusive::member_hook<Inkscape::CanvasItem, boost::intrusive::list_member_hook<>, 157 &Inkscape::CanvasItem::member_hook> > CanvasItemList; 158 159 // Recursively print CanvasItem tree. 160 void canvas_item_print_tree(Inkscape::CanvasItem *item); 161 162 #endif // SEEN_CANVAS_ITEM_H 163 164 /* 165 Local Variables: 166 mode:c++ 167 c-file-style:"stroustrup" 168 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) 169 indent-tabs-mode:nil 170 fill-column:99 171 End: 172 */ 173 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : 174