summaryrefslogtreecommitdiffstats
path: root/src/ui/widget/canvas.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/widget/canvas.h')
-rw-r--r--src/ui/widget/canvas.h234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/ui/widget/canvas.h b/src/ui/widget/canvas.h
new file mode 100644
index 0000000..f2a434a
--- /dev/null
+++ b/src/ui/widget/canvas.h
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef INKSCAPE_UI_WIDGET_CANVAS_H
+#define INKSCAPE_UI_WIDGET_CANVAS_H
+/*
+ * Authors:
+ * Tavmjong Bah
+ * PBS <pbs3141@gmail.com>
+ *
+ * Copyright (C) 2022 Authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <memory>
+#include <gtkmm.h>
+#include <2geom/rect.h>
+#include <2geom/int-rect.h>
+#include "display/rendermode.h"
+
+class SPDesktop;
+
+namespace Inkscape {
+
+class CanvasItem;
+class CanvasItemGroup;
+class Drawing;
+
+namespace UI {
+namespace Widget {
+
+class CanvasPrivate;
+
+/**
+ * A Gtk::DrawingArea widget for Inkscape's canvas.
+ */
+class Canvas : public Gtk::DrawingArea
+{
+ using parent_type = Gtk::DrawingArea;
+
+public:
+
+ Canvas();
+ ~Canvas() override;
+
+ /* Configuration */
+
+ // Desktop (Todo: Remove.)
+ void set_desktop(SPDesktop *desktop) { _desktop = desktop; }
+ SPDesktop *get_desktop() const { return _desktop; }
+
+ // Drawing
+ void set_drawing(Inkscape::Drawing *drawing);
+
+ // Canvas item root
+ CanvasItemGroup *get_canvas_item_root() const { return _canvas_item_root; }
+
+ // Geometry
+ void set_pos (const Geom::IntPoint &pos);
+ void set_pos (const Geom::Point &fpos) { set_pos(fpos.round()); }
+ void set_affine(const Geom::Affine &affine);
+ const Geom::IntPoint& get_pos () const {return _pos;}
+ const Geom::Affine& get_affine() const {return _affine;}
+
+ // Background
+ void set_background_color(guint32 rgba);
+ void set_background_checkerboard(guint32 rgba = 0xC4C4C4FF, bool use_alpha = false);
+
+ // Rendering modes
+ void set_render_mode(Inkscape::RenderMode mode);
+ void set_color_mode (Inkscape::ColorMode mode);
+ void set_split_mode (Inkscape::SplitMode mode);
+ Inkscape::RenderMode get_render_mode() const { return _render_mode; }
+ Inkscape::ColorMode get_color_mode() const { return _color_mode; }
+ Inkscape::SplitMode get_split_mode() const { return _split_mode; }
+
+ // CMS
+ void set_cms_key(std::string key) {
+ _cms_key = std::move(key);
+ _cms_active = !_cms_key.empty();
+ }
+ const std::string& get_cms_key() const { return _cms_key; }
+ void set_cms_active(bool active) { _cms_active = active; }
+ bool get_cms_active() const { return _cms_active; }
+
+ /* Observers */
+
+ // Geometry
+ Geom::IntPoint get_dimensions() const;
+ bool world_point_inside_canvas(Geom::Point const &world) const; // desktop-events.cpp
+ Geom::Point canvas_to_world(Geom::Point const &window) const;
+ Geom::IntRect get_area_world() const;
+
+ // State
+ bool is_dragging() const { return _is_dragging; } // selection-chemistry.cpp
+
+ // Encapsulation leaks
+ Cairo::RefPtr<Cairo::ImageSurface> get_backing_store() const; // canvas-item-rotate.cpp
+ Cairo::RefPtr<Cairo::Pattern> get_background_pattern() const { return _background; } // canvas-item-rect.cpp, canvas-item-ctrl.cpp
+
+ /* Methods */
+
+ // Invalidation
+ void redraw_all(); // Mark everything as having changed.
+ void redraw_area(Geom::Rect& area); // Mark a rectangle of world space as having changed.
+ void redraw_area(int x0, int y0, int x1, int y1);
+ void redraw_area(Geom::Coord x0, Geom::Coord y0, Geom::Coord x1, Geom::Coord y1);
+ void request_update(); // Mark geometry as needing recalculation.
+
+ // Gobblers (tool-base.cpp)
+ int gobble_key_events(guint keyval, guint mask);
+ void gobble_motion_events(guint mask);
+
+ // Callback run on destructor of any canvas item
+ void canvas_item_destructed(Inkscape::CanvasItem *item);
+
+ // State
+ Inkscape::CanvasItem *get_current_canvas_item() const { return _current_canvas_item; }
+ void set_current_canvas_item(Inkscape::CanvasItem *item) {
+ _current_canvas_item = item;
+ }
+ Inkscape::CanvasItem *get_grabbed_canvas_item() const { return _grabbed_canvas_item; }
+ void set_grabbed_canvas_item(Inkscape::CanvasItem *item, Gdk::EventMask mask) {
+ _grabbed_canvas_item = item;
+ _grabbed_event_mask = mask;
+ }
+ void set_drawing_disabled(bool disable); // Disable during path ops, etc.
+ void set_all_enter_events(bool on) { _all_enter_events = on; }
+
+protected:
+
+ void get_preferred_width_vfunc (int &minimum_width, int &natural_width ) const override;
+ void get_preferred_height_vfunc(int &minimum_height, int &natural_height) const override;
+
+ // Event handlers
+ bool on_scroll_event (GdkEventScroll* ) override;
+ bool on_button_event (GdkEventButton* );
+ bool on_button_press_event (GdkEventButton* ) override;
+ bool on_button_release_event(GdkEventButton* ) override;
+ bool on_enter_notify_event (GdkEventCrossing*) override;
+ bool on_leave_notify_event (GdkEventCrossing*) override;
+ bool on_focus_in_event (GdkEventFocus* ) override;
+ bool on_key_press_event (GdkEventKey* ) override;
+ bool on_key_release_event (GdkEventKey* ) override;
+ bool on_motion_notify_event (GdkEventMotion* ) override;
+
+ void on_realize() override;
+ void on_unrealize() override;
+ void on_size_allocate(Gtk::Allocation&) override;
+ bool on_draw(const Cairo::RefPtr<Cairo::Context>&) override;
+
+private:
+
+ /* Configuration */
+
+ // Desktop
+ SPDesktop *_desktop = nullptr;
+
+ // Drawing
+ Inkscape::Drawing *_drawing = nullptr;
+
+ // Canvas item root
+ CanvasItemGroup *_canvas_item_root = nullptr;
+
+ // Geometry
+ Geom::IntPoint _pos; ///< Coordinates of top-left pixel of canvas view within canvas.
+ Geom::Affine _affine; ///< The affine that we have been requested to draw at.
+
+ // Background
+ Cairo::RefPtr<Cairo::Pattern> _background; ///< The background of the widget.
+
+ // Rendering modes
+ Inkscape::RenderMode _render_mode = Inkscape::RenderMode::NORMAL;
+ Inkscape::SplitMode _split_mode = Inkscape::SplitMode::NORMAL;
+ Inkscape::ColorMode _color_mode = Inkscape::ColorMode::NORMAL;
+
+ // CMS
+ std::string _cms_key;
+ bool _cms_active = false;
+
+ /* Internal state */
+
+ // Event handling/item picking
+ GdkEvent _pick_event; ///< Event used to find currently selected item.
+ bool _in_repick; ///< For tracking recursion of pick_current_item().
+ bool _left_grabbed_item; ///< ?
+ bool _all_enter_events; ///< Keep all enter events. Only set true in connector-tool.cpp.
+ bool _is_dragging; ///< Used in selection-chemistry to block undo/redo.
+ int _state; ///< Last known modifier state (SHIFT, CTRL, etc.).
+
+ Inkscape::CanvasItem *_current_canvas_item; ///< Item containing cursor, nullptr if none.
+ Inkscape::CanvasItem *_current_canvas_item_new; ///< Item to become _current_item, nullptr if none.
+ Inkscape::CanvasItem *_grabbed_canvas_item; ///< Item that holds a pointer grab; nullptr if none.
+ Gdk::EventMask _grabbed_event_mask;
+
+ // Drawing
+ bool _drawing_disabled = false; ///< Disable drawing during critical operations
+ bool _need_update = true; // Set true so setting CanvasItem bounds are calculated at least once.
+
+ // Split view
+ Inkscape::SplitDirection _split_direction;
+ Geom::Point _split_position;
+ Inkscape::SplitDirection _hover_direction;
+ bool _split_dragging;
+ Geom::Point _split_drag_start;
+
+ void add_clippath(const Cairo::RefPtr<Cairo::Context>&);
+ void set_cursor();
+
+ // Opaque pointer to implementation
+ friend class CanvasPrivate;
+ std::unique_ptr<CanvasPrivate> d;
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_CANVAS_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:fileencoding=utf-8:textwidth=99 :