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/dialog/guides.cpp | 369 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 src/ui/dialog/guides.cpp (limited to 'src/ui/dialog/guides.cpp') diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp new file mode 100644 index 0000000..9be41a5 --- /dev/null +++ b/src/ui/dialog/guides.cpp @@ -0,0 +1,369 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * Simple guideline dialog. + */ +/* Authors: + * Lauris Kaplinski + * Andrius R. + * Johan Engelen + * Abhishek Sharma + * + * Copyright (C) 1999-2007 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "guides.h" + +#include + +#include "desktop.h" +#include "document-undo.h" +#include "document.h" +#include "message-context.h" + +#include "include/gtkmm_version.h" + +#include "object/sp-guide.h" +#include "object/sp-namedview.h" + +#include "ui/dialog-events.h" +#include "ui/tools/tool-base.h" +#include "ui/widget/spinbutton.h" + +#include "widgets/desktop-widget.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop) +: _desktop(desktop), _guide(guide), + _locked_toggle(_("Lo_cked")), + _relative_toggle(_("Rela_tive change")), + _spin_button_x(C_("Guides", "_X:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu), + _spin_button_y(C_("Guides", "_Y:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu), + _label_entry(_("_Label:"), _("Optionally give this guideline a name")), + _spin_angle(_("_Angle:"), "", UNIT_TYPE_RADIAL), + _mode(true), _oldpos(0.,0.), _oldangle(0.0) +{ + _locked_toggle.set_use_underline(); + _locked_toggle.set_tooltip_text(_("Lock the movement of guides")); + _relative_toggle.set_use_underline(); + _relative_toggle.set_tooltip_text(_("Move and/or rotate the guide relative to current settings")); +} + +bool GuidelinePropertiesDialog::_relative_toggle_status = false; // initialize relative checkbox status for when this dialog is opened for first time +Glib::ustring GuidelinePropertiesDialog::_angle_unit_status = DEG; // initialize angle unit status + +GuidelinePropertiesDialog::~GuidelinePropertiesDialog() { + // save current status + _relative_toggle_status = _relative_toggle.get_active(); + _angle_unit_status = _spin_angle.getUnit()->abbr; +} + +void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) { + GuidelinePropertiesDialog dialog(guide, desktop); + dialog._setup(); + dialog.run(); +} + +void GuidelinePropertiesDialog::_modeChanged() +{ + _mode = !_relative_toggle.get_active(); + if (!_mode) { + // relative + _spin_angle.setValue(0); + + _spin_button_y.setValue(0); + _spin_button_x.setValue(0); + } else { + // absolute + _spin_angle.setValueKeepUnit(_oldangle, DEG); + + _spin_button_x.setValueKeepUnit(_oldpos[Geom::X], "px"); + _spin_button_y.setValueKeepUnit(_oldpos[Geom::Y], "px"); + } +} + +void GuidelinePropertiesDialog::_onOK() +{ + this->_onOKimpl(); + DocumentUndo::done(_guide->document, _("Set guide properties"), ""); + +} + +void GuidelinePropertiesDialog::_onOKimpl() +{ + double deg_angle = _spin_angle.getValue(DEG); + if (!_mode) + deg_angle += _oldangle; + Geom::Point normal; + if ( deg_angle == 90. || deg_angle == 270. || deg_angle == -90. || deg_angle == -270.) { + normal = Geom::Point(1.,0.); + } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) { + normal = Geom::Point(0.,1.); + } else { + double rad_angle = Geom::rad_from_deg( deg_angle ); + normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); + } + //To allow reposition from dialog + _guide->set_locked(false, false); + + _guide->set_normal(normal, true); + + double const points_x = _spin_button_x.getValue("px"); + double const points_y = _spin_button_y.getValue("px"); + Geom::Point newpos(points_x, points_y); + if (!_mode) + newpos += _oldpos; + + _guide->moveto(newpos, true); + + const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() ); + + _guide->set_label(name, true); + + const bool locked = _locked_toggle.get_active(); + + _guide->set_locked(locked, true); + + g_free((gpointer) name); + + const auto c = _color.get_rgba(); + unsigned r = c.get_red_u()/257, g = c.get_green_u()/257, b = c.get_blue_u()/257; + //TODO: why 257? verify this! + // don't know why, but introduced: 761f7da58cd6d625b88c24eee6fae1b7fa3bfcdd + + _guide->set_color(r, g, b, true); +} + +void GuidelinePropertiesDialog::_onDelete() +{ + SPDocument *doc = _guide->document; + if (_guide->remove(true)) + DocumentUndo::done(doc, _("Delete guide"), ""); +} + +void GuidelinePropertiesDialog::_onDuplicate() +{ + _guide = _guide->duplicate(); + this->_onOKimpl(); + DocumentUndo::done(_guide->document, _("Duplicate guide"), ""); +} + +void GuidelinePropertiesDialog::_response(gint response) +{ + switch (response) { + case Gtk::RESPONSE_OK: + _onOK(); + break; + case -12: + _onDelete(); + break; + case -13: + _onDuplicate(); + break; + case Gtk::RESPONSE_CANCEL: + break; + case Gtk::RESPONSE_DELETE_EVENT: + break; + default: + g_assert_not_reached(); + } +} + +void GuidelinePropertiesDialog::_setup() { + set_title(_("Guideline")); + add_button(_("_OK"), Gtk::RESPONSE_OK); + add_button(_("_Duplicate"), -13); + add_button(_("_Delete"), -12); + add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL); + + auto mainVBox = get_content_area(); + _layout_table.set_row_spacing(4); + _layout_table.set_column_spacing(4); + _layout_table.set_border_width(4); + + mainVBox->pack_start(_layout_table, false, false, 0); + + _label_name.set_label("foo0"); + _label_name.set_halign(Gtk::ALIGN_START); + _label_name.set_valign(Gtk::ALIGN_CENTER); + + _label_descr.set_label("foo1"); + _label_descr.set_halign(Gtk::ALIGN_START); + _label_descr.set_valign(Gtk::ALIGN_CENTER); + + _label_name.set_halign(Gtk::ALIGN_FILL); + _label_name.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_label_name, 0, 0, 3, 1); + + _label_descr.set_halign(Gtk::ALIGN_FILL); + _label_descr.set_valign(Gtk::ALIGN_FILL); + _layout_table.attach(_label_descr, 0, 1, 3, 1); + + _label_entry.set_halign(Gtk::ALIGN_FILL); + _label_entry.set_valign(Gtk::ALIGN_FILL); + _label_entry.set_hexpand(); + _layout_table.attach(_label_entry, 1, 2, 2, 1); + + _color.set_halign(Gtk::ALIGN_FILL); + _color.set_valign(Gtk::ALIGN_FILL); + _color.set_hexpand(); + _color.set_margin_end(6); + _layout_table.attach(_color, 1, 3, 2, 1); + + // unitmenus + /* fixme: We should allow percents here too, as percents of the canvas size */ + _unit_menu.setUnitType(UNIT_TYPE_LINEAR); + _unit_menu.setUnit("px"); + if (_desktop->namedview->display_units) { + _unit_menu.setUnit( _desktop->namedview->display_units->abbr ); + } + _spin_angle.setUnit(_angle_unit_status); + + // position spinbuttons + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + size_t minimumexponent = std::min(std::abs(prefs->getInt("/options/svgoutput/minimumexponent", -8)), 5); //we limit to 5 to minimize rounding errors + _spin_button_x.setDigits(minimumexponent); + _spin_button_x.setAlignment(1.0); + _spin_button_x.setIncrements(1.0, 10.0); + _spin_button_x.setRange(-1e6, 1e6); + _spin_button_y.setDigits(minimumexponent); + + _spin_button_y.setAlignment(1.0); + _spin_button_y.setIncrements(1.0, 10.0); + _spin_button_y.setRange(-1e6, 1e6); + + _spin_button_x.set_halign(Gtk::ALIGN_FILL); + _spin_button_x.set_valign(Gtk::ALIGN_FILL); + _spin_button_x.set_hexpand(); + _layout_table.attach(_spin_button_x, 1, 4, 1, 1); + + _spin_button_y.set_halign(Gtk::ALIGN_FILL); + _spin_button_y.set_valign(Gtk::ALIGN_FILL); + _spin_button_y.set_hexpand(); + _layout_table.attach(_spin_button_y, 1, 5, 1, 1); + + _unit_menu.set_halign(Gtk::ALIGN_FILL); + _unit_menu.set_valign(Gtk::ALIGN_FILL); + _unit_menu.set_margin_end(6); + _layout_table.attach(_unit_menu, 2, 4, 1, 1); + + // angle spinbutton + _spin_angle.setDigits(3); + _spin_angle.setDigits(minimumexponent); + _spin_angle.setAlignment(1.0); + _spin_angle.setIncrements(1.0, 10.0); + _spin_angle.setRange(-3600., 3600.); + + _spin_angle.set_halign(Gtk::ALIGN_FILL); + _spin_angle.set_valign(Gtk::ALIGN_FILL); + _spin_angle.set_hexpand(); + _layout_table.attach(_spin_angle, 1, 6, 2, 1); + + // mode radio button + _relative_toggle.set_halign(Gtk::ALIGN_FILL); + _relative_toggle.set_valign(Gtk::ALIGN_FILL); + _relative_toggle.set_hexpand(); + _relative_toggle.set_margin_start(6); + _layout_table.attach(_relative_toggle, 1, 7, 2, 1); + + // locked radio button + _locked_toggle.set_halign(Gtk::ALIGN_FILL); + _locked_toggle.set_valign(Gtk::ALIGN_FILL); + _locked_toggle.set_hexpand(); + _locked_toggle.set_margin_start(6); + _layout_table.attach(_locked_toggle, 1, 8, 2, 1); + + _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged)); + _relative_toggle.set_active(_relative_toggle_status); + + bool global_guides_lock = _desktop->namedview->getLockGuides(); + if(global_guides_lock){ + _locked_toggle.set_sensitive(false); + } + _locked_toggle.set_active(_guide->getLocked()); + + // This results in the dialog closing when entering a value in one of the spinbuttons and pressing enter (see LP bug 484187) + auto sbx = dynamic_cast(_spin_button_x.getWidget()); + auto sby = dynamic_cast(_spin_button_y.getWidget()); + auto sba = dynamic_cast(_spin_button_y.getWidget()); + + if(sbx) sbx->signal_activate().connect(sigc::mem_fun(this, &GuidelinePropertiesDialog::on_sb_activate)); + if(sby) sby->signal_activate().connect(sigc::mem_fun(this, &GuidelinePropertiesDialog::on_sb_activate)); + if(sba) sba->signal_activate().connect(sigc::mem_fun(this, &GuidelinePropertiesDialog::on_sb_activate)); + + // dialog + set_default_response(Gtk::RESPONSE_OK); + signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response)); + + // initialize dialog + _oldpos = _guide->getPoint(); + if (_guide->isVertical()) { + _oldangle = 90; + } else if (_guide->isHorizontal()) { + _oldangle = 0; + } else { + _oldangle = Geom::deg_from_rad( std::atan2( - _guide->getNormal()[Geom::X], _guide->getNormal()[Geom::Y] ) ); + } + + { + gchar *label = g_strdup_printf(_("Guideline ID: %s"), _guide->getId()); + _label_name.set_label(label); + g_free(label); + } + { + gchar *guide_description = _guide->description(false); + gchar *label = g_strdup_printf(_("Current: %s"), guide_description); + g_free(guide_description); + _label_descr.set_markup(label); + g_free(label); + } + + // init name entry + _label_entry.getEntry()->set_text(_guide->getLabel() ? _guide->getLabel() : ""); + + Gdk::RGBA c; + c.set_rgba(((_guide->getColor()>>24)&0xff) / 255.0, ((_guide->getColor()>>16)&0xff) / 255.0, ((_guide->getColor()>>8)&0xff) / 255.0); + _color.set_rgba(c); + + _modeChanged(); // sets values of spinboxes. + + if ( _oldangle == 90. || _oldangle == 270. || _oldangle == -90. || _oldangle == -270.) { + _spin_button_x.grabFocusAndSelectEntry(); + } else if ( _oldangle == 0. || _oldangle == 180. || _oldangle == -180.) { + _spin_button_y.grabFocusAndSelectEntry(); + } else { + _spin_angle.grabFocusAndSelectEntry(); + } + + set_position(Gtk::WIN_POS_MOUSE); + + show_all_children(); + set_modal(true); + _desktop->setWindowTransient (gobj()); + property_destroy_with_parent() = true; +} + +void +GuidelinePropertiesDialog::on_sb_activate() +{ + activate_default(); +} +} +} +} + +/* + 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