From 9c8d160a5d30ff7682a509f15d61c0d050603584 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 18 Jan 2025 08:09:48 +0530 Subject: [PATCH 1/5] Feature: Add a way to set polygon length using star/polygon tool --- share/ui/object-attributes.glade | 45 +++++++++++++++++ share/ui/toolbar-star.ui | 33 +++++++++++++ src/attributes.cpp | 1 + src/attributes.h | 1 + src/object/sp-star.cpp | 48 +++++++++++++++++- src/object/sp-star.h | 7 +-- src/ui/dialog/object-attributes.cpp | 30 +++++++++++- src/ui/toolbar/star-toolbar.cpp | 75 ++++++++++++++++++++++++++++- src/ui/toolbar/star-toolbar.h | 8 +++ 9 files changed, 240 insertions(+), 8 deletions(-) diff --git a/share/ui/object-attributes.glade b/share/ui/object-attributes.glade index f6efcfbc36..44a4bd900b 100644 --- a/share/ui/object-attributes.glade +++ b/share/ui/object-attributes.glade @@ -560,6 +560,12 @@ 0.01 0.10 + + 0 + 10000 + 0.10 + 5 + 4 4 @@ -603,6 +609,16 @@ + + + start + Length: + + 0 + 5 + + + True @@ -644,6 +660,20 @@ + + + True + Lenght of side + True + 6 + adjustment-star-length + 2 + + 1 + 5 + + + 4 @@ -762,6 +792,21 @@ + + + True + start + False + edit-clear-value + + + 2 + 5 + + + 40 diff --git a/share/ui/toolbar-star.ui b/share/ui/toolbar-star.ui index ddaf932d71..ae1622cdb2 100644 --- a/share/ui/toolbar-star.ui +++ b/share/ui/toolbar-star.ui @@ -29,6 +29,11 @@ True True + + 1000000 + 0.10 + 5 + start center @@ -195,6 +200,34 @@ + + + Length of side + + + 5 + Length: + + + + + True + 7 + 0.000 + _length_adj + 0.10 + 3 + + + + + + + + + diff --git a/src/attributes.cpp b/src/attributes.cpp index 99657120d1..642cf36898 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -211,6 +211,7 @@ static SPStyleProp const props[] = { {SPAttr::INKSCAPE_FLATSIDED, "inkscape:flatsided"}, {SPAttr::INKSCAPE_ROUNDED, "inkscape:rounded"}, {SPAttr::INKSCAPE_RANDOMIZED, "inkscape:randomized"}, + {SPAttr::INKSCAPE_LENGTH, "inkscape:length"}, /* SPSpiral */ {SPAttr::SODIPODI_EXPANSION, "sodipodi:expansion"}, {SPAttr::SODIPODI_REVOLUTION, "sodipodi:revolution"}, diff --git a/src/attributes.h b/src/attributes.h index f42ab8a935..1234df43a3 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -210,6 +210,7 @@ enum class SPAttr { INKSCAPE_FLATSIDED, INKSCAPE_ROUNDED, INKSCAPE_RANDOMIZED, + INKSCAPE_LENGTH, /* SPSpiral */ SODIPODI_EXPANSION, SODIPODI_REVOLUTION, diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index de4e195d97..6be9640c68 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -38,7 +38,8 @@ SPStar::SPStar() : SPShape() , center(0, 0), flatsided(false), rounded(0.0), - randomized(0.0) + randomized(0.0), + length(1.0) { this->r[0] = 1.0; this->r[1] = 0.001; @@ -61,6 +62,7 @@ void SPStar::build(SPDocument * document, Inkscape::XML::Node * repr) { this->readAttr(SPAttr::SODIPODI_ARG2); this->readAttr(SPAttr::INKSCAPE_ROUNDED); this->readAttr(SPAttr::INKSCAPE_RANDOMIZED); + this->readAttr(SPAttr::INKSCAPE_LENGTH); } Inkscape::XML::Node* SPStar::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { @@ -80,6 +82,7 @@ Inkscape::XML::Node* SPStar::write(Inkscape::XML::Document *xml_doc, Inkscape::X repr->setAttributeSvgDouble("sodipodi:arg2", this->arg[1]); repr->setAttributeSvgDouble("inkscape:rounded", this->rounded); repr->setAttributeSvgDouble("inkscape:randomized", this->randomized); + repr->setAttributeSvgDouble("inkscape:length", this->length); } this->set_shape(); @@ -206,6 +209,16 @@ void SPStar::set(SPAttr key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SPAttr::INKSCAPE_LENGTH: + if (value) { + this->length = g_ascii_strtod (value, nullptr); + } else { + this->length = 1.0; + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: // CPPIFY: see header file SPShape::set(key, value); @@ -522,6 +535,39 @@ void SPStar::update_patheffect(bool write) { SPShape::update_patheffect(write); } +/** + * Calculate the average side length of the polygon. + * + * For spoked polygons (stars) this is the radius delta; for non-spoked + * polygons this is the regular side length directly. + * + * @returns the average length of the polygon sides. + */ +double SPStar::getSideLength() const +{ + if (!flatsided) { + // Pointy star + // return std::abs(r[0] - r[1]); + double theta = 2 * M_PI / sides; // Angle between two outer vertices + double delta_theta = theta / 2; // Offset for inner vertex + double x1 = r[0] * cos(0); + double y1 = r[0] * sin(0); + double x2 = r[1] * cos(delta_theta); + double y2 = r[1] * sin(delta_theta); + + // Distance between the two points (outer and inner) + return Geom::distance(Geom::Point(x1, y1), Geom::Point(x2, y2)); + } + + double diameter = 0.0; + auto tr = i2doc_affine(); + for (gint i = 0; i < sides; i++) { + diameter += Geom::distance(sp_star_get_xy(this, SP_STAR_POINT_KNOT1, i, false) * tr, + sp_star_get_xy(this, SP_STAR_POINT_KNOT1, (i + 1) % sides, false) * tr); + } + return diameter / sides; +} + /** * sp_star_get_xy: Get X-Y value as item coordinate system * @star: star item diff --git a/src/object/sp-star.h b/src/object/sp-star.h index 47abebf70b..1c5fa3b779 100644 --- a/src/object/sp-star.h +++ b/src/object/sp-star.h @@ -37,11 +37,7 @@ public: double rounded; double randomized; - -// CPPIFY: This derivation is a bit weird. -// parent_class = reinterpret_cast(g_type_class_ref(SP_TYPE_SHAPE)); -// So shouldn't star be derived from shape instead of polygon? -// What does polygon have that shape doesn't? + double length; void build(SPDocument *document, Inkscape::XML::Node *repr) override; Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override; @@ -55,6 +51,7 @@ public: void update_patheffect(bool write) override; void set_shape() override; Geom::Affine set_transform(Geom::Affine const& xform) override; + double getSideLength() const; }; void sp_star_position_set (SPStar *star, int sides, Geom::Point center, double r1, double r2, double arg1, double arg2, bool isflat, double rounded, double randomized); diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index 9bf7aaec46..f078dbf3bc 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -684,12 +684,14 @@ public: _ratio(get_derived_widget(builder, "star-ratio")), _rounded(get_derived_widget(builder, "star-rounded")), _rand(get_derived_widget(builder, "star-rand")), + _length(get_derived_widget(builder, "star-length")), _poly(get_widget(builder, "star-poly")), _star(get_widget(builder, "star-star")), _align(get_widget(builder, "star-align")), _clear_rnd(get_widget(builder, "star-rnd-clear")), _clear_round(get_widget(builder, "star-round-clear")), - _clear_ratio(get_widget(builder, "star-ratio-clear")) + _clear_ratio(get_widget(builder, "star-ratio-clear")), + _clear_length(get_widget(builder, "star-length-clear")) { _title = _("Star"); _widget = &_main; @@ -726,9 +728,31 @@ public: _path->updateRepr(); }); }); + _length.get_adjustment()->signal_value_changed().connect([this](){ + change_value(_path, _length.get_adjustment(), [this](double length){ + _path->setAttributeDouble("inkscape:length", length); + _path->updateRepr(); + + auto adj = _length.get_adjustment(); + auto value = Util::Quantity::convert(adj->get_value(), _tracker->getActiveUnit(), "px"); + + if (auto star = cast(_path)) { + auto scale = Geom::Scale(value / star->getSideLength()); + auto set_tmp = ObjectSet{_desktop}; + set_tmp.add(_path); + set_tmp.scaleRelative(star->center, scale); + + auto repr = _path->getRepr(); + repr->setAttributeSvgDouble("inkscape:length", adj->get_value()); + _path->updateRepr(); + } + }); + }); + _clear_rnd.signal_clicked().connect([this](){ _rand.get_adjustment()->set_value(0); }); _clear_round.signal_clicked().connect([this](){ _rounded.get_adjustment()->set_value(0); }); _clear_ratio.signal_clicked().connect([this](){ _ratio.get_adjustment()->set_value(0.5); }); + _clear_length.signal_clicked().connect([this](){ _length.get_adjustment()->set_value(_path->length); }); _poly.signal_toggled().connect([this](){ set_flat(true); }); _star.signal_toggled().connect([this](){ set_flat(false); }); @@ -755,9 +779,11 @@ public: } _rounded.set_value(_path->rounded); _rand.set_value(_path->randomized); + _length.set_value(_path->length); _clear_rnd .set_visible(_path->randomized != 0); _clear_round.set_visible(_path->rounded != 0); _clear_ratio.set_visible(std::abs(_ratio.get_value() - 0.5) > 0.0005); + _clear_length.set_visible(std::abs(_length.get_value() - 1.0) > 0.0005); _poly.set_active(_path->flatsided); _star.set_active(!_path->flatsided); @@ -782,9 +808,11 @@ private: Inkscape::UI::Widget::SpinButton& _ratio; Inkscape::UI::Widget::SpinButton& _rounded; Inkscape::UI::Widget::SpinButton& _rand; + Inkscape::UI::Widget::SpinButton& _length; Gtk::Button& _clear_rnd; Gtk::Button& _clear_round; Gtk::Button& _clear_ratio; + Gtk::Button& _clear_length; Gtk::Button& _align; Gtk::ToggleButton &_poly; Gtk::ToggleButton &_star; diff --git a/src/ui/toolbar/star-toolbar.cpp b/src/ui/toolbar/star-toolbar.cpp index 27ef1109ea..eed6f53aee 100644 --- a/src/ui/toolbar/star-toolbar.cpp +++ b/src/ui/toolbar/star-toolbar.cpp @@ -41,6 +41,8 @@ #include "ui/icon-names.h" #include "ui/tools/star-tool.h" #include "ui/util.h" +#include "ui/widget/combo-tool-item.h" +#include "ui/widget/unit-tracker.h" #include "ui/widget/spinbutton.h" using Inkscape::DocumentUndo; @@ -59,6 +61,8 @@ StarToolbar::StarToolbar(Glib::RefPtr const &builder) , _spoke_item{get_derived_widget(builder, "_spoke_item")} , _roundedness_item{get_derived_widget(builder, "_roundedness_item")} , _randomization_item{get_derived_widget(builder, "_randomization_item")} + , _tracker{std::make_unique(Util::UNIT_TYPE_LINEAR)} + , _length_item{get_derived_widget(builder, "_length_item")} { bool is_flat_sided = Preferences::get()->getBool("/tools/shapes/star/isflatsided", false); @@ -111,6 +115,7 @@ StarToolbar::StarToolbar(Glib::RefPtr const &builder) setup_derived_spin_button(_spoke_item, "proportion", 0.5, &StarToolbar::proportion_value_changed); setup_derived_spin_button(_roundedness_item, "rounded", 0.0, &StarToolbar::rounded_value_changed); setup_derived_spin_button(_randomization_item, "randomized", 0.0, &StarToolbar::randomized_value_changed); + setup_derived_spin_button(_length_item, "length", 0.0, &StarToolbar::length_value_changed); // Flatsided checkbox _flat_item_buttons.push_back(&get_widget(builder, "flat_polygon_button")); @@ -128,6 +133,10 @@ StarToolbar::StarToolbar(Glib::RefPtr const &builder) _spoke_box.set_visible(!is_flat_sided); + auto unit_menu = _tracker->create_tool_item(_("Units"), ("")); + get_widget(builder, "unit_menu_box").append(*unit_menu); + _tracker->addAdjustment(_length_item.get_adjustment()->gobj()); + _initMenuBtns(); } @@ -166,6 +175,7 @@ void StarToolbar::setDesktop(SPDesktop *desktop) { if (_desktop) { _selection_changed_conn.disconnect(); + _selection_modified_conn.disconnect(); if (_repr) { _detachRepr(); @@ -177,10 +187,16 @@ void StarToolbar::setDesktop(SPDesktop *desktop) if (_desktop) { auto sel = _desktop->getSelection(); _selection_changed_conn = sel->connectChanged(sigc::mem_fun(*this, &StarToolbar::_selectionChanged)); + _selection_modified_conn = sel->connectChanged(sigc::mem_fun(*this, &StarToolbar::_selectionModified)); _selectionChanged(sel); // Synthesize an emission to trigger the update } } +void StarToolbar::setActiveUnit(Util::Unit const *unit) +{ + _tracker->setActiveUnit(unit); +} + void StarToolbar::side_mode_changed(int mode) { bool const flat = mode == 0; @@ -356,6 +372,29 @@ void StarToolbar::randomized_value_changed() } } +void StarToolbar::length_value_changed() +{ + if (!_blocker.pending() || _tracker->isUpdating()) { + // in turn, prevent listener from responding + auto guard = _blocker.block(); + + auto adj = _length_item.get_adjustment(); + auto value = Util::Quantity::convert(adj->get_value(), _tracker->getActiveUnit(), "px"); + for (auto item : _desktop->getSelection()->items()) { + if (auto star = cast(item)) { + auto scale = Geom::Scale(value / star->getSideLength()); + auto set_tmp = ObjectSet{_desktop}; + set_tmp.add(item); + set_tmp.scaleRelative(star->center, scale); + + auto repr = item->getRepr(); + repr->setAttributeSvgDouble("inkscape:length", adj->get_value()); + item->updateRepr(); + } + } + } +} + void StarToolbar::_setDefaults() { _batchundo = true; @@ -393,20 +432,49 @@ void StarToolbar::_selectionChanged(Selection *selection) int n_selected = 0; XML::Node *repr = nullptr; + double lengths = 0; for (auto item : selection->items()) { - if (is(item)) { + if (auto star = cast(item)) { n_selected++; repr = item->getRepr(); + lengths += star->getSideLength(); } } _mode_item.set_markup(n_selected == 0 ? _("New:") : _("Change:")); + _length_item.set_sensitive(n_selected > 0); if (n_selected == 1) { _attachRepr(repr); _repr->synthesizeEvents(*this); // Fixme: BAD } + _selectionModified(selection); +} + +void StarToolbar::_selectionModified(Selection *selection) +{ + if (!_blocker.pending()|| _tracker->isUpdating()) { + auto guard = _blocker.block(); + auto length_adj = _length_item.get_adjustment(); + + int n_selected = 0; + double lengths = 0; + for (auto item : selection->items()) { + if (auto star = cast(item)) { + n_selected++; + lengths += star->getSideLength(); + + auto repr = item->getRepr(); + repr->setAttributeSvgDouble("inkscape:length", length_adj->get_value()); + item->updateRepr(); + } + } + if (n_selected > 0) { + auto value = Util::Quantity::convert(lengths / n_selected, "px", _tracker->getActiveUnit()); + length_adj->set_value(value); + } + } } void StarToolbar::notifyAttributeChanged(XML::Node &, GQuark name_, Util::ptr_shared, Util::ptr_shared) @@ -426,6 +494,7 @@ void StarToolbar::notifyAttributeChanged(XML::Node &, GQuark name_, Util::ptr_sh bool isFlatSided = Preferences::get()->getBool("/tools/shapes/star/isflatsided", false); auto mag_adj = _magnitude_item.get_adjustment(); auto spoke_adj = _spoke_item.get_adjustment(); + auto length_adj = _length_item.get_adjustment(); if (!strcmp(name, "inkscape:randomized")) { double randomized = _repr->getAttributeDouble("inkscape:randomized", 0.0); @@ -457,6 +526,10 @@ void StarToolbar::notifyAttributeChanged(XML::Node &, GQuark name_, Util::ptr_sh int sides = _repr->getAttributeInt("sodipodi:sides", 0); mag_adj->set_value(sides); } + else if (!strcmp(name, "inkscape:length")) { + double length = _repr->getAttributeDouble("inkscape:length", 0.0); + length_adj->set_value(length); + } } } // namespace Inkscape::UI::Toolbar diff --git a/src/ui/toolbar/star-toolbar.h b/src/ui/toolbar/star-toolbar.h index d3dbd2726d..9bad4f4659 100644 --- a/src/ui/toolbar/star-toolbar.h +++ b/src/ui/toolbar/star-toolbar.h @@ -45,6 +45,7 @@ namespace Tools { class ToolBase; } namespace Widget { class Label; class SpinButton; +class UnitTracker; } // namespace Widget } // namespace UI namespace XML { class Node; } @@ -61,6 +62,7 @@ public: ~StarToolbar() override; void setDesktop(SPDesktop *desktop) override; + void setActiveUnit(Util::Unit const *unit) override; private: StarToolbar(Glib::RefPtr const &builder); @@ -74,6 +76,9 @@ private: UI::Widget::SpinButton &_spoke_item; UI::Widget::SpinButton &_roundedness_item; UI::Widget::SpinButton &_randomization_item; + UI::Widget::SpinButton &_length_item; + + std::unique_ptr _tracker; XML::Node *_repr = nullptr; void _attachRepr(XML::Node *repr); @@ -82,6 +87,7 @@ private: bool _batchundo = false; OperationBlocker _blocker; sigc::connection _selection_changed_conn; + sigc::connection _selection_modified_conn; void setup_derived_spin_button(UI::Widget::SpinButton &btn, Glib::ustring const &name, double default_value, ValueChangedMemFun value_changed_mem_fun); @@ -90,8 +96,10 @@ private: void proportion_value_changed(); void rounded_value_changed(); void randomized_value_changed(); + void length_value_changed(); void _setDefaults(); void _selectionChanged(Selection *selection); + void _selectionModified(Selection *selection); void notifyAttributeChanged(XML::Node &node, GQuark name, Util::ptr_shared old_value, Util::ptr_shared new_value) override; }; -- GitLab From d3c6fe2032bc75e2ad6ebf22ce23d5ae4a65aca5 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 18 Jan 2025 10:17:09 +0530 Subject: [PATCH 2/5] Fix getSideLength logic for pointy star --- src/object/sp-star.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 6be9640c68..603ab942c7 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -547,16 +547,21 @@ double SPStar::getSideLength() const { if (!flatsided) { // Pointy star - // return std::abs(r[0] - r[1]); - double theta = 2 * M_PI / sides; // Angle between two outer vertices - double delta_theta = theta / 2; // Offset for inner vertex - double x1 = r[0] * cos(0); - double y1 = r[0] * sin(0); - double x2 = r[1] * cos(delta_theta); - double y2 = r[1] * sin(delta_theta); - - // Distance between the two points (outer and inner) - return Geom::distance(Geom::Point(x1, y1), Geom::Point(x2, y2)); + double totalLength = 0.0; + auto tr = i2doc_affine(); + + for (gint i = 0; i < sides; i++) { + Geom::Point outer1 = sp_star_get_xy(this, SP_STAR_POINT_KNOT1, i, false) * tr; + Geom::Point inner1 = sp_star_get_xy(this, SP_STAR_POINT_KNOT2, i, false) * tr; + + totalLength += Geom::distance(outer1, inner1); + + Geom::Point outer2 = sp_star_get_xy(this, SP_STAR_POINT_KNOT1, (i + 1) % sides, false) * tr; + totalLength += Geom::distance(inner1, outer2); + } + + // Return the average side length (since we have 2 * sides distances, divide by 2 * sides) + return totalLength / (2 * sides); } double diameter = 0.0; -- GitLab From a2704630904358fec0cbb118d566f1a560179e97 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 18 Jan 2025 11:29:16 +0530 Subject: [PATCH 3/5] Update defalut value and decimal precision --- share/ui/object-attributes.glade | 19 ++----------------- src/object/sp-star.cpp | 4 ++-- src/ui/dialog/object-attributes.cpp | 6 +----- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/share/ui/object-attributes.glade b/share/ui/object-attributes.glade index 44a4bd900b..d6f0aaf5bf 100644 --- a/share/ui/object-attributes.glade +++ b/share/ui/object-attributes.glade @@ -665,9 +665,9 @@ True Lenght of side True - 6 + 7 adjustment-star-length - 2 + 3 1 5 @@ -792,21 +792,6 @@ - - - True - start - False - edit-clear-value - - - 2 - 5 - - - 40 diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 603ab942c7..9c09e22ffd 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -39,7 +39,7 @@ SPStar::SPStar() : SPShape() , flatsided(false), rounded(0.0), randomized(0.0), - length(1.0) + length(0.0) { this->r[0] = 1.0; this->r[1] = 0.001; @@ -213,7 +213,7 @@ void SPStar::set(SPAttr key, const gchar* value) { if (value) { this->length = g_ascii_strtod (value, nullptr); } else { - this->length = 1.0; + this->length = 0.0; } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index f078dbf3bc..c9afb01e3a 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -690,8 +690,7 @@ public: _align(get_widget(builder, "star-align")), _clear_rnd(get_widget(builder, "star-rnd-clear")), _clear_round(get_widget(builder, "star-round-clear")), - _clear_ratio(get_widget(builder, "star-ratio-clear")), - _clear_length(get_widget(builder, "star-length-clear")) + _clear_ratio(get_widget(builder, "star-ratio-clear")) { _title = _("Star"); _widget = &_main; @@ -752,7 +751,6 @@ public: _clear_rnd.signal_clicked().connect([this](){ _rand.get_adjustment()->set_value(0); }); _clear_round.signal_clicked().connect([this](){ _rounded.get_adjustment()->set_value(0); }); _clear_ratio.signal_clicked().connect([this](){ _ratio.get_adjustment()->set_value(0.5); }); - _clear_length.signal_clicked().connect([this](){ _length.get_adjustment()->set_value(_path->length); }); _poly.signal_toggled().connect([this](){ set_flat(true); }); _star.signal_toggled().connect([this](){ set_flat(false); }); @@ -783,7 +781,6 @@ public: _clear_rnd .set_visible(_path->randomized != 0); _clear_round.set_visible(_path->rounded != 0); _clear_ratio.set_visible(std::abs(_ratio.get_value() - 0.5) > 0.0005); - _clear_length.set_visible(std::abs(_length.get_value() - 1.0) > 0.0005); _poly.set_active(_path->flatsided); _star.set_active(!_path->flatsided); @@ -812,7 +809,6 @@ private: Gtk::Button& _clear_rnd; Gtk::Button& _clear_round; Gtk::Button& _clear_ratio; - Gtk::Button& _clear_length; Gtk::Button& _align; Gtk::ToggleButton &_poly; Gtk::ToggleButton &_star; -- GitLab From 704195159afce7307f49c6e82981eb9313373477 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sun, 19 Jan 2025 01:14:23 +0530 Subject: [PATCH 4/5] Fixed transformation issues and reverted changes of dialog --- share/ui/object-attributes.glade | 30 ------------------- src/attributes.cpp | 1 - src/attributes.h | 1 - src/object/sp-star.cpp | 45 ++++++++++++++++++++--------- src/object/sp-star.h | 2 +- src/ui/dialog/object-attributes.cpp | 25 +--------------- src/ui/toolbar/star-toolbar.cpp | 32 ++++++++++---------- 7 files changed, 50 insertions(+), 86 deletions(-) diff --git a/share/ui/object-attributes.glade b/share/ui/object-attributes.glade index d6f0aaf5bf..f6efcfbc36 100644 --- a/share/ui/object-attributes.glade +++ b/share/ui/object-attributes.glade @@ -560,12 +560,6 @@ 0.01 0.10 - - 0 - 10000 - 0.10 - 5 - 4 4 @@ -609,16 +603,6 @@ - - - start - Length: - - 0 - 5 - - - True @@ -660,20 +644,6 @@ - - - True - Lenght of side - True - 7 - adjustment-star-length - 3 - - 1 - 5 - - - 4 diff --git a/src/attributes.cpp b/src/attributes.cpp index 642cf36898..99657120d1 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -211,7 +211,6 @@ static SPStyleProp const props[] = { {SPAttr::INKSCAPE_FLATSIDED, "inkscape:flatsided"}, {SPAttr::INKSCAPE_ROUNDED, "inkscape:rounded"}, {SPAttr::INKSCAPE_RANDOMIZED, "inkscape:randomized"}, - {SPAttr::INKSCAPE_LENGTH, "inkscape:length"}, /* SPSpiral */ {SPAttr::SODIPODI_EXPANSION, "sodipodi:expansion"}, {SPAttr::SODIPODI_REVOLUTION, "sodipodi:revolution"}, diff --git a/src/attributes.h b/src/attributes.h index 1234df43a3..f42ab8a935 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -210,7 +210,6 @@ enum class SPAttr { INKSCAPE_FLATSIDED, INKSCAPE_ROUNDED, INKSCAPE_RANDOMIZED, - INKSCAPE_LENGTH, /* SPSpiral */ SODIPODI_EXPANSION, SODIPODI_REVOLUTION, diff --git a/src/object/sp-star.cpp b/src/object/sp-star.cpp index 9c09e22ffd..dff17d8d57 100644 --- a/src/object/sp-star.cpp +++ b/src/object/sp-star.cpp @@ -38,8 +38,7 @@ SPStar::SPStar() : SPShape() , center(0, 0), flatsided(false), rounded(0.0), - randomized(0.0), - length(0.0) + randomized(0.0) { this->r[0] = 1.0; this->r[1] = 0.001; @@ -62,7 +61,6 @@ void SPStar::build(SPDocument * document, Inkscape::XML::Node * repr) { this->readAttr(SPAttr::SODIPODI_ARG2); this->readAttr(SPAttr::INKSCAPE_ROUNDED); this->readAttr(SPAttr::INKSCAPE_RANDOMIZED); - this->readAttr(SPAttr::INKSCAPE_LENGTH); } Inkscape::XML::Node* SPStar::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { @@ -82,7 +80,6 @@ Inkscape::XML::Node* SPStar::write(Inkscape::XML::Document *xml_doc, Inkscape::X repr->setAttributeSvgDouble("sodipodi:arg2", this->arg[1]); repr->setAttributeSvgDouble("inkscape:rounded", this->rounded); repr->setAttributeSvgDouble("inkscape:randomized", this->randomized); - repr->setAttributeSvgDouble("inkscape:length", this->length); } this->set_shape(); @@ -209,16 +206,6 @@ void SPStar::set(SPAttr key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; - case SPAttr::INKSCAPE_LENGTH: - if (value) { - this->length = g_ascii_strtod (value, nullptr); - } else { - this->length = 0.0; - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - break; - default: // CPPIFY: see header file SPShape::set(key, value); @@ -573,6 +560,36 @@ double SPStar::getSideLength() const return diameter / sides; } +/** + * Set the average side length of the polygon. + * + * For spoked polygons (stars) this is the radius delta; for non-spoked + * polygons this is the regular side length directly. + * + * @param length the new average length of the polygon sides. + */ +void SPStar::setSideLength(double length) { + double currentLength = getSideLength(); + if (currentLength <= 0 || length <= 0) { + return; // Prevent division by zero or invalid scaling + } + + double scale = length / currentLength; + + if (!flatsided) { + // Pointy star + r[0] *= scale; + r[1] *= scale; + } else { + // Flat star + r[0] *= scale; + } + + this -> set_shape(); + + requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + /** * sp_star_get_xy: Get X-Y value as item coordinate system * @star: star item diff --git a/src/object/sp-star.h b/src/object/sp-star.h index 1c5fa3b779..1066847f57 100644 --- a/src/object/sp-star.h +++ b/src/object/sp-star.h @@ -37,7 +37,6 @@ public: double rounded; double randomized; - double length; void build(SPDocument *document, Inkscape::XML::Node *repr) override; Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override; @@ -52,6 +51,7 @@ public: void set_shape() override; Geom::Affine set_transform(Geom::Affine const& xform) override; double getSideLength() const; + void setSideLength(double length); }; void sp_star_position_set (SPStar *star, int sides, Geom::Point center, double r1, double r2, double arg1, double arg2, bool isflat, double rounded, double randomized); diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index c9afb01e3a..f73c6d5151 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -684,7 +684,6 @@ public: _ratio(get_derived_widget(builder, "star-ratio")), _rounded(get_derived_widget(builder, "star-rounded")), _rand(get_derived_widget(builder, "star-rand")), - _length(get_derived_widget(builder, "star-length")), _poly(get_widget(builder, "star-poly")), _star(get_widget(builder, "star-star")), _align(get_widget(builder, "star-align")), @@ -727,26 +726,6 @@ public: _path->updateRepr(); }); }); - _length.get_adjustment()->signal_value_changed().connect([this](){ - change_value(_path, _length.get_adjustment(), [this](double length){ - _path->setAttributeDouble("inkscape:length", length); - _path->updateRepr(); - - auto adj = _length.get_adjustment(); - auto value = Util::Quantity::convert(adj->get_value(), _tracker->getActiveUnit(), "px"); - - if (auto star = cast(_path)) { - auto scale = Geom::Scale(value / star->getSideLength()); - auto set_tmp = ObjectSet{_desktop}; - set_tmp.add(_path); - set_tmp.scaleRelative(star->center, scale); - - auto repr = _path->getRepr(); - repr->setAttributeSvgDouble("inkscape:length", adj->get_value()); - _path->updateRepr(); - } - }); - }); _clear_rnd.signal_clicked().connect([this](){ _rand.get_adjustment()->set_value(0); }); _clear_round.signal_clicked().connect([this](){ _rounded.get_adjustment()->set_value(0); }); @@ -754,7 +733,6 @@ public: _poly.signal_toggled().connect([this](){ set_flat(true); }); _star.signal_toggled().connect([this](){ set_flat(false); }); - _align.signal_clicked().connect([this](){ change_value(_path, {}, [this](double) { align_star_shape(_path); }); }); @@ -777,7 +755,7 @@ public: } _rounded.set_value(_path->rounded); _rand.set_value(_path->randomized); - _length.set_value(_path->length); + _clear_rnd .set_visible(_path->randomized != 0); _clear_round.set_visible(_path->rounded != 0); _clear_ratio.set_visible(std::abs(_ratio.get_value() - 0.5) > 0.0005); @@ -805,7 +783,6 @@ private: Inkscape::UI::Widget::SpinButton& _ratio; Inkscape::UI::Widget::SpinButton& _rounded; Inkscape::UI::Widget::SpinButton& _rand; - Inkscape::UI::Widget::SpinButton& _length; Gtk::Button& _clear_rnd; Gtk::Button& _clear_round; Gtk::Button& _clear_ratio; diff --git a/src/ui/toolbar/star-toolbar.cpp b/src/ui/toolbar/star-toolbar.cpp index eed6f53aee..30595c6999 100644 --- a/src/ui/toolbar/star-toolbar.cpp +++ b/src/ui/toolbar/star-toolbar.cpp @@ -379,17 +379,13 @@ void StarToolbar::length_value_changed() auto guard = _blocker.block(); auto adj = _length_item.get_adjustment(); + Preferences::get()->setDouble("/tools/shapes/star/length", adj->get_value()); + auto value = Util::Quantity::convert(adj->get_value(), _tracker->getActiveUnit(), "px"); + for (auto item : _desktop->getSelection()->items()) { if (auto star = cast(item)) { - auto scale = Geom::Scale(value / star->getSideLength()); - auto set_tmp = ObjectSet{_desktop}; - set_tmp.add(item); - set_tmp.scaleRelative(star->center, scale); - - auto repr = item->getRepr(); - repr->setAttributeSvgDouble("inkscape:length", adj->get_value()); - item->updateRepr(); + star -> setSideLength(value); } } } @@ -464,10 +460,6 @@ void StarToolbar::_selectionModified(Selection *selection) if (auto star = cast(item)) { n_selected++; lengths += star->getSideLength(); - - auto repr = item->getRepr(); - repr->setAttributeSvgDouble("inkscape:length", length_adj->get_value()); - item->updateRepr(); } } if (n_selected > 0) { @@ -526,9 +518,19 @@ void StarToolbar::notifyAttributeChanged(XML::Node &, GQuark name_, Util::ptr_sh int sides = _repr->getAttributeInt("sodipodi:sides", 0); mag_adj->set_value(sides); } - else if (!strcmp(name, "inkscape:length")) { - double length = _repr->getAttributeDouble("inkscape:length", 0.0); - length_adj->set_value(length); + + double lengths = 0; + int n_selected = 0; + for (auto item : _desktop->getSelection()->items()) { + if (auto star = cast(item)) { + n_selected++; + lengths += star->getSideLength(); + } + } + + if (n_selected > 0) { + auto value = Util::Quantity::convert(lengths / n_selected, "px", _tracker->getActiveUnit()); + length_adj->set_value(value); } } -- GitLab From 0f529ec8a0006424d0fb07dbb6e4e8304c429f94 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Sat, 25 Jan 2025 10:33:43 +0530 Subject: [PATCH 5/5] changed length to edge --- share/ui/toolbar-star.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/ui/toolbar-star.ui b/share/ui/toolbar-star.ui index ae1622cdb2..fc4aca3415 100644 --- a/share/ui/toolbar-star.ui +++ b/share/ui/toolbar-star.ui @@ -202,11 +202,11 @@ - Length of side + Length of edge 5 - Length: + Edge: -- GitLab