path-manipulator.cpp revision b18fc2f12a153daa3f0ff461ba29d7d28136112d
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Path manipulator - implementation
9589ae957c17876584db2e3f997664f80bd72136Alex Valavanis * Krzysztof KosiĆski <tweenk.pl@gmail.com>
9589ae957c17876584db2e3f997664f80bd72136Alex Valavanis * Copyright (C) 2009 Authors
9589ae957c17876584db2e3f997664f80bd72136Alex Valavanis * Released under GNU GPL, read the file 'COPYING' for more information
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b/// Types of path changes that we must react to.
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b} // anonymous namespace
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Notifies the path manipulator when something changes the path being edited
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * (e.g. undo / redo)
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_bclass PathManipulatorObserver : public Inkscape::XML::NodeObserver {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b PathManipulatorObserver(PathManipulator *p) : _pm(p), _blocked(false) {}
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b virtual void notifyAttributeChanged(Inkscape::XML::Node &, GQuark attr,
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b // do nothing if blocked
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b if (_blocked) return;
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis GQuark path_d = g_quark_from_static_string("d");
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b GQuark path_transform = g_quark_from_static_string("transform");
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b GQuark lpe_quark = _pm->_lpe_key.empty() ? 0 : g_quark_from_string(_pm->_lpe_key.data());
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b // only react to "d" (path data) and "transform" attribute changes
9589ae957c17876584db2e3f997664f80bd72136Alex Valavanisvoid build_segment(Geom::PathBuilder &, Node *, Node *);
, _show_handles(true)
, _show_outline(false)
_getGeometry();
delete _dragpoint;
delete _observer;
clear();
if (empty()) return false;
case GDK_MOTION_NOTIFY:
if (!_path) return;
if (!empty()) {
_path = 0;
if (j->selected()) {
bool nothing_selected = true;
if (!j->selected()) {
nothing_selected = false;
if (nothing_selected) {
if (dir == 0) return;
unsigned num = 0;
++num;
num = 0;
if (dir > 0) {
if ((*i)->closed()) {
if ((*i)->closed()) {
++num;
if (j->selected()) {
if (!_num_selected) return;
if (!_num_selected) return;
else ++num_unselected;
if (num_unselected == 0) {
while (num_selected > 0) {
unsigned num_points = 0;
bool use_pos = false;
++num_points;
if (use_pos) {
pos_valid = false;
--num_selected;
++cur;
--end;
bool becomes_open = false;
becomes_open = true;
n->sink();
if (becomes_open) {
if (!_num_selected) return;
else ++num_unselected;
if (num_selected == 0) {
while (num_selected > 0) {
unsigned del_len = 0;
++del_len;
unsigned seg = 0;
for (unsigned s = 0; s < samples_per_segment; ++s) {
++seg;
delete[] bezier_data;
if (_num_selected == 0) return;
bool has_unselected = false;
unsigned num_selected = 0;
if (j->selected()) {
++num_selected;
has_unselected = true;
if (!has_unselected) {
while (num_selected > 0) {
unsigned num_points = 0;
++num_points;
if (j->selected()) {
(*i)->reverse();
if (!_num_selected) return;
switch (type) {
case SEGMENT_STRAIGHT:
case SEGMENT_CUBIC_BEZIER:
if (show) {
if (!j->selected()) continue;
j->showHandles(true);
j->showHandles(false);
++insert_at;
return inserted;
switch (type) {
case PATH_CHANGE_D: {
_getGeometry();
++curpos;
case PATH_CHANGE_TRANSFORM: {
clear();
if (i->empty()) continue;
if ((*i)->closed()) {
prev = i;
++spi;
_setGeometry();
if (!_show_outline) {
if (_show_path_direction) {
if (lpe) {
if (!_spcurve)
if (empty()) return;
// copied from nodepath.cpp
if (lpe) {
handles[i]));
node));
if (n->isEndNode()) {
update();
update();
if (!_show_handles) return;
if (!node) return;
if (selected) {
else --_num_selected;
writeXML();
if (!pvp) return;
double fracpart;
return ret;