Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
ctrl-handle-manager.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <sigc++/signal.h>
5#include <glib/gi18n.h>
6#include <glibmm/main.h>
7#include <giomm/file.h>
8#include <giomm/filemonitor.h>
9
10#include "ctrl-handle-styling.h"
11
12#include <sigc++/scoped_connection.h>
13#include "io/resource.h"
14#include "preferences.h"
15
16namespace Inkscape::Handles {
17namespace {
18
19class ManagerImpl final : public Manager
20{
21public:
22 ManagerImpl();
23
24private:
25 // Most recent css (shared between all CanvasItemContexts)
26 std::shared_ptr<Css const> css;
27
28 // For file system monitoring.
29 Glib::RefPtr<Gio::FileMonitor> monitor;
30 sigc::scoped_connection timeout;
31
32 // Emitted when the css changes.
33 sigc::signal<void()> signal_css_updated;
34
35 void updateCss();
36 void monitor_file(std::string const& file_name);
37
38 friend Manager;
39};
40
41ManagerImpl::ManagerImpl()
42{
43 current_theme = Inkscape::Preferences::get()->getIntLimited("/handles/color-scheme-index", 0, 0, get_handle_themes().size() - 1);
44
45 // Set the initial css.
46 updateCss();
47
48 // During application startup, we check to see if the user has selected custom css
49 // in preferences. We don't want to monitor shipped css files, only user defined
50 // custom css.
51 if (get_handle_themes().at(current_theme).file_name == USER_CUSTOM_CSS_FILE_NAME) {
52 monitor_file(USER_CUSTOM_CSS_FILE_NAME);
53 }
54}
55
59void ManagerImpl::monitor_file(std::string const& file_name)
60{
62 auto file = Gio::File::create_for_path(path);
63 monitor = file->monitor_file();
64 monitor->signal_changed().connect([this] (Glib::RefPtr<Gio::File> const &, Glib::RefPtr<Gio::File> const &, Gio::FileMonitor::Event) {
65 if (timeout) return;
66 timeout = Glib::signal_timeout().connect([this] {
67 updateCss();
68 signal_css_updated.emit();
69 return false;
70 }, 200);
71 });
72}
73
74void ManagerImpl::updateCss()
75{
76 auto& filename = get_handle_themes().at(current_theme).file_name;
77 css = std::make_shared<Css const>(parse_css(filename));
78}
79
80} // namespace
81
83{
84 static ManagerImpl instance;
85 return instance;
86}
87
88std::shared_ptr<Css const> Manager::getCss() const
89{
90 auto &d = static_cast<ManagerImpl const &>(*this);
91 return d.css;
92}
93
94sigc::connection Manager::connectCssUpdated(sigc::slot<void()> &&slot)
95{
96 auto &d = static_cast<ManagerImpl &>(*this);
97 return d.signal_css_updated.connect(std::move(slot));
98}
99
100// predefined handle color themes
101const std::vector<ColorTheme>& Manager::get_handle_themes() const {
102#define translation_context "Handle color scheme name"
103 static std::vector<ColorTheme> themes = {
104 // default blue scheme
105 {"handle-theme-azure.css", C_(translation_context, "Azure"), true, 0x2a7fff},
106 // red scheme
107 {"handle-theme-crimson.css", C_(translation_context, "Crimson"), true, 0xff1a5e},
108 // green scheme
109 {"handle-theme-spruce.css", C_(translation_context, "Spruce"), true, 0x05ca85},
110 // purple scheme
111 {"handle-theme-violet.css", C_(translation_context, "Violet"), true, 0xbb61f3},
112 // yellow scheme
113 {"handle-theme-gold.css", C_(translation_context, "Gold"), true, 0xebca00},
114 // gray scheme
115 {"handle-theme-steel.css", C_(translation_context, "Steel"), true, 0x9db4d8},
116 // a "negative" version
117 {"handle-theme-negative.css", C_(translation_context, "Negative"), false, 0xa0a0b0},
118 // reserved for user custom style
119 {USER_CUSTOM_CSS_FILE_NAME, C_(translation_context, "Custom"), true, 0x808080},
120 };
121 return themes;
122#undef translation_context
123}
124
126 auto& themes = get_handle_themes();
127 if (static_cast<size_t>(index) >= themes.size()) {
128 g_warning("Invalid handle color theme index, css not loaded.");
129 return;
130 }
132 Inkscape::Preferences::get()->setInt("/handles/color-scheme-index", index);
133 auto &d = static_cast<ManagerImpl&>(*this);
134 d.updateCss();
135 d.signal_css_updated.emit();
136
137 // A user might cycle through the available themes, if they switch from
138 // custom we clear any existing handler, if they eventually land
139 // on custom, we want to start monitoring it again.
140 d.monitor.reset();
141 if (d.get_handle_themes().at(current_theme).file_name == USER_CUSTOM_CSS_FILE_NAME) {
142 d.monitor_file(USER_CUSTOM_CSS_FILE_NAME);
143 }
144}
145
146} // namespace Inkscape::Handles
147
148/*
149 Local Variables:
150 mode:c++
151 c-file-style:"stroustrup"
152 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
153 indent-tabs-mode:nil
154 fill-column:99
155 End:
156*/
157// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
std::shared_ptr< Css const > getCss() const
const std::vector< ColorTheme > & get_handle_themes() const
sigc::connection connectCssUpdated(sigc::slot< void()> &&slot)
static Preferences * get()
Access the singleton Preferences object.
void setInt(Glib::ustring const &pref_path, int value)
Set an integer value.
int getIntLimited(Glib::ustring const &pref_path, int def=0, int min=INT_MIN, int max=INT_MAX)
Retrieve a limited integer.
Glib::RefPtr< Gio::FileMonitor > monitor
sigc::signal< void()> signal_css_updated
std::shared_ptr< Css const > css
sigc::scoped_connection timeout
friend Manager
std::string file_name
Classes related to control handle styling.
Css parse_css(const std::string &css_file_name)
constexpr auto USER_CUSTOM_CSS_FILE_NAME
std::string get_path_string(Domain domain, Type type, char const *filename, char const *extra)
Definition resource.cpp:148
Singleton class to access the preferences file in a convenient way.
Inkscape::IO::Resource - simple resource API.
int index