30#include <glibmm/i18n.h>
31#include <gtkmm/adjustment.h>
32#include <gtkmm/comboboxtext.h>
33#include <gtkmm/togglebutton.h>
76 _tracker->prependUnit(UnitTable::get().getUnit(
"px"));
78 if (prefs->getBool(
"/tools/calligraphic/abs_width")) {
79 _tracker->setActiveUnitByLabel(prefs->getString(
"/tools/calligraphic/unit"));
82 auto &usepressure_btn = get_widget<Gtk::ToggleButton>(
builder,
"usepressure_btn");
83 auto &tracebackground_btn = get_widget<Gtk::ToggleButton>(
builder,
"tracebackground_btn");
96 { 1, _(
"(hairline)")},
100 {15, _(
"(default)")},
105 {100, _(
"(broad stroke)")}
109 {-100, _(
"(speed blows up stroke)")},
112 { -10, _(
"(slight widening)")},
113 { 0, _(
"(constant width)")},
114 { 10, _(
"(slight thinning, default)")},
117 { 100, _(
"(speed deflates stroke)")}
121 { 0, _(
"(no inertia)")},
122 { 2, _(
"(slight smoothing, default)")},
123 { 10, _(
"(noticeable lagging)")},
126 {100, _(
"(maximum inertia)")}
130 {-90, _(
"(left edge up)")},
133 { 0, _(
"(horizontal)")},
134 { 30, _(
"(default)")},
136 { 90, _(
"(right edge up)")}
141 { 0, _(
"(perpendicular to stroke, \"brush\")")},
145 { 90, _(
"(almost fixed, default)")},
146 {100, _(
"(fixed by Angle, \"pen\")")}
150 { 0, _(
"(blunt caps, default)")},
151 {0.3, _(
"(slightly bulging)")},
154 {1.4, _(
"(approximately round)")},
155 {5.0, _(
"(long protruding caps)")}
159 { 0, _(
"(smooth line)")},
160 { 10, _(
"(slight tremor)")},
161 { 20, _(
"(noticeable tremor)")},
164 {100, _(
"(maximum tremor)")}
168 { 0, _(
"(no wiggle)")},
169 { 20, _(
"(slight deviation)")},
172 {100, _(
"(wild waves and curls)")}
180 auto unit_menu =
_tracker->create_tool_item(_(
"Units"),
"");
181 get_widget<Gtk::Box>(
builder,
"unit_menu_box").append(*unit_menu);
186 _usepressure_pusher = std::make_unique<SimplePrefPusher>(&usepressure_btn,
"/tools/calligraphic/usepressure");
188 &usepressure_btn,
"/tools/calligraphic/usepressure"));
191 _widget_map[
"tracebackground"] = &tracebackground_btn;
192 _tracebackground_pusher = std::make_unique<SimplePrefPusher>(&tracebackground_btn,
"/tools/calligraphic/tracebackground");
194 &tracebackground_btn,
195 "/tools/calligraphic/tracebackground"));
201 _angle_item.set_sensitive(!prefs->getBool(
"/tools/calligraphic/usetilt",
true));
202 _usetilt_btn->set_active(prefs->getBool(
"/tools/calligraphic/usetilt",
true));
205 get_widget<Gtk::Button>(
builder,
"profile_edit_btn")
218 auto const path =
"/tools/calligraphic/" +
name;
219 auto const val = prefs->getDouble(path, default_value);
220 auto adj = btn.get_adjustment();
222 if (
name ==
"width") {
223 auto const unit = UnitTable::get().getUnit(prefs->getString(
"/tools/calligraphic/unit"));
224 adj = Gtk::Adjustment::create(Quantity::convert(val,
"px", unit), 0.001, 100, 1.0, 10.0);
225 btn.set_adjustment(adj);
230 adj->signal_value_changed().connect(sigc::mem_fun(*
this, value_changed_mem_fun));
233 _tracker->addAdjustment(adj->gobj());
239 auto const unit =
_tracker->getActiveUnit();
241 prefs->setBool(
"/tools/calligraphic/abs_width",
_tracker->getCurrentLabel() !=
"%");
242 prefs->setDouble(
"/tools/calligraphic/width",
243 Quantity::convert(
_width_item.get_adjustment()->get_value(), unit,
"px"));
304 for (
auto i = presets.begin(); i != presets.end(); ++i, ++
index) {
308 for (
auto &j : preset) {
309 auto const entry_name = j.getEntryName();
310 if (entry_name ==
"id" || entry_name ==
"name") {
314 if (
auto widget =
_widget_map[entry_name.data()]) {
315 if (
auto adj =
dynamic_cast<Gtk::Adjustment *
>(widget)) {
316 double v = j.getDouble();
317 if (std::abs(adj->get_value() - v) > 1e-6) {
321 }
else if (
auto toggle =
dynamic_cast<Gtk::ToggleButton *
>(widget)) {
322 bool v = j.getBool();
323 if (toggle->get_active() != v) {
360 if (!preset_name.empty()) {
381 Glib::ustring preset_path =
"";
382 if (
mode - 1 < presets.size()) {
383 preset_path = presets.at(
mode - 1);
386 if (!preset_path.empty()) {
392 for (
auto &i : preset) {
393 auto const entry_name = i.getEntryName();
394 if (entry_name ==
"id" || entry_name ==
"name") {
397 if (
auto widget =
_widget_map[entry_name.data()]) {
398 if (
auto adj =
dynamic_cast<Gtk::Adjustment *
>(widget)) {
399 adj->set_value(i.getDouble());
400 }
else if (
auto toggle =
dynamic_cast<Gtk::ToggleButton *
>(widget)) {
401 toggle->set_active(i.getBool());
403 g_warning(
"Unknown widget type for preset: %s\n", entry_name.data());
406 g_warning(
"Bad key found in a preset record: %s\n", entry_name.data());
421 auto const unit =
_tracker->getActiveUnit();
423 prefs->setBool(
"/tools/calligraphic/abs_width",
_tracker->getCurrentLabel() !=
"%");
424 prefs->setDouble(
"/tools/calligraphic/width",
425 std::clamp(prefs->getDouble(
"/tools/calligraphic/width"), Quantity::convert(0.001, unit,
"px"),
426 Quantity::convert(100, unit,
"px")));
427 prefs->setString(
"/tools/calligraphic/unit", unit->abbr);
444 if (current_profile_name == _(
"No preset")) {
445 current_profile_name =
"";
448 CalligraphicProfileRename::show(
_desktop, current_profile_name);
449 if (!CalligraphicProfileRename::applied()) {
454 Glib::ustring new_profile_name = CalligraphicProfileRename::getProfileName();
456 if (new_profile_name.empty()) {
466 int total_presets = presets.size();
468 Glib::ustring save_path;
470 for (
int i = 0; i < presets.size(); i++) {
471 auto &p = presets[i];
472 auto const name = prefs->getString(p +
"/name");
473 if (!
name.empty() && (new_profile_name ==
name || current_profile_name ==
name)) {
480 if (CalligraphicProfileRename::deleted() && new_index != -1) {
481 prefs->remove(save_path);
487 if (new_index == -1) {
489 new_index = total_presets + 1;
490 auto const profile_id = g_strdup_printf(
"/dcc%d", new_index);
491 save_path = Glib::ustring(
"/tools/calligraphic/preset") + profile_id;
495 for (
auto const &[widget_name, widget] :
_widget_map) {
497 if (
auto adj =
dynamic_cast<Gtk::Adjustment *
>(widget)) {
498 prefs->setDouble(save_path +
"/" + widget_name, adj->get_value());
499 }
else if (
auto toggle =
dynamic_cast<Gtk::ToggleButton *
>(widget)) {
500 prefs->setBool(save_path +
"/" + widget_name, toggle->get_active());
502 g_warning(
"Unknown widget type for preset: %s\n", widget_name.c_str());
505 g_warning(
"Bad key when writing preset: %s\n", widget_name.c_str());
508 prefs->setString(save_path +
"/name", new_profile_name);
Dialog for naming calligraphic profiles.
std::vector< Entry > getAllEntries(Glib::ustring const &path)
Get all entries from the specified directory.
Glib::ustring getString(Glib::ustring const &pref_path, Glib::ustring const &def="")
Retrieve an UTF-8 string.
static Preferences * get()
Access the singleton Preferences object.
std::vector< Glib::ustring > getAllDirs(Glib::ustring const &path)
Get all subdirectories of the specified directory.
void setDouble(Glib::ustring const &pref_path, double value)
Set a floating point value.
void setBool(Glib::ustring const &pref_path, bool value)
Set a Boolean value.
Editable view implementation.
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
W & get_derived_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id, Args &&... args)
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Miscellaneous supporting code.
Glib::RefPtr< Gtk::Builder > builder