// SPDX-License-Identifier: GPL-2.0-or-later /* * Authors: * Bryce Harrington * Derek P. Moore * buliabyak@gmail.com * * Copyright (C) 2004-2005 Authors * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include "scalar-unit.h" #include "spinbutton.h" using Inkscape::Util::unit_table; namespace Inkscape { namespace UI { namespace Widget { ScalarUnit::ScalarUnit(Glib::ustring const &label, Glib::ustring const &tooltip, UnitType unit_type, Glib::ustring const &suffix, Glib::ustring const &icon, UnitMenu *unit_menu, bool mnemonic) : Scalar(label, tooltip, suffix, icon, mnemonic), _unit_menu(unit_menu), _hundred_percent(0), _absolute_is_increment(false), _percentage_is_increment(false) { if (_unit_menu == nullptr) { _unit_menu = new UnitMenu(); g_assert(_unit_menu); _unit_menu->setUnitType(unit_type); remove(*_widget); Gtk::Box *widget_holder = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 6); widget_holder->pack_start(*_widget, Gtk::PACK_SHRINK); widget_holder->pack_start(*Gtk::manage(_unit_menu), Gtk::PACK_SHRINK); pack_start(*Gtk::manage(widget_holder), Gtk::PACK_SHRINK); } _unit_menu->signal_changed() .connect_notify(sigc::mem_fun(*this, &ScalarUnit::on_unit_changed)); static_cast(_widget)->setUnitMenu(_unit_menu); lastUnits = _unit_menu->getUnitAbbr(); } ScalarUnit::ScalarUnit(Glib::ustring const &label, Glib::ustring const &tooltip, ScalarUnit &take_unitmenu, Glib::ustring const &suffix, Glib::ustring const &icon, bool mnemonic) : Scalar(label, tooltip, suffix, icon, mnemonic), _unit_menu(take_unitmenu._unit_menu), _hundred_percent(0), _absolute_is_increment(false), _percentage_is_increment(false) { _unit_menu->signal_changed() .connect_notify(sigc::mem_fun(*this, &ScalarUnit::on_unit_changed)); static_cast(_widget)->setUnitMenu(_unit_menu); lastUnits = _unit_menu->getUnitAbbr(); } void ScalarUnit::initScalar(double min_value, double max_value) { g_assert(_unit_menu != nullptr); Scalar::setDigits(_unit_menu->getDefaultDigits()); Scalar::setIncrements(_unit_menu->getDefaultStep(), _unit_menu->getDefaultPage()); Scalar::setRange(min_value, max_value); } bool ScalarUnit::setUnit(Glib::ustring const &unit) { g_assert(_unit_menu != nullptr); // First set the unit if (!_unit_menu->setUnit(unit)) { return false; } lastUnits = unit; return true; } void ScalarUnit::setUnitType(UnitType unit_type) { g_assert(_unit_menu != nullptr); _unit_menu->setUnitType(unit_type); lastUnits = _unit_menu->getUnitAbbr(); } void ScalarUnit::resetUnitType(UnitType unit_type) { g_assert(_unit_menu != nullptr); _unit_menu->resetUnitType(unit_type); lastUnits = _unit_menu->getUnitAbbr(); } Unit const * ScalarUnit::getUnit() const { g_assert(_unit_menu != nullptr); return _unit_menu->getUnit(); } UnitType ScalarUnit::getUnitType() const { g_assert(_unit_menu); return _unit_menu->getUnitType(); } void ScalarUnit::setValue(double number, Glib::ustring const &units) { g_assert(_unit_menu != nullptr); _unit_menu->setUnit(units); Scalar::setValue(number); } void ScalarUnit::setValueKeepUnit(double number, Glib::ustring const &units) { g_assert(_unit_menu != nullptr); if (units == "") { // set the value in the default units Scalar::setValue(number); } else { double conversion = _unit_menu->getConversion(units); Scalar::setValue(number / conversion); } } void ScalarUnit::setValue(double number) { Scalar::setValue(number); } double ScalarUnit::getValue(Glib::ustring const &unit_name) const { g_assert(_unit_menu != nullptr); if (unit_name == "") { // Return the value in the default units return Scalar::getValue(); } else { double conversion = _unit_menu->getConversion(unit_name); return conversion * Scalar::getValue(); } } void ScalarUnit::grabFocusAndSelectEntry() { _widget->grab_focus(); static_cast(_widget)->select_region(0, 20); } void ScalarUnit::setAlignment(double xalign) { xalign = std::clamp(xalign,0.0,1.0); static_cast(_widget)->set_alignment(xalign); } void ScalarUnit::setHundredPercent(double number) { _hundred_percent = number; } void ScalarUnit::setAbsoluteIsIncrement(bool value) { _absolute_is_increment = value; } void ScalarUnit::setPercentageIsIncrement(bool value) { _percentage_is_increment = value; } double ScalarUnit::PercentageToAbsolute(double value) { // convert from percent to absolute double convertedVal = 0; double hundred_converted = _hundred_percent / _unit_menu->getConversion("px"); // _hundred_percent is in px if (_percentage_is_increment) value += 100; convertedVal = 0.01 * hundred_converted * value; if (_absolute_is_increment) convertedVal -= hundred_converted; return convertedVal; } double ScalarUnit::AbsoluteToPercentage(double value) { double convertedVal = 0; // convert from absolute to percent if (_hundred_percent == 0) { if (_percentage_is_increment) convertedVal = 0; else convertedVal = 100; } else { double hundred_converted = _hundred_percent / _unit_menu->getConversion("px", lastUnits); // _hundred_percent is in px if (_absolute_is_increment) value += hundred_converted; convertedVal = 100 * value / hundred_converted; if (_percentage_is_increment) convertedVal -= 100; } return convertedVal; } double ScalarUnit::getAsPercentage() { double convertedVal = AbsoluteToPercentage(Scalar::getValue()); return convertedVal; } void ScalarUnit::setFromPercentage(double value) { double absolute = PercentageToAbsolute(value); Scalar::setValue(absolute); } void ScalarUnit::on_unit_changed() { g_assert(_unit_menu != nullptr); Glib::ustring abbr = _unit_menu->getUnitAbbr(); if (_suffix) { _suffix->set_label(abbr); } Inkscape::Util::Unit const *new_unit = unit_table.getUnit(abbr); Inkscape::Util::Unit const *old_unit = unit_table.getUnit(lastUnits); double convertedVal = 0; if (old_unit->type == UNIT_TYPE_DIMENSIONLESS && new_unit->type == UNIT_TYPE_LINEAR) { convertedVal = PercentageToAbsolute(Scalar::getValue()); } else if (old_unit->type == UNIT_TYPE_LINEAR && new_unit->type == UNIT_TYPE_DIMENSIONLESS) { convertedVal = AbsoluteToPercentage(Scalar::getValue()); } else { double conversion = _unit_menu->getConversion(lastUnits); convertedVal = Scalar::getValue() / conversion; } Scalar::setValue(convertedVal); lastUnits = abbr; } } // namespace Widget } // namespace UI } // namespace Inkscape /* 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 :