Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
canvas-page.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Inkscape pages implementation
4 *
5 * Authors:
6 * Martin Owens <doctormo@geek-2.com>
7 *
8 * Copyright (C) 2021 Martin Owens
9 *
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#include "canvas-page.h"
14#include "canvas-item-rect.h"
15#include "canvas-item-text.h"
16#include "colors/utils.h"
17
18namespace Inkscape {
19
20CanvasPage::CanvasPage() = default;
21CanvasPage::~CanvasPage() = default;
22
26void CanvasPage::add(Geom::Rect size, CanvasItemGroup *background_group, CanvasItemGroup *border_group)
27{
28 // Foreground 'border'
29 if (auto item = new CanvasItemRect(border_group, size)) {
30 item->set_name("foreground");
31 item->set_is_page(true);
32 canvas_items.emplace_back(item);
33 }
34
35 // Background rectangle 'fill'
36 if (auto item = new CanvasItemRect(background_group, size)) {
37 item->set_name("background");
38 item->set_is_page(true);
39 item->set_dashed(false);
40 item->set_inverted(false);
41 item->set_stroke(0x00000000);
42 canvas_items.emplace_back(item);
43 }
44
45 if (auto item = new CanvasItemRect(border_group, size)) {
46 item->set_name("margin");
47 item->set_dashed(false);
48 item->set_inverted(false);
49 item->set_stroke(_margin_color.toRGBA());
50 canvas_items.emplace_back(item);
51 }
52
53 if (auto item = new CanvasItemRect(border_group, size)) {
54 item->set_name("bleed");
55 item->set_dashed(false);
56 item->set_inverted(false);
57 item->set_stroke(_bleed_color.toRGBA());
58 canvas_items.emplace_back(item);
59 }
60
61 if (auto label = new CanvasItemText(border_group, Geom::Point(0, 0), "{Page Label}")) {
62 label->set_fixed_line(false);
63 canvas_items.emplace_back(label);
64 }
65}
70{
71 g_assert(canvas != nullptr);
72 for (auto it = canvas_items.begin(); it != canvas_items.end();) {
73 if (canvas == (*it)->get_canvas()) {
74 it = canvas_items.erase(it);
75 } else {
76 ++it;
77 }
78 }
79}
80
82{
83 for (auto &item : canvas_items) {
84 item->set_visible(true);
85 }
86}
87
89{
90 for (auto &item : canvas_items) {
91 item->set_visible(false);
92 }
93}
94
96 for (auto& item: canvas_items) {
97 if (item->get_name() == "margin" || item->get_name() == "bleed") {
98 item->set_visible(show);
99 }
100 }
101}
102
110void CanvasPage::update(Geom::Rect size, Geom::OptRect margin, Geom::OptRect bleed, const char *txt, bool outline, bool is_yaxisdown)
111{
112 // Put these in the preferences?
113 bool border_on_top = _border_on_top;
114 guint32 shadow_color = _border_color.toRGBA(); // there's no separate shadow color in the UI, border color is used
115 guint32 select_color = 0x000000cc;
116 guint32 border_color = _border_color.toRGBA();
117 guint32 margin_color = _margin_color.toRGBA();
118 guint32 bleed_color = _bleed_color.toRGBA();
119
120 // This is used when showing the viewport as *not a page* it's mostly
121 // never used as the first page is normally the viewport too.
122 if (outline) {
123 border_on_top = false;
124 _shadow_size = 0;
125 border_color = select_color;
126 }
127
128 for (auto &item : canvas_items) {
129 if (auto rect = dynamic_cast<CanvasItemRect *>(item.get())) {
130 if (rect->get_name() == "margin") {
131 rect->set_stroke(margin_color);
132 bool vis = margin && *margin != size;
133 rect->set_visible(vis);
134 if (vis) {
135 rect->set_rect(*margin);
136 }
137 continue;
138 }
139 if (rect->get_name() == "bleed") {
140 rect->set_stroke(bleed_color);
141 bool vis = bleed && *bleed != size;
142 rect->set_visible(vis);
143 if (vis) {
144 rect->set_rect(*bleed);
145 }
146 continue;
147 }
148
149 rect->set_rect(size);
150
151 bool is_foreground = (rect->get_name() == "foreground");
152 // This will put the border on the background OR foreground layer as needed.
153 if (is_foreground == border_on_top) {
154 rect->set_visible(true);
155 rect->set_stroke(is_selected ? select_color : border_color);
156 } else {
157 rect->set_visible(false);
158 rect->set_stroke(0x0);
159 }
160 // This undoes the hide for the background rect, and additionally gives it a fill and shadow.
161 if (!is_foreground) {
162 rect->set_visible(true);
163/*
164 if (_checkerboard) {
165 // draw checkerboard pattern, ignore alpha (background color doesn't support it)
166 rect->set_background_checkerboard(_background_color, false);
167 }
168 else {
169 // Background color does not support transparency; draw opaque pages
170 rect->set_background(_background_color | 0xff);
171 }
172*/
173 rect->set_fill(_background_color.toRGBA());
174 rect->set_shadow(shadow_color, _shadow_size);
175 } else {
176 rect->set_fill(0x0);
177 rect->set_shadow(0x0, 0);
178 }
179 } else if (auto label = dynamic_cast<CanvasItemText *>(item.get())) {
180 _updateTextItem(label, size, txt ? txt : "", is_yaxisdown);
181 }
182 }
183}
184
188void CanvasPage::_updateTextItem(CanvasItemText *label, Geom::Rect page, std::string txt, bool is_yaxisdown)
189{
190 // Default style for the label
191 int fontsize = 10.0;
192 uint32_t foreground = 0xffffffff;
193 uint32_t background = 0x00000099;
194 uint32_t selected = 0x0e5bf199;
195 Geom::Point anchor(0.0, 1.0);
196 Geom::Point coord = page.corner(0);
197 double radius = 0.2;
198
199 // Change the colors for whiter/lighter backgrounds
201 foreground = 0x000000ff;
202 background = 0xffffff99;
203 selected = 0x50afe7ff;
204 }
205
206 if (_label_style == "below") {
207 radius = 1.0;
208 fontsize = 14.0;
209 anchor = Geom::Point(0.5, -0.2);
210 coord = Geom::Point(page.midpoint().x(), is_yaxisdown ? page.bottom() : page.top());
211
212 if (!txt.empty()) {
213 std::string bullet = is_selected ? " \u2022 " : " ";
214 txt = bullet + txt + bullet;
215 }
216 }
217
218 label->set_fontsize(fontsize);
219 label->set_fill(foreground);
220 label->set_background(is_selected ? selected : background);
221 label->set_bg_radius(radius);
222 label->set_anchor(anchor);
223 label->set_coord(coord);
224 label->set_visible(!txt.empty());
225 label->set_text(std::move(txt));
226 label->set_border(4.0);
227}
228
229bool CanvasPage::setOnTop(bool on_top)
230{
231 if (on_top != _border_on_top) {
232 _border_on_top = on_top;
233 return true;
234 }
235 return false;
236}
237
238bool CanvasPage::setShadow(int shadow)
239{
240 if (_shadow_size != shadow) {
241 _shadow_size = shadow;
242 return true;
243 }
244 return false;
245}
246
247bool CanvasPage::setPageColor(Color const &border, Color const &bg, Color const &canvas, Color const &margin, Color const &bleed)
248{
249 if (std::tie(border, bg, canvas, margin, bleed) != std::tie(_border_color, _background_color, _canvas_color, _margin_color, _bleed_color)) {
252 _canvas_color = canvas;
254 _bleed_color = bleed;
255 return true;
256 }
257 return false;
258}
259
260bool CanvasPage::setLabelStyle(const std::string &style)
261{
262 if (style != _label_style) {
263 _label_style = style;
264 return true;
265 }
266 return false;
267}
268
269} // namespace Inkscape
270
271/*
272 Local Variables:
273 mode:c++
274 c-file-style:"stroustrup"
275 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
276 indent-tabs-mode:nil
277 fill-column:99
278 End:
279*/
280// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
uint64_t page
Definition canvas.cpp:171
int margin
Definition canvas.cpp:166
Axis-aligned rectangle that can be empty.
Definition rect.h:203
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
std::vector< CanvasItemPtr< CanvasItem > > canvas_items
Definition canvas-page.h:55
void update(Geom::Rect size, Geom::OptRect margin, Geom::OptRect bleed, const char *txt, bool outline, bool is_yaxisdown)
Update the visual representation of a page on screen.
std::string _label_style
Definition canvas-page.h:65
void _updateTextItem(CanvasItemText *label, Geom::Rect page, std::string txt, bool is_yaxisdown)
Update the page's textual label.
void add(Geom::Rect size, CanvasItemGroup *background_group, CanvasItemGroup *foreground_group)
Add the page canvas to the given canvas item groups (canvas view is implicit)
void set_guides_visible(bool show)
bool setPageColor(Color const &border, Color const &bg, Color const &canvas, Color const &margin, Color const &bleed)
void remove(UI::Widget::Canvas *canvas)
Hide the page in the given canvas widget.
bool setLabelStyle(const std::string &style)
bool setShadow(int shadow)
bool setOnTop(bool on_top)
uint32_t toRGBA(double opacity=1.0) const
Return an sRGB conversion of the color in RGBA int32 format.
Definition color.cpp:117
A widget for Inkscape's canvas.
Definition canvas.h:62
unsigned int guint32
SPItem * item
Glib::ustring label
double get_perceptual_lightness(Color const &color)
Return a value for how the light the color appears to be using HSLUV.
Definition utils.cpp:174
Helper class to stream background task notifications as a series of messages.
Geom::PathVector outline(Geom::Path const &input, double width, double miter, LineJoinType join, LineCapType butt, double tolerance)
Strokes the path given by input.
double border