Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
combo-enums.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Authors:
4 * Nicholas Bishop <nicholasbishop@gmail.com>
5 * Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
6 *
7 * Copyright (C) 2007 Authors
8 *
9 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
10 */
11
12#ifndef INKSCAPE_UI_WIDGET_COMBO_ENUMS_H
13#define INKSCAPE_UI_WIDGET_COMBO_ENUMS_H
14
15#include <glibmm/i18n.h>
16#include <glibmm/refptr.h>
17#include <glibmm/ustring.h>
18#include <gtkmm/liststore.h>
19#include <gtkmm/stringlist.h>
20#include <gtkmm/stringobject.h>
21#include <gtkmm/treemodel.h>
22
23#include "attr-widget.h"
24// #include "template-list.h"
26#include "ui/widget/labelled.h"
27#include "util/enums.h"
28
29namespace Inkscape::UI::Widget {
30
34template <typename E> class ComboBoxEnum
35 : public DropDownList
36 , public AttrWidget
37{
38public:
39 [[nodiscard]] ComboBoxEnum(E const default_value, const Util::EnumDataConverter<E>& c,
40 SPAttr const a = SPAttr::INVALID, bool const sort = true,
41 const char* translation_context = nullptr)
42 : ComboBoxEnum{c, a, sort, translation_context, static_cast<unsigned>(default_value)}
43 {
44 set_active_by_id(default_value);
45 }
46
48 SPAttr const a = SPAttr::INVALID, bool const sort = true,
49 const char * const translation_context = nullptr)
50 : ComboBoxEnum{c, a, sort, translation_context, 0u}
51 {
52 set_active(0);
53 }
54
55 void set_active(unsigned int pos) {
56 set_selected(pos);
57 }
58
59 unsigned int get_active() const {
60 return get_selected();
61 }
62
63private:
64 struct Data {
65 E id;
66 Glib::ustring label;
67 Glib::ustring key;
68 bool separator = false;
69 };
70 std::vector<Data> _enums;
71
73 SPAttr const a, bool const sort,
74 const char * const translation_context,
75 unsigned const default_value)
76 : AttrWidget(a, default_value)
77 , setProgrammatically(false)
78 , _converter(c) {
79
80 property_selected().signal_changed().connect(signal_attr_changed().make_slot());
81
82 _enums.reserve(_converter._length);
83 bool separator = false;
84
85 for (unsigned int i = 0; i < _converter._length; ++i) {
86 const auto& data = _converter.data(i);
87 if (data.key == "-") {
88 separator = true;
89 continue;
90 }
91
92 Glib::ustring translated = translation_context ?
93 g_dpgettext2(nullptr, translation_context, data.label.c_str()) :
94 gettext(data.label.c_str());
95 _enums.push_back(Data{data.id, translated, data.key, separator});
96 separator = false;
97 }
98
99 if (sort) {
100 std::sort(begin(_enums), end(_enums), [](const auto& a, const auto& b){ return a.label < b.label; });
101 }
102
103 set_row_separator_func([this](unsigned int pos){
104 return pos < _enums.size() && _enums[pos].separator;
105 });
106
107 for (auto& el : _enums) {
108 append(el.label);
109 }
110 }
111
112public:
113 [[nodiscard]] Glib::ustring get_as_attribute() const final
114 {
115 auto pos = get_selected();
116 if (pos < _enums.size()) {
117 return _enums[pos].key;
118 }
119 return {};
120 }
121
122 void set_from_attribute(SPObject * const o) final
123 {
124 setProgrammatically = true;
125
126 if (auto const val = attribute_value(o)) {
127 set_active_by_id(_converter.get_id_from_key(val));
128 } else {
129 set_active(get_default()->as_uint());
130 }
131 }
132
133 std::optional<E> get_selected_id() const {
134 auto pos = get_selected();
135 if (pos < _enums.size()) {
136 return _enums[pos].id;
137 }
138 return {};
139 }
140
141 void set_active_by_id(E id) {
142 setProgrammatically = true;
143 auto index = get_active_by_id(id);
144 if (index >= 0) {
146 }
147 };
148
149 void set_active_by_key(const Glib::ustring& key) {
150 setProgrammatically = true;
151 set_active_by_id( _converter.get_id_from_key(key) );
152 };
153
155
156private:
157 [[nodiscard]] int get_active_by_id(E const id) const
158 {
159 auto it = std::find_if(begin(_enums), end(_enums), [id](const auto& el){ return el.id == id; });
160 return it == end(_enums) ? -1 : std::distance(begin(_enums), it);
161 }
162
164};
165
166
170template <typename E> class LabelledComboBoxEnum
171 : public Labelled
172{
173public:
174 [[nodiscard]] LabelledComboBoxEnum(Glib::ustring const &label,
175 Glib::ustring const &tooltip,
177 Glib::ustring const &icon = {},
178 bool const mnemonic = true,
179 bool const sort = true)
180 : Labelled{label, tooltip,
181 Gtk::make_managed<ComboBoxEnum<E>>(c, SPAttr::INVALID, sort),
182 icon, mnemonic}
183 {
184 }
185
187 {
188 return static_cast<ComboBoxEnum<E> *>(getWidget());
189 }
190};
191
192} // namespace Inkscape::UI::Widget
193
194#endif // INKSCAPE_UI_WIDGET_COMBO_ENUMS_H
195
196/*
197 Local Variables:
198 mode:c++
199 c-file-style:"stroustrup"
200 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
201 indent-tabs-mode:nil
202 fill-column:99
203 End:
204*/
205// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
SPAttr
Definition attributes.h:27
@ INVALID
Must have value 0.
DefaultValueHolder * get_default()
const gchar * attribute_value(SPObject *o) const
sigc::signal< void()> & signal_attr_changed()
Simplified management of enumerations in the UI as combobox.
Definition combo-enums.h:37
void set_from_attribute(SPObject *const o) final
ComboBoxEnum(Util::EnumDataConverter< E > const &c, SPAttr const a, bool const sort, const char *const translation_context, unsigned const default_value)
Definition combo-enums.h:72
const Util::EnumDataConverter< E > & _converter
unsigned int get_active() const
Definition combo-enums.h:59
ComboBoxEnum(Util::EnumDataConverter< E > const &c, SPAttr const a=SPAttr::INVALID, bool const sort=true, const char *const translation_context=nullptr)
Definition combo-enums.h:47
std::optional< E > get_selected_id() const
void set_active(unsigned int pos)
Definition combo-enums.h:55
ComboBoxEnum(E const default_value, const Util::EnumDataConverter< E > &c, SPAttr const a=SPAttr::INVALID, bool const sort=true, const char *translation_context=nullptr)
Definition combo-enums.h:39
int get_active_by_id(E const id) const
Glib::ustring get_as_attribute() const final
void set_active_by_key(const Glib::ustring &key)
unsigned int append(const Glib::ustring &item)
void set_row_separator_func(std::function< bool(unsigned int)> callback)
Simplified management of enumerations in the UI as combobox, plus the functionality of Labelled.
LabelledComboBoxEnum(Glib::ustring const &label, Glib::ustring const &tooltip, Util::EnumDataConverter< E > const &c, Glib::ustring const &icon={}, bool const mnemonic=true, bool const sort=true)
Adds a label with optional icon to another widget.
Definition labelled.h:31
Gtk::Widget const * getWidget() const
Definition labelled.h:48
Simplified management of enumerations of svg items with UI labels.
Definition enums.h:42
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
double c[8][4]
Simple DropDown widget presenting popup list of string items to choose from.
Glib::ustring label
Definition desktop.h:50
Custom widgets.
Definition desktop.h:126
static cairo_user_data_key_t key
static const Point data[]
int index