From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/ui/widget/combo-tool-item.cpp | 290 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 src/ui/widget/combo-tool-item.cpp (limited to 'src/ui/widget/combo-tool-item.cpp') diff --git a/src/ui/widget/combo-tool-item.cpp b/src/ui/widget/combo-tool-item.cpp new file mode 100644 index 0000000..ffc7e75 --- /dev/null +++ b/src/ui/widget/combo-tool-item.cpp @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Authors: + * Tavmjong Bah + * + * Copyright (C) 2017 Tavmjong Bah + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + + +/** \file + A combobox that can be displayed in a toolbar. +*/ + +#include "combo-tool-item.h" +#include "preferences.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +ComboToolItem* +ComboToolItem::create(const Glib::ustring &group_label, + const Glib::ustring &tooltip, + const Glib::ustring &stock_id, + Glib::RefPtr store, + bool has_entry) +{ + return new ComboToolItem(group_label, tooltip, stock_id, store, has_entry); +} + +ComboToolItem::ComboToolItem(Glib::ustring group_label, + Glib::ustring tooltip, + Glib::ustring stock_id, + Glib::RefPtr store, + bool has_entry) : + _active(-1), + _group_label(std::move( group_label )), + _tooltip(std::move( tooltip )), + _stock_id(std::move( stock_id )), + _store (std::move(store)), + _use_label (true), + _use_icon (false), + _use_pixbuf (true), + _icon_size ( Gtk::ICON_SIZE_LARGE_TOOLBAR ), + _combobox (nullptr), + _group_label_widget(nullptr), + _container(Gtk::manage(new Gtk::Box())), + _menuitem (nullptr) +{ + add(*_container); + _container->set_spacing(3); + + // ": " is added to the group label later + if (!_group_label.empty()) { + // we don't expect trailing spaces + // g_assert(_group_label.raw()[_group_label.raw().size() - 1] != ' '); + + // strip space (note: raw() indexing is much cheaper on Glib::ustring) + if (_group_label.raw()[_group_label.raw().size() - 1] == ' ') { + _group_label.resize(_group_label.size() - 1); + } + } + if (!_group_label.empty()) { + // we don't expect a trailing colon + // g_assert(_group_label.raw()[_group_label.raw().size() - 1] != ':'); + + // strip colon (note: raw() indexing is much cheaper on Glib::ustring) + if (_group_label.raw()[_group_label.raw().size() - 1] == ':') { + _group_label.resize(_group_label.size() - 1); + } + } + + + // Create combobox + _combobox = Gtk::manage (new Gtk::ComboBox(has_entry)); + _combobox->set_model(_store); + + populate_combobox(); + + _combobox->signal_changed().connect( + sigc::mem_fun(*this, &ComboToolItem::on_changed_combobox)); + _container->pack_start(*_combobox); + + show_all(); +} + +void +ComboToolItem::focus_on_click( bool focus_on_click ) +{ + _combobox->set_focus_on_click(focus_on_click); +} + + +void +ComboToolItem::use_label(bool use_label) +{ + _use_label = use_label; + populate_combobox(); +} + +void +ComboToolItem::use_icon(bool use_icon) +{ + _use_icon = use_icon; + populate_combobox(); +} + +void +ComboToolItem::use_pixbuf(bool use_pixbuf) +{ + _use_pixbuf = use_pixbuf; + populate_combobox(); +} + +void +ComboToolItem::use_group_label(bool use_group_label) +{ + if (use_group_label == (_group_label_widget != nullptr)) { + return; + } + if (use_group_label) { + _container->remove(*_combobox); + _group_label_widget = Gtk::manage(new Gtk::Label(_group_label + ": ")); + _container->pack_start(*_group_label_widget); + _container->pack_start(*_combobox); + } else { + _container->remove(*_group_label_widget); + delete _group_label_widget; + _group_label_widget = nullptr; + } +} + +void +ComboToolItem::populate_combobox() +{ + _combobox->clear(); + + ComboToolItemColumns columns; + if (_use_icon) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/theme/symbolicIcons", false)) { + auto children = _store->children(); + for (auto row : children) { + Glib::ustring icon = row[columns.col_icon]; + gint pos = icon.find("-symbolic"); + if (pos == std::string::npos) { + icon += "-symbolic"; + } + row[columns.col_icon] = icon; + } + } + Gtk::CellRendererPixbuf *renderer = new Gtk::CellRendererPixbuf; + renderer->set_property ("stock_size", Gtk::ICON_SIZE_LARGE_TOOLBAR); + _combobox->pack_start (*Gtk::manage(renderer), false); + _combobox->add_attribute (*renderer, "icon_name", columns.col_icon ); + } else if (_use_pixbuf) { + Gtk::CellRendererPixbuf *renderer = new Gtk::CellRendererPixbuf; + //renderer->set_property ("stock_size", Gtk::ICON_SIZE_LARGE_TOOLBAR); + _combobox->pack_start (*Gtk::manage(renderer), false); + _combobox->add_attribute (*renderer, "pixbuf", columns.col_pixbuf ); + } + + if (_use_label) { + _combobox->pack_start(columns.col_label); + } + + std::vector cells = _combobox->get_cells(); + for (auto & cell : cells) { + _combobox->add_attribute (*cell, "sensitive", columns.col_sensitive); + } + + set_tooltip_text(_tooltip); + _combobox->set_tooltip_text(_tooltip); + _combobox->set_active (_active); +} + +void +ComboToolItem::set_active (gint active) { + if (_active != active) { + + _active = active; + + if (_combobox) { + _combobox->set_active (active); + } + + if (active < _radiomenuitems.size()) { + _radiomenuitems[ active ]->set_active(); + } + } +} + +Glib::ustring +ComboToolItem::get_active_text () { + Gtk::TreeModel::Row row = _store->children()[_active]; + ComboToolItemColumns columns; + Glib::ustring label = row[columns.col_label]; + return label; +} + +bool +ComboToolItem::on_create_menu_proxy() +{ + if (_menuitem == nullptr) { + + _menuitem = Gtk::manage (new Gtk::MenuItem(_group_label)); + Gtk::Menu *menu = Gtk::manage (new Gtk::Menu); + + Gtk::RadioButton::Group group; + int index = 0; + auto children = _store->children(); + for (auto row : children) { + ComboToolItemColumns columns; + Glib::ustring label = row[columns.col_label ]; + Glib::ustring icon = row[columns.col_icon ]; + Glib::ustring tooltip = row[columns.col_tooltip ]; + bool sensitive = row[columns.col_sensitive ]; + + Gtk::RadioMenuItem* button = Gtk::manage(new Gtk::RadioMenuItem(group)); + button->set_label (label); + button->set_tooltip_text( tooltip ); + button->set_sensitive( sensitive ); + + button->signal_toggled().connect( sigc::bind<0>( + sigc::mem_fun(*this, &ComboToolItem::on_toggled_radiomenu), index++) + ); + + menu->add (*button); + + _radiomenuitems.push_back( button ); + } + + if ( _active < _radiomenuitems.size()) { + _radiomenuitems[ _active ]->set_active(); + } + + _menuitem->set_submenu (*menu); + _menuitem->show_all(); + } + + set_proxy_menu_item(_group_label, *_menuitem); + return true; +} + +void +ComboToolItem::on_changed_combobox() { + + int row = _combobox->get_active_row_number(); + set_active( row ); + _changed.emit (_active); + _changed_after.emit (_active); +} + +void +ComboToolItem::on_toggled_radiomenu(int n) { + + // toggled emitted twice, first for button toggled off, second for button toggled on. + // We want to react only to the button turned on. + if ( n < _radiomenuitems.size() &&_radiomenuitems[ n ]->get_active()) { + set_active ( n ); + _changed.emit (_active); + _changed_after.emit (_active); + } +} + +} +} +} +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3