summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 44aa4bd)
raw | patch | inline | side by side (parent: 44aa4bd)
author | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Sat, 5 Dec 2009 02:48:07 +0000 (03:48 +0100) | ||
committer | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Sat, 5 Dec 2009 02:48:07 +0000 (03:48 +0100) |
prepare to fix LPE path parameters
src/ui/tool/multi-path-manipulator.cpp | patch | blob | history | |
src/ui/tool/multi-path-manipulator.h | patch | blob | history | |
src/ui/tool/node-tool.cpp | patch | blob | history | |
src/ui/tool/node-tool.h | patch | blob | history | |
src/ui/tool/path-manipulator.cpp | patch | blob | history | |
src/ui/tool/path-manipulator.h | patch | blob | history | |
src/ui/tool/shape-record.h | [new file with mode: 0644] | patch | blob |
index 6b245702a1fbc36d2e37f4586f7fbaf1e26d74bd..7c539f6b90850e5140d63337a24bb1a4b4966a0e 100644 (file)
#include "desktop-handles.h"
#include "document.h"
#include "message-stack.h"
+#include "preferences.h"
#include "sp-path.h"
#include "ui/tool/control-point-selection.h"
#include "ui/tool/event-utils.h"
}
}
-void MultiPathManipulator::setItems(std::map<SPPath*,
- std::pair<Geom::Matrix, guint32> > const &items)
+void MultiPathManipulator::setItems(std::set<ShapeRecord> const &s)
{
- typedef std::map<SPPath*, std::pair<Geom::Matrix, guint32> > TransMap;
- typedef std::set<SPPath*> ItemSet;
- ItemSet to_remove, to_add, current, new_items;
-
- for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) {
- current.insert(i->first);
- }
- for (TransMap::const_iterator i = items.begin(); i != items.end(); ++i) {
- new_items.insert(i->first);
+ std::set<ShapeRecord> shapes(s);
+
+ // iterate over currently edited items, modifying / removing them as necessary
+ for (MapType::iterator i = _mmap.begin(); i != _mmap.end();) {
+ std::set<ShapeRecord>::iterator si = shapes.find(i->first);
+ if (si == shapes.end()) {
+ // This item is no longer supposed to be edited - remove its manipulator
+ _mmap.erase(i++);
+ } else {
+ ShapeRecord const &sr = i->first;
+ ShapeRecord const &sr_new = *si;
+ // if the shape record differs, replace the key only and modify other values
+ if (sr.edit_transform != sr_new.edit_transform ||
+ sr.role != sr_new.role)
+ {
+ boost::shared_ptr<PathManipulator> hold(i->second);
+ if (sr.edit_transform != sr_new.edit_transform)
+ hold->setControlsTransform(sr_new.edit_transform);
+ if (sr.role != sr_new.role) {
+ //hold->setOutlineColor(_getOutlineColor(sr_new.role));
+ }
+ _mmap.erase(sr);
+ _mmap.insert(std::make_pair(sr_new, hold));
+ }
+ shapes.erase(si); // remove the processed record
+ ++i;
+ }
}
- std::set_difference(current.begin(), current.end(), new_items.begin(), new_items.end(),
- std::inserter(to_remove, to_remove.end()));
- std::set_difference(new_items.begin(), new_items.end(), current.begin(), current.end(),
- std::inserter(to_add, to_add.end()));
-
- for (ItemSet::iterator i = to_remove.begin(); i != to_remove.end(); ++i) {
- _mmap.erase(*i);
- }
- for (ItemSet::iterator i = to_add.begin(); i != to_add.end(); ++i) {
- boost::shared_ptr<PathManipulator> pm;
- TransMap::const_iterator f = items.find(*i);
- pm.reset(new PathManipulator(_path_data, *i, f->second.first, f->second.second));
- pm->showHandles(_show_handles);
- pm->showOutline(_show_outline);
- pm->showPathDirection(_show_path_direction);
- _mmap.insert(std::make_pair(*i, pm));
+ // add newly selected items
+ for (std::set<ShapeRecord>::iterator i = shapes.begin(); i != shapes.end(); ++i) {
+ ShapeRecord const &r = *i;
+ if (!SP_IS_PATH(r.item)) continue;
+ boost::shared_ptr<PathManipulator> newpm(new PathManipulator(_path_data, (SPPath*) r.item,
+ r.edit_transform, _getOutlineColor(r.role)));
+ newpm->showHandles(_show_handles);
+ // always show outlines for clips and masks
+ newpm->showOutline(_show_outline || r.role != SHAPE_ROLE_NORMAL);
+ newpm->showPathDirection(_show_path_direction);
+ _mmap.insert(std::make_pair(r, newpm));
}
}
void MultiPathManipulator::showOutline(bool show)
{
- invokeForAll(&PathManipulator::showOutline, show);
+ for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) {
+ // always show outlines for clipping paths and masks
+ i->second->showOutline(show || i->first.role != SHAPE_ROLE_NORMAL);
+ }
_show_outline = show;
}
_show_path_direction = show;
}
+void MultiPathManipulator::updateOutlineColors()
+{
+ //for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) {
+ // i->second->setOutlineColor(_getOutlineColor(i->first.role));
+ //}
+}
+
bool MultiPathManipulator::event(GdkEvent *event)
{
switch (event->type) {
_changed.unblock();
}
+guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ switch(role) {
+ case SHAPE_ROLE_CLIPPING_PATH:
+ return prefs->getColor("/tools/nodes/clipping_path_color", 0x00ff00ff);
+ case SHAPE_ROLE_MASK:
+ return prefs->getColor("/tools/nodes/mask_color", 0x0000ffff);
+ case SHAPE_ROLE_LPE_PARAM:
+ return prefs->getColor("/tools/nodes/lpe_param_color", 0xb700ffff);
+ case SHAPE_ROLE_NORMAL:
+ default:
+ return prefs->getColor("/tools/nodes/outline_color", 0xff0000ff);
+ }
+}
+
} // namespace UI
} // namespace Inkscape
index 89c86b0196574d47e5c46899361502d0f8bb689d..b66451ad31b293ee73646d0058780eac7c924511 100644 (file)
#include <sigc++/connection.h>
#include "display/display-forward.h"
#include "forward.h"
+#include "ui/tool/commit-events.h"
#include "ui/tool/manipulator.h"
#include "ui/tool/node-types.h"
-#include "ui/tool/commit-events.h"
+#include "ui/tool/shape-record.h"
struct SPCanvasGroup;
bool empty() { return _mmap.empty(); }
unsigned size() { return _mmap.empty(); }
// TODO fix this garbage!
- void setItems(std::map<SPPath*, std::pair<Geom::Matrix, guint32> > const &items);
+ void setItems(std::set<ShapeRecord> const &);
+ //std::map<SPPath*, std::pair<Geom::Matrix, guint32> > const &items);
void clear() { _mmap.clear(); }
void cleanup();
void showOutline(bool show);
void showHandles(bool show);
void showPathDirection(bool show);
- void setOutlineTransform(SPPath *item, Geom::Matrix const &t);
+ void updateOutlineColors();
sigc::signal<void> signal_coords_changed;
private:
- typedef std::pair<SPPath*, boost::shared_ptr<PathManipulator> > MapPair;
- typedef std::map<SPPath*, boost::shared_ptr<PathManipulator> > MapType;
+ typedef std::pair<ShapeRecord, boost::shared_ptr<PathManipulator> > MapPair;
+ typedef std::map<ShapeRecord, boost::shared_ptr<PathManipulator> > MapType;
template <typename R>
void invokeForAll(R (PathManipulator::*method)()) {
void _commit(CommitEvent cps);
void _done(gchar const *);
void _doneWithCleanup(gchar const *);
- void _storeClipMaskItems(SPObject *obj, std::set<SPPath*> &, bool);
+ guint32 _getOutlineColor(ShapeRole role);
MapType _mmap;
PathSharedData const &_path_data;
index a57057c92b0d7c77375679d111b190d08ae83191..31c7227447226d9ba83d3b4b945fdb9aa32ab95e 100644 (file)
#include "ui/tool/multi-path-manipulator.h"
#include "ui/tool/path-manipulator.h"
#include "ui/tool/selector.h"
+#include "ui/tool/shape-record.h"
#include "pixmaps/cursor-node.xpm"
#include "pixmaps/cursor-node-d.xpm"
event_context->hot_y = 1;
new (&nt->_selection_changed_connection) sigc::connection();
+ new (&nt->_selection_modified_connection) sigc::connection();
new (&nt->_mouseover_changed_connection) sigc::connection();
//new (&nt->_mgroup) Inkscape::UI::ManipulatorGroup(nt->desktop);
new (&nt->_selected_nodes) CSelPtr();
nt->enableGrDrag(false);
nt->_selection_changed_connection.disconnect();
+ nt->_selection_modified_connection.disconnect();
nt->_mouseover_changed_connection.disconnect();
nt->_multipath.~MultiPathPtr();
nt->_selected_nodes.~CSelPtr();
nt->_path_data.~PathSharedDataPtr();
nt->_selection_changed_connection.~connection();
+ nt->_selection_modified_connection.~connection();
nt->_mouseover_changed_connection.~connection();
if (nt->_node_message_context) {
sigc::bind<0>(
sigc::ptr_fun(&ink_node_tool_selection_changed),
nt));
+ nt->_selection_modified_connection.disconnect();
+ nt->_selection_modified_connection =
+ selection->connectModified(
+ sigc::hide(sigc::bind<0>(
+ sigc::ptr_fun(&ink_node_tool_selection_changed),
+ nt)));
nt->_mouseover_changed_connection.disconnect();
nt->_mouseover_changed_connection =
Inkscape::UI::ControlPoint::signal_mouseover_change.connect(
}
}
+/** Recursively collect ShapeRecords */
+void gather_items(InkNodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::ShapeRole role,
+ std::set<Inkscape::UI::ShapeRecord> &s)
+{
+ using namespace Inkscape::UI;
+ if (!obj) return;
+ if (role != SHAPE_ROLE_NORMAL && (SP_IS_GROUP(obj) || SP_IS_OBJECTGROUP(obj))) {
+ for (SPObject *c = obj->children; c; c = c->next) {
+ gather_items(nt, base, c, role, s);
+ }
+ } else if (SP_IS_ITEM(obj)) {
+ SPItem *item = static_cast<SPItem*>(obj);
+ ShapeRecord r;
+ r.item = item;
+ // TODO add support for objectBoundingBox
+ r.edit_transform = base ? sp_item_i2doc_affine(base) : Geom::identity();
+ r.role = role;
+ r.edit_original = false;
+ if (s.insert(r).second) {
+ // this item was encountered the first time
+ if (nt->edit_clipping_paths && item->clip_ref) {
+ gather_items(nt, item, item->clip_ref->getObject(), SHAPE_ROLE_CLIPPING_PATH, s);
+ }
+ if (nt->edit_masks && item->mask_ref) {
+ gather_items(nt, item, item->mask_ref->getObject(), SHAPE_ROLE_MASK, s);
+ }
+ }
+ }
+}
+
struct IsPath {
bool operator()(SPItem *i) const { return SP_IS_PATH(i); }
};
void ink_node_tool_selection_changed(InkNodeTool *nt, Inkscape::Selection *sel)
{
using namespace Inkscape::UI;
+
+ std::set<ShapeRecord> shapes;
+
// TODO this is ugly!!!
- typedef std::map<SPItem*, std::pair<Geom::Matrix, guint32> > TransMap;
- typedef std::map<SPPath*, std::pair<Geom::Matrix, guint32> > PathMap;
+ //typedef std::map<SPItem*, std::pair<Geom::Matrix, guint32> > TransMap;
+ //typedef std::map<SPPath*, std::pair<Geom::Matrix, guint32> > PathMap;
GSList const *ilist = sel->itemList();
- TransMap items;
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
for (GSList *i = const_cast<GSList*>(ilist); i; i = i->next) {
SPObject *obj = static_cast<SPObject*>(i->data);
if (SP_IS_ITEM(obj)) {
- items.insert(std::make_pair(SP_ITEM(obj),
- std::make_pair(Geom::identity(),
- prefs->getColor("/tools/nodes/outline_color", 0xff0000ff))));
- if (nt->edit_clipping_paths && SP_ITEM(i->data)->clip_ref) {
- store_clip_mask_items(SP_ITEM(i->data),
- SP_OBJECT(SP_ITEM(i->data)->clip_ref->getObject()), items,
- nt->desktop->dt2doc(),
- prefs->getColor("/tools/nodes/clipping_path_color", 0x00ff00ff));
- }
- if (nt->edit_masks && SP_ITEM(i->data)->mask_ref) {
- store_clip_mask_items(SP_ITEM(i->data),
- SP_OBJECT(SP_ITEM(i->data)->mask_ref->getObject()), items,
- nt->desktop->dt2doc(),
- prefs->getColor("/tools/nodes/mask_color", 0x0000ffff));
- }
+ gather_items(nt, NULL, static_cast<SPItem*>(obj), SHAPE_ROLE_NORMAL, shapes);
}
}
// ugly hack: set the first editable non-path item for knotholder
// maybe use multiple ShapeEditors for now, to allow editing many shapes at once?
bool something_set = false;
- for (TransMap::iterator i = items.begin(); i != items.end(); ++i) {
- SPItem *obj = i->first;
- if (SP_IS_SHAPE(obj) && !SP_IS_PATH(obj)) {
- nt->shape_editor->set_item(obj, SH_KNOTHOLDER);
+ for (std::set<ShapeRecord>::iterator i = shapes.begin(); i != shapes.end(); ++i) {
+ ShapeRecord const &r = *i;
+ if (SP_IS_SHAPE(r.item) && !SP_IS_PATH(r.item)) {
+ nt->shape_editor->set_item(r.item, SH_KNOTHOLDER);
something_set = true;
break;
}
@@ -347,16 +374,8 @@ void ink_node_tool_selection_changed(InkNodeTool *nt, Inkscape::Selection *sel)
if (!something_set) {
nt->shape_editor->unset_item(SH_KNOTHOLDER);
}
-
- PathMap p;
- for (TransMap::iterator i = items.begin(); i != items.end(); ++i) {
- if (SP_IS_PATH(i->first)) {
- p.insert(std::make_pair(SP_PATH(i->first),
- std::make_pair(i->second.first, i->second.second)));
- }
- }
- nt->_multipath->setItems(p);
+ nt->_multipath->setItems(shapes);
ink_node_tool_update_tip(nt, NULL);
nt->desktop->updateNow();
}
index f47ea0ccb799a3e1fcbc7bf60043a1c6506422a1..65b16ff72172e8ffb80a2bc0da335cb70bc176ef 100644 (file)
--- a/src/ui/tool/node-tool.h
+++ b/src/ui/tool/node-tool.h
{
sigc::connection _selection_changed_connection;
sigc::connection _mouseover_changed_connection;
+ sigc::connection _selection_modified_connection;
Inkscape::MessageContext *_node_message_context;
SPItem *flashed_item;
Inkscape::Display::TemporaryItem *flash_tempitem;
index ef85723306e1f284cab3183c8429051bcb517c5d..e9ec78b2e08a51d6e892d7d4ec90421c7207a35c 100644 (file)
_updateOutline();
}
+void PathManipulator::setControlsTransform(Geom::Matrix const &tnew)
+{
+ Geom::Matrix delta = _i2d_transform.inverse() * _edit_transform.inverse() * tnew * _i2d_transform;
+ _edit_transform = tnew;
+ for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
+ for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
+ j->transform(delta);
+ }
+ }
+ _createGeometryFromControlPoints();
+}
+
/** Insert a node in the segment beginning with the supplied iterator,
* at the given time value */
NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, double t)
index 9ed9e4fb6b0c9d796a9dbb46bd02c4558feb39ee..01a2b6cbf5bbc3c756c7d812252e044d69f0508d 100644 (file)
void showOutline(bool show);
void showHandles(bool show);
void showPathDirection(bool show);
- void setOutlineTransform(Geom::Matrix const &);
+ void setControlsTransform(Geom::Matrix const &);
NodeList::iterator subdivideSegment(NodeList::iterator after, double t);
diff --git a/src/ui/tool/shape-record.h b/src/ui/tool/shape-record.h
--- /dev/null
@@ -0,0 +1,56 @@
+/** @file
+ * Structures that store data needed for shape editing which are not contained
+ * directly in the XML node
+ */
+/* Authors:
+ * Krzysztof Kosiński <tweenk.pl@gmail.com>
+ *
+ * Copyright (C) 2009 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_UI_TOOL_SHAPE_RECORD_H
+#define SEEN_UI_TOOL_SHAPE_RECORD_H
+
+#include <boost/operators.hpp>
+#include <2geom/matrix.h>
+
+class SPItem;
+namespace Inkscape {
+namespace UI {
+
+/** Role of the shape in the drawing - affects outline display and color */
+enum ShapeRole {
+ SHAPE_ROLE_NORMAL,
+ SHAPE_ROLE_CLIPPING_PATH,
+ SHAPE_ROLE_MASK,
+ SHAPE_ROLE_LPE_PARAM // implies edit_original set to true in ShapeRecord
+};
+
+struct ShapeRecord :
+ public boost::totally_ordered<ShapeRecord>
+{
+ SPItem *item; // SP node for the edited shape
+ Geom::Matrix edit_transform; // how to transform controls - used for clipping paths and masks
+ ShapeRole role;
+ bool edit_original; // whether to use original-d instead of d for editing
+
+ inline bool operator==(ShapeRecord const &o) const { return item == o.item; }
+ inline bool operator<(ShapeRecord const &o) const { return item < o.item; }
+};
+
+} // namespace UI
+} // namespace Inkscape
+
+#endif
+
+/*
+ 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:encoding=utf-8:textwidth=99 :