Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
util.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Utility functions for UI
4 *
5 * Authors:
6 * Tavmjong Bah
7 * John Smith
8 *
9 * Copyright (C) 2013, 2018 Authors
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#ifndef UI_UTIL_SEEN
14#define UI_UTIL_SEEN
15
16#include <gtkmm/notebook.h>
17#include <2geom/rect.h>
18
19/*
20 * Use these errors when building from glade files for graceful
21 * fallbacks and prevent crashes from corrupt ui files.
22 */
23class UIBuilderError : public std::exception {};
26
27namespace Cairo {
28class Matrix;
29class ImageSurface;
30} // namespace Cairo
31
32namespace Glib {
33class ustring;
34} // namespace Glib
35
36namespace Gtk {
37class Editable;
38class Label;
39class TextBuffer;
40class Widget;
41} // namespace Gtk
42
43namespace Inkscape::Colors {
44class Color;
45} // namespace Inkscape::Colors
46
47Glib::ustring ink_ellipsize_text(Glib::ustring const &src, std::size_t maxlen);
48
49void reveal_widget(Gtk::Widget *widget, bool show);
50
51// check if widget in a container is actually visible
52bool is_widget_effectively_visible(Gtk::Widget const *widget);
53
54namespace Inkscape::UI {
55
56void set_icon_sizes(Gtk::Widget *parent, int pixel_size);
57void set_icon_sizes(GtkWidget *parent, int pixel_size);
58
59void gui_warning(const std::string &msg, Gtk::Window * parent_window = nullptr);
60
62enum class ForEachResult {
63 _continue, // go on to the next widget
64 _break, // stop here, return current widget
65 _skip // do not recurse into current widget, go to the next one
66};
67
69void system_open(const Glib::ustring &path);
71std::vector<Gtk::Widget *> get_children(Gtk::Widget &widget);
73Gtk::Widget &get_nth_child(Gtk::Widget &widget, std::size_t index);
75template <typename Widget> void remove_all_children(Widget &widget)
76{
77 for (auto const child: get_children(widget)) {
78 widget.remove(*child);
79 }
80}
81
89template <typename Func>
90Gtk::Widget *for_each_child(Gtk::Widget &widget, Func &&func,
91 bool const plus_self = false, bool const recurse = false,
92 int const level = 0)
93{
94 static_assert(std::is_invocable_r_v<ForEachResult, Func, Gtk::Widget &>);
95
96 if (plus_self) {
97 auto ret = func(widget);
98 if (ret == ForEachResult::_break) return &widget;
99
100 // skip this widget?
101 if (ret == ForEachResult::_skip) return nullptr;
102 }
103
104 if (!recurse && level > 0) return nullptr;
105
106 for (auto const child: get_children(widget)) {
107 auto const descendant = for_each_child(*child, func, true, recurse, level + 1);
108 if (descendant) return descendant;
109 }
110
111 return nullptr;
112}
113
118template <typename Func>
119Gtk::Widget *for_each_descendant(Gtk::Widget &widget, Func &&func)
120{
121 return for_each_child(widget, std::forward<Func>(func), true, true);
122}
123
125template <typename Func>
126Gtk::Widget *for_each_parent(Gtk::Widget &widget, Func &&func)
127{
128 static_assert(std::is_invocable_r_v<ForEachResult, Func, Gtk::Widget &>);
129 for (auto parent = widget.get_parent(); parent; parent = parent->get_parent()) {
130 if (func(*parent) == ForEachResult::_break) {
131 return parent;
132 }
133 }
134 return nullptr;
135}
136
138template <typename Func>
139Gtk::Widget* for_each_page(Gtk::Notebook& notebook, Func&& func) {
140 static_assert(std::is_invocable_r_v<ForEachResult, Func, Gtk::Widget&>);
141
142 const int page_number = notebook.get_n_pages();
143 for (int page_index = 0; page_index < page_number; ++page_index) {
144 auto page = notebook.get_nth_page(page_index);
145 if (!page) continue;
146
147 if (func(*page) == ForEachResult::_break) return page;
148 }
149
150 return nullptr;
151}
152
153[[nodiscard]] Gtk::Widget *find_widget_by_name(Gtk::Widget &parent, Glib::ustring const &name, bool visible_only);
154[[nodiscard]] Gtk::Widget *find_focusable_widget(Gtk::Widget &parent);
155[[nodiscard]] bool is_descendant_of(Gtk::Widget const &descendant, Gtk::Widget const &ancestor);
156[[nodiscard]] bool contains_focus(Gtk::Widget &widget);
157
158[[nodiscard]] int get_font_size(Gtk::Widget &widget);
159
160// If max_width_chars is > 0, then the created Label has :max-width-chars set to
161// that limit, the :ellipsize mode is set to the passed-in @a mode, & a ::query-
162// tooltip handler is connected to show the label as the tooltip when ellipsized
163void ellipsize(Gtk::Label &label, int max_width_chars, Pango::EllipsizeMode mode);
164
165} // namespace Inkscape::UI
166
167// Mix two RGBA colors using simple linear interpolation:
168// 0 -> only a, 1 -> only b, x in 0..1 -> (1 - x)*a + x*b
169Gdk::RGBA mix_colors(const Gdk::RGBA& a, const Gdk::RGBA& b, float ratio);
170
171// Create the same color, but with a different opacity (alpha)
172Gdk::RGBA change_alpha(const Gdk::RGBA& color, double new_alpha);
173
176double get_luminance(const Gdk::RGBA &color);
177
178// Get CSS color for a Widget, based on its current state & a given CSS class.
179// N.B.!! Big GTK devs donʼt think changing classes should work ‘within a frame’
180// …but it does… & GTK3 GtkCalendar does that – so keep doing it, till we canʼt!
181Gdk::RGBA get_color_with_class(Gtk::Widget &widget,
182 Glib::ustring const &css_class);
183
184// Convert a Gdk color to a hex code for css injection.
185Glib::ustring gdk_to_css_color(const Gdk::RGBA& color);
186Gdk::RGBA css_color_to_gdk(const char *value);
187
188guint32 to_guint32(Gdk::RGBA const &rgba);
189Gdk::RGBA color_to_rgba(Inkscape::Colors::Color const &color);
190Gdk::RGBA to_rgba(guint32 const u32);
191
192// convert Gdk::RGBA into 32-bit rrggbbaa color, optionally replacing alpha, if specified
193uint32_t conv_gdk_color_to_rgba(const Gdk::RGBA& color, double replace_alpha = -1);
194
195Geom::IntRect cairo_to_geom(const Cairo::RectangleInt &rect);
196Cairo::RectangleInt geom_to_cairo(const Geom::IntRect &rect);
197Cairo::Matrix geom_to_cairo(const Geom::Affine &affine);
198Geom::IntPoint dimensions(const Cairo::RefPtr<Cairo::ImageSurface> &surface);
199Geom::IntPoint dimensions(const Gdk::Rectangle &allocation);
200
201template <typename T>
202inline Gdk::Graphene::Rect geom_to_gtk(Geom::GenericRect<T> const &rect) {
203 return Gdk::Graphene::Rect(rect.left(), rect.top(), rect.width(), rect.height());
204}
205inline Gdk::Graphene::Point geom_to_gtk(Geom::IntPoint const &point) {
206 return Gdk::Graphene::Point(point.x(), point.y());
207}
208inline Gdk::Graphene::Point geom_to_gtk(Geom::Point const &point) {
209 return Gdk::Graphene::Point(point.x(), point.y());
210}
211
212// create a gradient with multiple steps to approximate profile described by given cubic spline
213std::vector<GskColorStop> create_cubic_gradient(
214 const Gdk::RGBA& from,
215 const Gdk::RGBA& to,
216 Geom::Point ctrl1,
217 Geom::Point ctrl2,
218 Geom::Point p0 = Geom::Point(0, 0),
219 Geom::Point p1 = Geom::Point(1, 1),
220 int steps = 8
221);
222
223// If on Windows, get the native window & set it to DWMA_USE_IMMERSIVE_DARK_MODE
224void set_dark_titlebar(Glib::RefPtr<Gdk::Surface> const &surface, bool is_dark);
225unsigned int get_color_value(const Glib::ustring color);
226
227// Parse string that can contain floating point numbers and round them to given precision;
228// Used on path data ("d" attribute).
229Glib::ustring round_numbers(const Glib::ustring& text, int precision);
230
231// As above, but operating in-place on a TextBuffer
232void truncate_digits(const Glib::RefPtr<Gtk::TextBuffer>& buffer, int precision);
233
238Glib::RefPtr<Gdk::Texture> to_texture(Cairo::RefPtr<Cairo::Surface> const &surface);
239
240// Restrict widget's min size (min-width & min-height) to specified minimum to keep it square (when it's centered).
241// Widget has to have a name given with set_name.
242void restrict_minsize_to_square(Gtk::Widget& widget, int min_size_px);
243
245char const *get_text(Gtk::Editable const &editable);
246
247#endif // UI_UTIL_SEEN
248
249/*
250 Local Variables:
251 mode:c++
252 c-file-style:"stroustrup"
253 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
254 indent-tabs-mode:nil
255 fill-column:99
256 End:
257*/
258// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
uint32_t Color
Cairo::RefPtr< Cairo::ImageSurface > surface
Definition canvas.cpp:137
uint64_t page
Definition canvas.cpp:171
3x3 matrix representing an affine transformation.
Definition affine.h:70
Axis aligned, non-empty, generic rectangle.
C top() const
Return top coordinate of the rectangle (+Y is downwards).
C left() const
Return leftmost coordinate of the rectangle (+X is to the right).
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
Two-dimensional point with integer coordinates.
Definition int-point.h:57
constexpr IntCoord x() const noexcept
Definition int-point.h:77
constexpr IntCoord y() const noexcept
Definition int-point.h:79
Two-dimensional point that doubles as a vector.
Definition point.h:66
constexpr Coord y() const noexcept
Definition point.h:106
constexpr Coord x() const noexcept
Definition point.h:104
Glib::ustring msg
static char const *const parent
Definition dir-util.cpp:70
unsigned int guint32
Glib::ustring label
Control handle rendering/caching.
Definition desktop.h:50
A set of useful color modifying functions which do not fit as generic methods on the color class itse...
Definition profile.cpp:24
User interface code.
Definition desktop.h:113
Gtk::Widget * for_each_parent(Gtk::Widget &widget, Func &&func)
Call Func with a reference to successive parents, until Func returns _break.
Definition util.h:126
void remove_all_children(Widget &widget)
For each child in get_children(widget), call widget.remove(*child). May not cause delete child!
Definition util.h:75
void set_icon_sizes(Gtk::Widget *parent, int pixel_size)
Recursively set all the icon sizes inside this parent widget.
Definition util.cpp:98
void gui_warning(const std::string &msg, Gtk::Window *parent_window)
Definition util.cpp:119
Gtk::Widget & get_nth_child(Gtk::Widget &widget, std::size_t const index)
Get the widgetʼs child at the given position. Throws std::out_of_range if the index is invalid.
Definition util.cpp:150
Gtk::Widget * for_each_descendant(Gtk::Widget &widget, Func &&func)
Like for_each_child() but also tests the initial widget & recurses through childrenʼs children.
Definition util.h:119
Gtk::Widget * find_widget_by_name(Gtk::Widget &parent, Glib::ustring const &name, bool visible_only)
Returns a named descendent of parent, which has the given name, or nullptr if there's none.
Definition util.cpp:169
bool is_descendant_of(Gtk::Widget const &descendant, Gtk::Widget const &ancestor)
Returns if widget is a descendant of given ancestor, i.e.: itself, a child, or a childʼs child.
Definition util.cpp:195
int get_font_size(Gtk::Widget &widget)
Get the relative font size as determined by a widgetʼs style/Pango contexts.
Definition util.cpp:224
ForEachResult
Whether for_each_*() will continue or stop after calling Func per child.
Definition util.h:62
std::vector< Gtk::Widget * > get_children(Gtk::Widget &widget)
Get a vector of the widgetʼs children, from get_first_child() through each get_next_sibling().
Definition util.cpp:141
void ellipsize(Gtk::Label &label, int const max_width_chars, Pango::EllipsizeMode const mode)
Definition util.cpp:236
Gtk::Widget * for_each_child(Gtk::Widget &widget, Func &&func, bool const plus_self=false, bool const recurse=false, int const level=0)
Call Func with a reference to each child of parent, until it returns _break.
Definition util.h:90
Gtk::Widget * for_each_page(Gtk::Notebook &notebook, Func &&func)
Similar to for_each_child, but only iterates over pages in a notebook.
Definition util.h:139
void system_open(const Glib::ustring &path)
Opens the given path with platform-specific tools.
Definition util.cpp:128
bool contains_focus(Gtk::Widget &widget)
Returns if widget or one of its descendants has focus.
Definition util.cpp:204
Gtk::Widget * find_focusable_widget(Gtk::Widget &parent)
This function traverses a tree of widgets searching for first focusable widget.
Definition util.cpp:185
int mode
Ocnode * child[8]
Definition quantize.cpp:33
Axis-aligned rectangle.
int index
Glib::ustring name
Definition toolbars.cpp:55
Glib::ustring ink_ellipsize_text(Glib::ustring const &src, std::size_t maxlen)
Definition util.cpp:52
Glib::ustring round_numbers(const Glib::ustring &text, int precision)
Definition util.cpp:458
unsigned int get_color_value(const Glib::ustring color)
Color is store as a string in the form #RRGGBBAA, '0' means "unset".
Definition util.cpp:260
double get_luminance(const Gdk::RGBA &color)
Calculate luminance of an RGBA color from its RGB in range 0 to 1 inclusive.
Definition util.cpp:280
Glib::RefPtr< Gdk::Texture > to_texture(Cairo::RefPtr< Cairo::Surface > const &surface)
Convert an image surface in ARGB32 format to a texture.
Definition util.cpp:495
Gdk::RGBA to_rgba(guint32 const u32)
Definition util.cpp:310
Cairo::RectangleInt geom_to_cairo(const Geom::IntRect &rect)
Definition util.cpp:338
uint32_t conv_gdk_color_to_rgba(const Gdk::RGBA &color, double replace_alpha=-1)
Definition util.cpp:408
Gdk::Graphene::Rect geom_to_gtk(Geom::GenericRect< T > const &rect)
Definition util.h:202
guint32 to_guint32(Gdk::RGBA const &rgba)
Definition util.cpp:297
Gdk::RGBA css_color_to_gdk(const char *value)
Definition util.cpp:328
void restrict_minsize_to_square(Gtk::Widget &widget, int min_size_px)
Definition util.cpp:522
bool is_widget_effectively_visible(Gtk::Widget const *widget)
Definition util.cpp:82
std::vector< GskColorStop > create_cubic_gradient(const Gdk::RGBA &from, const Gdk::RGBA &to, Geom::Point ctrl1, Geom::Point ctrl2, Geom::Point p0=Geom::Point(0, 0), Geom::Point p1=Geom::Point(1, 1), int steps=8)
Definition util.cpp:363
Gdk::RGBA get_color_with_class(Gtk::Widget &widget, Glib::ustring const &css_class)
Definition util.cpp:288
char const * get_text(Gtk::Editable const &editable)
Get the text from a GtkEditable without the temporary copy imposed by gtkmm.
Definition util.cpp:534
Gdk::RGBA change_alpha(const Gdk::RGBA &color, double new_alpha)
Definition util.cpp:402
Gdk::RGBA mix_colors(const Gdk::RGBA &a, const Gdk::RGBA &b, float ratio)
Definition util.cpp:268
Geom::IntRect cairo_to_geom(const Cairo::RectangleInt &rect)
Definition util.cpp:343
void reveal_widget(Gtk::Widget *widget, bool show)
Show widget, if the widget has a Gtk::Reveal parent, reveal instead.
Definition util.cpp:68
void truncate_digits(const Glib::RefPtr< Gtk::TextBuffer > &buffer, int precision)
Definition util.cpp:466
void set_dark_titlebar(Glib::RefPtr< Gdk::Surface > const &surface, bool is_dark)
Definition util.cpp:418
Gdk::RGBA color_to_rgba(Inkscape::Colors::Color const &color)
Definition util.cpp:305
Glib::ustring gdk_to_css_color(const Gdk::RGBA &color)
These GUI related color conversions allow us to convert from SVG xml attributes to Gdk colors,...
Definition util.cpp:325
Geom::IntPoint dimensions(const Cairo::RefPtr< Cairo::ImageSurface > &surface)
Definition util.cpp:353