20#include <glibmm/i18n.h>
21#include <glibmm/convert.h>
22#include <glibmm/regex.h>
24#include <gtkmm/scale.h>
25#include <sigc++/functors/mem_fun.h>
52 set_column_spacing(12);
68 Glib::ustring
const &label,
70 Glib::ustring
const &suffix,
71 const Glib::ustring &tip,
73 Gtk::Widget *other_widget)
76 widget.set_tooltip_text(tip);
78 auto const hb = Gtk::make_managed<Gtk::Box>();
80 hb->set_hexpand(
true);
82 hb->set_valign(Gtk::Align::CENTER);
86 auto const label_widget = Gtk::make_managed<Gtk::Label>(label, Gtk::Align::START,
87 Gtk::Align::CENTER,
true);
88 label_widget->set_mnemonic_widget(widget);
89 label_widget->set_markup(label_widget->get_text());
92 label_widget->set_margin_start(12);
95 label_widget->set_valign(Gtk::Align::CENTER);
96 attach_next_to(*label_widget, Gtk::PositionType::BOTTOM);
101 hb->set_margin_start(12);
104 attach_next_to(*hb, Gtk::PositionType::BOTTOM, 2, 1);
108 if (!suffix.empty()) {
109 auto const suffix_widget = Gtk::make_managed<Gtk::Label>(suffix, Gtk::Align::START, Gtk::Align::CENTER,
true);
110 suffix_widget->set_markup(suffix_widget->get_text());
121 if (name.empty())
return;
123 auto const label_widget = Gtk::make_managed<Gtk::Label>(Glib::ustring(
"<b>").
append(name).
append(
"</b>"),
124 Gtk::Align::START, Gtk::Align::CENTER,
true);
126 label_widget->set_use_markup(
true);
127 label_widget->set_valign(Gtk::Align::CENTER);
128 attach_next_to(*label_widget, Gtk::PositionType::BOTTOM, columns, 1);
133 if (name.empty())
return;
135 auto const label_widget = Gtk::make_managed<Gtk::Label>(Glib::ustring(
"<i>").
append(name).
append(
"</i>"),
136 Gtk::Align::START , Gtk::Align::CENTER,
true);
137 label_widget->set_use_markup(
true);
138 label_widget->set_valign(Gtk::Align::CENTER);
139 label_widget->set_wrap(
true);
140 label_widget->set_wrap_mode(Pango::WrapMode::WORD);
141 attach_next_to(*label_widget, Gtk::PositionType::BOTTOM, 2, 1);
146 widget.set_tooltip_text (tip);
155 this->set_label(label);
161 if (this->get_visible())
170 Glib::ustring
const &string_value,
bool default_value,
PrefRadioButton* group_member)
176 this->set_label(label);
180 this->set_group(*group_member);
188 this->set_active(
false );
197 this->set_label(label);
201 this->set_group(*group_member);
215 if (this->get_visible() && this->get_active() )
229 for (
auto&&
item : buttons) {
230 auto* btn = Gtk::make_managed<PrefRadioButton>();
232 btn->set_tooltip_text(
item.tooltip);
234 if (!group) group = btn;
239 double lower,
double upper,
double step_increment,
double ,
240 double default_value,
bool is_int,
bool is_percent)
257 this->set_range (lower, upper);
258 this->set_increments (step_increment, 0);
259 this->set_value (value);
260 this->set_width_chars(6);
263 else if (step_increment < 0.1)
274 if (this->get_visible())
290 double lower,
double upper,
double step_increment,
291 double default_value,
UnitType unit_type, Glib::ustring
const &default_unit)
300 if (step_increment < 0.1) {
309 if (unitstr.length() == 0) {
310 unitstr = default_unit;
352 PangoLayout* layout = pango_cairo_create_layout (cr);
353 pango_layout_set_text(layout, txt, -1);
356 std::ostringstream sizestr;
358 fontdesc = fontdesc +
" " + sizestr.str();
360 pango_layout_set_font_description(layout, font_desc);
361 pango_font_description_free (font_desc);
363 PangoRectangle logical_extent;
364 pango_layout_get_pixel_extents(layout,
nullptr, &logical_extent);
366 pango_cairo_show_layout(cr, layout);
371 std::ostringstream number;
373 draw_text(cr, pos, number.str().c_str(),
true);
382 double const dist,
int const major_interval)
385 const double zoomcorr = prefs->
getDouble(
"/options/zoomcorrection/value", 1.0);
389 bool draw_minor =
true;
400 if ((i % major_interval) == 0) {
402 if (
static_cast<int>(mark) > last_pos) {
404 cr->line_to(mark, 0);
408 last_pos =
static_cast<int>(mark) + 1;
410 }
else if (draw_minor) {
425 auto const fg = get_color();
426 cr->set_line_width(1);
427 cr->set_source_rgb(fg.get_red(), fg.get_green(), fg.get_blue());
434 Glib::ustring abbr = prefs->
getString(
"/options/zoomcorrection/unit");
437 }
else if (abbr ==
"in") {
439 }
else if (abbr ==
"mm") {
441 }
else if (abbr ==
"pc") {
443 }
else if (abbr ==
"pt") {
445 }
else if (abbr ==
"px") {
456 if (this->get_visible() ||
freeze)
460 prefs->
setDouble(
"/options/zoomcorrection/value",
_slider->get_value() / 100.0);
470 if (this->get_visible() ||
freeze)
474 prefs->
setDouble(
"/options/zoomcorrection/value",
_sb->get_value() / 100.0);
483 if (!
_unit.get_sensitive()) {
492 if (
_ruler.get_visible()) {
499 return _sb->mnemonic_activate ( group_cycling );
504 double step_increment,
double page_increment,
double default_value)
507 double value = prefs->
getDoubleLimited(
"/options/zoomcorrection/value", default_value, lower, upper) * 100.0;
516 _slider->set_range (lower, upper);
517 _slider->set_increments (step_increment, page_increment);
522 _sb = Gtk::make_managed<Inkscape::UI::Widget::SpinButton>();
526 _sb->set_range (lower, upper);
527 _sb->set_increments (step_increment, 0);
528 _sb->set_value (value);
530 _sb->set_halign(Gtk::Align::CENTER);
531 _sb->set_valign(Gtk::Align::END);
533 _unit.set_sensitive(
false);
535 _unit.set_sensitive(
true);
537 _unit.set_halign(Gtk::Align::CENTER);
538 _unit.set_valign(Gtk::Align::END);
542 auto const table = Gtk::make_managed<Gtk::Grid>();
543 table->attach(*
_slider, 0, 0, 1, 1);
544 table->attach(*
_sb, 1, 0, 1, 1);
545 table->attach(
_ruler, 0, 1, 1, 1);
546 table->attach(
_unit, 1, 1, 1, 1);
554 if (this->get_visible() ||
freeze)
567 if (this->get_visible() ||
freeze)
581 return _sb ?
_sb->mnemonic_activate ( group_cycling ) :
false;
586 double lower,
double upper,
double step_increment,
double page_increment,
double default_value,
int digits)
597 _slider->set_range (lower, upper);
598 _slider->set_increments (step_increment, page_increment);
603 _sb = Gtk::make_managed<Inkscape::UI::Widget::SpinButton>();
605 _sb->set_range (lower, upper);
606 _sb->set_increments (step_increment, 0);
607 _sb->set_value (value);
608 _sb->set_digits(digits);
609 _sb->set_halign(Gtk::Align::CENTER);
610 _sb->set_valign(Gtk::Align::END);
613 auto const table = Gtk::make_managed<Gtk::Grid>();
615 table->attach(*
_slider, 0, 0, 1, 1);
616 if (
_sb) table->attach(*
_sb, 1, 0, 1, 1);
622 std::span<Glib::ustring const> labels,
623 std::span<int const> values,
624 int const default_value)
626 int const labels_size = labels.size();
627 int const values_size = values.size();
628 if (values_size != labels_size) {
629 std::cerr <<
"PrefCombo::"
630 <<
"Different number of values/labels in " <<
prefs_path.raw() << std::endl;
639 for (
int i = 0; i < labels_size; ++i) {
642 if (value == values[i])
645 this->set_active(row);
649 std::span<Glib::ustring const> labels,
650 std::span<Glib::ustring const> values,
651 Glib::ustring
const &default_value)
653 int const labels_size = labels.size();
654 int const values_size = values.size();
655 if (values_size != labels_size) {
656 std::cerr <<
"PrefCombo::"
657 <<
"Different number of values/labels in " <<
prefs_path.raw() << std::endl;
666 value = default_value;
669 for (
int i = 0; i < labels_size; ++i) {
672 if (value == values[i])
675 this->set_active(row);
680 if (this->get_visible())
695 bool visibility, Glib::ustring
const &default_string)
715 if (this->get_visible())
724 if (this->get_visible())
734 return relatedEntry->mnemonic_activate ( group_cycling );
750 auto const im =
sp_get_icon_image(
"applications-graphics", Gtk::IconSize::NORMAL);
752 auto const l = Gtk::make_managed<Gtk::Label>();
753 l->set_markup_with_mnemonic(_(
"_Browse..."));
768 if (this->get_visible()) {
778 if (this->get_visible()) {
781 static std::string open_path;
792 _(
"Select a bitmap editor")).release();
808 auto path = file->get_path();
813 if (!open_path.empty()) {
824 return relatedEntry->mnemonic_activate ( group_cycling );
834 auto const l = Gtk::make_managed<Gtk::Label>();
835 l->set_markup_with_mnemonic(_(
"Open"));
848 g_mkdir_with_parents(
relatedEntry->get_text().c_str(), 0700);
851 ShellExecute(NULL,
"open",
relatedEntry->get_text().c_str(), NULL, NULL, SW_SHOWDEFAULT);
852#elif defined(__APPLE__)
853 std::vector<std::string> argv = {
"open",
relatedEntry->get_text().raw() };
854 Glib::spawn_async(
"", argv, Glib::SpawnFlags::SEARCH_PATH);
856 char *
const path = g_filename_to_uri(
relatedEntry->get_text().c_str(), NULL, NULL);
857 std::vector<std::string> argv = {
"xdg-open", path };
858 Glib::spawn_async(
"", argv, Glib::SpawnFlags::SEARCH_PATH);
867 this->set_invisible_char(
'*');
868 this->set_visibility(visibility);
874 if (this->get_visible())
883 if (this->get_visible())
894 set_size_request(100,
height);
895 set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
903 value =
Glib::Regex::create(
"\\|")->replace_literal(value, 0,
"\n", (Glib::Regex::MatchFlags)0);
904 _text.get_buffer()->set_text(value);
913 Glib::ustring value =
_text.get_buffer()->get_text();
914 value =
Glib::Regex::create(
"\\n")->replace_literal(value, 0,
"|", (Glib::Regex::MatchFlags)0);
920 std::uint32_t
const default_rgba)
930 if (this->get_visible())
947 if (this->get_visible())
_PangoFontDescription PangoFontDescription
struct _PangoLayout PangoLayout
Two-dimensional point that doubles as a vector.
Preference storage class.
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
void setDoubleUnit(Glib::ustring const &pref_path, double value, Glib::ustring const &unit_abbr)
Set a floating point value with unit.
Glib::ustring getUnit(Glib::ustring const &pref_path)
Retrieve the unit string.
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
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.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
void setString(Glib::ustring const &pref_path, Glib::ustring const &value)
Set an UTF-8 string value.
void setDouble(Glib::ustring const &pref_path, double value)
Set a floating point value.
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.
void setBool(Glib::ustring const &pref_path, bool value)
Set a Boolean value.
double getDoubleLimited(Glib::ustring const &pref_path, double def=0.0, double min=DBL_MIN, double max=DBL_MAX, Glib::ustring const &unit="")
Retrieve a limited floating point value.
virtual bool show()=0
Show file selector.
This class provides an implementation-independent API for file "Open" dialogs.
virtual Glib::RefPtr< Gio::File > getFile()=0
static std::unique_ptr< FileOpenDialog > create(Gtk::Window &parentWindow, std::string const &path, FileDialogType fileTypes, char const *title)
Factory.
void add_group_note(Glib::ustring name)
void add_group_header(Glib::ustring name, int columns=1)
void add_line(bool indent, Glib::ustring const &label, Gtk::Widget &widget, Glib::ustring const &suffix, Glib::ustring const &tip, bool expand=true, Gtk::Widget *other_widget=nullptr)
Add a widget to the bottom row of the dialog page.
void set_tip(Gtk::Widget &widget, Glib::ustring const &tip)
void onRelatedEntryChangedCallback()
void onRelatedButtonClickedCallback()
bool on_mnemonic_activate(bool group_cycling) override
Gtk::Entry * relatedEntry
Glib::ustring _prefs_path
void init(Glib::ustring const &prefs_path, bool mask, Glib::ustring const &default_string)
Gtk::Button * relatedButton
Glib::ustring _default_string
void onRelatedButtonClickedCallback()
void onRelatedEntryChangedCallback()
bool on_mnemonic_activate(bool group_cycling) override
Gtk::Entry * relatedEntry
Glib::ustring _prefs_path
void init(Glib::ustring const &prefs_path, bool mask)
Gtk::Button * relatedButton
void on_changed() override
void init(Glib::ustring const &prefs_path, bool mask)
void on_changed() override
Glib::ustring _prefs_path
void init(Glib::ustring const &prefs_path, int height)
Glib::ustring _prefs_path
To do: update description of desktop.
Gtk::Window const * getToplevel() const
char const * label() const
Gets the author-visible label property for the object or a default if no label is defined.
Editable view implementation.
Virtual base definitions for native file dialogs.
static Glib::ustring const prefs_path
macro for checking gtkmm version
Gtk::Image * sp_get_icon_image(Glib::ustring const &icon_name, int size)
Raw stack of active status messages.
double dist(const Point &a, const Point &b)
void get_start_directory(std::string &start_path, Glib::ustring const &prefs_path, bool try_document_dir)
Set initial directory for dialog given a preference path.
void pack_end(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the end of box.
void pack_start(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the start of box.
@ UNIT_TYPE_DIMENSIONLESS
static void append(std::vector< T > &target, std::vector< T > &&source)
@ HORIZONTAL
The x-dimension (0).
@ VERTICAL
The y-dimension (1).
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
void cairo_move_to(cairo_t *cr, Geom::Point p1)
Singleton class to access the preferences file in a convenient way.