diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:50:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:50:49 +0000 |
commit | c853ffb5b2f75f5a889ed2e3ef89b818a736e87a (patch) | |
tree | 7d13a0883bb7936b84d6ecdd7bc332b41ed04bee /src/ui/toolbar/select-toolbar.cpp | |
parent | Initial commit. (diff) | |
download | inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.tar.xz inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.zip |
Adding upstream version 1.3+ds.upstream/1.3+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/ui/toolbar/select-toolbar.cpp')
-rw-r--r-- | src/ui/toolbar/select-toolbar.cpp | 654 |
1 files changed, 654 insertions, 0 deletions
diff --git a/src/ui/toolbar/select-toolbar.cpp b/src/ui/toolbar/select-toolbar.cpp new file mode 100644 index 0000000..82a421c --- /dev/null +++ b/src/ui/toolbar/select-toolbar.cpp @@ -0,0 +1,654 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Selector aux toolbar + * + * Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * bulia byak <buliabyak@users.sf.net> + * Jon A. Cruz <jon@joncruz.org> + * Abhishek Sharma + * + * Copyright (C) 2003-2005 authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "select-toolbar.h" + +#include <glibmm/i18n.h> + +#include <gtkmm/adjustment.h> +#include <gtkmm/separatortoolitem.h> + +#include <2geom/rect.h> + +#include "desktop.h" +#include "document-undo.h" +#include "document.h" +#include "selection.h" +#include "message-stack.h" +#include "selection-chemistry.h" + +#include "object/sp-item-transform.h" +#include "object/sp-namedview.h" + +#include "page-manager.h" + +#include "ui/icon-names.h" +#include "ui/widget/canvas.h" // Focus widget +#include "ui/widget/combo-tool-item.h" +#include "ui/widget/spin-button-tool-item.h" +#include "ui/widget/spinbutton.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/widget-sizes.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::DocumentUndo; +using Inkscape::Util::unit_table; + +namespace Inkscape { +namespace UI { +namespace Toolbar { + +SelectToolbar::SelectToolbar(SPDesktop *desktop) : + Toolbar(desktop), + _tracker(new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR)), + _lock_btn(Gtk::manage(new Gtk::ToggleToolButton())), + _select_touch_btn(Gtk::manage(new Gtk::ToggleToolButton())), + _transform_stroke_btn(Gtk::manage(new Gtk::ToggleToolButton())), + _transform_corners_btn(Gtk::manage(new Gtk::ToggleToolButton())), + _transform_gradient_btn(Gtk::manage(new Gtk::ToggleToolButton())), + _transform_pattern_btn(Gtk::manage(new Gtk::ToggleToolButton())), + _update(false), + _action_prefix("selector:toolbar:") +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Select Al_l"))); + button->set_tooltip_text(N_("Select all objects")); + button->set_icon_name(INKSCAPE_ICON("edit-select-all")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "win.select-all"); + add(*button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Select All in All La_yers"))); + button->set_tooltip_text(N_("Select all objects in all visible and unlocked layers")); + button->set_icon_name(INKSCAPE_ICON("edit-select-all-layers")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "win.select-all-layers"); + add(*button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("D_eselect"))); + button->set_tooltip_text(N_("Deselect any selected objects")); + button->set_icon_name(INKSCAPE_ICON("edit-select-none")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "win.select-none"); + add(*button); + _context_items.push_back(button); + } + + _select_touch_btn->set_label(_("Select by touch")); + _select_touch_btn->set_tooltip_text(_("Toggle selection box to select all touched objects.")); + _select_touch_btn->set_icon_name(INKSCAPE_ICON("selection-touch")); + _select_touch_btn->set_active(prefs->getBool("/tools/select/touch_box", false)); + _select_touch_btn->signal_toggled().connect(sigc::mem_fun(*this, &SelectToolbar::toggle_touch)); + + add(*_select_touch_btn); + + add(* Gtk::manage(new Gtk::SeparatorToolItem())); + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Rotate _90\xc2\xb0 CCW"))); + button->set_tooltip_text(N_("Rotate selection 90\xc2\xb0 counter-clockwise")); + button->set_icon_name(INKSCAPE_ICON("object-rotate-left")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.object-rotate-90-ccw"); + add(*button); + _context_items.push_back(button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Rotate _90\xc2\xb0 CW"))); + button->set_tooltip_text(N_("Rotate selection 90\xc2\xb0 clockwise")); + button->set_icon_name(INKSCAPE_ICON("object-rotate-right")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.object-rotate-90-cw"); + add(*button); + _context_items.push_back(button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Flip _Horizontal"))); + button->set_tooltip_text(N_("Flip selected objects horizontally")); + button->set_icon_name(INKSCAPE_ICON("object-flip-horizontal")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.object-flip-horizontal"); + add(*button); + _context_items.push_back(button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Flip _Vertical"))); + button->set_tooltip_text(N_("Flip selected objects vertically")); + button->set_icon_name(INKSCAPE_ICON("object-flip-vertical")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.object-flip-vertical"); + add(*button); + _context_items.push_back(button); + } + + add(* Gtk::manage(new Gtk::SeparatorToolItem())); + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Raise to _Top"))); + button->set_tooltip_text(N_("Raise selection to top")); + button->set_icon_name(INKSCAPE_ICON("selection-top")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.selection-top"); + add(*button); + _context_items.push_back(button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("_Raise"))); + button->set_tooltip_text(N_("Raise selection one step")); + button->set_icon_name(INKSCAPE_ICON("selection-raise")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.selection-raise"); + add(*button); + _context_items.push_back(button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("_Lower"))); + button->set_tooltip_text(N_("Lower selection one step")); + button->set_icon_name(INKSCAPE_ICON("selection-lower")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.selection-lower"); + add(*button); + _context_items.push_back(button); + } + + { + auto button = Gtk::manage(new Gtk::ToolButton(N_("Lower to _Bottom"))); + button->set_tooltip_text(N_("Lower selection to bottom")); + button->set_icon_name(INKSCAPE_ICON("selection-bottom")); + // Must use C API until GTK4 + gtk_actionable_set_action_name(GTK_ACTIONABLE(button->gobj()), "app.selection-bottom"); + add(*button); + _context_items.push_back(button); + } + + add(* Gtk::manage(new Gtk::SeparatorToolItem())); + + _tracker->addUnit(unit_table.getUnit("%")); + _tracker->setActiveUnit( desktop->getNamedView()->display_units ); + + // x-value control + auto x_val = prefs->getDouble("/tools/select/X", 0.0); + _adj_x = Gtk::Adjustment::create(x_val, -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP); + _adj_x->signal_value_changed().connect(sigc::bind(sigc::mem_fun(*this, &SelectToolbar::any_value_changed), _adj_x)); + _tracker->addAdjustment(_adj_x->gobj()); + + auto x_btn = Gtk::manage(new UI::Widget::SpinButtonToolItem("select-x", + C_("Select toolbar", "X:"), + _adj_x, + SPIN_STEP, 3)); + x_btn->get_spin_button()->addUnitTracker(_tracker.get()); + x_btn->set_focus_widget(_desktop->getCanvas()); + x_btn->set_all_tooltip_text(C_("Select toolbar", "Horizontal coordinate of selection")); + _context_items.push_back(x_btn); + add(*x_btn); + + // y-value control + auto y_val = prefs->getDouble("/tools/select/Y", 0.0); + _adj_y = Gtk::Adjustment::create(y_val, -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP); + _adj_y->signal_value_changed().connect(sigc::bind(sigc::mem_fun(*this, &SelectToolbar::any_value_changed), _adj_y)); + _tracker->addAdjustment(_adj_y->gobj()); + + auto y_btn = Gtk::manage(new UI::Widget::SpinButtonToolItem("select-y", + C_("Select toolbar", "Y:"), + _adj_y, + SPIN_STEP, 3)); + y_btn->get_spin_button()->addUnitTracker(_tracker.get()); + y_btn->set_focus_widget(_desktop->getCanvas()); + y_btn->set_all_tooltip_text(C_("Select toolbar", "Vertical coordinate of selection")); + _context_items.push_back(y_btn); + add(*y_btn); + + // width-value control + auto w_val = prefs->getDouble("/tools/select/width", 0.0); + _adj_w = Gtk::Adjustment::create(w_val, 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP); + _adj_w->signal_value_changed().connect(sigc::bind(sigc::mem_fun(*this, &SelectToolbar::any_value_changed), _adj_w)); + _tracker->addAdjustment(_adj_w->gobj()); + + auto w_btn = Gtk::manage(new UI::Widget::SpinButtonToolItem("select-width", + C_("Select toolbar", "W:"), + _adj_w, + SPIN_STEP, 3)); + w_btn->get_spin_button()->addUnitTracker(_tracker.get()); + w_btn->set_focus_widget(_desktop->getCanvas()); + w_btn->set_all_tooltip_text(C_("Select toolbar", "Width of selection")); + _context_items.push_back(w_btn); + add(*w_btn); + + // lock toggle + _lock_btn->set_label(_("Lock width and height")); + _lock_btn->set_tooltip_text(_("When locked, change both width and height by the same proportion")); + _lock_btn->set_icon_name(INKSCAPE_ICON("object-unlocked")); + _lock_btn->signal_toggled().connect(sigc::mem_fun(*this, &SelectToolbar::toggle_lock)); + _lock_btn->set_name("lock"); + add(*_lock_btn); + + // height-value control + auto h_val = prefs->getDouble("/tools/select/height", 0.0); + _adj_h = Gtk::Adjustment::create(h_val, 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP); + _adj_h->signal_value_changed().connect(sigc::bind(sigc::mem_fun(*this, &SelectToolbar::any_value_changed), _adj_h)); + _tracker->addAdjustment(_adj_h->gobj()); + + auto h_btn = Gtk::manage(new UI::Widget::SpinButtonToolItem("select-height", + C_("Select toolbar", "H:"), + _adj_h, + SPIN_STEP, 3)); + h_btn->get_spin_button()->addUnitTracker(_tracker.get()); + h_btn->set_focus_widget(_desktop->getCanvas()); + h_btn->set_all_tooltip_text(C_("Select toolbar", "Height of selection")); + _context_items.push_back(h_btn); + add(*h_btn); + + // units menu + auto unit_menu = _tracker->create_tool_item(_("Units"), ("") ); + add(*unit_menu); + + add(* Gtk::manage(new Gtk::SeparatorToolItem())); + + _transform_stroke_btn->set_label(_("Scale stroke width")); + _transform_stroke_btn->set_tooltip_text(_("When scaling objects, scale the stroke width by the same proportion")); + _transform_stroke_btn->set_icon_name(INKSCAPE_ICON("transform-affect-stroke")); + _transform_stroke_btn->set_active(prefs->getBool("/options/transform/stroke", true)); + _transform_stroke_btn->signal_toggled().connect(sigc::mem_fun(*this, &SelectToolbar::toggle_stroke)); + add(*_transform_stroke_btn); + + _transform_corners_btn->set_label(_("Scale rounded corners")); + _transform_corners_btn->set_tooltip_text(_("When scaling rectangles, scale the radii of rounded corners")); + _transform_corners_btn->set_icon_name(INKSCAPE_ICON("transform-affect-rounded-corners")); + _transform_corners_btn->set_active(prefs->getBool("/options/transform/rectcorners", true)); + _transform_corners_btn->signal_toggled().connect(sigc::mem_fun(*this, &SelectToolbar::toggle_corners)); + add(*_transform_corners_btn); + + _transform_gradient_btn->set_label(_("Move gradients")); + _transform_gradient_btn->set_tooltip_text(_("Move gradients (in fill or stroke) along with the objects")); + _transform_gradient_btn->set_icon_name(INKSCAPE_ICON("transform-affect-gradient")); + _transform_gradient_btn->set_active(prefs->getBool("/options/transform/gradient", true)); + _transform_gradient_btn->signal_toggled().connect(sigc::mem_fun(*this, &SelectToolbar::toggle_gradient)); + add(*_transform_gradient_btn); + + _transform_pattern_btn->set_label(_("Move patterns")); + _transform_pattern_btn->set_tooltip_text(_("Move patterns (in fill or stroke) along with the objects")); + _transform_pattern_btn->set_icon_name(INKSCAPE_ICON("transform-affect-pattern")); + _transform_pattern_btn->set_active(prefs->getBool("/options/transform/pattern", true)); + _transform_pattern_btn->signal_toggled().connect(sigc::mem_fun(*this, &SelectToolbar::toggle_pattern)); + add(*_transform_pattern_btn); + + assert(desktop); + auto *selection = desktop->getSelection(); + + // Force update when selection changes. + _connections.emplace_back( // + selection->connectModified(sigc::mem_fun(*this, &SelectToolbar::on_inkscape_selection_modified))); + _connections.emplace_back( + selection->connectChanged(sigc::mem_fun(*this, &SelectToolbar::on_inkscape_selection_changed))); + + // Update now. + layout_widget_update(selection); + + for (auto item : _context_items) { + if ( item->is_sensitive() ) { + item->set_sensitive(false); + } + } + + show_all(); +} + +void SelectToolbar::on_unrealize() +{ + for (auto &conn : _connections) { + conn.disconnect(); + } + + parent_type::on_unrealize(); +} + +GtkWidget * +SelectToolbar::create(SPDesktop *desktop) +{ + auto toolbar = new SelectToolbar(desktop); + return GTK_WIDGET(toolbar->gobj()); +} + +void +SelectToolbar::any_value_changed(Glib::RefPtr<Gtk::Adjustment>& adj) +{ + if (_update) { + return; + } + + if ( !_tracker || _tracker->isUpdating() ) { + /* + * When only units are being changed, don't treat changes + * to adjuster values as object changes. + */ + return; + } + _update = true; + + auto prefs = Inkscape::Preferences::get(); + auto selection = _desktop->getSelection(); + auto document = _desktop->getDocument(); + auto &pm = document->getPageManager(); + auto page = pm.getSelectedPageRect(); + auto page_correction = prefs->getBool("/options/origincorrection/page", true); + + document->ensureUpToDate(); + + Geom::OptRect bbox_vis = selection->visualBounds(); + Geom::OptRect bbox_geom = selection->geometricBounds(); + Geom::OptRect bbox_user = selection->preferredBounds(); + + if ( !bbox_user ) { + _update = false; + return; + } + + Unit const *unit = _tracker->getActiveUnit(); + g_return_if_fail(unit != nullptr); + + gdouble old_w = bbox_user->dimensions()[Geom::X]; + gdouble old_h = bbox_user->dimensions()[Geom::Y]; + gdouble new_w, new_h, new_x, new_y = 0; + + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + new_w = Quantity::convert(_adj_w->get_value(), unit, "px"); + new_h = Quantity::convert(_adj_h->get_value(), unit, "px"); + new_x = Quantity::convert(_adj_x->get_value(), unit, "px"); + new_y = Quantity::convert(_adj_y->get_value(), unit, "px"); + + } else { + gdouble old_x = bbox_user->min()[Geom::X] + (old_w * selection->anchor_x); + gdouble old_y = bbox_user->min()[Geom::Y] + (old_h * selection->anchor_y); + + // Adjust against selected page, so later correction isn't broken. + if (page_correction) { + old_x -= page.left(); + old_y -= page.top(); + } + + new_x = old_x * (_adj_x->get_value() / 100 / unit->factor); + new_y = old_y * (_adj_y->get_value() / 100 / unit->factor); + new_w = old_w * (_adj_w->get_value() / 100 / unit->factor); + new_h = old_h * (_adj_h->get_value() / 100 / unit->factor); + } + + // Adjust depending on the selected anchor. + gdouble x0 = (new_x - (old_w * selection->anchor_x)) - ((new_w - old_w) * selection->anchor_x); + gdouble y0 = (new_y - (old_h * selection->anchor_y)) - ((new_h - old_h) * selection->anchor_y); + + // Adjust according to the selected page, if needed + if (page_correction) { + x0 += page.left(); + y0 += page.top(); + } + + gdouble x1 = x0 + new_w; + gdouble xrel = new_w / old_w; + gdouble y1 = y0 + new_h; + gdouble yrel = new_h / old_h; + + // Keep proportions if lock is on + if ( _lock_btn->get_active() ) { + if (adj == _adj_h) { + x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; + } else if (adj == _adj_w) { + y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y]; + } + } + + // scales and moves, in px + double mh = fabs(x0 - bbox_user->min()[Geom::X]); + double sh = fabs(x1 - bbox_user->max()[Geom::X]); + double mv = fabs(y0 - bbox_user->min()[Geom::Y]); + double sv = fabs(y1 - bbox_user->max()[Geom::Y]); + + // unless the unit is %, convert the scales and moves to the unit + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + mh = Quantity::convert(mh, "px", unit); + sh = Quantity::convert(sh, "px", unit); + mv = Quantity::convert(mv, "px", unit); + sv = Quantity::convert(sv, "px", unit); + } + + char const *const actionkey = get_action_key(mh, sh, mv, sv); + + if (actionkey != nullptr) { + + bool transform_stroke = prefs->getBool("/options/transform/stroke", true); + bool preserve = prefs->getBool("/options/preservetransform/value", false); + + Geom::Affine scaler; + if (prefs->getInt("/tools/bounding_box") == 0) { // SPItem::VISUAL_BBOX + scaler = get_scale_transform_for_variable_stroke (*bbox_vis, *bbox_geom, transform_stroke, preserve, x0, y0, x1, y1); + } else { + // 1) We could have use the newer get_scale_transform_for_variable_stroke() here, but to avoid regressions + // we'll just use the old get_scale_transform_for_uniform_stroke() for now. + // 2) get_scale_transform_for_uniform_stroke() is intended for visual bounding boxes, not geometrical ones! + // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero + scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, 0, false, false, x0, y0, x1, y1); + } + + selection->applyAffine(scaler); + DocumentUndo::maybeDone(document, actionkey, _("Transform by toolbar"), INKSCAPE_ICON("tool-pointer")); + } + + _update = false; +} + +void +SelectToolbar::layout_widget_update(Inkscape::Selection *sel) +{ + if (_update) { + return; + } + + _update = true; + using Geom::X; + using Geom::Y; + if ( sel && !sel->isEmpty() ) { + Geom::OptRect const bbox(sel->preferredBounds()); + if ( bbox ) { + Unit const *unit = _tracker->getActiveUnit(); + g_return_if_fail(unit != nullptr); + + auto width = bbox->dimensions()[X]; + auto height = bbox->dimensions()[Y]; + auto x = bbox->min()[X] + (width * sel->anchor_x); + auto y = bbox->min()[Y] + (height * sel->anchor_y); + + auto prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/options/origincorrection/page", true)) { + auto &pm = _desktop->getDocument()->getPageManager(); + auto page = pm.getSelectedPageRect(); + x -= page.left(); + y -= page.top(); + } + + if (unit->type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) { + double const val = unit->factor * 100; + _adj_x->set_value(val); + _adj_y->set_value(val); + _adj_w->set_value(val); + _adj_h->set_value(val); + _tracker->setFullVal( _adj_x->gobj(), x ); + _tracker->setFullVal( _adj_y->gobj(), y ); + _tracker->setFullVal( _adj_w->gobj(), width ); + _tracker->setFullVal( _adj_h->gobj(), height ); + } else { + _adj_x->set_value(Quantity::convert(x, "px", unit)); + _adj_y->set_value(Quantity::convert(y, "px", unit)); + _adj_w->set_value(Quantity::convert(width, "px", unit)); + _adj_h->set_value(Quantity::convert(height, "px", unit)); + } + } + } + + _update = false; +} + +void +SelectToolbar::on_inkscape_selection_modified(Inkscape::Selection *selection, guint flags) +{ + assert(_desktop->getSelection() == selection); + if ((flags & (SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_PARENT_MODIFIED_FLAG | + SP_OBJECT_CHILD_MODIFIED_FLAG ))) + { + layout_widget_update(selection); + } +} + +void +SelectToolbar::on_inkscape_selection_changed(Inkscape::Selection *selection) +{ + assert(_desktop->getSelection() == selection); + { + bool setActive = (selection && !selection->isEmpty()); + + for (auto item : _context_items) { + if ( setActive != item->get_sensitive() ) { + item->set_sensitive(setActive); + } + } + + layout_widget_update(selection); + } +} + +char const *SelectToolbar::get_action_key(double mh, double sh, double mv, double sv) +{ + // do the action only if one of the scales/moves is greater than half the last significant + // digit in the spinbox (currently spinboxes have 3 fractional digits, so that makes 0.0005). If + // the value was changed by the user, the difference will be at least that much; otherwise it's + // just rounding difference between the spinbox value and actual value, so no action is + // performed + double const threshold = 5e-4; + char const *const action = ( mh > threshold ? "move:horizontal:" : + sh > threshold ? "scale:horizontal:" : + mv > threshold ? "move:vertical:" : + sv > threshold ? "scale:vertical:" : nullptr ); + if (!action) { + return nullptr; + } + _action_key = _action_prefix + action; + return _action_key.c_str(); +} + +void +SelectToolbar::toggle_lock() { + // use this roundabout way of changing image to make sure its size is preserved + auto btn = static_cast<Gtk::ToggleButton*>(_lock_btn->get_child()); + auto image = static_cast<Gtk::Image*>(btn->get_child()); + if (!image) { + g_warning("No GTK image in toolbar button 'lock'"); + return; + } + auto size = image->get_pixel_size(); + + if ( _lock_btn->get_active() ) { + image->set_from_icon_name("object-locked", Gtk::ICON_SIZE_BUTTON); + } else { + image->set_from_icon_name("object-unlocked", Gtk::ICON_SIZE_BUTTON); + } + image->set_pixel_size(size); +} + +void +SelectToolbar::toggle_touch() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/select/touch_box", _select_touch_btn->get_active()); +} + +void +SelectToolbar::toggle_stroke() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool active = _transform_stroke_btn->get_active(); + prefs->setBool("/options/transform/stroke", active); + if ( active ) { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>stroke width</b> is <b>scaled</b> when objects are scaled.")); + } else { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>stroke width</b> is <b>not scaled</b> when objects are scaled.")); + } +} + +void +SelectToolbar::toggle_corners() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool active = _transform_corners_btn->get_active(); + prefs->setBool("/options/transform/rectcorners", active); + if ( active ) { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>rounded rectangle corners</b> are <b>scaled</b> when rectangles are scaled.")); + } else { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>rounded rectangle corners</b> are <b>not scaled</b> when rectangles are scaled.")); + } +} + +void +SelectToolbar::toggle_gradient() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool active = _transform_gradient_btn->get_active(); + prefs->setBool("/options/transform/gradient", active); + if ( active ) { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>gradients</b> are <b>transformed</b> along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); + } else { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>gradients</b> remain <b>fixed</b> when objects are transformed (moved, scaled, rotated, or skewed).")); + } +} + +void +SelectToolbar::toggle_pattern() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool active = _transform_pattern_btn->get_active(); + prefs->setInt("/options/transform/pattern", active); + if ( active ) { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>patterns</b> are <b>transformed</b> along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); + } else { + _desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now <b>patterns</b> remain <b>fixed</b> when objects are transformed (moved, scaled, rotated, or skewed).")); + } +} + +} +} +} + +/* + 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 : |