summaryrefslogtreecommitdiffstats
path: root/src/live_effects/parameter/item.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/live_effects/parameter/item.cpp')
-rw-r--r--src/live_effects/parameter/item.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/live_effects/parameter/item.cpp b/src/live_effects/parameter/item.cpp
new file mode 100644
index 0000000..e54cb08
--- /dev/null
+++ b/src/live_effects/parameter/item.cpp
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Abhishek Sharma
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include "live_effects/parameter/item.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/lpe-clone-original.h"
+#include <glibmm/i18n.h>
+
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+
+#include "bad-uri-exception.h"
+#include "ui/widget/point.h"
+
+#include "live_effects/effect.h"
+#include "live_effects/lpeobject.h"
+#include "live_effects/lpe-clone-original.h"
+#include "svg/svg.h"
+
+#include "desktop.h"
+#include "inkscape.h"
+#include "message-stack.h"
+#include "selection-chemistry.h"
+#include "ui/icon-loader.h"
+#include "xml/repr.h"
+// clipboard support
+#include "ui/clipboard.h"
+// required for linking to other paths
+#include "object/uri.h"
+
+#include "ui/icon-names.h"
+
+namespace Inkscape {
+
+namespace LivePathEffect {
+
+ItemParam::ItemParam( const Glib::ustring& label, const Glib::ustring& tip,
+ const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr,
+ Effect* effect, const gchar * default_value)
+ : Parameter(label, tip, key, wr, effect),
+ changed(true),
+ href(nullptr),
+ ref( (SPObject*)effect->getLPEObj() )
+{
+ last_transform = Geom::identity();
+ defvalue = g_strdup(default_value);
+ ref_changed_connection = ref.changedSignal().connect(sigc::mem_fun(*this, &ItemParam::ref_changed));
+}
+
+ItemParam::~ItemParam()
+{
+ remove_link();
+ g_free(defvalue);
+}
+
+void
+ItemParam::param_set_default()
+{
+ param_readSVGValue(defvalue);
+}
+
+void
+ItemParam::param_update_default(const gchar * default_value){
+ defvalue = strdup(default_value);
+}
+
+void
+ItemParam::param_set_and_write_default()
+{
+ param_write_to_repr(defvalue);
+}
+
+bool
+ItemParam::param_readSVGValue(const gchar * strvalue)
+{
+ if (strvalue) {
+ remove_link();
+ if (strvalue[0] == '#') {
+ if (href)
+ g_free(href);
+ href = g_strdup(strvalue);
+ try {
+ ref.attach(Inkscape::URI(href));
+ //lp:1299948
+ SPItem* i = ref.getObject();
+ if (i) {
+ linked_modified_callback(i, SP_OBJECT_MODIFIED_FLAG);
+ } // else: document still processing new events. Repr of the linked object not created yet.
+ } catch (Inkscape::BadURIException &e) {
+ g_warning("%s", e.what());
+ ref.detach();
+ }
+ }
+ emit_changed();
+ return true;
+ }
+
+ return false;
+}
+
+Glib::ustring
+ItemParam::param_getSVGValue() const
+{
+ if (href) {
+ return href;
+ }
+ return "";
+}
+
+Glib::ustring
+ItemParam::param_getDefaultSVGValue() const
+{
+ return defvalue;
+}
+
+Gtk::Widget *
+ItemParam::param_newWidget()
+{
+ Gtk::HBox * _widget = Gtk::manage(new Gtk::HBox());
+ Gtk::Image *pIcon = Gtk::manage(sp_get_icon_image("edit-clone", Gtk::ICON_SIZE_BUTTON));
+ Gtk::Button * pButton = Gtk::manage(new Gtk::Button());
+ Gtk::Label* pLabel = Gtk::manage(new Gtk::Label(param_label));
+ static_cast<Gtk::HBox*>(_widget)->pack_start(*pLabel, true, true);
+ pLabel->set_tooltip_text(param_tooltip);
+ pButton->set_relief(Gtk::RELIEF_NONE);
+ pIcon->show();
+ pButton->add(*pIcon);
+ pButton->show();
+ pButton->signal_clicked().connect(sigc::mem_fun(*this, &ItemParam::on_link_button_click));
+ static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);
+ pButton->set_tooltip_text(_("Link to item on clipboard"));
+
+ static_cast<Gtk::HBox*>(_widget)->show_all_children();
+
+ return dynamic_cast<Gtk::Widget *> (_widget);
+}
+
+void
+ItemParam::emit_changed()
+{
+ changed = true;
+ signal_item_changed.emit();
+}
+
+
+void
+ItemParam::addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
+{
+}
+
+
+void
+ItemParam::start_listening(SPObject * to)
+{
+ if ( to == nullptr ) {
+ return;
+ }
+ linked_delete_connection = to->connectDelete(sigc::mem_fun(*this, &ItemParam::linked_delete));
+ linked_modified_connection = to->connectModified(sigc::mem_fun(*this, &ItemParam::linked_modified));
+ if (SP_IS_ITEM(to)) {
+ linked_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::mem_fun(*this, &ItemParam::linked_transformed));
+ }
+ linked_modified(to, SP_OBJECT_MODIFIED_FLAG); // simulate linked_modified signal, so that path data is updated
+}
+
+void
+ItemParam::quit_listening()
+{
+ linked_modified_connection.disconnect();
+ linked_delete_connection.disconnect();
+ linked_transformed_connection.disconnect();
+}
+
+void
+ItemParam::ref_changed(SPObject */*old_ref*/, SPObject *new_ref)
+{
+ quit_listening();
+ if ( new_ref ) {
+ start_listening(new_ref);
+ }
+}
+
+void
+ItemParam::remove_link()
+{
+ if (href) {
+ ref.detach();
+ g_free(href);
+ href = nullptr;
+ }
+}
+
+void
+ItemParam::linked_delete(SPObject */*deleted*/)
+{
+ quit_listening();
+ remove_link();
+}
+
+void ItemParam::linked_modified(SPObject *linked_obj, guint flags)
+{
+ linked_modified_callback(linked_obj, flags);
+}
+
+void ItemParam::linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item)
+{
+ linked_transformed_callback(rel_transf, moved_item);
+}
+
+void
+ItemParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/)
+{
+ emit_changed();
+ SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ last_transform = Geom::identity();
+}
+
+void
+ItemParam::linked_transformed_callback(Geom::Affine const *rel_transf, SPItem *moved_item)
+{
+ last_transform = *rel_transf;
+ param_effect->getLPEObj()->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ if (dynamic_cast<Inkscape::LivePathEffect::LPECloneOriginal *>(param_effect->getLPEObj()->get_lpe())) {
+ auto hreflist = param_effect->getLPEObj()->hrefList;
+ SPDesktop * desktop = SP_ACTIVE_DESKTOP;
+ if (desktop && hreflist.size()) {
+ Inkscape::Selection *selection = desktop->getSelection();
+ SPLPEItem *sp_lpe_item = dynamic_cast<SPLPEItem *>(*hreflist.begin());
+ SPLPEItem *moved_lpeitem = dynamic_cast<SPLPEItem *>(moved_item);
+ // here use moved item because sp_lpe_item never has optimized transforms because clone LPE
+ if (sp_lpe_item && !selection->includes(sp_lpe_item) && moved_lpeitem && !last_transform.isTranslation()) {
+ if (!moved_lpeitem->optimizeTransforms()) {
+ sp_lpe_item->transform *= last_transform.withoutTranslation();
+ }
+ sp_lpe_item->doWriteTransform(sp_lpe_item->transform);
+ }
+ }
+ }
+}
+
+
+void
+ItemParam::linkitem(Glib::ustring itemid)
+{
+ if (itemid.empty()) {
+ return;
+ }
+
+ // add '#' at start to make it an uri.
+ itemid.insert(itemid.begin(), '#');
+ if ( href && strcmp(itemid.c_str(), href) == 0 ) {
+ // no change, do nothing
+ return;
+ } else {
+ // TODO:
+ // check if id really exists in document, or only in clipboard document: if only in clipboard then invalid
+ // check if linking to object to which LPE is applied (maybe delegated to PathReference
+
+ param_write_to_repr(itemid.c_str());
+ DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
+ _("Link item parameter to path"));
+ }
+}
+
+void
+ItemParam::on_link_button_click()
+{
+ Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get();
+ const gchar * iid = cm->getFirstObjectID();
+ if (!iid) {
+ return;
+ }
+
+ Glib::ustring itemid(iid);
+ linkitem(itemid);
+}
+
+} /* namespace LivePathEffect */
+
+} /* 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 :