Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
svg-view-widget.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
6/*
7 * Authors:
8 * Tavmjong Bah <tavmjong@free.fr>
9 *
10 * Includes code moved from svg-view.cpp authored by:
11 * MenTaLGuy
12 * Ralf Stephan <ralf@ark.in-berlin.de>
13 * Jon A. Cruz <jon@joncruz.org>
14 *
15 * Copyright (C) 2018 Authors
16 *
17 * The contents of this file may be used under the GNU General Public License Version 2 or later.
18 * Read the file 'COPYING' for more information.
19 *
20 */
21
22#include "svg-view-widget.h"
23
24#include <iostream>
25#include <2geom/transforms.h>
26#include <giomm/appinfo.h>
27#include <gtkmm/window.h>
28
29#include "document.h"
30#include "display/drawing.h"
33#include "object/sp-item.h"
34#include "object/sp-root.h"
35#include "object/sp-anchor.h"
36#include "ui/widget/canvas.h"
38#include "util/units.h"
39
40namespace Inkscape::UI::View {
41
43{
44 _canvas = std::make_unique<Inkscape::UI::Widget::Canvas>();
45
46 _canvas->set_expand(true);
47 set_expand(false);
49
50 _drawing = new Inkscape::CanvasItemDrawing(_canvas->get_canvas_item_root());
51 _canvas->set_drawing(_drawing->get_drawing());
54
55 setDocument(document);
56}
57
62
63static void set_layer_modes(SPObject *obj, unsigned dkey)
64{
65 if (is<SPGroup>(obj) && !is<SPAnchor>(obj)) {
66 cast_unsafe<SPGroup>(obj)->setLayerDisplayMode(dkey, SPGroup::LAYER);
67 }
68
69 for (auto &c : obj->children) {
70 set_layer_modes(&c, dkey);
71 }
72}
73
75{
76 // Clear old document
77 if (_document) {
78 _document->getRoot()->invoke_hide(_dkey); // Removed from display tree
79 }
80
81 _document = document;
82
83 // Add new document
84 if (_document) {
85 auto drawing_item = _document->getRoot()->invoke_show(
87 _dkey,
88 SP_ITEM_SHOW_DISPLAY);
89
90 if (drawing_item) {
91 _drawing->get_drawing()->root()->prependChild(drawing_item);
92 }
93
95
96 doRescale();
97 }
98}
99
101{
102 // Triggers size_allocation which calls SVGViewWidget::size_allocate.
103 set_size_request(width, height);
104 queue_resize();
105}
106
107void SVGViewWidget::on_size_allocate(int const width, int const height, int const baseline)
108{
109 if (!(_width == width && _height == height)) {
110 if (width < 0 || height < 0) {
111 std::cerr << "SVGViewWidget::size_allocate: negative dimensions!" << std::endl;
112 } else {
113 _width = width;
114 _height = height;
115
116 if (_document) doRescale();
117 }
118 }
119
120 Bin::on_size_allocate(width, height, baseline);
121}
122
127bool SVGViewWidget::event(CanvasEvent const &event, DrawingItem *drawing_item)
128{
129 auto const spanchor = drawing_item ? cast<SPAnchor>(drawing_item->getItem()) : nullptr;
130 auto const href = spanchor ? spanchor->href : nullptr;
131
133 [&] (ButtonPressEvent const &event) {
134 if (event.num_press == 1 && event.button == 1) {
135 _clicking = true;
136 }
137 },
138 [&] (MotionEvent const &event) {
139 _clicking = false;
140 },
141 [&] (ButtonReleaseEvent const &event) {
142 if (event.button == 1 && _clicking && href) {
143 Gio::AppInfo::launch_default_for_uri(href);
144 }
145 _clicking = false;
146 },
147 [&] (EnterEvent const &event) {
148 if (href) {
149 set_cursor("pointer");
150 set_tooltip_text(href);
151 }
152 },
153 [&] (LeaveEvent const &event) {
154 if (href) {
155 set_cursor(Glib::RefPtr<Gdk::Cursor>{});
156 set_tooltip_text("");
157 }
158 },
159 [&] (CanvasEvent const &event) {}
160 );
161
162 return true;
163}
164
166{
167 if (!_document) {
168 std::cerr << "SVGViewWidget::doRescale: No document!" << std::endl;
169 return;
170 }
171
172 if (_document->getWidth().value("px") < 1e-9) {
173 std::cerr << "SVGViewWidget::doRescale: Width too small!" << std::endl;
174 return;
175 }
176
177 if (_document->getHeight().value("px") < 1e-9) {
178 std::cerr << "SVGViewWidget::doRescale: Height too small!" << std::endl;
179 return;
180 }
181
182 double x_offset = 0.0;
183 double y_offset = 0.0;
184 if (_rescale) {
187 if (_keepaspect) {
188 if (_hscale > _vscale) {
190 x_offset = (_document->getWidth().value("px") * _hscale - _width) / 2.0;
191 } else {
193 y_offset = (_document->getHeight().value("px") * _vscale - _height) / 2.0;
194 }
195 }
196 }
197
198 if (_drawing) {
199 _canvas->set_affine(Geom::Scale(_hscale, _vscale));
200 _canvas->set_pos(Geom::Point(x_offset, y_offset));
201 }
202}
203
204} // namespace Inkscape::UI::View
205
206/*
207 Local Variables:
208 mode:c++
209 c-file-style:"stroustrup"
210 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
211 indent-tabs-mode:nil
212 fill-column:99
213 End:
214*/
215// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
Inkscape canvas widget.
Two-dimensional point that doubles as a vector.
Definition point.h:66
Scaling from the origin.
Definition transforms.h:150
Inkscape::Drawing * get_drawing()
sigc::connection connect_drawing_event(sigc::slot< bool(CanvasEvent const &, Inkscape::DrawingItem *)> slot)
SVG drawing item for display.
SPItem * getItem() const
void prependChild(DrawingItem *item)
DrawingItem * root()
Definition drawing.h:47
void setCursorTolerance(double tol)
Definition drawing.h:61
bool event(CanvasEvent const &event, DrawingItem *drawing_item)
Callback connected with drawing_event.
void setDocument(SPDocument *document)
bool _rescale
Whether to rescale automatically.
void on_size_allocate(int width, int height, int baseline) override
SVGViewWidget(SPDocument *document=nullptr)
void doRescale()
Helper function that sets rescale ratio.
void setResize(int width, int height)
double _hscale
Horizontal scale.
std::unique_ptr< UI::Widget::Canvas > _canvas
void set_child(Gtk::Widget *child)
Sets (parents) the child widget, or unsets (unparents) it if child is null.
Definition bin.cpp:40
double value(Unit const *u) const
Return the quantity's value in the specified unit.
Definition units.cpp:565
Typed SVG document implementation.
Definition document.h:101
SPRoot * getRoot()
Returns our SPRoot.
Definition document.h:200
Inkscape::Util::Quantity getWidth() const
Definition document.cpp:848
Inkscape::Util::Quantity getHeight() const
Definition document.cpp:887
Inkscape::DrawingItem * invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
Definition sp-item.cpp:1277
void invoke_hide(unsigned int key)
Definition sp-item.cpp:1328
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
ChildrenList children
Definition sp-object.h:907
double c[8][4]
SVG drawing for display.
static void set_layer_modes(SPObject *obj, unsigned dkey)
static void set_expand(Gtk::Widget &widget, Gtk::Orientation const orientation, bool const expand)
Definition pack.cpp:42
void inspect_event(E &&event, Fs... funcs)
Perform pattern-matching on a CanvasEvent.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
SPRoot: SVG <svg> implementation.
A mouse button (left/right/middle) is pressed.
A mouse button (left/right/middle) is released.
Abstract base class for events.
The pointer has entered a widget or item.
The pointer has exited a widget or item.
Movement of the mouse pointer.
A light-weight widget containing an Inkscape canvas for rendering an SVG.
double height
double width
Affine transformation classes.