From 45c35505428e178b32c8f32f85058e4d894bd62d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 18 Jan 2013 23:32:27 +0100 Subject: Delete bspline node whith node tool and fix 1 segment continue shift error (bzr r11950.1.17) --- src/ui/tool/multi-path-manipulator.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 1f074c8da..c9e35e5b2 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,7 +671,16 @@ bool MultiPathManipulator::event(SPEventContext *event_context, GdkEvent *event) // a) del preserves shape, and control is not pressed // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor - deleteNodes(del_preserves_shape ^ held_control(event->key)); + guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); + if(mode==2){ + if(del_preserves_shape ^ held_control(event->key)) + deleteNodes(false); + else + deleteNodes(true); + } + else + //BSpline end + deleteNodes(del_preserves_shape ^ held_control(event->key)); // Delete any selected gradient nodes as well event_context->deleteSelectedDrag(held_control(event->key)); -- cgit v1.2.3 From 28b44133e0d9df8054e17ed9724ea645220e1530 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 14 Feb 2013 06:01:26 +0100 Subject: All done except cusp continuous and close bspline (bzr r11950.1.32) --- src/ui/tool/path-manipulator.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 35eb23f42..f1b2e12be 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -9,7 +9,9 @@ * Copyright (C) 2009 Authors * Released under GNU GPL, read the file 'COPYING' for more information */ - +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline end #include "live_effects/lpe-powerstroke.h" #include #include @@ -1257,9 +1259,26 @@ void PathManipulator::_updateOutline() sp_canvas_item_hide(_outline); return; } - Geom::PathVector pv = _spcurve->get_pathvector(); pv *= (_edit_transform * _i2d_transform); + //BSpline + if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) { + PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); + LivePathEffect::LPEBSpline *lpe_bsp = dynamic_cast( effect_list.front()->lpeobject->get_lpe()); + if (lpe_bsp) { + Geom::PathVector pv2; + for (Geom::PathVector::iterator i = pv.begin(); i != pv.end(); ++i) { + Geom::Path &path = *i; + for (Geom::Path::const_iterator j = path.begin(); j != path.end_default(); ++j) { + Geom::Path pv2j(j->pointAt(0)); + pv2j.appendNew(j->pointAt(1)); + pv2.push_back(pv2j); + } + } + pv = pv2; + } + } + //BSpline End // This SPCurve thing has to be killed with extreme prejudice SPCurve *_hc = new SPCurve(); if (_show_path_direction) { -- cgit v1.2.3 From 4a0858ff965d54fc08f721fbbc2503f9ab3d9d3c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 18 Feb 2013 11:23:51 +0100 Subject: refactor (bzr r11950.1.35) --- src/ui/tool/node.cpp | 26 ++++++++-- src/ui/tool/path-manipulator.cpp | 102 +++++++++++++++++++++++++++++++-------- src/ui/tool/path-manipulator.h | 6 +++ 3 files changed, 110 insertions(+), 24 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index dc6e0fbae..dff8d3dd9 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -13,7 +13,6 @@ #include #include <2geom/bezier-utils.h> #include <2geom/transforms.h> - #include "display/sp-ctrlline.h" #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" @@ -196,8 +195,13 @@ void Handle::move(Geom::Point const &new_pos) break; default: break; } - - setPosition(new_pos); + //BSpline + if(_pm().isBSpline()){ + Handle *h = this; + setPosition(_pm().BSplineHandleReposition(h)); + }else + setPosition(new_pos); + //BSpline End } void Handle::setPosition(Geom::Point const &p) @@ -550,10 +554,24 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); + //BSpline + float pos = 0; + if(_pm().isBSpline()){ + Node *n = this; + pos = _pm().BSplineMaxPosition(n); + } + //BSpline End setPosition(new_pos); _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); - + //BSpline + if(_pm().isBSpline()){ + Handle* front = &_front; + Handle* back = &_back; + _front.setPosition(_pm().BSplineHandleRepositionFixed(front,pos)); + _back.setPosition(_pm().BSplineHandleRepositionFixed(back,pos)); + } + //BSpline End // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f1b2e12be..b650987bc 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1102,7 +1102,6 @@ void PathManipulator::_createControlPointsFromGeometry() Geom::Curve const &cseg = pit->back_closed(); bool fuse_ends = pit->closed() && Geom::are_near(cseg.initialPoint(), cseg.finalPoint()); - for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) { Geom::Point pos = cit->finalPoint(); Node *current_node; @@ -1169,6 +1168,75 @@ void PathManipulator::_createControlPointsFromGeometry() } } + +bool PathManipulator::isBSpline(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) { + PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); + lpe_bsp = dynamic_cast( effect_list.front()->lpeobject->get_lpe()); + }else{ + lpe_bsp = NULL; + } + if(lpe_bsp){ + return true; + } + return false; +} +double PathManipulator::BSplineMaxPosition(Node *n){ + double nearestPointAt = 0; + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + Node * frontNode = n->nodeToward(n->front()); + if(frontNode){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(frontNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); + } + Node * backNode = n->nodeToward(n->back()); + if(backNode){ + lineInsideNodes->reset(); + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(backNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + using std::max; + nearestPointAt = max(nearestPointAt,1-Geom::nearest_point(n->back()->position(),*lineInsideNodes->first_segment())); + } + return nearestPointAt; +} + +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ + double nearestPointAt = 0; + Node *n = h->parent(); + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + Node * nextNode = n->nodeToward(h); + if(nextNode){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); + } + return SBasisInsideNodes.valueAt(nearestPointAt); +} + +Geom::Point PathManipulator::BSplineHandleRepositionFixed(Handle *h,double pos){ + Node *n = h->parent(); + if(n->back()->position() == h->position()) + pos = 1-pos; + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + Node * nextNode = n->nodeToward(h); + if(nextNode){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + }else{ + return n->position(); + } + return SBasisInsideNodes.valueAt(pos); +} + /** Construct the geometric representation of nodes and handles, update the outline * and display * \param alert_LPE if true, first the LPE is warned what the new path is going to be before updating it @@ -1184,14 +1252,25 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } NodeList::iterator prev = subpath->begin(); builder.moveTo(prev->position()); - for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { + if (this->isBSpline()) { + float pos = BSplineMaxPosition(i.ptr()); + i.ptr()->front()->setPosition(BSplineHandleRepositionFixed(i.ptr()->front(),pos)); + i.ptr()->back()->setPosition(BSplineHandleRepositionFixed(i.ptr()->back(),pos)); + } + //BSplie End build_segment(builder, prev.ptr(), i.ptr()); prev = i; } if (subpath->closed()) { // Here we link the last and first node if the path is closed. // If the last segment is Bezier, we add it. + if (this->isBSpline()) { + float pos = BSplineMaxPosition(prev.ptr()); + subpath->begin().ptr()->front()->setPosition(BSplineHandleRepositionFixed(subpath->begin().ptr()->front(),pos)); + prev.ptr()->back()->setPosition(BSplineHandleRepositionFixed(prev.ptr()->back(),pos)); + + } if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } @@ -1200,6 +1279,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } ++spi; } + builder.finish(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); @@ -1261,24 +1341,6 @@ void PathManipulator::_updateOutline() } Geom::PathVector pv = _spcurve->get_pathvector(); pv *= (_edit_transform * _i2d_transform); - //BSpline - if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) { - PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); - LivePathEffect::LPEBSpline *lpe_bsp = dynamic_cast( effect_list.front()->lpeobject->get_lpe()); - if (lpe_bsp) { - Geom::PathVector pv2; - for (Geom::PathVector::iterator i = pv.begin(); i != pv.end(); ++i) { - Geom::Path &path = *i; - for (Geom::Path::const_iterator j = path.begin(); j != path.end_default(); ++j) { - Geom::Path pv2j(j->pointAt(0)); - pv2j.appendNew(j->pointAt(1)); - pv2.push_back(pv2j); - } - } - pv = pv2; - } - } - //BSpline End // This SPCurve thing has to be killed with extreme prejudice SPCurve *_hc = new SPCurve(); if (_show_path_direction) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index a51b8c410..72d84a241 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -104,6 +104,12 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); + //BSpline + bool isBSpline(); + double BSplineMaxPosition(Node *n); + Geom::Point BSplineHandleReposition(Handle *h); + Geom::Point BSplineHandleRepositionFixed(Handle *h,double pos); + //BSpline End void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From dfe131791aef37e26fd0358c32222dacf813864c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 19 Feb 2013 12:08:14 +0100 Subject: Mayor refactor (bzr r11950.1.36) --- src/ui/tool/node.cpp | 39 +++++++++++++---- src/ui/tool/path-manipulator.cpp | 90 ++++++++++++++++++++++------------------ src/ui/tool/path-manipulator.h | 4 +- 3 files changed, 82 insertions(+), 51 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index dff8d3dd9..1a196c857 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -135,6 +135,15 @@ void Handle::move(Geom::Point const &new_pos) Node *node_away = _parent->nodeAwayFrom(this); // node in the opposite direction Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; + //BSpline + bool isBSpline = false; + double pos = 0; + Handle *h = NULL; + Handle *h2 = NULL; + if(_pm().isBSpline()){ + isBSpline = true; + //BSpline End + } if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -165,6 +174,15 @@ void Handle::move(Geom::Point const &new_pos) other->setDirection(*node_towards, *_parent); } } + //BSpline + if(isBSpline){ + h = this; + setPosition(_pm().BSplineHandleReposition(h)); + pos = _pm().BSplineHandlePosition(h); + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + } + //BSpline End setPosition(new_pos); return; } @@ -195,12 +213,15 @@ void Handle::move(Geom::Point const &new_pos) break; default: break; } + setPosition(new_pos); //BSpline - if(_pm().isBSpline()){ - Handle *h = this; + if(isBSpline){ + h = this; setPosition(_pm().BSplineHandleReposition(h)); - }else - setPosition(new_pos); + pos = _pm().BSplineHandlePosition(h); + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + } //BSpline End } @@ -555,10 +576,12 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); //BSpline - float pos = 0; + double pos = 0; if(_pm().isBSpline()){ Node *n = this; - pos = _pm().BSplineMaxPosition(n); + pos = _pm().BSplineHandlePosition(n->front()); + if(pos == 0) + pos = _pm().BSplineHandlePosition(n->back()); } //BSpline End setPosition(new_pos); @@ -568,8 +591,8 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline()){ Handle* front = &_front; Handle* back = &_back; - _front.setPosition(_pm().BSplineHandleRepositionFixed(front,pos)); - _back.setPosition(_pm().BSplineHandleRepositionFixed(back,pos)); + _front.setPosition(_pm().BSplineHandleReposition(front,pos)); + _back.setPosition(_pm().BSplineHandleReposition(back,pos)); } //BSpline End // if the node has a smooth handle after a line segment, it should be kept colinear diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index b650987bc..c4158931a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1182,31 +1182,8 @@ bool PathManipulator::isBSpline(){ } return false; } -double PathManipulator::BSplineMaxPosition(Node *n){ - double nearestPointAt = 0; - Geom::D2< Geom::SBasis > SBasisInsideNodes; - SPCurve *lineInsideNodes = new SPCurve(); - Node * frontNode = n->nodeToward(n->front()); - if(frontNode){ - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(frontNode->position()); - SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); - } - Node * backNode = n->nodeToward(n->back()); - if(backNode){ - lineInsideNodes->reset(); - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(backNode->position()); - SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - using std::max; - nearestPointAt = max(nearestPointAt,1-Geom::nearest_point(n->back()->position(),*lineInsideNodes->first_segment())); - } - return nearestPointAt; -} - -Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ - double nearestPointAt = 0; +double PathManipulator::BSplineHandlePosition(Handle *h){ + double pos = 0; Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); @@ -1215,19 +1192,23 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } - return SBasisInsideNodes.valueAt(nearestPointAt); + return pos; } -Geom::Point PathManipulator::BSplineHandleRepositionFixed(Handle *h,double pos){ +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ + double pos = 0; + pos = this->BSplineHandlePosition(h); + return BSplineHandleReposition(h,pos); +} + +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Node *n = h->parent(); - if(n->back()->position() == h->position()) - pos = 1-pos; Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode){ + if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); @@ -1251,26 +1232,53 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); + //BSpline + float pos = NULL; + bool isBSpline = false; + if(this->isBSpline()) + isBSpline = true; + if(isBSpline){ + pos = BSplineHandlePosition(prev.ptr()->front()); + prev.ptr()->front()->setPosition(BSplineHandleReposition(prev.ptr()->front(),pos)); + if(pos == 0){ + prev.ptr()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); + } + } + //BSpline End builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - if (this->isBSpline()) { - float pos = BSplineMaxPosition(i.ptr()); - i.ptr()->front()->setPosition(BSplineHandleRepositionFixed(i.ptr()->front(),pos)); - i.ptr()->back()->setPosition(BSplineHandleRepositionFixed(i.ptr()->back(),pos)); + //BSpline + if (isBSpline) { + pos = BSplineHandlePosition(i.ptr()->front()); + if(pos == 0) + pos = BSplineHandlePosition(i.ptr()->back()); + i.ptr()->front()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); + i.ptr()->back()->setPosition(BSplineHandleReposition(i.ptr()->back(),pos)); + if(pos == 0){ + i.ptr()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); + } } - //BSplie End + + //BSpline End build_segment(builder, prev.ptr(), i.ptr()); prev = i; } if (subpath->closed()) { // Here we link the last and first node if the path is closed. // If the last segment is Bezier, we add it. - if (this->isBSpline()) { - float pos = BSplineMaxPosition(prev.ptr()); - subpath->begin().ptr()->front()->setPosition(BSplineHandleRepositionFixed(subpath->begin().ptr()->front(),pos)); - prev.ptr()->back()->setPosition(BSplineHandleRepositionFixed(prev.ptr()->back(),pos)); - + //BSpline + if (isBSpline) { + pos = BSplineHandlePosition(prev.ptr()->front()); + if(pos == 0) + pos = BSplineHandlePosition(subpath->begin().ptr()->back()); + subpath->begin().ptr()->front()->setPosition(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); + prev.ptr()->back()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); + if(pos == 0){ + subpath->begin().ptr()->setPosition(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); + prev.ptr()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); + } } + //BSpline End if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 72d84a241..55958530d 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,9 +106,9 @@ private: void _createControlPointsFromGeometry(); //BSpline bool isBSpline(); - double BSplineMaxPosition(Node *n); + double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); - Geom::Point BSplineHandleRepositionFixed(Handle *h,double pos); + Geom::Point BSplineHandleReposition(Handle *h,double pos); //BSpline End void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); -- cgit v1.2.3 From 9af17a6572db964acebd2b7eeea29c8b722c8221 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 23 Feb 2013 23:34:58 +0100 Subject: Saved for next refactor (bzr r11950.1.37) --- src/ui/tool/curve-drag-point.cpp | 20 +++++++++++++------- src/ui/tool/node.cpp | 5 ++--- src/ui/tool/path-manipulator.cpp | 38 +++++++++++--------------------------- 3 files changed, 26 insertions(+), 37 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index b83ce1b3c..40dcb5058 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,9 +53,12 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - first->front()->move(first->front()->position() + delta); - second->back()->move(second->back()->position() - delta); - + //BSpline + if(!_pm.isBSpline()){ + first->front()->move(first->front()->position() + delta); + second->back()->move(second->back()->position() - delta); + } + //BSpline End _pm.update(); } else { _segment_was_degenerate = false; @@ -87,10 +90,13 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - - first->front()->move(first->front()->position() + offset0); - second->back()->move(second->back()->position() + offset1); - + //BSpline + if(!_pm.isBSpline()){ + first->front()->move(first->front()->position() + offset0); + second->back()->move(second->back()->position() + offset1); + }else if(weight>=0.8)second->back()->move(new_pos); + else if(weight<=0.2)first->front()->move(new_pos); + //BSpline End _pm.update(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1a196c857..c6a2df749 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -142,6 +142,7 @@ void Handle::move(Geom::Point const &new_pos) Handle *h2 = NULL; if(_pm().isBSpline()){ isBSpline = true; + _parent->_selection.insert(_parent); //BSpline End } @@ -174,6 +175,7 @@ void Handle::move(Geom::Point const &new_pos) other->setDirection(*node_towards, *_parent); } } + setPosition(new_pos); //BSpline if(isBSpline){ h = this; @@ -183,7 +185,6 @@ void Handle::move(Geom::Point const &new_pos) this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); } //BSpline End - setPosition(new_pos); return; } @@ -580,8 +581,6 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline()){ Node *n = this; pos = _pm().BSplineHandlePosition(n->front()); - if(pos == 0) - pos = _pm().BSplineHandlePosition(n->back()); } //BSpline End setPosition(new_pos); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index c4158931a..ecb8abcf4 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1185,21 +1185,18 @@ bool PathManipulator::isBSpline(){ double PathManipulator::BSplineHandlePosition(Handle *h){ double pos = 0; Node *n = h->parent(); - Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); if(nextNode){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } return pos; } Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ - double pos = 0; - pos = this->BSplineHandlePosition(h); + double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } @@ -1208,7 +1205,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode && pos != 0){ + if(nextNode){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); @@ -1233,50 +1230,37 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } NodeList::iterator prev = subpath->begin(); //BSpline - float pos = NULL; + double pos =0; bool isBSpline = false; if(this->isBSpline()) isBSpline = true; if(isBSpline){ pos = BSplineHandlePosition(prev.ptr()->front()); - prev.ptr()->front()->setPosition(BSplineHandleReposition(prev.ptr()->front(),pos)); - if(pos == 0){ - prev.ptr()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); - } + prev->front()->setPosition(BSplineHandleReposition(prev->front(),pos)); } //BSpline End builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { //BSpline if (isBSpline) { - pos = BSplineHandlePosition(i.ptr()->front()); - if(pos == 0) - pos = BSplineHandlePosition(i.ptr()->back()); - i.ptr()->front()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); - i.ptr()->back()->setPosition(BSplineHandleReposition(i.ptr()->back(),pos)); - if(pos == 0){ - i.ptr()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); - } + pos = BSplineHandlePosition(i->back()); + i->front()->setPosition(BSplineHandleReposition(i->front(),pos)); + i->back()->setPosition(BSplineHandleReposition(i->back(),pos)); } //BSpline End build_segment(builder, prev.ptr(), i.ptr()); prev = i; } + if (subpath->closed()) { // Here we link the last and first node if the path is closed. // If the last segment is Bezier, we add it. //BSpline if (isBSpline) { - pos = BSplineHandlePosition(prev.ptr()->front()); - if(pos == 0) - pos = BSplineHandlePosition(subpath->begin().ptr()->back()); - subpath->begin().ptr()->front()->setPosition(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); - prev.ptr()->back()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); - if(pos == 0){ - subpath->begin().ptr()->setPosition(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); - prev.ptr()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); - } + pos = BSplineHandlePosition(prev.next()->back()); + subpath->begin()->front()->setPosition(BSplineHandleReposition(subpath->begin()->front(),pos)); + prev.next()->back()->setPosition(BSplineHandleReposition(prev.next()->back(),pos)); } //BSpline End if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { -- cgit v1.2.3 From ca40dfd444c2543a6debc0786fa8679a108b1056 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 25 Feb 2013 10:59:10 +0100 Subject: BSpline refactor (bzr r11950.1.38) --- src/ui/tool/node.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c6a2df749..6dc6c7528 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -577,13 +577,29 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); //BSpline + double prevPos = 0; double pos = 0; + double nextPos = 0; + Node *n = this; + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); if(_pm().isBSpline()){ - Node *n = this; + if(prevNode) + prevPos = _pm().BSplineHandlePosition(prevNode->front()); pos = _pm().BSplineHandlePosition(n->front()); + if(nextNode) + nextPos = _pm().BSplineHandlePosition(nextNode->back()); } //BSpline End setPosition(new_pos); + //BSpline + if(prevNode){ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); + } + if(nextNode){ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); + } + //BSpline End _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); //BSpline -- cgit v1.2.3 From ecc57932f1e7d157950ada2901f6ea6f3acc8aad Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 28 Feb 2013 04:43:21 +0100 Subject: Fixed closed pc->ea (bzr r11950.1.40) --- src/ui/tool/node.cpp | 38 ++++++++++++++++----------------- src/ui/tool/path-manipulator.cpp | 45 ++++++++++++++-------------------------- 2 files changed, 34 insertions(+), 49 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index fef904006..4cac0e543 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -138,12 +138,14 @@ void Handle::move(Geom::Point const &new_pos) //BSpline bool isBSpline = false; double pos = 0; - Handle *h = this; + Handle *h = NULL; + Handle *h2 = NULL; if(_pm().isBSpline()){ isBSpline = true; - _parent->_selection.insert(_parent); - //BSpline End + if(!_parent->selected()) + _parent->_selection.insert(_parent); } + //BSpline End if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -177,12 +179,11 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //BSpline if(isBSpline){ + h = this; setPosition(_pm().BSplineHandleReposition(h)); pos = _pm().BSplineHandlePosition(h); - other->setPosition(_pm().BSplineHandleReposition(other,pos)); - if(pos == 0){ - _parent->setPosition(h->position()); - } + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); } //BSpline End return; @@ -217,12 +218,11 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //BSpline if(isBSpline){ + h = this; setPosition(_pm().BSplineHandleReposition(h)); pos = _pm().BSplineHandlePosition(h); - other->setPosition(_pm().BSplineHandleReposition(other,pos)); - if(pos == 0){ - _parent->setPosition(h->position()); - } + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); } //BSpline End } @@ -588,21 +588,25 @@ void Node::move(Geom::Point const &new_pos) if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); pos = _pm().BSplineHandlePosition(n->front()); + if(pos == 0) + pos = _pm().BSplineHandlePosition(n->back()); if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); } //BSpline End setPosition(new_pos); //BSpline - if(prevNode){ + if(prevNode) prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); - } - if(nextNode){ + if(nextNode) nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); - } //BSpline End _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); + //BSpline End + // if the node has a smooth handle after a line segment, it should be kept colinear + // with the segment + _fixNeighbors(old_pos, new_pos); //BSpline if(_pm().isBSpline()){ Handle* front = &_front; @@ -610,10 +614,6 @@ void Node::move(Geom::Point const &new_pos) _front.setPosition(_pm().BSplineHandleReposition(front,pos)); _back.setPosition(_pm().BSplineHandleReposition(back,pos)); } - //BSpline End - // if the node has a smooth handle after a line segment, it should be kept colinear - // with the segment - _fixNeighbors(old_pos, new_pos); } void Node::transform(Geom::Affine const &m) diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index ecb8abcf4..7c23ee153 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1182,15 +1182,20 @@ bool PathManipulator::isBSpline(){ } return false; } + double PathManipulator::BSplineHandlePosition(Handle *h){ + using Geom::X; + using Geom::Y; double pos = 0; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode){ + Geom::Point positionH = h->position(); + positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + if(nextNode && n->position() != h->position()){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); } return pos; } @@ -1201,18 +1206,23 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ } Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ + using Geom::X; + using Geom::Y; + Geom::Point ret(0,0); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode){ + if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + ret = SBasisInsideNodes.valueAt(pos); + ret = Geom::Point(ret[X] + 0.0625,ret[Y] + 0.0625); }else{ - return n->position(); + ret = n->position(); } - return SBasisInsideNodes.valueAt(pos); + return ret; } /** Construct the geometric representation of nodes and handles, update the outline @@ -1229,26 +1239,8 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); - //BSpline - double pos =0; - bool isBSpline = false; - if(this->isBSpline()) - isBSpline = true; - if(isBSpline){ - pos = BSplineHandlePosition(prev.ptr()->front()); - prev->front()->setPosition(BSplineHandleReposition(prev->front(),pos)); - } - //BSpline End builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - //BSpline - if (isBSpline) { - pos = BSplineHandlePosition(i->back()); - i->front()->setPosition(BSplineHandleReposition(i->front(),pos)); - i->back()->setPosition(BSplineHandleReposition(i->back(),pos)); - } - - //BSpline End build_segment(builder, prev.ptr(), i.ptr()); prev = i; } @@ -1256,13 +1248,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) if (subpath->closed()) { // Here we link the last and first node if the path is closed. // If the last segment is Bezier, we add it. - //BSpline - if (isBSpline) { - pos = BSplineHandlePosition(prev.next()->back()); - subpath->begin()->front()->setPosition(BSplineHandleReposition(subpath->begin()->front(),pos)); - prev.next()->back()->setPosition(BSplineHandleReposition(prev.next()->back(),pos)); - } - //BSpline End if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } -- cgit v1.2.3 From 93394bdda7e0c876eafe9847a01c6d91e0dc0f7a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 5 Mar 2013 22:51:31 +0100 Subject: BPower for testing. (bzr r11950.1.45) --- src/ui/tool/node.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 4cac0e543..e7d62d619 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -142,8 +142,14 @@ void Handle::move(Geom::Point const &new_pos) Handle *h2 = NULL; if(_pm().isBSpline()){ isBSpline = true; - if(!_parent->selected()) - _parent->_selection.insert(_parent); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + _parent->_selection.erase(n); + } + //if(!_parent->selected()) + _parent->_selection.insert(_parent); } //BSpline End @@ -596,10 +602,12 @@ void Node::move(Geom::Point const &new_pos) //BSpline End setPosition(new_pos); //BSpline - if(prevNode) - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); - if(nextNode) - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); + if(_pm().isBSpline()){ + if(prevNode) + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); + if(nextNode) + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); + } //BSpline End _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); -- cgit v1.2.3 From caaed5a4603d40a0043bdcb564e213ea9e7d0021 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 6 Mar 2013 04:01:15 +0100 Subject: Permanent show outline in BSpline mode (bzr r11950.1.47) --- src/ui/tool/path-manipulator.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7c23ee153..0a100ecfb 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -895,6 +895,9 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { + //BSpline + if(isBSpline()) show = true; + //BSpline if (show == _show_outline) return; _show_outline = show; _updateOutline(); -- cgit v1.2.3 From b2981a3b8f54bccfa45c76f57b38c9c93808d2fc Mon Sep 17 00:00:00 2001 From: root Date: Tue, 12 Mar 2013 00:48:05 +0100 Subject: ~sub fix, double click to reset default handles and control to 10% step (bzr r11950.1.51) --- src/ui/tool/multi-path-manipulator.cpp | 4 +- src/ui/tool/node.cpp | 68 +++++++++++++++++++++++++++++++--- src/ui/tool/node.h | 3 ++ 3 files changed, 69 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index c9e35e5b2..2ef8c1766 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -296,6 +296,7 @@ void MultiPathManipulator::invertSelectionInSubpaths() invokeForAll(&PathManipulator::invertSelectionInSubpaths); } + void MultiPathManipulator::setNodeType(NodeType type) { if (_selection.empty()) return; @@ -307,7 +308,7 @@ void MultiPathManipulator::setNodeType(NodeType type) Node *node = dynamic_cast(*i); if (node) { retract_handles &= (node->type() == NODE_CUSP); - node->setType(type); + node->setType(type,true); } } @@ -324,6 +325,7 @@ void MultiPathManipulator::setNodeType(NodeType type) _done(retract_handles ? _("Retract handles") : _("Change node type")); } + void MultiPathManipulator::setSegmentType(SegmentType type) { if (_selection.empty()) return; diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index e7d62d619..bee2cc477 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -29,6 +29,9 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include +//BSpline +#include +//BSpline End; namespace { @@ -146,10 +149,11 @@ void Handle::move(Geom::Point const &new_pos) Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - //if(!_parent->selected()) - _parent->_selection.insert(_parent); + if(n != _parent) + _parent->_selection.erase(n); + } + if(!_parent->selected()) + _parent->_selection.insert(_parent); } //BSpline End @@ -307,12 +311,33 @@ bool Handle::_eventHandler(SPEventContext *event_context, GdkEvent *event) break; default: break; } + //BSpline + case GDK_2BUTTON_PRESS: + handle_2button_press(); + break; + //BSpline End default: break; } return ControlPoint::_eventHandler(event_context, event); } +//BSpline +void Handle::handle_2button_press(){ + if(_pm().isBSpline()){ + Handle *h = NULL; + Handle *h2 = NULL; + double pos = 0; + h = this; + setPosition(_pm().BSplineHandleReposition(h,0.3334)); + pos = _pm().BSplineHandlePosition(h); + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + _pm().update(); + } +} +//BSpline End + bool Handle::grabbed(GdkEventMotion *) { _saved_other_pos = other()->position(); @@ -360,6 +385,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; + //BSpline + if(_pm().isBSpline()){ + Handle *h = NULL; + double pos = 0; + h = this; + setPosition(new_pos); + pos = ceilf(_pm().BSplineHandlePosition(h)*10)/10; + new_pos=_pm().BSplineHandleReposition(h,pos); + } + //BSpline End } std::vector unselected; @@ -728,7 +763,7 @@ void Node::updateHandles() _front._handleControlStyling(); _back._handleControlStyling(); } - + void Node::setType(NodeType type, bool update_handles) { @@ -738,6 +773,27 @@ void Node::setType(NodeType type, bool update_handles) return; } + //BSpline + if(_pm().isBSpline()){ + if (isEndNode()) return; + Handle* front = &_front; + Handle* back = &_back; + double pos = 0.3334; + switch (type) { + case NODE_CUSP: + if(update_handles) + pos = 0; + else + pos = _pm().BSplineHandlePosition(front);; + break; + default: break; + } + type = NODE_CUSP; + _front.setPosition(_pm().BSplineHandleReposition(front,pos)); + _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + } + //BSpline End + // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -821,7 +877,9 @@ void Node::setType(NodeType type, bool update_handles) default: break; } } + _type = type; + _setControlType(nodeTypeToCtrlType(_type)); updateState(); } diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 591dd8532..e74698b1a 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -107,6 +107,9 @@ protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); + //Bspline + virtual void handle_2button_press(); + //BSpline End virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); virtual void ungrabbed(GdkEventButton *event); -- cgit v1.2.3 From 732618cd7d6159ee47cc0dd8b86cf07790e3e724 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 17 Mar 2013 13:29:02 +0100 Subject: Working with widjets (bzr r11950.1.56) --- src/ui/dialog/dialog-manager.cpp | 7 +++++++ src/ui/dialog/document-properties.cpp | 2 ++ src/ui/dialog/export.cpp | 26 +++++--------------------- src/ui/dialog/export.h | 19 ++++++++++++------- src/ui/dialog/fill-and-stroke.cpp | 15 --------------- src/ui/dialog/find.cpp | 4 ---- src/ui/dialog/find.h | 6 +----- src/ui/dialog/glyphs.h | 2 +- src/ui/dialog/icon-preview.cpp | 4 ---- src/ui/dialog/input.cpp | 2 -- src/ui/dialog/layer-properties.h | 6 +++--- src/ui/dialog/object-properties.cpp | 6 ------ src/ui/dialog/object-properties.h | 10 ---------- src/ui/dialog/svg-fonts-dialog.cpp | 4 ++++ src/ui/dialog/svg-fonts-dialog.h | 4 ++-- src/ui/dialog/text-edit.cpp | 1 - src/ui/dialog/text-edit.h | 2 +- src/ui/dialog/tracedialog.cpp | 1 - src/ui/dialog/xml-tree.h | 2 +- src/ui/tool/control-point.cpp | 2 +- src/ui/tool/node-tool.h | 3 +++ src/ui/tool/path-manipulator.h | 2 +- src/ui/widget/entry.cpp | 2 -- src/ui/widget/entry.h | 6 +++--- src/ui/widget/frame.h | 8 +++++--- src/ui/widget/registered-widget.h | 2 +- src/ui/widget/selected-style.h | 2 +- src/ui/widget/style-swatch.h | 2 +- 28 files changed, 55 insertions(+), 97 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 993f48d8f..faba47769 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -53,7 +53,10 @@ #include "ui/dialog/export.h" #include "ui/dialog/xml-tree.h" #include "ui/dialog/clonetiler.h" + +#ifdef ENABLE_SVG_FONTS #include "ui/dialog/svg-fonts-dialog.h" +#endif // ENABLE_SVG_FONTS namespace Inkscape { namespace UI { @@ -115,7 +118,9 @@ DialogManager::DialogManager() { registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); +#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); +#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); @@ -149,7 +154,9 @@ DialogManager::DialogManager() { registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); +#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); +#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index d335fb303..045b34814 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -792,6 +792,8 @@ void DocumentProperties::build_scripting() _page_external_scripts->table().attach(_external_remove_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0); #endif + row++; + //# Set up the External Scripts box _ExternalScriptsListStore = Gtk::ListStore::create(_ExternalScriptsListColumns); _ExternalScriptsList.set_model(_ExternalScriptsListStore); diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 086e52a6c..603786742 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -22,21 +22,14 @@ #include #include -#include +#include +#include +#include #include #include -#include -#include -#include #include -#if WITH_GTKMM_3_0 -# include -#else -# include -#endif -#include -#include - +#include +#include #ifdef WITH_GNOME_VFS # include // gnome_vfs_initialized #endif @@ -133,15 +126,6 @@ namespace Inkscape { namespace UI { namespace Dialog { -/** A list of strings that is used both in the preferences, and in the - data fields to describe the various values of \c selection_type. */ -static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; - -/** The names on the buttons for the various selection types. */ -static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; - Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), current_key(SELECTION_PAGE), diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index b10c98fd2..5dca9cfa5 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -14,12 +14,10 @@ #include #include - -#include #include #include -#include #include +#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" @@ -27,14 +25,11 @@ #include "ui/widget/button.h" #include "ui/widget/entry.h" -namespace Gtk { -class Dialog; -} - namespace Inkscape { namespace UI { namespace Dialog { + /** What type of button is being pressed */ enum selection_type { SELECTION_PAGE = 0, /**< Export the whole page */ @@ -44,6 +39,16 @@ enum selection_type { SELECTION_NUMBER_OF /**< A counter for the number of these guys */ }; +/** A list of strings that is used both in the preferences, and in the + data fields to describe the various values of \c selection_type. */ +static const char * selection_names[SELECTION_NUMBER_OF] = { + "page", "drawing", "selection", "custom"}; + +/** The names on the buttons for the various selection types. */ +static const char * selection_labels[SELECTION_NUMBER_OF] = { + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + + /** * A dialog widget to export to various image formats such as bitmap and png. * diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 19b873d54..8de2da18b 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -132,24 +132,14 @@ void FillAndStroke::_layoutPageFill() { fillWdgt = manage(sp_fill_style_widget_new()); - -#if WITH_GTKMM_3_0 _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1); -#else - _page_fill->table().attach(*fillWdgt, 0, 1, 0, 1); -#endif } void FillAndStroke::_layoutPageStrokePaint() { strokeWdgt = manage(sp_stroke_style_paint_widget_new()); - -#if WITH_GTKMM_3_0 _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1); -#else - _page_stroke_paint->table().attach(*strokeWdgt, 0, 1, 0, 1); -#endif } void @@ -158,12 +148,7 @@ FillAndStroke::_layoutPageStrokeStyle() //Gtk::Widget *strokeStyleWdgt = manage(Glib::wrap(sp_stroke_style_line_widget_new())); //Gtk::Widget *strokeStyleWdgt = static_cast(sp_stroke_style_line_widget_new()); strokeStyleWdgt = sp_stroke_style_line_widget_new(); - -#if WITH_GTKMM_3_0 _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 0, 1, 1); -#else - _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 1, 0, 1); -#endif } void diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index def7b5bdb..d3ce99b00 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -15,10 +15,7 @@ #endif #include "find.h" - -#include #include - #include "verbs.h" #include "message-stack.h" @@ -59,7 +56,6 @@ #include "xml/attribute-record.h" #include -#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h index 14d54b8d4..77a6c9d02 100644 --- a/src/ui/dialog/find.h +++ b/src/ui/dialog/find.h @@ -21,11 +21,7 @@ #include "ui/widget/entry.h" #include "ui/widget/frame.h" #include - -#include -#include -#include -#include +#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index 3d0571244..6571af0a4 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -20,7 +20,7 @@ class Label; class ListStore; } -struct SPFontSelector; +class SPFontSelector; class font_instance; diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 801ab2922..de213ca85 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -20,11 +20,7 @@ #include #include #include - #include -#include -#include - #include #include #include diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 82e65435d..9c9f7faa3 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -17,9 +17,7 @@ #include #include - #include -#include #include #include #include diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index 0e2f8ed94..9de303f89 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -80,9 +80,9 @@ protected: void perform(LayerPropertiesDialog &dialog); }; - friend struct Rename; - friend struct Create; - friend struct Move; + friend class Rename; + friend class Create; + friend class Move; Strategy *_strategy; SPDesktop *_desktop; diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 8a2b0299a..114204961 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -38,12 +38,6 @@ #include "sp-item.h" #include -#if WITH_GTKMM_3_0 -# include -#else -# include -#endif - namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index 624a18246..b49293ea1 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -35,8 +35,6 @@ #include "ui/widget/panel.h" #include "ui/widget/frame.h" - -#include #include #include #include @@ -48,14 +46,6 @@ class SPAttributeTable; class SPDesktop; class SPItem; -namespace Gtk { -#if WITH_GTKMM_3_0 -class Grid; -#else -class Table; -#endif -} - namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index bce63093d..0da39dd73 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -15,6 +15,8 @@ # include #endif +#ifdef ENABLE_SVG_FONTS + #include "svg-fonts-dialog.h" #include "document-private.h" #include "document-undo.h" @@ -943,6 +945,8 @@ SvgFontsDialog::~SvgFontsDialog(){} } // namespace UI } // namespace Inkscape +#endif //#ifdef ENABLE_SVG_FONTS + /* Local Variables: mode:c++ diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h index 01f70654a..9be984820 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -34,8 +34,8 @@ class HScale; #endif } -struct SPGlyph; -struct SPGlyphKerning; +class SPGlyph; +class SPGlyphKerning; class SvgFont; class SvgFontDrawingArea : Gtk::DrawingArea{ diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 67c6578f9..a71227861 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -57,7 +57,6 @@ extern "C" { #include "widgets/icon.h" #include "widgets/font-selector.h" #include -#include #include "unit-constants.h" diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h index f27fdfc87..3fdeea05d 100644 --- a/src/ui/dialog/text-edit.h +++ b/src/ui/dialog/text-edit.h @@ -30,7 +30,7 @@ #include "ui/dialog/desktop-tracker.h" class SPItem; -struct SPFontSelector; +class SPFontSelector; class font_instance; class SPCSSAttr; diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index bd467555e..1ad827a56 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -20,7 +20,6 @@ #include #include "ui/widget/spinbutton.h" #include "ui/widget/frame.h" -#include #include #include //for GTK_RESPONSE* types diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h index 58ef3aef8..0a6e3a786 100644 --- a/src/ui/dialog/xml-tree.h +++ b/src/ui/dialog/xml-tree.h @@ -29,7 +29,7 @@ #include "message.h" class SPDesktop; -class SPObject; +struct SPObject; struct SPXMLViewAttrList; struct SPXMLViewContent; struct SPXMLViewTree; diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index 069dcc67b..8c4924f26 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -7,8 +7,8 @@ */ #include -#include #include +#include #include <2geom/point.h> #include "desktop.h" #include "desktop-handles.h" diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index bc5267bb2..49b1496d4 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -25,6 +25,9 @@ #define INK_IS_NODE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INK_TYPE_NODE_TOOL)) #define INK_IS_NODE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INK_TYPE_NODE_TOOL)) +class InkNodeTool; +class InkNodeToolClass; + namespace Inkscape { namespace Display { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 8bc097ed6..a235a3b05 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -22,7 +22,7 @@ struct SPCanvasItem; class SPCurve; -class SPPath; +struct SPPath; namespace Inkscape { namespace XML { class Node; } diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 64d28119a..173e014d9 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -13,8 +13,6 @@ #include "entry.h" -#include - namespace Inkscape { namespace UI { namespace Widget { diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h index de5cceadd..53b848fc9 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -11,10 +11,10 @@ #define INKSCAPE_UI_WIDGET_ENTRY__H #include "labelled.h" +#include -namespace Gtk { -class Entry; -} +#include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/frame.h b/src/ui/widget/frame.h index a04666651..cf736d8a1 100644 --- a/src/ui/widget/frame.h +++ b/src/ui/widget/frame.h @@ -10,9 +10,11 @@ #ifndef INKSCAPE_UI_WIDGET_FRAME_H #define INKSCAPE_UI_WIDGET_FRAME_H -#include -#include -#include +#include + +namespace Gtk { +class Frame; +} namespace Inkscape { namespace UI { diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index fa35b815e..2a7843a51 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -32,7 +32,7 @@ #include -struct SPUnit; +class SPUnit; class SPDocument; namespace Gtk { diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 9b78cb17f..6d5222429 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -40,7 +40,7 @@ #include "helper/units.h" class SPDesktop; -struct SPUnit; +class SPUnit; namespace Inkscape { namespace UI { diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index d7bab3732..2b9c32b2e 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -26,7 +26,7 @@ #include "button.h" #include "preferences.h" -struct SPUnit; +class SPUnit; struct SPStyle; class SPCSSAttr; -- cgit v1.2.3 From a5fc5840c370d58f395b7b256a11fd11ef3a9a54 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 18 Mar 2013 02:53:59 +0100 Subject: working whith widgets (bzr r11950.1.57) --- src/ui/tool/node.cpp | 5 ++++- src/ui/tool/node.h | 3 +++ src/ui/tool/path-manipulator.cpp | 16 +++++++++++++--- src/ui/tool/path-manipulator.h | 3 +++ 4 files changed, 23 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index bee2cc477..b628d3500 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,6 +113,9 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _degenerate(true) { setVisible(false); + //BSpline + setControlBsplineSteps( _pm().getControlBsplineSteps()); + //BSpline End; } Handle::~Handle() @@ -391,7 +394,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) double pos = 0; h = this; setPosition(new_pos); - pos = ceilf(_pm().BSplineHandlePosition(h)*10)/10; + pos = ceilf(_pm().BSplineHandlePosition(h)*controlBsplineSteps)/controlBsplineSteps; new_pos=_pm().BSplineHandleReposition(h,pos); } //BSpline End diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index e74698b1a..953ac0061 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -109,12 +109,15 @@ protected: virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); //Bspline virtual void handle_2button_press(); + virtual void setControlBsplineSteps(int controlBsplineStepsValue){controlBsplineSteps = controlBsplineStepsValue;}; + int controlBsplineSteps; //BSpline End virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); virtual void ungrabbed(GdkEventButton *event); virtual bool clicked(GdkEventButton *event); + virtual Glib::ustring _getTip(unsigned state) const; virtual Glib::ustring _getDragTip(GdkEventMotion *event) const; virtual bool _hasDragTips() const { return true; } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 0a100ecfb..b46e85622 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -36,6 +36,7 @@ #include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/path.h" #include "sp-path.h" +#include "sp-lpe-item.h" #include "helper/geom.h" #include "preferences.h" #include "style.h" @@ -1174,9 +1175,8 @@ void PathManipulator::_createControlPointsFromGeometry() bool PathManipulator::isBSpline(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; - if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) { - PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); - lpe_bsp = dynamic_cast( effect_list.front()->lpeobject->get_lpe()); + if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ + lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); }else{ lpe_bsp = NULL; } @@ -1186,6 +1186,16 @@ bool PathManipulator::isBSpline(){ return false; } +int PathManipulator::getControlBsplineSteps(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ + lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); + if(lpe_bsp){ + return lpe_bsp->steps; + } + } + return 2; +} double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index a235a3b05..04148592b 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -89,6 +89,9 @@ public: void updateHandles(); void setControlsTransform(Geom::Affine const &); void hideDragPoint(); + //BSpline + int getControlBsplineSteps(); + //BSpline End MultiPathManipulator &mpm() { return _multi_path_manipulator; } NodeList::iterator subdivideSegment(NodeList::iterator after, double t); -- cgit v1.2.3 From 4e41340374ba833e748ffbbc610a28c7c3559557 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 19 Mar 2013 04:35:35 +0100 Subject: Working width widgets (bzr r11950.1.58) --- src/ui/tool/node.cpp | 7 ++----- src/ui/tool/node.h | 5 +---- src/ui/tool/path-manipulator.cpp | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index b628d3500..819f5db54 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -110,12 +110,9 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _handle_colors, data.handle_group), _parent(parent), _handle_line(ControlManager::getManager().createControlLine(data.handle_line_group)), - _degenerate(true) + _degenerate(true),controlBsplineSteps(2) { setVisible(false); - //BSpline - setControlBsplineSteps( _pm().getControlBsplineSteps()); - //BSpline End; } Handle::~Handle() @@ -394,7 +391,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) double pos = 0; h = this; setPosition(new_pos); - pos = ceilf(_pm().BSplineHandlePosition(h)*controlBsplineSteps)/controlBsplineSteps; + pos = ceilf(_pm().BSplineHandlePosition(h)*_pm().getControlBsplineSteps())/_pm().getControlBsplineSteps(); new_pos=_pm().BSplineHandleReposition(h,pos); } //BSpline End diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 953ac0061..7152f37fd 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -89,7 +89,6 @@ public: virtual void setVisible(bool); virtual void move(Geom::Point const &p); - virtual void setPosition(Geom::Point const &p); inline void setRelativePos(Geom::Point const &p); void setLength(double len); @@ -109,8 +108,6 @@ protected: virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); //Bspline virtual void handle_2button_press(); - virtual void setControlBsplineSteps(int controlBsplineStepsValue){controlBsplineSteps = controlBsplineStepsValue;}; - int controlBsplineSteps; //BSpline End virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); @@ -129,7 +126,7 @@ private: // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; bool _degenerate; // True if the handle is retracted, i.e. has zero length. This is used often internally so it makes sense to cache this - + int controlBsplineSteps; /** * Control point of a cubic Bezier curve in a path. * diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index b46e85622..853d9336a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1191,7 +1191,7 @@ int PathManipulator::getControlBsplineSteps(){ if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); if(lpe_bsp){ - return lpe_bsp->steps; + return lpe_bsp->steps+1; } } return 2; -- cgit v1.2.3 From fc95705f9d5761fe111a445c51afc505d08738a7 Mon Sep 17 00:00:00 2001 From: jtx Date: Tue, 19 Mar 2013 17:56:26 +0100 Subject: Fixing regression (bzr r11950.1.61) --- src/ui/dialog/dialog-manager.cpp | 7 ------- src/ui/dialog/document-properties.cpp | 2 -- src/ui/dialog/export.cpp | 26 +++++++++++++++++++++----- src/ui/dialog/export.h | 19 +++++++------------ src/ui/dialog/fill-and-stroke.cpp | 15 +++++++++++++++ src/ui/dialog/find.cpp | 4 ++++ src/ui/dialog/find.h | 6 +++++- src/ui/dialog/glyphs.h | 2 +- src/ui/dialog/icon-preview.cpp | 4 ++++ src/ui/dialog/input.cpp | 2 ++ src/ui/dialog/layer-properties.h | 6 +++--- src/ui/dialog/object-properties.cpp | 6 ++++++ src/ui/dialog/object-properties.h | 10 ++++++++++ src/ui/dialog/svg-fonts-dialog.cpp | 4 ---- src/ui/dialog/svg-fonts-dialog.h | 4 ++-- src/ui/dialog/text-edit.cpp | 1 + src/ui/dialog/text-edit.h | 2 +- src/ui/dialog/tracedialog.cpp | 1 + src/ui/dialog/xml-tree.h | 2 +- src/ui/tool/control-point.cpp | 2 +- src/ui/tool/node-tool.h | 3 --- src/ui/tool/path-manipulator.h | 2 +- src/ui/widget/entry.cpp | 2 ++ src/ui/widget/entry.h | 6 +++--- src/ui/widget/frame.h | 8 +++----- src/ui/widget/registered-widget.h | 2 +- src/ui/widget/selected-style.h | 2 +- src/ui/widget/style-swatch.h | 2 +- 28 files changed, 97 insertions(+), 55 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index faba47769..993f48d8f 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -53,10 +53,7 @@ #include "ui/dialog/export.h" #include "ui/dialog/xml-tree.h" #include "ui/dialog/clonetiler.h" - -#ifdef ENABLE_SVG_FONTS #include "ui/dialog/svg-fonts-dialog.h" -#endif // ENABLE_SVG_FONTS namespace Inkscape { namespace UI { @@ -118,9 +115,7 @@ DialogManager::DialogManager() { registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); -#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); -#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); @@ -154,9 +149,7 @@ DialogManager::DialogManager() { registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); -#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); -#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 045b34814..d335fb303 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -792,8 +792,6 @@ void DocumentProperties::build_scripting() _page_external_scripts->table().attach(_external_remove_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0); #endif - row++; - //# Set up the External Scripts box _ExternalScriptsListStore = Gtk::ListStore::create(_ExternalScriptsListColumns); _ExternalScriptsList.set_model(_ExternalScriptsListStore); diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index ac039bf77..99a8c08d2 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -22,14 +22,21 @@ #include #include -#include -#include -#include +#include #include #include -#include +#include +#include #include -#include +#include +#if WITH_GTKMM_3_0 +# include +#else +# include +#endif +#include +#include + #ifdef WITH_GNOME_VFS # include // gnome_vfs_initialized #endif @@ -126,6 +133,15 @@ namespace Inkscape { namespace UI { namespace Dialog { +/** A list of strings that is used both in the preferences, and in the + data fields to describe the various values of \c selection_type. */ +static const char * selection_names[SELECTION_NUMBER_OF] = { + "page", "drawing", "selection", "custom"}; + +/** The names on the buttons for the various selection types. */ +static const char * selection_labels[SELECTION_NUMBER_OF] = { + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), current_key(SELECTION_PAGE), diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 5dca9cfa5..b10c98fd2 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -14,10 +14,12 @@ #include #include + +#include #include #include +#include #include -#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" @@ -25,11 +27,14 @@ #include "ui/widget/button.h" #include "ui/widget/entry.h" +namespace Gtk { +class Dialog; +} + namespace Inkscape { namespace UI { namespace Dialog { - /** What type of button is being pressed */ enum selection_type { SELECTION_PAGE = 0, /**< Export the whole page */ @@ -39,16 +44,6 @@ enum selection_type { SELECTION_NUMBER_OF /**< A counter for the number of these guys */ }; -/** A list of strings that is used both in the preferences, and in the - data fields to describe the various values of \c selection_type. */ -static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; - -/** The names on the buttons for the various selection types. */ -static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; - - /** * A dialog widget to export to various image formats such as bitmap and png. * diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 8de2da18b..19b873d54 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -132,14 +132,24 @@ void FillAndStroke::_layoutPageFill() { fillWdgt = manage(sp_fill_style_widget_new()); + +#if WITH_GTKMM_3_0 _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1); +#else + _page_fill->table().attach(*fillWdgt, 0, 1, 0, 1); +#endif } void FillAndStroke::_layoutPageStrokePaint() { strokeWdgt = manage(sp_stroke_style_paint_widget_new()); + +#if WITH_GTKMM_3_0 _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1); +#else + _page_stroke_paint->table().attach(*strokeWdgt, 0, 1, 0, 1); +#endif } void @@ -148,7 +158,12 @@ FillAndStroke::_layoutPageStrokeStyle() //Gtk::Widget *strokeStyleWdgt = manage(Glib::wrap(sp_stroke_style_line_widget_new())); //Gtk::Widget *strokeStyleWdgt = static_cast(sp_stroke_style_line_widget_new()); strokeStyleWdgt = sp_stroke_style_line_widget_new(); + +#if WITH_GTKMM_3_0 _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 0, 1, 1); +#else + _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 1, 0, 1); +#endif } void diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index d3ce99b00..def7b5bdb 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -15,7 +15,10 @@ #endif #include "find.h" + +#include #include + #include "verbs.h" #include "message-stack.h" @@ -56,6 +59,7 @@ #include "xml/attribute-record.h" #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h index 77a6c9d02..14d54b8d4 100644 --- a/src/ui/dialog/find.h +++ b/src/ui/dialog/find.h @@ -21,7 +21,11 @@ #include "ui/widget/entry.h" #include "ui/widget/frame.h" #include -#include + +#include +#include +#include +#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index 6571af0a4..3d0571244 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -20,7 +20,7 @@ class Label; class ListStore; } -class SPFontSelector; +struct SPFontSelector; class font_instance; diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index de213ca85..801ab2922 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -20,7 +20,11 @@ #include #include #include + #include +#include +#include + #include #include #include diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 9c9f7faa3..82e65435d 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -17,7 +17,9 @@ #include #include + #include +#include #include #include #include diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index 9de303f89..0e2f8ed94 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -80,9 +80,9 @@ protected: void perform(LayerPropertiesDialog &dialog); }; - friend class Rename; - friend class Create; - friend class Move; + friend struct Rename; + friend struct Create; + friend struct Move; Strategy *_strategy; SPDesktop *_desktop; diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 114204961..8a2b0299a 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -38,6 +38,12 @@ #include "sp-item.h" #include +#if WITH_GTKMM_3_0 +# include +#else +# include +#endif + namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index b49293ea1..624a18246 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -35,6 +35,8 @@ #include "ui/widget/panel.h" #include "ui/widget/frame.h" + +#include #include #include #include @@ -46,6 +48,14 @@ class SPAttributeTable; class SPDesktop; class SPItem; +namespace Gtk { +#if WITH_GTKMM_3_0 +class Grid; +#else +class Table; +#endif +} + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 0da39dd73..bce63093d 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -15,8 +15,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS - #include "svg-fonts-dialog.h" #include "document-private.h" #include "document-undo.h" @@ -945,8 +943,6 @@ SvgFontsDialog::~SvgFontsDialog(){} } // namespace UI } // namespace Inkscape -#endif //#ifdef ENABLE_SVG_FONTS - /* Local Variables: mode:c++ diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h index 9be984820..01f70654a 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -34,8 +34,8 @@ class HScale; #endif } -class SPGlyph; -class SPGlyphKerning; +struct SPGlyph; +struct SPGlyphKerning; class SvgFont; class SvgFontDrawingArea : Gtk::DrawingArea{ diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 84d469750..c87e94fc6 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -57,6 +57,7 @@ extern "C" { #include "widgets/icon.h" #include "widgets/font-selector.h" #include +#include #include "unit-constants.h" diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h index 3fdeea05d..f27fdfc87 100644 --- a/src/ui/dialog/text-edit.h +++ b/src/ui/dialog/text-edit.h @@ -30,7 +30,7 @@ #include "ui/dialog/desktop-tracker.h" class SPItem; -class SPFontSelector; +struct SPFontSelector; class font_instance; class SPCSSAttr; diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index 1ad827a56..bd467555e 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -20,6 +20,7 @@ #include #include "ui/widget/spinbutton.h" #include "ui/widget/frame.h" +#include #include #include //for GTK_RESPONSE* types diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h index 0a6e3a786..58ef3aef8 100644 --- a/src/ui/dialog/xml-tree.h +++ b/src/ui/dialog/xml-tree.h @@ -29,7 +29,7 @@ #include "message.h" class SPDesktop; -struct SPObject; +class SPObject; struct SPXMLViewAttrList; struct SPXMLViewContent; struct SPXMLViewTree; diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index 8c4924f26..069dcc67b 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -7,8 +7,8 @@ */ #include +#include #include -#include #include <2geom/point.h> #include "desktop.h" #include "desktop-handles.h" diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index 49b1496d4..bc5267bb2 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -25,9 +25,6 @@ #define INK_IS_NODE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INK_TYPE_NODE_TOOL)) #define INK_IS_NODE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INK_TYPE_NODE_TOOL)) -class InkNodeTool; -class InkNodeToolClass; - namespace Inkscape { namespace Display { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 04148592b..79db1a1c1 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -22,7 +22,7 @@ struct SPCanvasItem; class SPCurve; -struct SPPath; +class SPPath; namespace Inkscape { namespace XML { class Node; } diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 173e014d9..64d28119a 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -13,6 +13,8 @@ #include "entry.h" +#include + namespace Inkscape { namespace UI { namespace Widget { diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h index 53b848fc9..de5cceadd 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -11,10 +11,10 @@ #define INKSCAPE_UI_WIDGET_ENTRY__H #include "labelled.h" -#include -#include -#include +namespace Gtk { +class Entry; +} namespace Inkscape { namespace UI { diff --git a/src/ui/widget/frame.h b/src/ui/widget/frame.h index cf736d8a1..a04666651 100644 --- a/src/ui/widget/frame.h +++ b/src/ui/widget/frame.h @@ -10,11 +10,9 @@ #ifndef INKSCAPE_UI_WIDGET_FRAME_H #define INKSCAPE_UI_WIDGET_FRAME_H -#include - -namespace Gtk { -class Frame; -} +#include +#include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 2a7843a51..fa35b815e 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -32,7 +32,7 @@ #include -class SPUnit; +struct SPUnit; class SPDocument; namespace Gtk { diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 6d5222429..9b78cb17f 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -40,7 +40,7 @@ #include "helper/units.h" class SPDesktop; -class SPUnit; +struct SPUnit; namespace Inkscape { namespace UI { diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index 2b9c32b2e..d7bab3732 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -26,7 +26,7 @@ #include "button.h" #include "preferences.h" -class SPUnit; +struct SPUnit; struct SPStyle; class SPCSSAttr; -- cgit v1.2.3 From b887e821e03cae71b2116d58e64efb62eb9be0be Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 20 Mar 2013 01:47:49 +0100 Subject: For testing, widget added, regression fixed (bzr r11950.1.62) --- src/ui/tool/path-manipulator.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 853d9336a..c3ab19a4e 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1176,7 +1176,12 @@ void PathManipulator::_createControlPointsFromGeometry() bool PathManipulator::isBSpline(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ - lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); + Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + }else{ + lpe_bsp = NULL; + } }else{ lpe_bsp = NULL; } -- cgit v1.2.3 From 49c304e53558c96b2442c06c9beccf5082bb8fe2 Mon Sep 17 00:00:00 2001 From: jtx Date: Wed, 20 Mar 2013 18:12:37 +0100 Subject: Fixing node fault (bzr r11950.4.2) --- src/ui/tool/multi-path-manipulator.cpp | 2 +- src/ui/tool/node.cpp | 47 +++++++++++++--------------------- src/ui/tool/node.h | 8 ++++-- 3 files changed, 25 insertions(+), 32 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 3623bb006..94860093d 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -307,7 +307,7 @@ void MultiPathManipulator::setNodeType(NodeType type) Node *node = dynamic_cast(*i); if (node) { retract_handles &= (node->type() == NODE_CUSP); - node->setType(type,true); + node->setType(type); } } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index e0aec8bb5..738d98e82 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,6 +113,7 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _degenerate(true),controlBsplineSteps(2) { setVisible(false); + isBSpline = _pm().isBSpline; } Handle::~Handle() @@ -143,8 +144,7 @@ void Handle::move(Geom::Point const &new_pos) double pos = 0; Handle *h = NULL; Handle *h2 = NULL; - if(_pm().isBSpline){ - isBSpline = true; + if(isBSpline){ typedef ControlPointSelection::Set Set; Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -324,7 +324,7 @@ bool Handle::_eventHandler(SPEventContext *event_context, GdkEvent *event) //BSpline void Handle::handle_2button_press(){ - if(_pm().isBSpline){ + if(isBSpline){ Handle *h = NULL; Handle *h2 = NULL; double pos = 0; @@ -386,7 +386,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } new_pos = result; //BSpline - if(_pm().isBSpline){ + if(isBSpline){ Handle *h = NULL; double pos = 0; h = this; @@ -398,7 +398,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - if (snap && ( (!held_control(*event) && _pm().isBSpline) || !_pm().isBSpline)) { + if (snap && ( (!held_control(*event) && isBSpline) || !isBSpline)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -580,6 +580,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { // NOTE we do not set type here, because the handles are still degenerate + isBSpline = _pm().isBSpline; } Node const *Node::_next() const @@ -625,7 +626,7 @@ void Node::move(Geom::Point const &new_pos) Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - if(_pm().isBSpline){ + if(isBSpline){ if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); pos = _pm().BSplineHandlePosition(n->front()); @@ -637,7 +638,7 @@ void Node::move(Geom::Point const &new_pos) //BSpline End setPosition(new_pos); //BSpline - if(_pm().isBSpline){ + if(isBSpline){ if(prevNode) prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); if(nextNode) @@ -651,7 +652,7 @@ void Node::move(Geom::Point const &new_pos) // with the segment _fixNeighbors(old_pos, new_pos); //BSpline - if(_pm().isBSpline){ + if(isBSpline){ Handle* front = &_front; Handle* back = &_back; _front.setPosition(_pm().BSplineHandleReposition(front,pos)); @@ -773,27 +774,6 @@ void Node::setType(NodeType type, bool update_handles) return; } - //BSpline - if(_pm().isBSpline){ - if (isEndNode()) return; - Handle* front = &_front; - Handle* back = &_back; - double pos = 0.3334; - switch (type) { - case NODE_CUSP: - if(update_handles) - pos = 0; - else - pos = _pm().BSplineHandlePosition(front);; - break; - default: break; - } - type = NODE_CUSP; - _front.setPosition(_pm().BSplineHandleReposition(front,pos)); - _back.setPosition(_pm().BSplineHandleReposition(back,pos)); - } - //BSpline End - // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -882,6 +862,15 @@ void Node::setType(NodeType type, bool update_handles) _setControlType(nodeTypeToCtrlType(_type)); updateState(); + //BSpline + if(isBSpline){ + Handle* front = &_front; + Handle* back = &_back; + double pos = _pm().BSplineHandlePosition(front); + _front.setPosition(_pm().BSplineHandleReposition(front,pos)); + _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + } + //BSpline End } void Node::pickBestType() diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 7152f37fd..a384db7cc 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -120,7 +120,9 @@ protected: virtual bool _hasDragTips() const { return true; } private: - + //BSpline + bool isBSpline; + //BSpline End inline PathManipulator &_pm(); Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction @@ -236,7 +238,9 @@ protected: virtual bool _hasDragTips() const { return true; } private: - + //BSpline + bool isBSpline; + //BSpline End Node(Node const &); void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos); void _updateAutoHandles(); -- cgit v1.2.3 From d8278200b80518c4a7c2f4fda642102ff268851d Mon Sep 17 00:00:00 2001 From: jtx Date: Wed, 20 Mar 2013 18:50:31 +0100 Subject: Fixing node fault (bzr r11950.4.3) --- src/ui/tool/node.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 738d98e82..93b45bde7 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,7 +113,12 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _degenerate(true),controlBsplineSteps(2) { setVisible(false); - isBSpline = _pm().isBSpline; + std::string strPathManipulatorName = "PathManipulator"; + if(std::string(typeid(_pm()).name()) == strPathManipulatorName) + isBSpline = _pm().isBSpline; + else + //Esto no es cierto realmente pero evita que casque al crear nodos + isBSpline = false; } Handle::~Handle() @@ -580,7 +585,12 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { // NOTE we do not set type here, because the handles are still degenerate - isBSpline = _pm().isBSpline; + std::string strPathManipulatorName = "PathManipulator"; + if(std::string(typeid(_pm()).name()) == strPathManipulatorName) + isBSpline = _pm().isBSpline; + else + //Esto no es cierto realmente pero evita que casque al crear nodos + isBSpline = false; } Node const *Node::_next() const -- cgit v1.2.3 From f99e35afe4c7d572a5e3a98b12571e577c1b3d14 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 21 Mar 2013 02:39:16 +0100 Subject: Fixed redraw handles at node delete (bzr r11950.1.64) --- src/ui/tool/path-manipulator.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fc4439711..431cc2d96 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -664,12 +664,6 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite start.prev()->front()->setPosition(result[1]); end->back()->setPosition(result[2]); - //BSpline - if(isBSpline){ - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front())); - end->back()->setPosition(BSplineHandleReposition(end->back())); - } - //BSpline End } // We can't use nl->erase(start, end), because it would break when the stretch @@ -680,6 +674,12 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } + //BSpline + if(isBSpline){ + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front())); + end->back()->setPosition(BSplineHandleReposition(end->back())); + } + //BSpline End return del_len; } -- cgit v1.2.3 From a60fc5880c9bab8bf471c2ef808499182201b621 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 21 Mar 2013 10:53:39 +0100 Subject: Fixing errors at delete extrewmiuns nodes (bzr r11950.1.65) --- src/ui/tool/path-manipulator.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 431cc2d96..571e6dd7a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1197,13 +1197,19 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ double pos = 0; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); - Node * nextNode = n->nodeToward(h); - Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); - if(nextNode && n->position() != h->position()){ - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); + Node * nextNode = NULL; + try{ + nextNode = n->nodeToward(h); + }catch( char * str ) { + } + if(nextNode){ + Geom::Point positionH = h->position(); + positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + if(nextNode && n->position() != h->position()){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); + } } return pos; } @@ -1220,7 +1226,11 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); - Node * nextNode = n->nodeToward(h); + Node * nextNode = NULL; + try{ + nextNode = n->nodeToward(h); + }catch( char * str ) { + } if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); -- cgit v1.2.3 From d142ebe8740c40922c1a6aa423ca4e0e7d2335d6 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 22 Mar 2013 01:50:18 +0100 Subject: Fixed end extremium node delete fault, ready for testing (bzr r11950.1.66) --- src/ui/tool/path-manipulator.cpp | 36 +++++++++++++++++++++++------------- src/ui/tool/path-manipulator.h | 6 +++++- 2 files changed, 28 insertions(+), 14 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 571e6dd7a..8f6651dee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -9,9 +9,7 @@ * Copyright (C) 2009 Authors * Released under GNU GPL, read the file 'COPYING' for more information */ -//BSpline -#include "live_effects/lpe-bspline.h" -//BSpline end + #include "live_effects/lpe-powerstroke.h" #include #include @@ -46,6 +44,9 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline end namespace Inkscape { namespace UI { @@ -149,8 +150,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - - LivePathEffect::LPEBSpline *lpe_bsp = NULL; + //BSpline + lpe_bsp = NULL; if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ @@ -162,6 +163,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, isBSpline = true; controlBSplineSteps = lpe_bsp->steps+1; } + //BSpline End } PathManipulator::~PathManipulator() @@ -676,8 +678,15 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite } //BSpline if(isBSpline){ - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front())); - end->back()->setPosition(BSplineHandleReposition(end->back())); + double pos = 0; + if(start.prev()){ + pos = BSplineHandlePosition(start.prev()->back()); + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),pos)); + } + if(end){ + pos = BSplineHandlePosition(end->front()); + end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); + } } //BSpline End @@ -1192,16 +1201,19 @@ void PathManipulator::_createControlPointsFromGeometry() } double PathManipulator::BSplineHandlePosition(Handle *h){ + //BSpline + if(lpe_bsp){ + controlBSplineSteps = lpe_bsp->steps+1; + } + //BSpline End using Geom::X; using Geom::Y; double pos = 0; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - try{ + if(!n->isEndNode()) nextNode = n->nodeToward(h); - }catch( char * str ) { - } if(nextNode){ Geom::Point positionH = h->position(); positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); @@ -1227,10 +1239,8 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - try{ + if(!n->isEndNode()) nextNode = n->nodeToward(h); - }catch( char * str ) { - } if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 948d4544b..496bd957c 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -19,6 +19,9 @@ #include #include "ui/tool/node.h" #include "ui/tool/manipulator.h" +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline end struct SPCanvasItem; class SPCurve; @@ -96,6 +99,7 @@ public: bool search_unselected, bool closest); //BSpline bool isBSpline; + int controlBSplineSteps; //BSpline End // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -107,7 +111,7 @@ private: void _createControlPointsFromGeometry(); //BSpline - int controlBSplineSteps; + LivePathEffect::LPEBSpline *lpe_bsp; double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From c34969161a38e67408b654a8b308b45ca638811f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 23 Mar 2013 15:57:26 +0100 Subject: Remove extra code (bzr r11950.1.69) --- src/ui/tool/path-manipulator.cpp | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 84e300306..f8c5deea2 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -841,11 +841,6 @@ void PathManipulator::scaleHandle(Node *n, int which, int dir, bool pixel) relpos *= ((rellen + length_change) / rellen); } h->setRelativePos(relpos); - - if(isBSpline){ - double pos = BSplineHandlePosition(h); - h->setPosition(BSplineHandleReposition(h,pos)); - } update(); gchar const *key = which < 0 ? "handle:scale:left" : "handle:scale:right"; _commit(_("Scale handle"), key); @@ -870,12 +865,6 @@ void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) } h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); - - if(isBSpline){ - double pos = BSplineHandlePosition(h); - h->setPosition(BSplineHandleReposition(h,pos)); - } - update(); gchar const *key = which < 0 ? "handle:rotate:left" : "handle:rotate:right"; -- cgit v1.2.3 From a7ced41f3fa6933d0da0151ef42e82e0862581fb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 1 Apr 2013 01:09:52 +0200 Subject: Fix scale and rotate some nodes (bzr r11950.1.78) --- src/ui/tool/node.cpp | 41 ++++++++++++++++++++-------------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 26 ++++++++++++++++--------- src/ui/tool/path-manipulator.h | 1 + 4 files changed, 39 insertions(+), 31 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index b4976bde5..dfa9c5d84 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -139,7 +139,6 @@ void Handle::move(Geom::Point const &new_pos) Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; //BSpline - double pos = 0; Handle *h = NULL; Handle *h2 = NULL; if(_pm().isBSpline){ @@ -189,9 +188,9 @@ void Handle::move(Geom::Point const &new_pos) if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); - pos = _pm().BSplineHandlePosition(h); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } //BSpline End return; @@ -228,9 +227,9 @@ void Handle::move(Geom::Point const &new_pos) if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); - pos = _pm().BSplineHandlePosition(h); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } //BSpline End } @@ -325,12 +324,12 @@ void Handle::handle_2button_press(){ if(_pm().isBSpline){ Handle *h = NULL; Handle *h2 = NULL; - double pos = 0; + _parent->bsplineWeight = 0; h = this; setPosition(_pm().BSplineHandleReposition(h,0.3334)); - pos = _pm().BSplineHandlePosition(h); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); _pm().update(); } } @@ -386,12 +385,12 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) //BSpline if(_pm().isBSpline){ Handle *h = NULL; - double pos = 0; + _parent->bsplineWeight = 0; h = this; setPosition(new_pos); int steps = _pm().getSteps(); - pos = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; - new_pos=_pm().BSplineHandleReposition(h,pos); + _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; + new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); } //BSpline End } @@ -579,6 +578,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { // NOTE we do not set type here, because the handles are still degenerate + this->bsplineWeight = 0.3334; } Node const *Node::_next() const @@ -619,7 +619,6 @@ void Node::move(Geom::Point const &new_pos) Geom::Point delta = new_pos - position(); //BSpline double prevPos = 0; - double pos = 0; double nextPos = 0; Node *n = this; Node * nextNode = n->nodeToward(n->front()); @@ -627,9 +626,9 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline){ if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); - pos = _pm().BSplineHandlePosition(n->front()); - if(pos == 0) - pos = _pm().BSplineHandlePosition(n->back()); + n->bsplineWeight = _pm().BSplineHandlePosition(n->front()); + if(n->bsplineWeight == 0) + n->bsplineWeight = _pm().BSplineHandlePosition(n->back()); if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); } @@ -653,8 +652,8 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; - _front.setPosition(_pm().BSplineHandleReposition(front,pos)); - _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + _front.setPosition(_pm().BSplineHandleReposition(front,n->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(back,n->bsplineWeight)); } } @@ -864,10 +863,10 @@ void Node::setType(NodeType type, bool update_handles) if(isBSpline){ Handle* front = &_front; Handle* back = &_back; - double pos = _pm().BSplineHandlePosition(front); - if(pos !=0) pos = 0.3334; - _front.setPosition(_pm().BSplineHandleReposition(front,pos)); - _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + this->bsplineWeight = _pm().BSplineHandlePosition(front); + if(this->bsplineWeight !=0) this->bsplineWeight = 0.3334; + _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); } //BSpline End } diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 2b547256b..f6d5beadc 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -180,7 +180,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - + double bsplineWeight; /** * Gets the handle that faces the given adjacent node. * Will abort with error if the given node is not adjacent. diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1607585c5..be5514e1f 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -862,7 +862,6 @@ void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) int snaps = prefs->getIntLimited("/options/rotationsnapsperpi/value", 12, 1, 1000); angle = M_PI * dir / snaps; } - h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); update(); @@ -1211,14 +1210,12 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ Node * nextNode = NULL; if(!n->isEndNode()) nextNode = n->nodeToward(h); - if(nextNode){ - Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); - if(nextNode && n->position() != h->position()){ - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); - } + Geom::Point positionH = h->position(); + positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + if(nextNode && n->position() != h->position()){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); } return pos; } @@ -1250,6 +1247,11 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } +void PathManipulator::BSplineNodeHandlesReposition(Node *n){ + n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); + n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); +} + /** Construct the geometric representation of nodes and handles, update the outline * and display * \param alert_LPE if true, first the LPE is warned what the new path is going to be before updating it @@ -1264,8 +1266,14 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); + if(isBSpline){ + BSplineNodeHandlesReposition(prev.ptr()); + } builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { + if(isBSpline){ + BSplineNodeHandlesReposition(i.ptr()); + } build_segment(builder, prev.ptr(), i.ptr()); prev = i; } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index e68cabef1..743d70b96 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -115,6 +115,7 @@ private: double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); + void BSplineNodeHandlesReposition(Node *n); //BSpline End void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); -- cgit v1.2.3 From 6ffc63f4ecd0550225a6fc752aba128575733a22 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Apr 2013 10:03:19 +0200 Subject: Fixed scale-rotate isue with paths multiples (bzr r11950.1.80) --- src/ui/tool/node.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index dfa9c5d84..1f609dfa0 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1118,6 +1118,12 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); + //BSpline + if(_pm().isBSpline){ + this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); + _pm().BSplineNodeHandlesReposition(this); + } + //BSpline End break; } SelectableControlPoint::_setState(state); -- cgit v1.2.3 From 30858428c74d1fa0f119f40b99fa5e51836d8599 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 8 Apr 2013 00:50:31 +0200 Subject: Change width only for selected nodes by widget (bzr r11950.1.83) --- src/ui/tool/node.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1f609dfa0..8f1c37649 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -577,8 +577,8 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _type(NODE_CUSP), _handles_shown(false) { - // NOTE we do not set type here, because the handles are still degenerate this->bsplineWeight = 0.3334; + // NOTE we do not set type here, because the handles are still degenerate } Node const *Node::_next() const diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index be5514e1f..6cad60fee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1248,8 +1248,22 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ } void PathManipulator::BSplineNodeHandlesReposition(Node *n){ - n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); - n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); + if(n->selected()){ + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + double prevPos = 0; + double nextPos = 0; + if(prevNode) + prevPos = BSplineHandlePosition(prevNode->front()); + if(nextNode) + nextPos = BSplineHandlePosition(nextNode->back()); + n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); + n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); + if(prevNode) + prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); + if(nextNode) + nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); + } } /** Construct the geometric representation of nodes and handles, update the outline -- cgit v1.2.3 From 458ca2842297a5eae7e4f6fc394b227d61881c8d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 17 Apr 2013 23:03:51 +0200 Subject: Update color lines overlay, with halo of 1 px matched by Gez. Fix some crash snapping. Added new button widget to make cusp node (bzr r11950.1.96) --- src/ui/tool/node.cpp | 17 +++++++++++++---- src/ui/tool/path-manipulator.cpp | 12 ++++++------ 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 8f1c37649..011d0d296 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -146,10 +146,8 @@ void Handle::move(Geom::Point const &new_pos) Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); - if(n != _parent) - _parent->_selection.erase(n); + _parent->_selection.erase(n); } - if(!_parent->selected()) _parent->_selection.insert(_parent); } //BSpline End @@ -187,8 +185,8 @@ void Handle::move(Geom::Point const &new_pos) //BSpline if(_pm().isBSpline){ h = this; - setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); + setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); h2 = this->other(); this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } @@ -422,6 +420,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); + //BSpline + if(_pm().isBSpline){ + Handle *h = NULL; + _parent->bsplineWeight = 0; + h = this; + setPosition(new_pos); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); + new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); + } + //BSpline End } @@ -452,6 +460,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); + _parent->bsplineWeight = 0; } } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 6cad60fee..9da27e807 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1204,14 +1204,14 @@ int PathManipulator::getSteps(){ double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; - double pos = 0; + double pos = 0.0000; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; if(!n->isEndNode()) nextNode = n->nodeToward(h); Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); @@ -1235,12 +1235,12 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Node * nextNode = NULL; if(!n->isEndNode()) nextNode = n->nodeToward(h); - if(nextNode && pos != 0){ + if(nextNode && pos != 0.0000){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); ret = SBasisInsideNodes.valueAt(pos); - ret = Geom::Point(ret[X] + 0.0625,ret[Y] + 0.0625); + ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); }else{ ret = n->position(); } @@ -1251,8 +1251,8 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ if(n->selected()){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - double prevPos = 0; - double nextPos = 0; + double prevPos = 0.0000; + double nextPos = 0.0000; if(prevNode) prevPos = BSplineHandlePosition(prevNode->front()); if(nextNode) -- cgit v1.2.3 From 9555c8e9051ba5b5d80912a6fd79f85cf12829d6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 18 Apr 2013 21:55:41 +0200 Subject: Back to original colors (bzr r11950.1.99) --- src/ui/control-manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index 9425bc3f0..5a3c5a496 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -59,9 +59,9 @@ ControlFlags& operator ^=(ControlFlags &lhs, ControlFlags rhs) #define FILL_COLOR_MOUSEOVER 0xff0000ff // Default color for line: -#define LINE_COLOR_PRIMARY 0x23abcdff -#define LINE_COLOR_SECONDARY 0xf372ebff -#define LINE_COLOR_TERTIARY 0xe68024ff +#define LINE_COLOR_PRIMARY 0x0000ff7f +#define LINE_COLOR_SECONDARY 0xff00007f +#define LINE_COLOR_TERTIARY 0xffff007f namespace Inkscape { -- cgit v1.2.3 From be4b46000a9a9f29d79b2e939c0669f6ddf0c59f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 27 Apr 2013 02:01:11 +0200 Subject: Fixed important selection bug when changing to cusp nodes (bzr r11950.1.109) --- src/ui/tool/node.cpp | 69 +++++++++++++++++++++++----------------- src/ui/tool/path-manipulator.cpp | 6 ++-- 2 files changed, 44 insertions(+), 31 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 011d0d296..d342d6c3d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -141,17 +141,7 @@ void Handle::move(Geom::Point const &new_pos) //BSpline Handle *h = NULL; Handle *h2 = NULL; - if(_pm().isBSpline){ - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - _parent->_selection.insert(_parent); - } //BSpline End - if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -322,7 +312,7 @@ void Handle::handle_2button_press(){ if(_pm().isBSpline){ Handle *h = NULL; Handle *h2 = NULL; - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; h = this; setPosition(_pm().BSplineHandleReposition(h,0.3334)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); @@ -343,6 +333,7 @@ bool Handle::grabbed(GdkEventMotion *) void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) { + Geom::Point parent_pos = _parent->position(); Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; @@ -383,7 +374,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) //BSpline if(_pm().isBSpline){ Handle *h = NULL; - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; h = this; setPosition(new_pos); int steps = _pm().getSteps(); @@ -423,7 +414,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) //BSpline if(_pm().isBSpline){ Handle *h = NULL; - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; h = this; setPosition(new_pos); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); @@ -460,7 +451,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; } } @@ -472,11 +463,33 @@ void Handle::ungrabbed(GdkEventButton *event) _drag_out = false; _pm()._handleUngrabbed(); + //BSpline + if(_pm().isBSpline){ + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + _parent->_selection.erase(n); + } + _parent->_selection.insert(_parent); + } + //BSpline End } bool Handle::clicked(GdkEventButton *event) { _pm()._handleClicked(this, event); + //BSpline + if(_pm().isBSpline){ + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + _parent->_selection.erase(n); + } + _parent->_selection.insert(_parent); + } + //BSpline End return true; } @@ -627,8 +640,8 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); //BSpline - double prevPos = 0; - double nextPos = 0; + double prevPos = 0.0000; + double nextPos = 0.0000; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); @@ -636,7 +649,7 @@ void Node::move(Geom::Point const &new_pos) if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); n->bsplineWeight = _pm().BSplineHandlePosition(n->front()); - if(n->bsplineWeight == 0) + if(n->bsplineWeight == 0.0000) n->bsplineWeight = _pm().BSplineHandlePosition(n->back()); if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); @@ -770,7 +783,7 @@ void Node::updateHandles() _front._handleControlStyling(); _back._handleControlStyling(); } - + void Node::setType(NodeType type, bool update_handles) { @@ -779,7 +792,14 @@ void Node::setType(NodeType type, bool update_handles) updateState(); // The size of the control might have changed return; } - + //BSpline + bool isBSpline = false; + try { + isBSpline = nodeList().subpathList().pm().isBSpline; + } + catch( char * str ) { + } + //BSpline End // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -863,28 +883,19 @@ void Node::setType(NodeType type, bool update_handles) default: break; } //BSpline - bool isBSpline = false; - try { - isBSpline = nodeList().subpathList().pm().isBSpline; - } - catch( char * str ) { - } if(isBSpline){ Handle* front = &_front; Handle* back = &_back; this->bsplineWeight = _pm().BSplineHandlePosition(front); - if(this->bsplineWeight !=0) this->bsplineWeight = 0.3334; + if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); } //BSpline End } - _type = type; - _setControlType(nodeTypeToCtrlType(_type)); updateState(); - } void Node::pickBestType() diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9da27e807..cad794860 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1239,9 +1239,11 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + n->bsplineWeight = pos; ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); }else{ + n->bsplineWeight = 0.0000; ret = n->position(); } return ret; @@ -1257,8 +1259,8 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ prevPos = BSplineHandlePosition(prevNode->front()); if(nextNode) nextPos = BSplineHandlePosition(nextNode->back()); - n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); - n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); + n->front()->setPosition(BSplineHandleReposition(n->front())); + n->back()->setPosition(BSplineHandleReposition(n->back())); if(prevNode) prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); if(nextNode) -- cgit v1.2.3 From dd30de233b38518008030c2c0a2366332422b236 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 6 May 2013 02:54:50 +0200 Subject: Removed auto select nodes, not decide for the user. Added auto update all selected handles when drag (bzr r11950.1.111) --- src/ui/tool/node.cpp | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index d342d6c3d..1d7b5850f 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -216,8 +216,15 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } //BSpline End } @@ -463,33 +470,11 @@ void Handle::ungrabbed(GdkEventButton *event) _drag_out = false; _pm()._handleUngrabbed(); - //BSpline - if(_pm().isBSpline){ - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - _parent->_selection.insert(_parent); - } - //BSpline End } bool Handle::clicked(GdkEventButton *event) { _pm()._handleClicked(this, event); - //BSpline - if(_pm().isBSpline){ - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - _parent->_selection.insert(_parent); - } - //BSpline End return true; } -- cgit v1.2.3 From 417a1e079bbc94ac0d8c6631832e47a35098ba98 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 May 2013 03:36:46 +0200 Subject: Change only selected nodes (bzr r11950.1.113) --- src/ui/tool/node.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1d7b5850f..5362a6c45 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -219,11 +219,13 @@ void Handle::move(Geom::Point const &new_pos) typedef ControlPointSelection::Set Set; Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + if((*i)->selected()){ + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } } //BSpline End -- cgit v1.2.3 From e17c04bd7386e2e346b7f4f760f6e6ba3c24b886 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 17 May 2013 00:53:42 +0200 Subject: Fix error with try-catch (bzr r11950.1.115) --- src/ui/tool/node.cpp | 61 ++++++++++++++++++++++++++++++++-------- src/ui/tool/path-manipulator.cpp | 2 +- src/ui/tool/path-manipulator.h | 2 +- 3 files changed, 51 insertions(+), 14 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 5362a6c45..89a0f4163 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -175,10 +175,25 @@ void Handle::move(Geom::Point const &new_pos) //BSpline if(_pm().isBSpline){ h = this; + setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + if((*i)->selected()){ + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } + } + if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } //BSpline End return; @@ -192,6 +207,30 @@ void Handle::move(Geom::Point const &new_pos) Geom::Point new_delta = (Geom::dot(delta, direction) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); + //BSpline + if(_pm().isBSpline){ + h = this; + setPosition(_pm().BSplineHandleReposition(h)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + if((*i)->selected()){ + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } + } + if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } + } + //BSpline End return; } @@ -227,6 +266,12 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } } + if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } //BSpline End } @@ -779,14 +824,6 @@ void Node::setType(NodeType type, bool update_handles) updateState(); // The size of the control might have changed return; } - //BSpline - bool isBSpline = false; - try { - isBSpline = nodeList().subpathList().pm().isBSpline; - } - catch( char * str ) { - } - //BSpline End // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -870,7 +907,7 @@ void Node::setType(NodeType type, bool update_handles) default: break; } //BSpline - if(isBSpline){ + if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; this->bsplineWeight = _pm().BSplineHandlePosition(front); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index cad794860..7785dd685 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -110,6 +110,7 @@ void build_segment(Geom::PathBuilder &, Node *, Node *); PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) + , isBSpline(true) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) @@ -157,7 +158,6 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } - isBSpline = false; if(lpe_bsp){ isBSpline = true; } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 743d70b96..2fc0b90da 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -96,7 +96,7 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, - bool search_unselected, bool closest); + bool search_unselected, bool closest); //BSpline bool isBSpline; int getSteps(); -- cgit v1.2.3 From 9291d4e3a3ad22bef4669b74568ee6d43ba74547 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 18 May 2013 10:38:35 +0200 Subject: Fix error with envelope lpe (bzr r11950.1.117) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7785dd685..eb60abe2a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -152,7 +152,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); //BSpline lpe_bsp = NULL; - if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ + if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); -- cgit v1.2.3 From d67294affd2f6b0f71c67b75cf521bfe308500f9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 29 May 2013 01:33:43 +0200 Subject: Fixed a error that handles all kinds of pathas as bsplines (bzr r11950.1.119) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index eb60abe2a..ea007dfee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -110,7 +110,7 @@ void build_segment(Geom::PathBuilder &, Node *, Node *); PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) - , isBSpline(true) + , isBSpline(false) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) -- cgit v1.2.3 From 62ccb3999c5a5ec6f94de993d5b8a903f98adb5c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 20 Sep 2013 02:29:43 +0200 Subject: Fixed ~sub advertising for a compile problem (bzr r11950.1.143) --- src/ui/tool/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index ce022cec6..4500c5de0 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "event-context.h" +#include "selection.h" namespace Inkscape { namespace Display { -- cgit v1.2.3 From 987dd0e7eae4dded4049771af56b72889d05c461 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 26 Sep 2013 18:28:28 +0200 Subject: Compiling problem solved thaks to ~suv (bzr r11950.1.149) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e08a36e2e..dac67295a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -152,12 +152,14 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); //BSpline lpe_bsp = NULL; - if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ - Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); + + if (_path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } + if(lpe_bsp){ isBSpline = true; } -- cgit v1.2.3 From debe6f792f37d4ca3acb297eea230503cc3522a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 27 Sep 2013 12:21:37 +0200 Subject: Fix editing paths in live effect (bzr r11950.1.154) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1add4d176..3690efdad 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -153,7 +153,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, //BSpline lpe_bsp = NULL; - if (_path->hasPathEffect()){ + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); -- cgit v1.2.3 From 514675a4b3eeb5835ad2466b692b3d00c6333c4a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Sep 2013 17:58:15 +0200 Subject: Fixed a bug editing paths in others LPE -envelope- (bzr r11950.1.157) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 3690efdad..910f75258 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1312,7 +1312,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); if (alert_LPE) { - if (_path->hasPathEffect()) { + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()) { PathEffectList effect_list = sp_lpe_item_get_effect_list(_path); LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast( effect_list.front()->lpeobject->get_lpe() ); if (lpe_pwr) { -- cgit v1.2.3 From 5ef4eb74cfdec7aad437518db0ab99414bd3eae6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Oct 2013 23:20:25 +0200 Subject: Fix moving handles (bzr r11950.1.160) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f72313315..18ad45f72 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1268,10 +1268,12 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ nextPos = BSplineHandlePosition(nextNode->back()); n->front()->setPosition(BSplineHandleReposition(n->front())); n->back()->setPosition(BSplineHandleReposition(n->back())); - if(prevNode) + if(prevNode && !prevNode->isEndNode()) prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); - if(nextNode) + prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); + if(nextNode && !nextNode->isEndNode()) nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),prevPos)); } } -- cgit v1.2.3 From bc37c9b9c4663786b04a65ba6a27d55b2395eeb9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Oct 2013 23:56:02 +0200 Subject: fix whith bspline handles (bzr r11950.1.162) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 18ad45f72..fd286873b 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1268,12 +1268,14 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ nextPos = BSplineHandlePosition(nextNode->back()); n->front()->setPosition(BSplineHandleReposition(n->front())); n->back()->setPosition(BSplineHandleReposition(n->back())); - if(prevNode && !prevNode->isEndNode()) + if(prevNode && !prevNode->isEndNode()){ prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); - if(nextNode && !nextNode->isEndNode()) + } + if(nextNode && !nextNode->isEndNode()){ nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),prevPos)); + } } } -- cgit v1.2.3 From cdc3d492add4c4bd63d96dcb53c406f9ef631ec9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Oct 2013 09:27:04 +0200 Subject: Fix in BSpline (bzr r11950.1.163) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fd286873b..e9372aef3 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1274,7 +1274,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ } if(nextNode && !nextNode->isEndNode()){ nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),prevPos)); + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); } } } -- cgit v1.2.3 From 202528bb3f6f9e90b8651bb81bb017af46787933 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 6 Oct 2013 09:57:14 +0200 Subject: Fix in bsplines (bzr r11950.1.165) --- src/ui/tool/curve-drag-point.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index fce19f9ad..f4628fb8f 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -94,8 +94,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(!_pm.isBSpline){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8)second->back()->move(new_pos); - else if(weight<=0.2)first->front()->move(new_pos); + }else if(weight>=0.8 && !second->isEndNode())second->back()->move(new_pos); + else if(weight<=0.2 && !first->isEndNode())first->front()->move(new_pos); //BSpline End _pm.update(); } -- cgit v1.2.3 From 3111608afecf747627810a6222cb7ca1eded6962 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Oct 2013 12:18:59 +0200 Subject: UX improvements (bzr r11950.1.166) --- src/ui/tool/path-manipulator.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e9372aef3..809d2628f 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -683,7 +683,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite } //BSpline if(isBSpline){ - double pos = 0; + double pos = 0.0000; if(start.prev()){ pos = BSplineHandlePosition(start.prev()->back()); start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),pos)); @@ -1215,8 +1215,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - if(!n->isEndNode()) - nextNode = n->nodeToward(h); + nextNode = n->nodeToward(h); Geom::Point positionH = h->position(); positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ @@ -1235,13 +1234,12 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; - Geom::Point ret(0,0); + Geom::Point ret = h->position(); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - if(!n->isEndNode()) - nextNode = n->nodeToward(h); + nextNode = n->nodeToward(h); if(nextNode && pos != 0.0000){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); @@ -1250,8 +1248,10 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); }else{ - n->bsplineWeight = 0.0000; - ret = n->position(); + if(pos == 0.0000){ + n->bsplineWeight = 0.0000; + ret = n->position(); + } } return ret; } @@ -1262,19 +1262,23 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * prevNode = n->nodeToward(n->back()); double prevPos = 0.0000; double nextPos = 0.0000; - if(prevNode) + if(prevNode){ prevPos = BSplineHandlePosition(prevNode->front()); - if(nextNode) + n->back()->setPosition(BSplineHandleReposition(n->back())); + } + if(nextNode){ nextPos = BSplineHandlePosition(nextNode->back()); - n->front()->setPosition(BSplineHandleReposition(n->front())); - n->back()->setPosition(BSplineHandleReposition(n->back())); - if(prevNode && !prevNode->isEndNode()){ + n->front()->setPosition(BSplineHandleReposition(n->front())); + } + if(prevNode){ + if(!prevNode->isEndNode()) + prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); - prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); } - if(nextNode && !nextNode->isEndNode()){ + if(nextNode){ + if(!nextNode->isEndNode()) + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); } } } -- cgit v1.2.3 From e8e2929ccb133b015db1de73de0efbb982d455a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 00:36:15 +0200 Subject: Fix bspline and strip multi node bspline power editing whith node tool because UX (bzr r11950.1.168) --- src/ui/tool/node.cpp | 102 +++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 5f5757a14..1151dc41b 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -176,23 +176,23 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - if((*i)->selected()){ - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } - } - if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } + //typedef ControlPointSelection::Set Set; + //Set &nodes = _parent->_selection.allPoints(); + //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + // if((*i)->selected()){ + // Node *n = static_cast(*i); + // h = n->front(); + // h2 = n->back(); + // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} + //} + //if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} } //BSpline End return; @@ -211,23 +211,23 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - if((*i)->selected()){ - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } - } - if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } + //typedef ControlPointSelection::Set Set; + //Set &nodes = _parent->_selection.allPoints(); + //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + // if((*i)->selected()){ + // Node *n = static_cast(*i); + // h = n->front(); + // h2 = n->back(); + // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + // } + //} + //if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} } //BSpline End return; @@ -254,23 +254,23 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - if((*i)->selected()){ - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } - } - if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } + //typedef ControlPointSelection::Set Set; + //Set &nodes = _parent->_selection.allPoints(); + //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + // if((*i)->selected()){ + // Node *n = static_cast(*i); + // h = n->front(); + // h2 = n->back(); + // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + // } + //} + //if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} } //BSpline End } -- cgit v1.2.3 From f26927f8891498ca9466ea865f17a790b73ccff6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 01:39:48 +0200 Subject: Fix scaling handles (bzr r11950.1.170) --- src/ui/tool/path-manipulator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 809d2628f..620c52e34 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1213,12 +1213,12 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::Y; double pos = 0.0000; Node *n = h->parent(); - SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; nextNode = n->nodeToward(h); Geom::Point positionH = h->position(); positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ + SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); @@ -1263,11 +1263,11 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ double prevPos = 0.0000; double nextPos = 0.0000; if(prevNode){ - prevPos = BSplineHandlePosition(prevNode->front()); + prevPos = BSplineHandlePosition(prevNode->front(),prevNode->bsplineWeight); n->back()->setPosition(BSplineHandleReposition(n->back())); } if(nextNode){ - nextPos = BSplineHandlePosition(nextNode->back()); + nextPos = BSplineHandlePosition(nextNode->back(),nextNode->bsplineWeight); n->front()->setPosition(BSplineHandleReposition(n->front())); } if(prevNode){ -- cgit v1.2.3 From c2d73f1a14e1d461553465892bc9a3767313878a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 01:54:04 +0200 Subject: Fix scaling handles (bzr r11950.1.171) --- src/ui/tool/path-manipulator.cpp | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 620c52e34..27def4cb1 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1257,29 +1257,19 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ } void PathManipulator::BSplineNodeHandlesReposition(Node *n){ - if(n->selected()){ - Node * nextNode = n->nodeToward(n->front()); - Node * prevNode = n->nodeToward(n->back()); - double prevPos = 0.0000; - double nextPos = 0.0000; - if(prevNode){ - prevPos = BSplineHandlePosition(prevNode->front(),prevNode->bsplineWeight); - n->back()->setPosition(BSplineHandleReposition(n->back())); - } - if(nextNode){ - nextPos = BSplineHandlePosition(nextNode->back(),nextNode->bsplineWeight); - n->front()->setPosition(BSplineHandleReposition(n->front())); - } - if(prevNode){ - if(!prevNode->isEndNode()) - prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); - prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); - } - if(nextNode){ - if(!nextNode->isEndNode()) - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); - nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); - } + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + if(prevNode){ + n->back()->setPosition(BSplineHandleReposition(n->back())); + if(!prevNode->isEndNode()) + prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); + prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); + } + if(nextNode){ + n->front()->setPosition(BSplineHandleReposition(n->front())); + if(!nextNode->isEndNode()) + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); + nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); } } -- cgit v1.2.3 From 6255e3bc1ad8c5c3824483e55e6f3c9de6941e5f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 15:42:58 +0200 Subject: fix in nodes (bzr r11950.1.172) --- src/ui/tool/node.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1151dc41b..7506a54a8 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -635,6 +635,8 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { this->bsplineWeight = 0.3334; + if(_front->position() == this->position() && _back->position() == this->position()) + this->bsplineWeight = 0.0000; // NOTE we do not set type here, because the handles are still degenerate } -- cgit v1.2.3 From 0eb0148cade3cc19d1cf85fadd5928c8c8ee1674 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 15:47:51 +0200 Subject: update to trunk (bzr r11950.1.173) --- src/ui/tool/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7506a54a8..c5ab2f316 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -635,7 +635,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { this->bsplineWeight = 0.3334; - if(_front->position() == this->position() && _back->position() == this->position()) + if(this->front()->position() == this->position() && this->back()->position() == this->position()) this->bsplineWeight = 0.0000; // NOTE we do not set type here, because the handles are still degenerate } -- cgit v1.2.3 From f238a7004752e4e56b7e6d602f675c97c0ce4733 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:09:32 +0200 Subject: Fixing BSplines (bzr r11950.1.174) --- src/ui/tool/node.cpp | 1 + src/ui/tool/path-manipulator.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c5ab2f316..c6d4537dd 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -726,6 +726,7 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); + _pm().BSplineNodeHandlesReposition(this); } Geom::Rect Node::bounds() const diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 27def4cb1..b90fa4ac7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1261,12 +1261,16 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * prevNode = n->nodeToward(n->back()); if(prevNode){ n->back()->setPosition(BSplineHandleReposition(n->back())); + if(prevNode->front()->position() == prevNode->position()) + prevNode->bsplineWeight = 0.000; if(!prevNode->isEndNode()) prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); } if(nextNode){ n->front()->setPosition(BSplineHandleReposition(n->front())); + if(nextNode->front()->position() == nextNode->position()) + nextNode->bsplineWeight = 0.000; if(!nextNode->isEndNode()) nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); @@ -1287,14 +1291,14 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); - if(isBSpline){ - BSplineNodeHandlesReposition(prev.ptr()); - } + //if(isBSpline){ + // BSplineNodeHandlesReposition(prev.ptr()); + //} builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - if(isBSpline){ - BSplineNodeHandlesReposition(i.ptr()); - } + //if(isBSpline){ + // BSplineNodeHandlesReposition(i.ptr()); + //} build_segment(builder, prev.ptr(), i.ptr()); prev = i; } -- cgit v1.2.3 From 46699ed807e748453d6aaa054f87c0582c38d72e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:24:27 +0200 Subject: fix bsplines (bzr r11950.1.175) --- src/ui/tool/node.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c6d4537dd..cbfd3ec0d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -635,8 +635,6 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { this->bsplineWeight = 0.3334; - if(this->front()->position() == this->position() && this->back()->position() == this->position()) - this->bsplineWeight = 0.0000; // NOTE we do not set type here, because the handles are still degenerate } -- cgit v1.2.3 From a4dcddb133064faf3f24f8f1a3f664f4d3d700b9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:46:13 +0200 Subject: fix bsplines (bzr r11950.1.176) --- src/ui/tool/node.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index cbfd3ec0d..f6d100b57 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -724,7 +724,10 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - _pm().BSplineNodeHandlesReposition(this); + if(_pm().isBSpline){ + this->front().setPosition(BSplineHandleReposition(this->front(),this->bsplineWeight)); + this->back().setPosition(BSplineHandleReposition(this->back(),this->bsplineWeight)); + } } Geom::Rect Node::bounds() const -- cgit v1.2.3 From db5de41dd8f09821561a14db45192a76479e2536 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:50:52 +0200 Subject: fix bsplines (bzr r11950.1.177) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index f6d100b57..91f8e8a54 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -725,8 +725,8 @@ void Node::transform(Geom::Affine const &m) * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); if(_pm().isBSpline){ - this->front().setPosition(BSplineHandleReposition(this->front(),this->bsplineWeight)); - this->back().setPosition(BSplineHandleReposition(this->back(),this->bsplineWeight)); + _front.setPosition(BSplineHandleReposition(_front,this->bsplineWeight)); + _back.setPosition(BSplineHandleReposition(_back,this->bsplineWeight)); } } -- cgit v1.2.3 From c868eae8e1cc980621791d982c519fc14139f906 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:56:26 +0200 Subject: fix bsplines (bzr r11950.1.178) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 91f8e8a54..933bfe0ca 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -725,8 +725,8 @@ void Node::transform(Geom::Affine const &m) * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); if(_pm().isBSpline){ - _front.setPosition(BSplineHandleReposition(_front,this->bsplineWeight)); - _back.setPosition(BSplineHandleReposition(_back,this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(_front,this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(_back,this->bsplineWeight)); } } -- cgit v1.2.3 From bae8160a80e84129b87846e09dee0a0aa0c08e0e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 18:52:27 +0200 Subject: fix bsplines (bzr r11950.1.179) --- src/ui/tool/node.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 933bfe0ca..8564f1f1a 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -725,8 +725,9 @@ void Node::transform(Geom::Affine const &m) * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); if(_pm().isBSpline){ - _front.setPosition(_pm().BSplineHandleReposition(_front,this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(_back,this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + _pm().BSplineNodeHandlesReposition(this); } } -- cgit v1.2.3 From 3ed9b4ff7ebbae3ba6446d911001688bcbbdc847 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 10 Nov 2013 12:17:23 +0100 Subject: Update to trunk (bzr r11950.1.196) --- src/ui/tools/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 4d15ab70e..b3acb79ad 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "ui/tools/tool-base.h" +#include "selection.h" namespace Inkscape { namespace Display { -- cgit v1.2.3 From ebc5ac2b758155192114ea1bec8b3d32820a18d3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 3 Dec 2013 16:55:14 +0100 Subject: Fix a bug delete BSpline LPE from a path retain some BSpline properties (bzr r11950.1.206) --- src/ui/tool/node.cpp | 63 +++++++++++++++++++++------------------- src/ui/tool/path-manipulator.cpp | 52 +++++++++++++++++++-------------- src/ui/tool/path-manipulator.h | 16 +++++----- 3 files changed, 72 insertions(+), 59 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 230d39e2e..af823a787 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,9 +28,9 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include -//BSpline + #include -//BSpline End; +; namespace { @@ -137,10 +137,10 @@ void Handle::move(Geom::Point const &new_pos) Node *node_away = _parent->nodeAwayFrom(this); // node in the opposite direction Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; - //BSpline + Handle *h = NULL; Handle *h2 = NULL; - //BSpline End + _pm().BSpline(); if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -171,7 +171,7 @@ void Handle::move(Geom::Point const &new_pos) } } setPosition(new_pos); - //BSpline + if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); @@ -194,7 +194,7 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); //} } - //BSpline End + return; } @@ -206,7 +206,7 @@ void Handle::move(Geom::Point const &new_pos) Geom::Point new_delta = (Geom::dot(delta, direction) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //BSpline + if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); @@ -229,7 +229,7 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); //} } - //BSpline End + return; } @@ -249,7 +249,7 @@ void Handle::move(Geom::Point const &new_pos) default: break; } setPosition(new_pos); - //BSpline + if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); @@ -272,7 +272,7 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); //} } - //BSpline End + } void Handle::setPosition(Geom::Point const &p) @@ -349,19 +349,20 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - //BSpline + case GDK_2BUTTON_PRESS: handle_2button_press(); break; - //BSpline End + default: break; } return ControlPoint::_eventHandler(event_context, event); } -//BSpline + void Handle::handle_2button_press(){ + _pm().BSpline(); if(_pm().isBSpline){ Handle *h = NULL; Handle *h2 = NULL; @@ -374,7 +375,7 @@ void Handle::handle_2button_press(){ _pm().update(); } } -//BSpline End + bool Handle::grabbed(GdkEventMotion *) { @@ -392,7 +393,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) SnapManager &sm = _desktop->namedview->snap_manager; bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap(); boost::optional ctrl_constraint; - + _pm().BSpline(); // with Alt, preserve length if (held_alt(*event)) { new_pos = parent_pos + Geom::unit_vector(new_pos - parent_pos) * _saved_length; @@ -424,17 +425,17 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - //BSpline + if(_pm().isBSpline){ Handle *h = NULL; _parent->bsplineWeight = 0.0000; h = this; setPosition(new_pos); - int steps = _pm().getSteps(); + int steps = _pm().BSplineGetSteps(); _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); } - //BSpline End + } std::vector unselected; @@ -464,7 +465,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); - //BSpline + if(_pm().isBSpline){ Handle *h = NULL; _parent->bsplineWeight = 0.0000; @@ -473,7 +474,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) _parent->bsplineWeight = _pm().BSplineHandlePosition(h); new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); } - //BSpline End + } @@ -674,9 +675,10 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - //BSpline + double prevPos = 0.0000; double nextPos = 0.0000; + _pm().BSpline(); Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); @@ -689,23 +691,23 @@ void Node::move(Geom::Point const &new_pos) if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); } - //BSpline End + setPosition(new_pos); - //BSpline + if(_pm().isBSpline){ if(prevNode) prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); if(nextNode) nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); } - //BSpline End + _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); - //BSpline End + // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - //BSpline + if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; @@ -724,6 +726,7 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); + _pm().BSpline(); if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); @@ -914,7 +917,7 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - //BSpline + _pm().BSpline(); if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; @@ -923,7 +926,7 @@ void Node::setType(NodeType type, bool update_handles) _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); } - //BSpline End + } _type = type; _setControlType(nodeTypeToCtrlType(_type)); @@ -1170,12 +1173,12 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //BSpline + _pm().BSpline(); if(_pm().isBSpline){ this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); _pm().BSplineNodeHandlesReposition(this); } - //BSpline End + break; } SelectableControlPoint::_setState(state); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e66c6a899..fd421e587 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -43,9 +43,9 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" -//BSpline + #include "live_effects/lpe-bspline.h" -//BSpline end + namespace Inkscape { namespace UI { @@ -150,20 +150,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - //BSpline - lpe_bsp = NULL; - - if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); - if(thisEffect){ - lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - } - } - - if(lpe_bsp){ - isBSpline = true; - } - //BSpline End + BSpline(); } PathManipulator::~PathManipulator() @@ -681,7 +668,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - //BSpline + if(isBSpline){ double pos = 0.0000; if(start.prev()){ @@ -693,7 +680,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); } } - //BSpline End + return del_len; } @@ -928,9 +915,9 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - //BSpline + if(isBSpline) show = true; - //BSpline + if (show == _show_outline) return; _show_outline = show; _updateOutline(); @@ -1204,10 +1191,33 @@ void PathManipulator::_createControlPointsFromGeometry() } } -int PathManipulator::getSteps(){ +int PathManipulator::BSplineGetSteps(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } return lpe_bsp->steps+1; } +void PathManipulator::BSpline(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } + isBSpline = false; + if(lpe_bsp){ + isBSpline = true; + } +} + double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index b40a479f7..2a59df464 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -19,9 +19,9 @@ #include #include "ui/tool/node.h" #include "ui/tool/manipulator.h" -//BSpline + #include "live_effects/lpe-bspline.h" -//BSpline end + struct SPCanvasItem; class SPCurve; @@ -97,10 +97,10 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - //BSpline + bool isBSpline; - int getSteps(); - //BSpline End + int BSplineGetSteps(); + // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -110,13 +110,13 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - //BSpline - LivePathEffect::LPEBSpline *lpe_bsp; + + void BSpline(); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); void BSplineNodeHandlesReposition(Node *n); - //BSpline End + void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From fb006b59b6d7b6d059dffe3389a829d2213f648d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 28 Dec 2013 23:34:45 +0100 Subject: Fix crash bug continuing empty paths (bzr r11950.1.210) --- src/ui/tools/pen-tool.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index ebbc533b8..178a940a2 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1648,6 +1648,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) Geom::Point C(0,0); if(!pc->sa || pc->sa->curve->is_empty()){ tmpCurve = pc->green_curve->create_reverse(); + if(pc->green_curve->get_segment_count()==0)return; Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); @@ -1715,6 +1716,7 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) SPCurve *lastSeg = new SPCurve(); if(!pc->sa || pc->sa->curve->is_empty()){ tmpCurve = pc->green_curve->create_reverse(); + if(pc->green_curve->get_segment_count()==0)return; Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ lastSeg->moveto((*cubic)[0]); -- cgit v1.2.3 From 57865cd8a96b1b5c72f44c9b97d1a828caf09f95 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 19:45:52 +0100 Subject: Refactorizing (bzr r11950.1.211) --- src/ui/tool/curve-drag-point.cpp | 6 +- src/ui/tool/node.cpp | 210 +++++++++++++++------------------------ src/ui/tool/path-manipulator.cpp | 7 +- src/ui/tool/path-manipulator.h | 2 +- 4 files changed, 82 insertions(+), 143 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index c25fa2d52..f847a6ab3 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -90,13 +90,11 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - //BSpline if(!_pm.isBSpline){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8 && !second->isEndNode())second->back()->move(new_pos); - else if(weight<=0.2 && !first->isEndNode())first->front()->move(new_pos); - //BSpline End + }else if(weight>=0.8 && !second->isEndNode() && held_shift(*event))second->back()->move(new_pos); + else if(weight<=0.2 && !first->isEndNode() && held_shift(*event))first->front()->move(new_pos); _pm.update(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index af823a787..70e374424 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -138,9 +138,6 @@ void Handle::move(Geom::Point const &new_pos) Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; - Handle *h = NULL; - Handle *h2 = NULL; - _pm().BSpline(); if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -171,30 +168,13 @@ void Handle::move(Geom::Point const &new_pos) } } setPosition(new_pos); - + + //If is bspline move other handle if(_pm().isBSpline){ - h = this; - setPosition(_pm().BSplineHandleReposition(h)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - //typedef ControlPointSelection::Set Set; - //Set &nodes = _parent->_selection.allPoints(); - //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - // if((*i)->selected()){ - // Node *n = static_cast(*i); - // h = n->front(); - // h2 = n->back(); - // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} - //} - //if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} + setPosition(_pm().BSplineHandleReposition(this)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } - return; } @@ -206,28 +186,12 @@ void Handle::move(Geom::Point const &new_pos) Geom::Point new_delta = (Geom::dot(delta, direction) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - + + //If is bspline move both handles if(_pm().isBSpline){ - h = this; - setPosition(_pm().BSplineHandleReposition(h)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - //typedef ControlPointSelection::Set Set; - //Set &nodes = _parent->_selection.allPoints(); - //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - // if((*i)->selected()){ - // Node *n = static_cast(*i); - // h = n->front(); - // h2 = n->back(); - // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - // } - //} - //if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} + setPosition(_pm().BSplineHandleReposition(this)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } return; @@ -249,28 +213,12 @@ void Handle::move(Geom::Point const &new_pos) default: break; } setPosition(new_pos); - + + //If is bspline move other handle if(_pm().isBSpline){ - h = this; - setPosition(_pm().BSplineHandleReposition(h)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - //typedef ControlPointSelection::Set Set; - //Set &nodes = _parent->_selection.allPoints(); - //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - // if((*i)->selected()){ - // Node *n = static_cast(*i); - // h = n->front(); - // h2 = n->back(); - // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - // } - //} - //if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} + setPosition(_pm().BSplineHandleReposition(this)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } } @@ -362,16 +310,10 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven void Handle::handle_2button_press(){ - _pm().BSpline(); if(_pm().isBSpline){ - Handle *h = NULL; - Handle *h2 = NULL; - _parent->bsplineWeight = 0.0000; - h = this; - setPosition(_pm().BSplineHandleReposition(h,0.3334)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + setPosition(_pm().BSplineHandleReposition(this,0.3334)); + _parent->bsplineWeight = 0.3334; + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); _pm().update(); } } @@ -393,7 +335,6 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) SnapManager &sm = _desktop->namedview->snap_manager; bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap(); boost::optional ctrl_constraint; - _pm().BSpline(); // with Alt, preserve length if (held_alt(*event)) { new_pos = parent_pos + Geom::unit_vector(new_pos - parent_pos) * _saved_length; @@ -427,19 +368,18 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) new_pos = result; if(_pm().isBSpline){ - Handle *h = NULL; - _parent->bsplineWeight = 0.0000; - h = this; setPosition(new_pos); int steps = _pm().BSplineGetSteps(); - _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; - new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); + _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; + new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); } } std::vector unselected; - if (snap && ( (!held_control(*event) && _pm().isBSpline) || !_pm().isBSpline)) { + + //IF Snap and Not CTRL && BSpline or BSPLINE is false + if (snap && (((!held_control(*event) && _pm().isBSpline) && (!held_shift(*event) && _pm().isBSpline)) || !_pm().isBSpline)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -465,16 +405,11 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); - if(_pm().isBSpline){ - Handle *h = NULL; - _parent->bsplineWeight = 0.0000; - h = this; setPosition(new_pos); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); } - } @@ -489,6 +424,10 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } + + if(_pm().isBSpline && !held_shift(*event) && !held_control(*event)){ + new_pos=_last_drag_origin(); + } move(new_pos); // needed for correct update, even though it's redundant _pm().update(); } @@ -505,7 +444,9 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - _parent->bsplineWeight = 0.0000; + if(_pm().isBSpline){ + _parent->bsplineWeight = 0.0000; + } } } @@ -548,13 +489,18 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; + bool isBSpline = false; + if( _parent->bsplineWeight != 0.0000) + isBSpline = true; bool can_shift_rotate = _parent->type() == NODE_CUSP && !other()->isDegenerate(); - if (can_shift_rotate) { + if (can_shift_rotate && !isBSpline) { more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); - } else { + } else if(isBSpline){ + more = C_("Path handle tip", "move:Shift, reset:double click, more: Ctrl"); + }else { more = C_("Path handle tip", "more: Ctrl, Alt"); } - if (state_held_alt(state)) { + if (state_held_alt(state) && !isBSpline) { if (state_held_control(state)) { if (state_held_shift(state) && can_shift_rotate) { return format_tip(C_("Path handle tip", @@ -577,18 +523,24 @@ Glib::ustring Handle::_getTip(unsigned state) const } } else { if (state_held_control(state)) { - if (state_held_shift(state) && can_shift_rotate) { + if (state_held_shift(state) && can_shift_rotate && !isBSpline) { return format_tip(C_("Path handle tip", "Shift+Ctrl: snap rotation angle to %g° increments and rotate both handles"), snap_increment_degrees()); - } else { + } else if(isBSpline){ + return format_tip(C_("Path handle tip", + "Ctrl: Move handle by his actual steps in BSpline Live Effect")); + }else{ return format_tip(C_("Path handle tip", "Ctrl: snap rotation angle to %g° increments, click to retract"), snap_increment_degrees()); } - } else if (state_held_shift(state) && can_shift_rotate) { + } else if (state_held_shift(state) && can_shift_rotate && !isBSpline) { return C_("Path hande tip", "Shift: rotate both handles by the same angle"); + } else if(state_held_shift(state) && isBSpline){ + return C_("Path hande tip", + "Shift: move handle"); } } @@ -676,31 +628,14 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - double prevPos = 0.0000; - double nextPos = 0.0000; - _pm().BSpline(); + double oldPos = 0.0000; Node *n = this; - Node * nextNode = n->nodeToward(n->front()); - Node * prevNode = n->nodeToward(n->back()); if(_pm().isBSpline){ - if(prevNode) - prevPos = _pm().BSplineHandlePosition(prevNode->front()); - n->bsplineWeight = _pm().BSplineHandlePosition(n->front()); - if(n->bsplineWeight == 0.0000) - n->bsplineWeight = _pm().BSplineHandlePosition(n->back()); - if(nextNode) - nextPos = _pm().BSplineHandlePosition(nextNode->back()); + oldPos = n->bsplineWeight; } setPosition(new_pos); - - if(_pm().isBSpline){ - if(prevNode) - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); - if(nextNode) - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); - } - + _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); @@ -709,15 +644,18 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); if(_pm().isBSpline){ - Handle* front = &_front; - Handle* back = &_back; - _front.setPosition(_pm().BSplineHandleReposition(front,n->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(back,n->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); + _pm().BSplineNodeHandlesReposition(this); } } void Node::transform(Geom::Affine const &m) { + double oldPos = 0.0000; + if(_pm().isBSpline){ + oldPos = this->bsplineWeight; + } Geom::Point old_pos = position(); setPosition(position() * m); _front.setPosition(_front.position() * m); @@ -726,10 +664,9 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - _pm().BSpline(); if(_pm().isBSpline){ - _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); _pm().BSplineNodeHandlesReposition(this); } } @@ -817,6 +754,8 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } + if(!_pm().isBSpline) + this->bsplineWeight = 0.0000; } void Node::updateHandles() @@ -917,14 +856,10 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - _pm().BSpline(); if(_pm().isBSpline){ - Handle* front = &_front; - Handle* back = &_back; - this->bsplineWeight = _pm().BSplineHandlePosition(front); if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; - _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); } } @@ -1175,8 +1110,19 @@ void Node::_setState(State state) mgr.setPrelight(_canvas_item, false); _pm().BSpline(); if(_pm().isBSpline){ - this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); - _pm().BSplineNodeHandlesReposition(this); + if(!this->back()->isDegenerate()){ + this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); + }else if (!this->front()->isDegenerate()){ + this->bsplineWeight = _pm().BSplineHandlePosition(this->front()); + }else{ + this->bsplineWeight = 0.0000; + } + if(!this->front()->isDegenerate()){ + this->front()->setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); + } + if(!this->back()->isDegenerate()){ + this->back()->setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + } } break; diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fd421e587..4aec42100 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1294,6 +1294,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; + BSpline(); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { @@ -1301,14 +1302,8 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); - //if(isBSpline){ - // BSplineNodeHandlesReposition(prev.ptr()); - //} builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - //if(isBSpline){ - // BSplineNodeHandlesReposition(i.ptr()); - //} build_segment(builder, prev.ptr(), i.ptr()); prev = i; } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 2a59df464..547e687a7 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -116,7 +116,7 @@ private: Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); void BSplineNodeHandlesReposition(Node *n); - + void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From 4c6918c72721a35e0347e9e087396238e72eb62e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 20:41:32 +0100 Subject: Refactorizing (bzr r11950.1.212) --- src/ui/tool/curve-drag-point.cpp | 2 - src/ui/tool/multi-path-manipulator.cpp | 3 -- src/ui/tool/multi-path-manipulator.h | 2 +- src/ui/tool/node.cpp | 21 ++++------ src/ui/tool/node.h | 9 ++--- src/ui/tool/path-manipulator.cpp | 11 +---- src/ui/tool/path-manipulator.h | 7 +--- src/ui/tools/freehand-base.cpp | 8 ---- src/ui/tools/freehand-base.h | 2 - src/ui/tools/node-tool.h | 1 - src/ui/tools/pen-tool.cpp | 74 ++++++---------------------------- src/ui/tools/pen-tool.h | 2 - src/ui/tools/pencil-tool.cpp | 8 ---- 13 files changed, 29 insertions(+), 121 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index f847a6ab3..5387e597d 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,12 +53,10 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - //BSpline if(!_pm.isBSpline){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); } - //BSpline End _pm.update(); } else { _segment_was_degenerate = false; diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 6da8b4104..3612f9c56 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -298,7 +298,6 @@ void MultiPathManipulator::invertSelectionInSubpaths() invokeForAll(&PathManipulator::invertSelectionInSubpaths); } - void MultiPathManipulator::setNodeType(NodeType type) { if (_selection.empty()) return; @@ -327,7 +326,6 @@ void MultiPathManipulator::setNodeType(NodeType type) _done(retract_handles ? _("Retract handles") : _("Change node type")); } - void MultiPathManipulator::setSegmentType(SegmentType type) { if (_selection.empty()) return; @@ -691,7 +689,6 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G deleteNodes(true); } else - //BSpline end deleteNodes(del_preserves_shape ^ held_control(event->key)); // Delete any selected gradient nodes as well diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index 4566a7a98..1328372c6 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -71,7 +71,7 @@ public: void setLiveObjects(bool set); void updateOutlineColors(); void updateHandles(); - + sigc::signal signal_coords_changed; /// Emitted whenever the coordinates /// shown in the status bar need updating private: diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 70e374424..7266c85bb 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,9 +28,7 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include - #include -; namespace { @@ -137,7 +135,7 @@ void Handle::move(Geom::Point const &new_pos) Node *node_away = _parent->nodeAwayFrom(this); // node in the opposite direction Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; - + if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -308,7 +306,6 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } - void Handle::handle_2button_press(){ if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -318,7 +315,6 @@ void Handle::handle_2button_press(){ } } - bool Handle::grabbed(GdkEventMotion *) { _saved_other_pos = other()->position(); @@ -335,6 +331,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) SnapManager &sm = _desktop->namedview->snap_manager; bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap(); boost::optional ctrl_constraint; + // with Alt, preserve length if (held_alt(*event)) { new_pos = parent_pos + Geom::unit_vector(new_pos - parent_pos) * _saved_length; @@ -366,14 +363,13 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - + if(_pm().isBSpline){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); } - } std::vector unselected; @@ -627,22 +623,22 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - + double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline){ oldPos = n->bsplineWeight; } - + setPosition(new_pos); _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); - + // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - + if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -774,6 +770,7 @@ void Node::setType(NodeType type, bool update_handles) updateState(); // The size of the control might have changed return; } + // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -861,7 +858,6 @@ void Node::setType(NodeType type, bool update_handles) _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); } - } _type = type; _setControlType(nodeTypeToCtrlType(_type)); @@ -1124,7 +1120,6 @@ void Node::_setState(State state) this->back()->setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); } } - break; } SelectableControlPoint::_setState(state); diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index d257db86a..01159e6a0 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -97,6 +97,7 @@ public: virtual void setVisible(bool); virtual void move(Geom::Point const &p); + virtual void setPosition(Geom::Point const &p); inline void setRelativePos(Geom::Point const &p); void setLength(double len); @@ -112,28 +113,25 @@ public: protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); - //Bspline virtual void handle_2button_press(); - //BSpline End - virtual bool _eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent *event); - virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); virtual void ungrabbed(GdkEventButton *event); virtual bool clicked(GdkEventButton *event); - virtual Glib::ustring _getTip(unsigned state) const; virtual Glib::ustring _getDragTip(GdkEventMotion *event) const; virtual bool _hasDragTips() const { return true; } private: + inline PathManipulator &_pm(); Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; bool _degenerate; // True if the handle is retracted, i.e. has zero length. This is used often internally so it makes sense to cache this + /** * Control point of a cubic Bezier curve in a path. * @@ -190,6 +188,7 @@ public: Handle *front() { return &_front; } Handle *back() { return &_back; } double bsplineWeight; + /** * Gets the handle that faces the given adjacent node. * Will abort with error if the given node is not adjacent. diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4aec42100..4cb6ce296 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -43,10 +43,8 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" - #include "live_effects/lpe-bspline.h" - namespace Inkscape { namespace UI { @@ -668,7 +666,6 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - if(isBSpline){ double pos = 0.0000; if(start.prev()){ @@ -680,7 +677,6 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); } } - return del_len; } @@ -856,9 +852,9 @@ void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) int snaps = prefs->getIntLimited("/options/rotationsnapsperpi/value", 12, 1, 1000); angle = M_PI * dir / snaps; } + h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); update(); - gchar const *key = which < 0 ? "handle:rotate:left" : "handle:rotate:right"; _commit(_("Rotate handle"), key); } @@ -915,9 +911,7 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - if(isBSpline) show = true; - if (show == _show_outline) return; _show_outline = show; _updateOutline(); @@ -1307,7 +1301,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) build_segment(builder, prev.ptr(), i.ptr()); prev = i; } - if (subpath->closed()) { // Here we link the last and first node if the path is closed. // If the last segment is Bezier, we add it. @@ -1319,7 +1312,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } ++spi; } - builder.finish(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); @@ -1380,6 +1372,7 @@ void PathManipulator::_updateOutline() sp_canvas_item_hide(_outline); return; } + Geom::PathVector pv = _spcurve->get_pathvector(); pv *= (_edit_transform * _i2d_transform); // This SPCurve thing has to be killed with extreme prejudice diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 547e687a7..31cc0d1fd 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -19,10 +19,8 @@ #include #include "ui/tool/node.h" #include "ui/tool/manipulator.h" - #include "live_effects/lpe-bspline.h" - struct SPCanvasItem; class SPCurve; class SPPath; @@ -97,10 +95,9 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - + bool isBSpline; int BSplineGetSteps(); - // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -110,13 +107,11 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - void BSpline(); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); void BSplineNodeHandlesReposition(Node *n); - void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 14a5b5b35..b6efaebd9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -247,12 +247,10 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //BSpline //Añadimos el modo BSpline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } - //BSPline End int shape = prefs->getInt(tool_name(dc) + "/shape", 0); bool shape_applied = false; @@ -489,7 +487,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); - if (c->is_empty()) { c->unref(); return; @@ -520,7 +517,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - //BSpline //Si la curva tiene un LPE del tipo BSpline ejecutamos spdc_flush_white //pasándole la curva de inicio necesaria Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -529,7 +525,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); spdc_flush_white(dc, dc->sa->curve); }else - //BSpline End spdc_flush_white(dc, NULL); return; } @@ -657,7 +652,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //BSpline //Modificamos la curva del "anchor" final para que sea igual que la curva de inicio. //Esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en //la que cerramos el trazado. @@ -670,7 +664,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) active->curve->ref(); } } - //BSpline End return active; } @@ -815,4 +808,3 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 7d60e217f..7e53684e3 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -57,7 +57,6 @@ public: SPCanvasItem *blue_bpath; SPCurve *blue_curve; - // Green GSList *green_bpaths; SPCurve *green_curve; @@ -143,4 +142,3 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index b3acb79ad..4d15ab70e 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,7 +14,6 @@ #include #include #include "ui/tools/tool-base.h" -#include "selection.h" namespace Inkscape { namespace Display { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 178a940a2..f8d8d4c90 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1,4 +1,4 @@ - /** \file +/** \file * Pen event context implementation. */ @@ -20,7 +20,6 @@ #include #include - #include "ui/tools/pen-tool.h" #include "sp-namedview.h" #include "desktop.h" @@ -43,7 +42,6 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//BSpline //Incluimos los archivos necesarios para las BSpline y Spiro #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -64,11 +62,9 @@ #include "live_effects/spiro.h" - #define INKSCAPE_LPE_BSPLINE_C #include "live_effects/lpe-bspline.h" #include <2geom/nearest-point.h> -//BSpline End #include "tool-factory.h" @@ -80,10 +76,6 @@ namespace UI { namespace Tools { static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p); -/* - *BSpline - *Added functions -*/ //Añade los modos spiro y bspline static void sp_pen_context_set_mode(PenTool *const pc, guint mode); //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro @@ -112,7 +104,7 @@ static void bspline_spiro_build(PenTool *const pc); static void bspline_doEffect(SPCurve * curve); //function spiro cloned from lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve); -//BSpline end + static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status = 0); static void spdc_pen_set_ctrl(PenTool *pc, Geom::Point const p, guint state); static void spdc_pen_finish_segment(PenTool *pc, Geom::Point p, guint state); @@ -205,14 +197,11 @@ void sp_pen_context_set_polyline_mode(PenTool *const pc) { guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); pc->polylines_only = (mode == 3 || mode == 4); pc->polylines_paraxial = (mode == 4); - //BSpline //we call the function which defines the Spiro modes and the BSpline //todo: merge to one function only sp_pen_context_set_mode(pc, mode); - //BSpline End } -//BSpline /* *.Set the mode of draw spiro, and bsplines */ @@ -220,7 +209,6 @@ void sp_pen_context_set_mode(PenTool *const pc, guint mode) { pc->spiro = (mode == 1); pc->bspline = (mode == 2); } -//BSpline End /** * Callback to initialize PenTool object. @@ -422,12 +410,11 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev if(!bevent.button == 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } - //BSpline end gint ret = FALSE; if (bevent.button == 1 && !event_context->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) - && (pc->expecting_clicks_for_LPE != 1)) { + && pc->expecting_clicks_for_LPE != 1) { if (Inkscape::have_viable_layer(desktop, dc->message_context) == false) { return TRUE; @@ -487,12 +474,10 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev // Set start anchor pc->sa = anchor; - //BSpline //Continuamos una curva existente if(anchor){ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } - //BSpline End if (anchor && !sp_pen_context_has_waiting_LPE(pc)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need // a fresh path to be created so don't continue an existing one @@ -544,10 +529,8 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev } } - //BSpline //Evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? PenTool::POINT : PenTool::CONTROL; - //BSpline End ret = TRUE; break; @@ -585,6 +568,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev if (pc->expecting_clicks_for_LPE > 0) { --pc->expecting_clicks_for_LPE; } + return ret; } @@ -609,8 +593,7 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me } Geom::Point const event_w(mevent.x, - mevent.y); - //BSpline + mevent.y); //we take out the function the const "tolerance" because we need it later Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -620,7 +603,6 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me return FALSE; // Do not drag if we're within tolerance from origin. } } - //BSpline END // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) @@ -736,7 +718,6 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me default: break; } - //BSpline //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(pc->bspline){ bspline_spiro_color(pc); @@ -748,7 +729,7 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me pen_drag_origin_w = event_w; } } - //BSpline End + return ret; } @@ -761,7 +742,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // skip event processing if events are disabled return FALSE; } - + gint ret = FALSE; ToolBase *event_context = SP_EVENT_CONTEXT(pc); @@ -776,7 +757,6 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); - //BSpline //with this we avoid creating a new point over the existing one if(pc->spiro || pc->bspline){ //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. @@ -784,7 +764,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r return FALSE; } } - //BSpline End + switch (pc->mode) { case PenTool::MODE_CLICK: switch (pc->state) { @@ -795,14 +775,12 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r p = anchor->dp; } pc->sa = anchor; - //BSpline //continuamos una curva existente if (anchor) { if(pc->bspline || pc->spiro){ bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); } } - //BSpline End spdc_pen_set_initial_point(pc, p); } else { // Set end anchor here @@ -827,12 +805,10 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r spdc_endpoint_snap(pc, p, revent.state); } spdc_pen_finish_segment(pc, p, revent.state); - //BSpline //Ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } - //BSpline End spdc_pen_finish(pc, TRUE); pc->state = PenTool::POINT; ret = TRUE; @@ -856,12 +832,10 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r case PenTool::CLOSE: spdc_endpoint_snap(pc, p, revent.state); spdc_pen_finish_segment(pc, p, revent.state); - //BSpline //Ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } - //BSpline End if (pc->green_closed) { // finishing at the start anchor, close curve spdc_pen_finish(pc, TRUE); @@ -873,7 +847,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r case PenTool::STOP: // This is allowed, if we just cancelled curve break; - default: + default: break; } pc->state = PenTool::POINT; @@ -911,6 +885,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // handled in spdc_check_for_and_apply_waiting_LPE() in draw-context.cpp } } + return ret; } @@ -938,20 +913,20 @@ static void pen_redraw_all (PenTool *const pc) SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); } if (pc->green_anchor) SP_CTRL(pc->green_anchor->ctrl)->moveto(pc->green_anchor->dp); + pc->red_curve->reset(); pc->red_curve->moveto(pc->p[0]); pc->red_curve->curveto(pc->p[1], pc->p[2], pc->p[3]); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); // handles - //BSpline //Ocultamos los tiradores en modo BSpline y spiro if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { - //BSpline End SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); sp_canvas_item_show(pc->c1); @@ -964,12 +939,10 @@ static void pen_redraw_all (PenTool *const pc) Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //BSpline //Ocultamos los tiradores en modo BSpline y spiro if ( cubic && (*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline ) { - //BSpline End Geom::Point p2 = (*cubic)[2]; SP_CTRL(pc->c0)->moveto(p2); pc->cl0->setCoords(p2, pc->p[0]); @@ -980,15 +953,12 @@ static void pen_redraw_all (PenTool *const pc) sp_canvas_item_hide(pc->cl0); } } - //BSpline + //Simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. //como es un redibujo simplemente no llamamos a la función global //sino al final de esta - - //BSpline //Lanzamos solamente el redibujado bspline_spiro_build(pc); - //BSpline End } static void pen_lastpoint_move (PenTool *const pc, gdouble x, gdouble y) @@ -1019,11 +989,9 @@ static void pen_lastpoint_move_screen (PenTool *const pc, gdouble x, gdouble y) static void pen_lastpoint_tocurve (PenTool *const pc) { - //BSpline //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->spiro && !pc->bspline) return; - //BSpline Geom::CubicBezier const * cubic; pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint()); //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos @@ -1070,13 +1038,11 @@ static void pen_lastpoint_tocurve (PenTool *const pc) } } - //Spiro Live pen_redraw_all(pc); } static void pen_lastpoint_toline (PenTool *const pc) { - //BSpline //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->bspline) return; @@ -1312,7 +1278,6 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) : pc->p[3])); pc->npoints = 2; - //BSpline //Eliminamos el último segmento de la curva verde if( pc->green_curve->get_segment_count() == 1){ pc->npoints = 5; @@ -1335,16 +1300,13 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) pc->p[1] = pc->p[0]; } } - //BSpline End sp_canvas_item_hide(pc->cl0); sp_canvas_item_hide(pc->cl1); pc->state = PenTool::POINT; spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //BSpline //Redibujamos bspline_spiro_build(pc); - //BSpline End ret = TRUE; } break; @@ -1358,12 +1320,10 @@ static void spdc_reset_colors(PenTool *pc) { // Red pc->red_curve->reset(); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); // Blue pc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), NULL); - // Green while (pc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); @@ -2111,8 +2071,6 @@ static void spiro_doEffect(SPCurve * curve) g_free (path); } -//BSpline end - static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status) { g_assert( pc->npoints != 0 ); @@ -2139,9 +2097,7 @@ static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p is_curve = false; } else { // one of the 'regular' modes - //SpiroLive if (pc->p[1] != pc->p[0] || pc->spiro) { - //SpiroLive End pc->red_curve->curveto(pc->p[1], p, p); is_curve = true; } else { @@ -2156,13 +2112,11 @@ static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p gchar *message = is_curve ? _("Curve segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path" ): _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"); - //BSpline if(pc->spiro || pc->bspline){ message = is_curve ? _("Curve segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path" ): _("Line segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path"); } - //BSpline End spdc_pen_set_angle_distance_status_message(pc, p, 0, message); } } @@ -2369,5 +2323,3 @@ void pen_set_to_nearest_horiz_vert(const PenTool *const pc, Geom::Point &pt, gui End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - - diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 553e4c557..b0b56feb4 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -48,11 +48,9 @@ public: bool polylines_only; bool polylines_paraxial; - //SpiroLive //Propiedad que guarda si el modo Spiro está activo o no bool spiro; bool bspline; - //SpiroLIve End int num_clicks; unsigned int expecting_clicks_for_LPE; // if positive, finish the path after this many clicks diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index c10bd15a3..2027f0981 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -692,10 +692,8 @@ interpolate(PencilTool *pc) return; } - //BSpline using Geom::X; using Geom::Y; - //BSpline end Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; @@ -727,12 +725,9 @@ interpolate(PencilTool *pc) { /* Fit and draw and reset state */ pc->green_curve->moveto(b[0]); - //BSpline Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); - //BSpline End for (int c = 0; c < n_segs; c++) { - //BSpline //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); @@ -743,7 +738,6 @@ interpolate(PencilTool *pc) }else{ pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); } - //BSpline } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve); @@ -884,7 +878,6 @@ fit_and_split(PencilTool *pc) /* Fit and draw and reset state */ pc->red_curve->reset(); pc->red_curve->moveto(b[0]); - //BSpline using Geom::X; using Geom::Y; //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc @@ -899,7 +892,6 @@ fit_and_split(PencilTool *pc) }else{ pc->red_curve->curveto(b[1], b[2], b[3]); } - //BSpline End sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); pc->red_curve_is_valid = true; } else { -- cgit v1.2.3 From 8c6ae51081f4d1d63ba84f9dd339b9f530f06c87 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 21:30:44 +0100 Subject: Start refactor, simplify node.cpp operations,general cleanup, changed brehabiour to need 'Shift' Key to move handles because it handle better operations with small zoom (bzr r11950.1.214) --- src/ui/tools/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 4d15ab70e..b3acb79ad 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "ui/tools/tool-base.h" +#include "selection.h" namespace Inkscape { namespace Display { -- cgit v1.2.3 From 8d781fb629a07fdbd828b2eeb18694bb32e88768 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 21:45:48 +0100 Subject: Updated tip strings (bzr r11950.1.215) --- src/ui/tool/node.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7266c85bb..305dd6798 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -492,7 +492,7 @@ Glib::ustring Handle::_getTip(unsigned state) const if (can_shift_rotate && !isBSpline) { more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); } else if(isBSpline){ - more = C_("Path handle tip", "move:Shift, reset:double click, more: Ctrl"); + more = C_("Path handle tip", "more: Ctrl"); }else { more = C_("Path handle tip", "more: Ctrl, Alt"); } @@ -545,9 +545,13 @@ Glib::ustring Handle::_getTip(unsigned state) const return format_tip(C_("Path handle tip", "Auto node handle: drag to convert to smooth node (%s)"), more); default: - return format_tip(C_("Path handle tip", - "%s: drag to shape the segment (%s)"), - handle_type_to_localized_string(_parent->type()), more); + if(!isBSpline){ + return format_tip(C_("Path handle tip", + "Auto node handle: drag to convert to smooth node (%s)"), more); + }else{ + return format_tip(C_("Path handle tip", + "BSpline node handle: Shift to drag, double click to reset (%s)"), more); + } } } -- cgit v1.2.3 From 140267c64cd9d19e372328d6f30c072102c2dd33 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 22:04:13 +0100 Subject: Refact (bzr r11950.1.216) --- src/ui/tool/node.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 305dd6798..85a407384 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -974,6 +974,7 @@ bool Node::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent _selection.spatialGrow(this, dir); } return true; + default: break; } -- cgit v1.2.3 From 1abfd51451a3df8a46ec9e23332aff72208ac942 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:19:31 +0100 Subject: Spanish comment of node.cpp (bzr r11950.1.217) --- src/ui/tool/node.cpp | 53 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 85a407384..9eab1d7dc 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //If is bspline move other handle + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); _parent->bsplineWeight = _pm().BSplineHandlePosition(this); @@ -185,7 +185,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //If is bspline move both handles + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); _parent->bsplineWeight = _pm().BSplineHandlePosition(this); @@ -212,7 +212,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //If is bspline move other handle + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); _parent->bsplineWeight = _pm().BSplineHandlePosition(this); @@ -295,7 +295,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - + //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -306,6 +306,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } +//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -363,7 +364,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - + //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el + //parametro "steps whith control" del efecto en vivo BSpline if(_pm().isBSpline){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -373,9 +375,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - - //IF Snap and Not CTRL && BSpline or BSPLINE is false - if (snap && (((!held_control(*event) && _pm().isBSpline) && (!held_shift(*event) && _pm().isBSpline)) || !_pm().isBSpline)) { + //spanish: si está activado el ajuste (snap) y no es bspline + if (snap && !_pm().isBSpline) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -401,11 +402,6 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); - if(_pm().isBSpline){ - setPosition(new_pos); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); - new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); - } } @@ -420,7 +416,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - + //spanish: si es bspline pero no está presionado SHIFT o CONTROL + //lo fija en la posición original if(_pm().isBSpline && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -440,6 +437,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); + //spanish: marca la fuerza del bspline como 0.0000 if(_pm().isBSpline){ _parent->bsplineWeight = 0.0000; } @@ -485,6 +483,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; + //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -587,7 +588,6 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _type(NODE_CUSP), _handles_shown(false) { - this->bsplineWeight = 0.3334; // NOTE we do not set type here, because the handles are still degenerate } @@ -627,7 +627,8 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline){ @@ -642,7 +643,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -652,6 +654,8 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; if(_pm().isBSpline){ oldPos = this->bsplineWeight; @@ -664,6 +668,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -754,8 +760,12 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - if(!_pm().isBSpline) - this->bsplineWeight = 0.0000; + //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. + //Cada vez que actuemos sobre dichos tiradores en un trazado + //bspline esta fuerza se tiene que actualizar + this->bsplineWeight = 0.0000; + if(_pm().isBSpline) + this->bsplineWeight = 0.3334; } void Node::updateHandles() @@ -857,6 +867,9 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } + //spanish: en los cambios de tipo de nodo, sobre trazados bspline, + //o bien los mantenemos con potencia 0.0000 en modo esquina + //o les damos la potencia por defecto en modo de curva if(_pm().isBSpline){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1109,7 +1122,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - _pm().BSpline(); + //spanish: esto muestra los tiradores al seleccionar los nodos if(_pm().isBSpline){ if(!this->back()->isDegenerate()){ this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); -- cgit v1.2.3 From 1866742fce895e2306c4e0bc032f9b73bfce2925 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:23:56 +0100 Subject: Spanish comment of node.h (bzr r11950.1.218) --- src/ui/tool/node.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 01159e6a0..b7d6951d0 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,6 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } + //spanish: creamos valor de potencia bspline asociado a cada nodo double bsplineWeight; /** -- cgit v1.2.3 From 58638901bd9d7408c4bd053673e3f7934adcb668 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:41:04 +0100 Subject: Spanish comment of curve-drag-point-cpp (bzr r11950.1.221) --- src/ui/tool/curve-drag-point.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index 5387e597d..0ee848f15 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,6 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; + //spanish: solo actualizamos los nodos si no es bspline if(!_pm.isBSpline){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -88,6 +89,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; + //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT if(!_pm.isBSpline){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); -- cgit v1.2.3 From 118a1dbf3b1b7145928aeb106d94b77f7f1cdfda Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:50:51 +0100 Subject: Spanish comment of multi-path-manipulator-cpp (bzr r11950.1.222) --- src/ui/tool/multi-path-manipulator.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 3612f9c56..c77d2d795 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -682,7 +682,9 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); + //spanish: si es trazado bspline (mode 2) if(mode==2){ + //spanish: ¿correcto? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else -- cgit v1.2.3 From bfc330ddc8564d132f885378f428fab10692edbb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 00:21:57 +0100 Subject: Spanish comment of path-manipulator-cpp (bzr r11950.1.223) --- src/ui/tool/path-manipulator.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4cb6ce296..47f736fcb 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -33,7 +33,6 @@ #include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/path.h" #include "sp-path.h" -#include "sp-lpe-item.h" #include "helper/geom.h" #include "preferences.h" #include "style.h" @@ -43,6 +42,7 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" +#include "sp-lpe-item.h" #include "live_effects/lpe-bspline.h" namespace Inkscape { @@ -104,7 +104,7 @@ private: }; void build_segment(Geom::PathBuilder &, Node *, Node *); - +//spanish: una propiedad isBSpline, por defecto falsa y una función al final de la función (BSpline()) que la define realmente PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) @@ -666,6 +666,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } + //spanish: si se borra, reajustamos los tiradores if(isBSpline){ double pos = 0.0000; if(start.prev()){ @@ -1185,7 +1186,9 @@ void PathManipulator::_createControlPointsFromGeometry() } } +//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza int PathManipulator::BSplineGetSteps(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ @@ -1194,24 +1197,22 @@ int PathManipulator::BSplineGetSteps(){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } - return lpe_bsp->steps+1; + int steps = 0; + if(lpe_bsp){ + steps = lpe_bsp->steps+1; + } + return steps; } +//spanish: determina si el trazado tiene efecto bspline void PathManipulator::BSpline(){ - LivePathEffect::LPEBSpline *lpe_bsp = NULL; - - if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); - if(thisEffect){ - lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - } - } isBSpline = false; - if(lpe_bsp){ + if(this->BSplineGetSteps()>0){ isBSpline = true; } } +//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1230,11 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } +//spanish: mueve el tirador a la posición que le corresponda Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } +//spanish: mueve el tirador a una posición específica Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1260,11 +1263,12 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } +//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); if(prevNode){ - n->back()->setPosition(BSplineHandleReposition(n->back())); + n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); if(prevNode->front()->position() == prevNode->position()) prevNode->bsplineWeight = 0.000; if(!prevNode->isEndNode()) @@ -1272,7 +1276,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); } if(nextNode){ - n->front()->setPosition(BSplineHandleReposition(n->front())); + n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); if(nextNode->front()->position() == nextNode->position()) nextNode->bsplineWeight = 0.000; if(!nextNode->isEndNode()) -- cgit v1.2.3 From c288aa062e611031f54f6ad8e5e3ee2f581cc783 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 00:29:07 +0100 Subject: Spanish comment of freehand-base.cpp (bzr r11950.1.224) --- src/ui/tool/path-manipulator.cpp | 1 - src/ui/tool/path-manipulator.h | 2 +- src/ui/tools/freehand-base.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 47f736fcb..e70717728 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -42,7 +42,6 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" -#include "sp-lpe-item.h" #include "live_effects/lpe-bspline.h" namespace Inkscape { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 31cc0d1fd..5f075834e 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -94,7 +94,7 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, - bool search_unselected, bool closest); + bool search_unselected, bool closest); bool isBSpline; int BSplineGetSteps(); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index b6efaebd9..5825a149c 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -247,7 +247,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //Añadimos el modo BSpline a los efectos en espera + //spanish: añadimos el modo bspline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -517,7 +517,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - //Si la curva tiene un LPE del tipo BSpline ejecutamos spdc_flush_white + //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white //pasándole la curva de inicio necesaria Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || @@ -652,8 +652,8 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //Modificamos la curva del "anchor" final para que sea igual que la curva de inicio. - //Esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en + //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. + //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en //la que cerramos el trazado. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || -- cgit v1.2.3 From cb0d2fad1fa3b8055b86f8d7e911b295e09cf27a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 00:31:15 +0100 Subject: Spanish comment of node-tool.cpp (bzr r11950.1.225) --- src/ui/tools/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index b3acb79ad..168ec995a 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "ui/tools/tool-base.h" +//spanish: lo necesitamos para llamarlo desde el Live Effect #include "selection.h" namespace Inkscape { -- cgit v1.2.3 From 14a50ad8c16b1d840e7a68ba8a75e2cec174a0a5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:02:40 +0100 Subject: Spanish comment of pencil-tool.cpp/.h (bzr r11950.1.226) --- src/ui/tools/pen-tool.cpp | 150 ++++++++++++++++------------------------------ src/ui/tools/pen-tool.h | 2 +- 2 files changed, 54 insertions(+), 98 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index f8d8d4c90..9b5acb6cc 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//Incluimos los archivos necesarios para las BSpline y Spiro +//spanish: incluimos los archivos necesarios para las BSpline y Spiro #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -76,29 +76,29 @@ namespace UI { namespace Tools { static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p); -//Añade los modos spiro y bspline +//spanish: añade los modos spiro y bspline static void sp_pen_context_set_mode(PenTool *const pc, guint mode); -//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(PenTool *const pc); -//Crea un nodo en modo bspline o spiro +//spanish: crea un nodo en modo bspline o spiro static void bspline_spiro(PenTool *const pc,bool shift); -//Crea un nodo de modo spiro o bspline +//spanish: crea un nodo de modo spiro o bspline static void bspline_spiro_on(PenTool *const pc); -//Crea un nodo de tipo CUSP +//spanish: crea un nodo de tipo CUSP static void bspline_spiro_off(PenTool *const pc); -//Continua una curva existente en modo bspline o spiro +//spanish: continua una curva existente en modo bspline o spiro static void bspline_spiro_start_anchor(PenTool *const pc,bool shift); -//Continua una curva exsitente con el nodo de union en modo bspline o spiro +//spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro static void bspline_spiro_start_anchor_on(PenTool *const pc); -//Continua una curva existente con el nodo de union en modo CUSP +//spanish: continua una curva existente con el nodo de union en modo CUSP static void bspline_spiro_start_anchor_off(PenTool *const pc); -//Modifica la "red_curve" cuando se detecta movimiento +//spanish: modifica la "red_curve" cuando se detecta movimiento static void bspline_spiro_motion(PenTool *const pc,bool shift); -//Cierra la curva con el último nodo en modo bspline o spiro +//spanish: cierra la curva con el último nodo en modo bspline o spiro static void bspline_spiro_end_anchor_on(PenTool *const pc); -//Cierra la curva con el último nodo en modo CUSP +//spanish: cierra la curva con el último nodo en modo CUSP static void bspline_spiro_end_anchor_off(PenTool *const pc); -//Unimos todas las curvas en juego y llamamos a la función doEffect. +//spanish: unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline_spiro_build(PenTool *const pc); //function bspline cloned from lpe-bspline.cpp static void bspline_doEffect(SPCurve * curve); @@ -195,6 +195,7 @@ PenTool::~PenTool() { void sp_pen_context_set_polyline_mode(PenTool *const pc) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); + //spanish: cambiamos los modos para dar cabida al modo bspline pc->polylines_only = (mode == 3 || mode == 4); pc->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -206,6 +207,7 @@ void sp_pen_context_set_polyline_mode(PenTool *const pc) { *.Set the mode of draw spiro, and bsplines */ void sp_pen_context_set_mode(PenTool *const pc, guint mode) { + //spanish: definimos los modos pc->spiro = (mode == 1); pc->bspline = (mode == 2); } @@ -474,7 +476,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev // Set start anchor pc->sa = anchor; - //Continuamos una curva existente + //spanish: continuamos una curva existente if(anchor){ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } @@ -529,7 +531,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev } } - //Evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar + //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -597,9 +599,8 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me //we take out the function the const "tolerance" because we need it later Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); - //"spiro_color" lo ejecutamos siempre sea o no spiro if (pen_within_tolerance) { - if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance) { + if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance ) { return FALSE; // Do not drag if we're within tolerance from origin. } } @@ -610,8 +611,10 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me // Find desktop coordinates Geom::Point p = dt->w2d(event_w); + // Test, whether we hit any anchor SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); + switch (pc->mode) { case PenTool::MODE_CLICK: switch (pc->state) { @@ -691,7 +694,9 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me case PenTool::CONTROL: case PenTool::CLOSE: // Placing controls is last operation in CLOSE state + // snap the handle + spdc_endpoint_snap_handle(pc, p, mevent.state); if (!pc->polylines_only) { spdc_pen_set_ctrl(pc, p, mevent.state); @@ -718,7 +723,7 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me default: break; } - //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. + //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(pc->bspline){ bspline_spiro_color(pc); bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); @@ -759,7 +764,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); //with this we avoid creating a new point over the existing one if(pc->spiro || pc->bspline){ - //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. + //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. if(pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } @@ -775,7 +780,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r p = anchor->dp; } pc->sa = anchor; - //continuamos una curva existente + //spanish: continuamos una curva existente if (anchor) { if(pc->bspline || pc->spiro){ bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); @@ -805,7 +810,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r spdc_endpoint_snap(pc, p, revent.state); } spdc_pen_finish_segment(pc, p, revent.state); - //Ocultamos la guia del penultimo nodo al cerrar la curva + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } @@ -832,7 +837,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r case PenTool::CLOSE: spdc_endpoint_snap(pc, p, revent.state); spdc_pen_finish_segment(pc, p, revent.state); - //Ocultamos la guia del penultimo nodo al cerrar la curva + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } @@ -925,7 +930,7 @@ static void pen_redraw_all (PenTool *const pc) sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); // handles - //Ocultamos los tiradores en modo BSpline y spiro + //spanish: ocultamos los tiradores en modo bspline y spiro if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); @@ -939,7 +944,7 @@ static void pen_redraw_all (PenTool *const pc) Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //Ocultamos los tiradores en modo BSpline y spiro + //spanish: ocultamos los tiradores en modo bspline y spiro if ( cubic && (*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline ) { @@ -954,9 +959,8 @@ static void pen_redraw_all (PenTool *const pc) } } - //Simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. - //como es un redibujo simplemente no llamamos a la función global - //sino al final de esta + //spanish: simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. + //como es un redibujo simplemente no llamamos a la función global sino al final de esta //Lanzamos solamente el redibujado bspline_spiro_build(pc); } @@ -989,12 +993,12 @@ static void pen_lastpoint_move_screen (PenTool *const pc, gdouble x, gdouble y) static void pen_lastpoint_tocurve (PenTool *const pc) { - //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->spiro && !pc->bspline) return; Geom::CubicBezier const * cubic; pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint()); - //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(pc->spiro||pc->bspline){ if(!pc->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1032,7 +1036,7 @@ static void pen_lastpoint_tocurve (PenTool *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } - //Si el último nodo es una union con otra curva + //spanish: si el último nodo es una union con otra curva if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ bspline_spiro_start_anchor(pc, false); } @@ -1043,11 +1047,11 @@ static void pen_lastpoint_tocurve (PenTool *const pc) static void pen_lastpoint_toline (PenTool *const pc) { - //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->bspline) return; - //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(pc->spiro || pc->bspline){ if(!pc->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1079,7 +1083,7 @@ static void pen_lastpoint_toline (PenTool *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } - //Si el último nodo es una union con otra curva + //spanish: si el último nodo es una union con otra curva if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ bspline_spiro_start_anchor(pc, true); } @@ -1268,7 +1272,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) } else { pc->p[1] = pc->p[0]; } - //Asignamos el valor a un tercio de distancia del último segmento. + //spanish: asignamos el valor a un tercio de distancia del último segmento. if(pc->bspline){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); } @@ -1278,7 +1282,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) : pc->p[3])); pc->npoints = 2; - //Eliminamos el último segmento de la curva verde + //spanish: eliminamos el último segmento de la curva verde if( pc->green_curve->get_segment_count() == 1){ pc->npoints = 5; if (pc->green_bpaths) { @@ -1290,7 +1294,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) }else{ pc->green_curve->backspace(); } - //Asignamos el valor de pc->p[1] a el opuesto de el ultimo segmento de la línea verde + //spanish: asignamos el valor de pc->p[1] a el opuesto de el ultimo segmento de la línea verde if(pc->spiro){ cubic = dynamic_cast(pc->green_curve->last_segment()); if ( cubic ) { @@ -1305,7 +1309,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) pc->state = PenTool::POINT; spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //Redibujamos + //spanish: redibujamos bspline_spiro_build(pc); ret = TRUE; } @@ -1381,7 +1385,7 @@ static void spdc_pen_set_angle_distance_status_message(PenTool *const pc, Geom:: } -//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(PenTool *const pc) { bool remake_green_bpaths = false; @@ -1719,7 +1723,7 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) } -//preparates the curves for its trasformation into BSline curves. +//spanish: preparates the curves for its trasformation into BSline curves. static void bspline_spiro_build(PenTool *const pc) { if(!pc->spiro && !pc->bspline) @@ -1748,7 +1752,7 @@ static void bspline_spiro_build(PenTool *const pc) } if(!curve->is_empty()){ - //cerramos la curva si estan cerca los puntos finales de la curva spiro + //spanish: cerramos la curva si estan cerca los puntos finales de la curva spiro if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1787,26 +1791,19 @@ static void bspline_spiro_build(PenTool *const pc) static void bspline_doEffect(SPCurve * curve) { + //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; - // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el penúltimo for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - //Si está vacío... if (path_it->empty()) continue; - //Itreadores - + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop - //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán - //los puntos clave para los manejadores. - //Esto hace que la curva BSpline no pierda su condición aunque se trasladen - //dichos manejadores SPCurve *nCurve = new SPCurve(); Geom::Point previousNode(0,0); Geom::Point node(0,0); @@ -1820,23 +1817,13 @@ static void bspline_doEffect(SPCurve * curve) Geom::D2< Geom::SBasis > SBasisHelper; Geom::CubicBezier const *cubic = NULL; if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! curve_endit = path_it->end_open(); } } - //Si la curva está cerrada calculamos el punto donde - //deveria estar el nodo BSpline de cierre/inicio de la curva - //en posible caso de que se cierre con una linea recta creando un nodo BSPline - - //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida SPCurve * in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); @@ -1851,8 +1838,6 @@ static void bspline_doEffect(SPCurve * curve) } in->reset(); delete in; - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); SPCurve * out = new SPCurve(); out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); @@ -1869,37 +1854,25 @@ static void bspline_doEffect(SPCurve * curve) } out->reset(); delete out; - //La curva BSpline se forma calculando el centro del segmanto de unión - //de el punto situado en las 2/3 partes de el segmento de entrada - //con el punto situado en la posición 1/3 del segmento de salida - //Estos dos puntos ademas estan posicionados en el lugas correspondiente de - //los manejadores de la curva SPCurve *lineHelper = new SPCurve(); lineHelper->moveto(pointAt2); lineHelper->lineto(nextPointAt1); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); delete lineHelper; - //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva previousNode = node; - //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); - //añadimos la curva generada a la curva pricipal nCurve->append_continuous(curveHelper, 0.0625); curveHelper->reset(); delete curveHelper; - //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; } - //Aberiguamos la ultima parte de la curva correspondiente al último segmento SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(node); - //Si está cerrada la curva, la cerramos sobre el valor guardado previamente - //Si no finalizamos en el punto final Geom::Point startNode(0,0); if (path_it->closed()) { SPCurve * start = new SPCurve(); @@ -1920,7 +1893,6 @@ static void bspline_doEffect(SPCurve * curve) end->moveto(curve_it1->initialPoint()); end->lineto(curve_it1->finalPoint()); Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis(); - //Geom::BezierCurve const *bezier = dynamic_cast(&*curve_endit); cubic = dynamic_cast(&*curve_it1); if(cubic){ lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()))); @@ -1932,7 +1904,6 @@ static void bspline_doEffect(SPCurve * curve) SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); delete lineHelper; - //Guardamos el principio de la curva startNode = SBasisHelper.valueAt(0.5); curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); nCurve->append_continuous(curveHelper, 0.0625); @@ -1950,7 +1921,6 @@ static void bspline_doEffect(SPCurve * curve) } curveHelper->reset(); delete curveHelper; - //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); } @@ -1961,12 +1931,12 @@ static void bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp +//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; - // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); guint len = curve->get_segment_count() + 2; @@ -1978,41 +1948,31 @@ static void spiro_doEffect(SPCurve * curve) if (path_it->empty()) continue; - // start of path { Geom::Point p = path_it->front().pointAt(0); path[ip].x = p[X]; path[ip].y = p[Y]; - path[ip].ty = '{' ; // for closed paths, this is overwritten + path[ip].ty = '{' ; ip++; } - // midpoints - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); - Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + Geom::Path::const_iterator curve_endit = path_it->end_default(); if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + const Geom::Curve &closingline = path_it->back_closed(); if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! curve_endit = path_it->end_open(); } } while ( curve_it2 != curve_endit ) { - /* This deals with the node between curve_it1 and curve_it2. - * Loop to end_default (so without last segment), loop ends when curve_it2 hits the end - * and then curve_it1 points to end or closing segment */ Geom::Point p = curve_it1->finalPoint(); path[ip].x = p[X]; path[ip].y = p[Y]; - // Determine type of spiro node this is, determined by the tangents (angles) of the curves - // TODO: see if this can be simplified by using /helpers/geom-nodetype.cpp:get_nodetype bool this_is_line = is_straight_curve(*curve_it1); bool next_is_line = is_straight_curve(*curve_it2); @@ -2036,15 +1996,13 @@ static void spiro_doEffect(SPCurve * curve) ip++; } - // add last point to the spiropath Geom::Point p = curve_it1->finalPoint(); path[ip].x = p[X]; path[ip].y = p[Y]; if (path_it->closed()) { - // curve_it1 points to the (visually) closing segment. determine the match between first and this last segment (the closing node) Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front()); switch (nodetype) { - case Geom::NODE_NONE: // can't happen! but if it does, it means the path isn't closed :-) + case Geom::NODE_NONE: path[ip].ty = '}'; ip++; break; @@ -2057,12 +2015,10 @@ static void spiro_doEffect(SPCurve * curve) break; } } else { - // set type to path closer path[ip].ty = '}'; ip++; } - // run subpath through spiro int sp_len = ip; Spiro::spiro_run(path, sp_len, *curve); ip = 0; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index b0b56feb4..4f87429f4 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -48,7 +48,7 @@ public: bool polylines_only; bool polylines_paraxial; - //Propiedad que guarda si el modo Spiro está activo o no + //spanish: propiedad que guarda si el modo Spiro está activo o no bool spiro; bool bspline; int num_clicks; -- cgit v1.2.3 From d8a7188e7a73050e329103b79e769b8fa498ede5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:04:31 +0100 Subject: Spanish comment of pencil-tool.cpp (bzr r11950.1.227) --- src/ui/tools/pencil-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 2027f0981..883b3fa36 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -728,7 +728,7 @@ interpolate(PencilTool *pc) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -880,7 +880,7 @@ fit_and_split(PencilTool *pc) pc->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From 3e2698fd64dbf8c63b1efc758be5b3a1c30fe1fc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:42:32 +0100 Subject: fix a bug whith degenerate handles (bzr r11950.1.229) --- src/ui/tool/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 9eab1d7dc..a932e5b7b 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -764,7 +764,7 @@ void Node::showHandles(bool v) //Cada vez que actuemos sobre dichos tiradores en un trazado //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; - if(_pm().isBSpline) + if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())) this->bsplineWeight = 0.3334; } -- cgit v1.2.3 From c08c28e9a22f0fe5f06e9dc34430c3acb16f3c13 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 2 Jan 2014 16:15:27 +0100 Subject: Fixed a boring bug sometimes curves be converted to lines, increasing a bit the distance from the handle to the line (bzr r11950.1.230) --- src/ui/tool/node.cpp | 21 ++++++++++++++++++--- src/ui/tool/path-manipulator.cpp | 6 ++---- src/ui/tools/pen-tool.cpp | 29 +++++++++++++++++------------ 3 files changed, 37 insertions(+), 19 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index a932e5b7b..39b21ae6d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1388,6 +1388,12 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { + //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion + bool isBSpline = false; + if( this->bsplineWeight != 0.0000) + isBSpline = true; if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { @@ -1417,15 +1423,24 @@ Glib::ustring Node::_getTip(unsigned state) const // No modifiers: assemble tip from node type char const *nodetype = node_type_to_localized_string(_type); if (_selection.transformHandlesEnabled() && selected()) { - if (_selection.size() == 1) { + if (_selection.size() == 1 && !isBSpline) { return format_tip(C_("Path node tip", "%s: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype); + }else if(_selection.size() == 1){ + return format_tip(C_("Path node tip", + "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),this->bsplineWeight); } return format_tip(C_("Path node tip", "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype); } - return format_tip(C_("Path node tip", - "%s: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype); + if (!isBSpline) { + return format_tip(C_("Path node tip", + "%s: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype); + }else{ + return format_tip(C_("Path node tip", + "BSpline node: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)")); + + } } Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) const diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e70717728..cda8374c5 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1219,13 +1219,11 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ Node *n = h->parent(); Node * nextNode = NULL; nextNode = n->nodeToward(h); - Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } return pos; } @@ -1252,7 +1250,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); n->bsplineWeight = pos; ret = SBasisInsideNodes.valueAt(pos); - ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); + ret = Geom::Point(ret[X] + 0.005,ret[Y] + 0.005); }else{ if(pos == 0.0000){ n->bsplineWeight = 0.0000; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9b5acb6cc..a48f8911a 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -959,7 +959,7 @@ static void pen_redraw_all (PenTool *const pc) } } - //spanish: simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. + //spanish: simplemente redibujamos la spiro. //como es un redibujo simplemente no llamamos a la función global sino al final de esta //Lanzamos solamente el redibujado bspline_spiro_build(pc); @@ -1451,7 +1451,7 @@ static void bspline_spiro_on(PenTool *const pc) pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0001,pc->p[2][Y] + 0.0001); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.005,pc->p[2][Y] + 0.005); } } @@ -1492,7 +1492,7 @@ static void bspline_spiro_start_anchor_on(PenTool *const pc) Geom::Point A = tmpCurve->last_segment()->initialPoint(); Geom::Point D = tmpCurve->last_segment()->finalPoint(); Geom::Point C = D + (1./3)*(A - D); - C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); if(cubic){ lastSeg->moveto(A); lastSeg->curveto((*cubic)[1],C,D); @@ -1549,19 +1549,23 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ using Geom::X; using Geom::Y; + if(pc->red_curve->is_empty()) return; + pc->npoints = 5; SPCurve *tmpCurve = new SPCurve(); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.005,pc->p[2][Y] + 0.005); if(pc->green_curve->is_empty() && !pc->sa){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.005,pc->p[1][Y] + 0.005); }else if(!pc->green_curve->is_empty()){ tmpCurve = pc->green_curve->copy(); }else{ tmpCurve = pc->sa->curve->copy(); if(pc->sa->start) tmpCurve = tmpCurve->create_reverse(); - } - if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){ + + if(!tmpCurve->is_empty()){ Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ if(pc->bspline){ @@ -1577,16 +1581,17 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ WPower->reset(); pc->p[1] = SBasisWPower.valueAt(WP); if(!Geom::are_near(pc->p[1],pc->p[0])) - pc->p[1] = Geom::Point(pc->p[1][X] + 0.0001,pc->p[1][Y] + 0.0001); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.005,pc->p[1][Y] + 0.005); if(shift) - pc->p[2]=pc->p[3]; - else - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = pc->p[3]; }else{ pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.005,pc->p[1][Y] + 0.005); } }else{ pc->p[1] = pc->p[0]; + if(shift) + pc->p[2] = pc->p[3]; } } @@ -1606,7 +1611,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) using Geom::X; using Geom::Y; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0001,pc->p[2][Y] + 0.0001); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.005,pc->p[2][Y] + 0.005); SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); @@ -1616,7 +1621,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); }else{ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] ); } @@ -1645,7 +1650,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); }else{ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] ); } -- cgit v1.2.3 From 0b15b05d641661e6b1d5cb73520c7cdead1cfc89 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Jan 2014 17:46:40 +0100 Subject: Fix a bug whith oposite handles on node move,and a little cleanup (bzr r11950.1.232) --- src/ui/tool/node.cpp | 18 ++++++++++-------- src/ui/tool/path-manipulator.cpp | 7 +------ 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 39b21ae6d..63556e499 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -170,7 +170,6 @@ void Handle::move(Geom::Point const &new_pos) //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } return; @@ -188,7 +187,6 @@ void Handle::move(Geom::Point const &new_pos) //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -215,7 +213,6 @@ void Handle::move(Geom::Point const &new_pos) //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -310,7 +307,6 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven void Handle::handle_2button_press(){ if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); - _parent->bsplineWeight = 0.3334; this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); _pm().update(); } @@ -764,8 +760,14 @@ void Node::showHandles(bool v) //Cada vez que actuemos sobre dichos tiradores en un trazado //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; - if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())) - this->bsplineWeight = 0.3334; + if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())){ + if (!_front.isDegenerate()) { + _pm().BSplineHandlePosition(&_front); + } + if (!_back.isDegenerate()) { + _pm().BSplineHandlePosition(&_back); + } + } } void Node::updateHandles() @@ -1125,9 +1127,9 @@ void Node::_setState(State state) //spanish: esto muestra los tiradores al seleccionar los nodos if(_pm().isBSpline){ if(!this->back()->isDegenerate()){ - this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); + _pm().BSplineHandlePosition(this->back()); }else if (!this->front()->isDegenerate()){ - this->bsplineWeight = _pm().BSplineHandlePosition(this->front()); + _pm().BSplineHandlePosition(this->front()); }else{ this->bsplineWeight = 0.0000; } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index cda8374c5..8a0568fbd 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1225,6 +1225,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } + n->bsplineWeight = pos; return pos; } @@ -1265,17 +1266,11 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); if(prevNode){ - n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); - if(prevNode->front()->position() == prevNode->position()) - prevNode->bsplineWeight = 0.000; if(!prevNode->isEndNode()) prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); } if(nextNode){ - n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); - if(nextNode->front()->position() == nextNode->position()) - nextNode->bsplineWeight = 0.000; if(!nextNode->isEndNode()) nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); -- cgit v1.2.3 From 7af8d4e83411f23c762da6bfbd2130e76923df7f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 19:34:23 +0100 Subject: show outline like normal paths, by good su_v suggestion (bzr r11950.1.239) --- src/ui/tool/path-manipulator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7bbe39f8d..654e1fa5d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -911,8 +911,8 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - if(isBSpline) show = true; - if (show == _show_outline) return; + //if(isBSpline) show = true; + //if (show == _show_outline) return; _show_outline = show; _updateOutline(); } -- cgit v1.2.3 From 2563a8cae7411cfee682cbd306f43d5721908c42 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 19:45:02 +0100 Subject: show outline by default in bspline, tnx to su_v suggestion (bzr r11950.1.241) --- src/ui/tool/path-manipulator.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 654e1fa5d..da364926a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -148,6 +148,9 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); + if(isBSpline){ + _show_outline(true); + } } PathManipulator::~PathManipulator() -- cgit v1.2.3 From e582ac68a9ebeca19cc10c47fb6b57a514937278 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 19:52:10 +0100 Subject: fix bug compiling (bzr r11950.1.242) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index da364926a..83af89732 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -149,7 +149,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); if(isBSpline){ - _show_outline(true); + _show_outline = true; } } -- cgit v1.2.3 From 2cb207295847d68e22aab2e8adb967819ff8feaa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 22:16:10 +0100 Subject: Hack to can show/hide bspline lines (bzr r11950.1.243) --- src/ui/tool/path-manipulator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 83af89732..9cda94097 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -150,6 +150,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, BSpline(); if(isBSpline){ _show_outline = true; + _updateOutline(); + _show_outline = false; } } @@ -914,8 +916,7 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - //if(isBSpline) show = true; - //if (show == _show_outline) return; + if (show == _show_outline) return; _show_outline = show; _updateOutline(); } -- cgit v1.2.3 From 210d60046203fad93e65f049c5c6a7516d967f07 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 23:40:40 +0100 Subject: add comment to bspline red outline hack (bzr r11950.1.244) --- src/ui/tool/path-manipulator.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9cda94097..4092cd22b 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -148,6 +148,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); + //Small Hack to default show red path in bspline on select, independent of the state of toogle button + //it become some inconsistent behaviour in the show_path toogle button if(isBSpline){ _show_outline = true; _updateOutline(); -- cgit v1.2.3 From 1e8014478b4185861ec348250a88d8476140b35f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 1 Feb 2014 12:33:03 +0100 Subject: Add correct preview for coninuing paths whith pencil and draw modes (bzr r11950.1.245) --- src/ui/tools/pen-tool.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index a48f8911a..8c13a0584 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -43,6 +43,10 @@ #include "tools-switch.h" #include "ui/control-manager.h" //spanish: incluimos los archivos necesarios para las BSpline y Spiro +#include "live_effects/effect.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" +#include "live_effects/parameter/path.h" #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -68,6 +72,8 @@ #include "tool-factory.h" +#include "live_effects/effect.h" + using Inkscape::ControlManager; @@ -1467,6 +1473,32 @@ static void bspline_spiro_off(PenTool *const pc) static void bspline_spiro_start_anchor(PenTool *const pc, bool shift) { + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + + if (SP_IS_LPE_ITEM(pc->white_item) && SP_LPE_ITEM(pc->white_item)->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(pc->white_item)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } + if(lpe_bsp){ + pc->bspline = true; + }else{ + pc->bspline = false; + } + LivePathEffect::LPESpiro *lpe_spi = NULL; + + if (SP_IS_LPE_ITEM(pc->white_item) && SP_LPE_ITEM(pc->white_item)->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(pc->white_item)->getPathEffectOfType(Inkscape::LivePathEffect::SPIRO); + if(thisEffect){ + lpe_spi = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } + if(lpe_spi){ + pc->spiro = true; + }else{ + pc->spiro = false; + } if(!pc->spiro && !pc->bspline) return; -- cgit v1.2.3 From b9f1c85c61ce91fedca5486ef371bf6301e76128 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Feb 2014 17:31:55 +0100 Subject: fixing su_v advertising memory bug (bzr r11950.1.247) --- src/ui/tools/freehand-base.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5825a149c..6561a0c2f 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -531,22 +531,33 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Step C - test start if (dc->sa) { - SPCurve *s = dc->sa->curve; - dc->white_curves = g_slist_remove(dc->white_curves, s); - if (dc->sa->start) { - s = reverse_then_unref(s); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ + dc->sa->curve->unref() + }else{ + SPCurve *s = dc->sa->curve; + dc->white_curves = g_slist_remove(dc->white_curves, s); + if (dc->sa->start) { + s = reverse_then_unref(s); + } + s->append_continuous(c, 0.0625); + c->unref(); + c = s; } - s->append_continuous(c, 0.0625); - c->unref(); - c = s; } else /* Step D - test end */ if (dc->ea) { - SPCurve *e = dc->ea->curve; - dc->white_curves = g_slist_remove(dc->white_curves, e); - if (!dc->ea->start) { - e = reverse_then_unref(e); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ + dc->ea->curve->unref() + SPCurve *e = dc->ea->curve; + dc->white_curves = g_slist_remove(dc->white_curves, e); + if (!dc->ea->start) { + e = reverse_then_unref(e); + } + c->append_continuous(e, 0.0625); + e->unref(); } - c->append_continuous(e, 0.0625); - e->unref(); } -- cgit v1.2.3 From 46c24197ff9e17b30d97cab8893d5017b9b99dc3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Feb 2014 20:10:00 +0100 Subject: update to trunk (bzr r11950.1.249) --- src/ui/tools/freehand-base.cpp | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 6561a0c2f..5825a149c 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -531,33 +531,22 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Step C - test start if (dc->sa) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ - dc->sa->curve->unref() - }else{ - SPCurve *s = dc->sa->curve; - dc->white_curves = g_slist_remove(dc->white_curves, s); - if (dc->sa->start) { - s = reverse_then_unref(s); - } - s->append_continuous(c, 0.0625); - c->unref(); - c = s; + SPCurve *s = dc->sa->curve; + dc->white_curves = g_slist_remove(dc->white_curves, s); + if (dc->sa->start) { + s = reverse_then_unref(s); } + s->append_continuous(c, 0.0625); + c->unref(); + c = s; } else /* Step D - test end */ if (dc->ea) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ - dc->ea->curve->unref() - SPCurve *e = dc->ea->curve; - dc->white_curves = g_slist_remove(dc->white_curves, e); - if (!dc->ea->start) { - e = reverse_then_unref(e); - } - c->append_continuous(e, 0.0625); - e->unref(); + SPCurve *e = dc->ea->curve; + dc->white_curves = g_slist_remove(dc->white_curves, e); + if (!dc->ea->start) { + e = reverse_then_unref(e); } + c->append_continuous(e, 0.0625); + e->unref(); } -- cgit v1.2.3 From 215e1988378008820be9bfb7d948d8b6e33eb0a1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Feb 2014 22:16:43 +0100 Subject: Removing hack for force show red lines in bspline mode (bzr r11950.1.251) --- src/ui/tool/path-manipulator.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4092cd22b..bad07daee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -148,13 +148,6 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); - //Small Hack to default show red path in bspline on select, independent of the state of toogle button - //it become some inconsistent behaviour in the show_path toogle button - if(isBSpline){ - _show_outline = true; - _updateOutline(); - _show_outline = false; - } } PathManipulator::~PathManipulator() -- cgit v1.2.3 From be22cb94d23816986838e9636ce44ee8537a8570 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 26 Feb 2014 22:29:31 +0100 Subject: Fixed some/all bugs related to continuing bspline/spiro curves advertaising by suv (bzr r11950.1.257) --- src/ui/tools/freehand-base.cpp | 37 +++++++++++++++++++++---------- src/ui/tools/pen-tool.cpp | 50 +++++++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 35 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5e406a0d4..d8a8e901a 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -469,7 +469,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // Concat RBG SPCurve *c = dc->green_curve; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // Green dc->green_curve = new SPCurve(); while (dc->green_bpaths) { @@ -490,12 +490,16 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); if (c->is_empty()) { + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + SPDesktop *desktop = dc->desktop; + spdc_selection_modified(sp_desktop_selection(desktop), 0, dc); + } c->unref(); return; } // Step A - test, whether we ended on green anchor - if ( forceclosed || ( dc->green_anchor && dc->green_anchor->active ) ) { + if ( forceclosed || (dc->green_anchor && dc->green_anchor->active) ) { // We hit green anchor, closing Green-Blue-Red dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed.")); c->closepath_current(); @@ -513,21 +517,33 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - c = reverse_then_unref(c); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { + dc->sa->curve = reverse_then_unref(dc->sa->curve); + } + dc->sa->curve->append_continuous(c, 0.0625); + c->unref(); + if(Geom::are_near(dc->sa->curve->first_path()->initialPoint(), dc->ea->dp)){ + dc->sa->curve->closepath_current(); + } + }else{ + if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { + c = reverse_then_unref(c); + } + dc->sa->curve->append_continuous(c, 0.0625); + c->unref(); + dc->sa->curve->closepath_current(); } - dc->sa->curve->append_continuous(c, 0.0625); - c->unref(); - dc->sa->curve->closepath_current(); //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white //pasándole la curva de inicio necesaria - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); spdc_flush_white(dc, dc->sa->curve); - }else + }else{ spdc_flush_white(dc, NULL); + } return; } @@ -550,10 +566,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->append_continuous(e, 0.0625); e->unref(); } - - spdc_flush_white(dc, c); - c->unref(); } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 8c13a0584..a344dc7a6 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -414,11 +414,18 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev ToolBase *event_context = SP_EVENT_CONTEXT(pc); //Test whether we hit any anchor. SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + //with this we avoid creating a new point over the existing one - if(!bevent.button == 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + if(bevent.button != 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + pc->state = PenTool::STOP; + if( anchor && anchor == pc->sa && pc->green_curve->is_empty()){ + //spanish Borrar siguiente linea para evitar un nodo encima de otro + spdc_pen_finish_segment(pc, event_dt, bevent.state); + spdc_pen_finish(pc, FALSE); + return TRUE; + } return FALSE; } - gint ret = FALSE; if (bevent.button == 1 && !event_context->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) @@ -486,7 +493,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev if(anchor){ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } - if (anchor && !sp_pen_context_has_waiting_LPE(pc)) { + if (anchor && (!sp_pen_context_has_waiting_LPE(pc) || pc->bspline || pc->spiro)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need // a fresh path to be created so don't continue an existing one p = anchor->dp; @@ -755,7 +762,6 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r } gint ret = FALSE; - ToolBase *event_context = SP_EVENT_CONTEXT(pc); if ( revent.button == 1 && !event_context->space_panning) { @@ -769,11 +775,10 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); //with this we avoid creating a new point over the existing one - if(pc->spiro || pc->bspline){ - //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. - if(pc->npoints > 0 && pc->p[0] == pc->p[3]){ - return FALSE; - } + //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. + + if((!anchor || anchor == pc->sa) && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + return TRUE; } switch (pc->mode) { @@ -1442,9 +1447,7 @@ static void bspline_spiro(PenTool *const pc, bool shift) if(!pc->spiro && !pc->bspline) return; - if(!pc->anchor_statusbar) - shift?bspline_spiro_off(pc):bspline_spiro_on(pc); - + shift?bspline_spiro_off(pc):bspline_spiro_on(pc); bspline_spiro_build(pc); } @@ -1628,10 +1631,11 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ } if(pc->anchor_statusbar && !pc->red_curve->is_empty()){ - if(shift) + if(shift){ bspline_spiro_end_anchor_off(pc); - else + }else{ bspline_spiro_end_anchor_on(pc); + } } bspline_spiro_build(pc); @@ -1675,10 +1679,9 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) tmpCurve = tmpCurve->create_reverse(); pc->green_curve->reset(); pc->green_curve = tmpCurve; - }else{ + }else { tmpCurve = pc->sa->curve->copy(); - if(!pc->sa->start) - tmpCurve = tmpCurve->create_reverse(); + if(!pc->sa->start) tmpCurve = tmpCurve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); @@ -1712,10 +1715,11 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) static void bspline_spiro_end_anchor_off(PenTool *const pc) { - pc->p[2] = pc->p[3]; SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); + pc->p[2] = pc->p[3]; if(!pc->sa || pc->sa->curve->is_empty()){ + tmpCurve = pc->green_curve->create_reverse(); if(pc->green_curve->get_segment_count()==0)return; Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); @@ -1734,10 +1738,9 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) pc->green_curve->reset(); pc->green_curve = tmpCurve; } - }else{ + }else { tmpCurve = pc->sa->curve->copy(); - if(!pc->sa->start) - tmpCurve = tmpCurve->create_reverse(); + if(!pc->sa->start) tmpCurve = tmpCurve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ lastSeg->moveto((*cubic)[0]); @@ -1789,7 +1792,7 @@ static void bspline_spiro_build(PenTool *const pc) } if(!curve->is_empty()){ - //spanish: cerramos la curva si estan cerca los puntos finales de la curva spiro + //spanish: cerramos la curva si estan cerca los puntos finales de la curva if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -2194,7 +2197,8 @@ static void spdc_pen_finish(PenTool *const pc, gboolean const closed) SPDesktop *const desktop = pc->desktop; pc->message_context->clear(); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - + if(pc->spiro || pc->bspline) pc->blue_curve->reset(); + //spanish para cancelar linea sin un segmento creado pc->red_curve->reset(); spdc_concat_colors_and_flush(pc, closed); pc->sa = NULL; -- cgit v1.2.3 From 1f76e96f90e3badb3b9693d477e6e75fbaaa1bd1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 28 Feb 2014 20:12:44 +0100 Subject: adding some comments (bzr r11950.1.260) --- src/ui/tool/node.cpp | 3 +-- src/ui/tools/freehand-base.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 63556e499..69f4a8e82 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -322,7 +322,6 @@ bool Handle::grabbed(GdkEventMotion *) void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) { - Geom::Point parent_pos = _parent->position(); Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; @@ -479,7 +478,7 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //spanish: un truco para, si el nodo tiene fuerza, nos marca que es //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index c65d8133b..861ea0503 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -483,6 +483,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); + //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente + //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada + //porque la modificamos al continuar por un anchor if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -493,7 +496,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) } // Step A - test, whether we ended on green anchor - if ( forceclosed || (dc->green_anchor && dc->green_anchor->active) ) { + if ( forceclosed || ( dc->green_anchor && dc->green_anchor->active ) ) { // We hit green anchor, closing Green-Blue-Red dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed.")); c->closepath_current(); @@ -511,6 +514,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); + //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor + //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { -- cgit v1.2.3 From 616ae6e54d98f03dc1ff3ce7d3c528521fd7e233 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 1 Mar 2014 16:28:13 +0100 Subject: Substitute isBSpline property by a cached function isBSpline(bool) (bzr r11950.1.261) --- src/ui/tool/curve-drag-point.cpp | 4 ++-- src/ui/tool/node.cpp | 30 +++++++++++++++--------------- src/ui/tool/path-manipulator.cpp | 19 +++++++++++-------- src/ui/tool/path-manipulator.h | 3 +-- 4 files changed, 29 insertions(+), 27 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index 0ee848f15..e5412fdc2 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -54,7 +54,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; //spanish: solo actualizamos los nodos si no es bspline - if(!_pm.isBSpline){ + if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); } @@ -90,7 +90,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT - if(!_pm.isBSpline){ + if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); }else if(weight>=0.8 && !second->isEndNode() && held_shift(*event))second->back()->move(new_pos); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 69f4a8e82..78d8fe833 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -168,7 +168,7 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //spanish: mueve el tirador y su opuesto la misma proporción - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -185,7 +185,7 @@ void Handle::move(Geom::Point const &new_pos) setRelativePos(new_delta); //spanish: mueve el tirador y su opuesto la misma proporción - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -211,7 +211,7 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //spanish: mueve el tirador y su opuesto la misma proporción - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -305,7 +305,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven //spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 void Handle::handle_2button_press(){ - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); _pm().update(); @@ -361,7 +361,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) new_pos = result; //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el //parametro "steps whith control" del efecto en vivo BSpline - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; @@ -371,7 +371,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) std::vector unselected; //spanish: si está activado el ajuste (snap) y no es bspline - if (snap && !_pm().isBSpline) { + if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -413,7 +413,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } //spanish: si es bspline pero no está presionado SHIFT o CONTROL //lo fija en la posición original - if(_pm().isBSpline && !held_shift(*event) && !held_control(*event)){ + if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } move(new_pos); // needed for correct update, even though it's redundant @@ -433,7 +433,7 @@ void Handle::ungrabbed(GdkEventButton *event) if (dist.length() <= drag_tolerance) { move(_parent->position()); //spanish: marca la fuerza del bspline como 0.0000 - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } } @@ -626,7 +626,7 @@ void Node::move(Geom::Point const &new_pos) //de nuevo una vez sea movido el nodo double oldPos = 0.0000; Node *n = this; - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ oldPos = n->bsplineWeight; } @@ -640,7 +640,7 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión //y despues los de los nodos colindantes - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); _pm().BSplineNodeHandlesReposition(this); @@ -652,7 +652,7 @@ void Node::transform(Geom::Affine const &m) //spanish: guardamos la fuerza anterior del nodo para reaplicarsela //de nuevo una vez sea movido el nodo double oldPos = 0.0000; - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; } Geom::Point old_pos = position(); @@ -665,7 +665,7 @@ void Node::transform(Geom::Affine const &m) _fixNeighbors(old_pos, position()); //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión //y despues los de los nodos colindantes - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); _pm().BSplineNodeHandlesReposition(this); @@ -759,7 +759,7 @@ void Node::showHandles(bool v) //Cada vez que actuemos sobre dichos tiradores en un trazado //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; - if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())){ + if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { _pm().BSplineHandlePosition(&_front); } @@ -871,7 +871,7 @@ void Node::setType(NodeType type, bool update_handles) //spanish: en los cambios de tipo de nodo, sobre trazados bspline, //o bien los mantenemos con potencia 0.0000 en modo esquina //o les damos la potencia por defecto en modo de curva - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); @@ -1124,7 +1124,7 @@ void Node::_setState(State state) mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); //spanish: esto muestra los tiradores al seleccionar los nodos - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); }else if (!this->front()->isDegenerate()){ diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index bad07daee..a6689d93d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -103,11 +103,9 @@ private: }; void build_segment(Geom::PathBuilder &, Node *, Node *); -//spanish: una propiedad isBSpline, por defecto falsa y una función al final de la función (BSpline()) que la define realmente PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) - , isBSpline(false) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) @@ -147,7 +145,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - BSpline(); + isBSpline(true); } PathManipulator::~PathManipulator() @@ -666,7 +664,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite start = next; } //spanish: si se borra, reajustamos los tiradores - if(isBSpline){ + if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ pos = BSplineHandlePosition(start.prev()->back()); @@ -1203,11 +1201,16 @@ int PathManipulator::BSplineGetSteps(){ } //spanish: determina si el trazado tiene efecto bspline -void PathManipulator::BSpline(){ - isBSpline = false; - if(this->BSplineGetSteps()>0){ +bool PathManipulator::isBSpline(bool recalculate){ + static int BSplineSteps = this->BSplineGetSteps(); + if(recalculate){ + BSplineSteps = this->BSplineGetSteps(); + } + bool isBSpline = false; + if(BSplineSteps>0){ isBSpline = true; } + return isBSpline; } //spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador @@ -1283,7 +1286,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; - BSpline(); + isBSpline(true); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 5f075834e..5186bfc95 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -96,7 +96,6 @@ public: NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - bool isBSpline; int BSplineGetSteps(); // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -107,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - void BSpline(); + bool isBSpline(bool recalculate); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From 9f066846c116c7a963bfaa805282b9b8d4c014e4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 2 Mar 2014 03:07:44 +0100 Subject: =?UTF-8?q?Fixed=20update=20to=20trunk,=20lot=20of=20changes=20vin?= =?UTF-8?q?=C3=ADcius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.265) --- src/ui/tools/pen-tool.cpp | 122 +++++++++++++++------------------------------- src/ui/tools/pen-tool.h | 29 ++++++++++- 2 files changed, 66 insertions(+), 85 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index c6d87e2d8..65823b642 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -81,52 +81,6 @@ namespace Inkscape { namespace UI { namespace Tools { -static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p); -//spanish: añade los modos spiro y bspline -static void sp_pen_context_set_mode(PenTool *const pc, guint mode); -//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro -static void bspline_spiro_color(PenTool *const pc); -//spanish: crea un nodo en modo bspline o spiro -static void bspline_spiro(PenTool *const pc,bool shift); -//spanish: crea un nodo de modo spiro o bspline -static void bspline_spiro_on(PenTool *const pc); -//spanish: crea un nodo de tipo CUSP -static void bspline_spiro_off(PenTool *const pc); -//spanish: continua una curva existente en modo bspline o spiro -static void bspline_spiro_start_anchor(PenTool *const pc,bool shift); -//spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro -static void bspline_spiro_start_anchor_on(PenTool *const pc); -//spanish: continua una curva existente con el nodo de union en modo CUSP -static void bspline_spiro_start_anchor_off(PenTool *const pc); -//spanish: modifica la "red_curve" cuando se detecta movimiento -static void bspline_spiro_motion(PenTool *const pc,bool shift); -//spanish: cierra la curva con el último nodo en modo bspline o spiro -static void bspline_spiro_end_anchor_on(PenTool *const pc); -//spanish: cierra la curva con el último nodo en modo CUSP -static void bspline_spiro_end_anchor_off(PenTool *const pc); -//spanish: unimos todas las curvas en juego y llamamos a la función doEffect. -static void bspline_spiro_build(PenTool *const pc); -//function bspline cloned from lpe-bspline.cpp -static void bspline_doEffect(SPCurve * curve); -//function spiro cloned from lpe-spiro.cpp -static void spiro_doEffect(SPCurve * curve); - -static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status = 0); -static void spdc_pen_set_ctrl(PenTool *pc, Geom::Point const p, guint state); -static void spdc_pen_finish_segment(PenTool *pc, Geom::Point p, guint state); - -static void spdc_pen_finish(PenTool *pc, gboolean closed); - -static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bevent); -static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &mevent); -static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &revent); -static gint pen_handle_2button_press(PenTool *const pc, GdkEventButton const &bevent); -static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event); -static void spdc_reset_colors(PenTool *pc); - -static void pen_disable_events(PenTool *const pc); -static void pen_enable_events(PenTool *const pc); - static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical @@ -217,13 +171,13 @@ void PenTool::setPolylineMode() { this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline //todo: merge to one function only - sp_pen_context_set_mode(this, mode); + this->_pen_context_set_mode(mode); } /* *.Set the mode of draw spiro, and bsplines */ -void sp_pen_context_set_mode(PenTool *const pc, guint mode) { +void PenTool::_pen_context_set_mode(guint mode) { //spanish: definimos los modos this->spiro = (mode == 1); this->bspline = (mode == 2); @@ -425,7 +379,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { Geom::Point const event_w(bevent.x, bevent.y); Geom::Point event_dt(desktop->w2d(event_w)); //Test whether we hit any anchor. - SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + SPDrawAnchor * const anchor = spdc_test_inside(this, event_w); ToolBase *event_context = SP_EVENT_CONTEXT(this); //with this we avoid creating a new point over the existing one @@ -433,8 +387,8 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ //spanish Borrar siguiente linea para evitar un nodo encima de otro - spdc_pen_finish_segment(pc, event_dt, bevent.state); - spdc_pen_finish(pc, FALSE); + _finishSegment(event_dt, bevent.state); + _finish( FALSE); return TRUE; } return FALSE; @@ -505,7 +459,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { this->sa = anchor; if(anchor){ - bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_start_anchor(bevent.state & GDK_SHIFT_MASK); } if (anchor && (!this->hasWaitingLPE()|| this->bspline || this->spiro)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need @@ -753,12 +707,12 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { } //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(this->bspline){ - bspline_spiro_color(pc); - bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_color(); + this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); }else{ if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { - bspline_spiro_color(pc); - bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_color(); + this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); pen_drag_origin_w = event_w; } } @@ -809,7 +763,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { //spanish: continuamos una curva existente if (anchor) { if(this->bspline || this->spiro){ - bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; } } this->_setInitialPoint(p); @@ -986,7 +940,7 @@ void PenTool::_redrawAll() { //spanish: simplemente redibujamos la spiro. //como es un redibujo simplemente no llamamos a la función global sino al final de esta //Lanzamos solamente el redibujado - bspline_spiro_build(pc); + this->_bspline_spiro_build(); } void PenTool::_lastpointMove(gdouble x, gdouble y) { @@ -1060,7 +1014,7 @@ void PenTool::_lastpointToCurve() { } //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ - bspline_spiro_start_anchor(pc, false); + this->_bspline_spiro_start_anchor(false); } } @@ -1107,7 +1061,7 @@ void PenTool::_lastpointToLine() { } //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ - bspline_spiro_start_anchor(pc, true); + this->_bspline_spiro_start_anchor(true); } } @@ -1332,7 +1286,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; //spanish: redibujamos - bspline_spiro_build(pc); + this->_bspline_spiro_build(); ret = TRUE; } break; @@ -1406,7 +1360,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro -static void bspline_spiro_color(PenTool *const pc) +void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; if(this->spiro){ @@ -1451,16 +1405,16 @@ static void bspline_spiro_color(PenTool *const pc) } -static void bspline_spiro(PenTool *const pc, bool shift) +void PenTool::_bspline_spiro(bool shift) { if(!this->spiro && !this->bspline) return; - shift?bspline_spiro_off(pc):bspline_spiro_on(pc); - bspline_spiro_build(pc); + shift?this->_bspline_spiro_off():this->_bspline_spiro_on(); + this->_bspline_spiro_build(); } -static void bspline_spiro_on(PenTool *const pc) +void PenTool::_bspline_spiro_on() { if(!this->red_curve->is_empty()){ using Geom::X; @@ -1473,7 +1427,7 @@ static void bspline_spiro_on(PenTool *const pc) } } -static void bspline_spiro_off(PenTool *const pc) +void PenTool::_bspline_spiro_off() { if(!this->red_curve->is_empty()){ this->npoints = 5; @@ -1483,7 +1437,7 @@ static void bspline_spiro_off(PenTool *const pc) } } -static void bspline_spiro_start_anchor(PenTool *const pc, bool shift) +void PenTool::_bspline_spiro_start_anchor(bool shift) { LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1518,12 +1472,12 @@ static void bspline_spiro_start_anchor(PenTool *const pc, bool shift) return; if(shift) - bspline_spiro_start_anchor_off(pc); + this->_bspline_spiro_start_anchor_off(); else - bspline_spiro_start_anchor_on(pc); + this->_bspline_spiro_start_anchor_on(); } -static void bspline_spiro_start_anchor_on(PenTool *const pc) +void PenTool::_bspline_spiro_start_anchor_on() { using Geom::X; using Geom::Y; @@ -1559,7 +1513,7 @@ static void bspline_spiro_start_anchor_on(PenTool *const pc) this->sa->curve = tmpCurve; } -static void bspline_spiro_start_anchor_off(PenTool *const pc) +void PenTool::_bspline_spiro_start_anchor_off() { SPCurve *tmpCurve = new SPCurve(); tmpCurve = this->sa->curve->copy(); @@ -1587,7 +1541,7 @@ static void bspline_spiro_start_anchor_off(PenTool *const pc) } -static void bspline_spiro_motion(PenTool *const pc, bool shift){ +void PenTool::_bspline_spiro_motion(bool shift){ if(!this->spiro && !this->bspline) return; @@ -1641,16 +1595,16 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ if(this->anchor_statusbar && !this->red_curve->is_empty()){ if(shift){ - bspline_spiro_end_anchor_off(pc); + this->_bspline_spiro_end_anchor_off(); }else{ - bspline_spiro_end_anchor_on(pc); + this->_bspline_spiro_end_anchor_on(); } } - bspline_spiro_build(pc); + this->_bspline_spiro_build(); } -static void bspline_spiro_end_anchor_on(PenTool *const pc) +void PenTool::_bspline_spiro_end_anchor_on() { using Geom::X; @@ -1721,7 +1675,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) } } -static void bspline_spiro_end_anchor_off(PenTool *const pc) +void PenTool::_bspline_spiro_end_anchor_off() { SPCurve *tmpCurve = new SPCurve(); @@ -1773,7 +1727,7 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) //spanish: preparates the curves for its trasformation into BSline curves. -static void bspline_spiro_build(PenTool *const pc) +void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) return; @@ -1812,9 +1766,9 @@ static void bspline_spiro_build(PenTool *const pc) //Effect *spr = static_cast ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); if(this->bspline){ - bspline_doEffect(curve); + this->_bspline_doEffect(curve); }else{ - spiro_doEffect(curve); + this->_spiro_doEffect(curve); } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); @@ -1838,7 +1792,7 @@ static void bspline_spiro_build(PenTool *const pc) } } -static void bspline_doEffect(SPCurve * curve) +void PenTool::_bspline_doEffect(SPCurve * curve) { //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) @@ -1981,7 +1935,7 @@ static void bspline_doEffect(SPCurve * curve) //Spiro function cloned from lpe-spiro.cpp //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp -static void spiro_doEffect(SPCurve * curve) +void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; @@ -2178,7 +2132,7 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { if (!this->red_curve->is_empty()) { - bspline_spiro(pc,(state & GDK_SHIFT_MASK)); + this->_bspline_spiro(state & GDK_SHIFT_MASK); this->green_curve->append_continuous(this->red_curve, 0.0625); SPCurve *curve = this->red_curve->copy(); diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 07fc037be..88e528b22 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -88,7 +88,34 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - + //spanish: añade los modos spiro y bspline + void _pen_context_set_mode(guint mode); + //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro + void _bspline_spiro_color(); + //spanish: crea un nodo en modo bspline o spiro + void _bspline_spiro(bool shift); + //spanish: crea un nodo de modo spiro o bspline + void _bspline_spiro_on(); + //spanish: crea un nodo de tipo CUSP + void _bspline_spiro_off(); + //spanish: continua una curva existente en modo bspline o spiro + void _bspline_spiro_start_anchor(bool shift); + //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro + void _bspline_spiro_start_anchor_on(); + //spanish: continua una curva existente con el nodo de union en modo CUSP + void _bspline_spiro_start_anchor_off(); + //spanish: modifica la "red_curve" cuando se detecta movimiento + void _bspline_spiro_motion(bool shift); + //spanish: cierra la curva con el último nodo en modo bspline o spiro + void _bspline_spiro_end_anchor_on(); + //spanish: cierra la curva con el último nodo en modo CUSP + void _bspline_spiro_end_anchor_off(); + //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. + void _bspline_spiro_build(); + //function bspline cloned from lpe-bspline.cpp + void _bspline_doEffect(SPCurve * curve); + //function spiro cloned from lpe-spiro.cpp + void _spiro_doEffect(SPCurve * curve); void _setInitialPoint(Geom::Point const p); void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0); void _setCtrl(Geom::Point const p, guint state); -- cgit v1.2.3 From 1d854ff519b9c0867bfa4ecaf2f6329ca256f06a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 10:29:06 -0500 Subject: Experimental merge of Ponyscape features into trunk (will not compile) (bzr r13090.1.1) --- src/ui/dialog/Makefile_insert | 4 + src/ui/dialog/lpe-powerstroke-properties.cpp | 203 +++ src/ui/dialog/lpe-powerstroke-properties.h | 99 ++ src/ui/dialog/objects.cpp | 2048 ++++++++++++++++++++++++++ src/ui/dialog/objects.h | 255 ++++ src/ui/dialog/tags.cpp | 1182 +++++++++++++++ src/ui/dialog/tags.h | 181 +++ src/ui/widget/clipmaskicon.cpp | 177 +++ src/ui/widget/clipmaskicon.h | 102 ++ src/ui/widget/highlight-picker.cpp | 176 +++ src/ui/widget/highlight-picker.h | 90 ++ src/ui/widget/insertordericon.cpp | 166 +++ src/ui/widget/insertordericon.h | 100 ++ src/ui/widget/layertypeicon.cpp | 167 +++ src/ui/widget/layertypeicon.h | 108 ++ 15 files changed, 5058 insertions(+) create mode 100644 src/ui/dialog/lpe-powerstroke-properties.cpp create mode 100644 src/ui/dialog/lpe-powerstroke-properties.h create mode 100644 src/ui/dialog/objects.cpp create mode 100644 src/ui/dialog/objects.h create mode 100644 src/ui/dialog/tags.cpp create mode 100644 src/ui/dialog/tags.h create mode 100644 src/ui/widget/clipmaskicon.cpp create mode 100644 src/ui/widget/clipmaskicon.h create mode 100644 src/ui/widget/highlight-picker.cpp create mode 100644 src/ui/widget/highlight-picker.h create mode 100644 src/ui/widget/insertordericon.cpp create mode 100644 src/ui/widget/insertordericon.h create mode 100644 src/ui/widget/layertypeicon.cpp create mode 100644 src/ui/widget/layertypeicon.h (limited to 'src/ui') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index c37767a08..1cf667f2a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -109,4 +109,8 @@ ink_common_sources += \ ui/dialog/undo-history.h \ ui/dialog/xml-tree.cpp \ ui/dialog/xml-tree.h \ + ui/dialog/lpe-powerstroke-properties.cpp \ + ui/dialog/lpe-powerstroke-properties.h \ + ui/dialog/objects.cpp \ + ui/dialog/objects.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp new file mode 100644 index 000000000..cef6f494e --- /dev/null +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -0,0 +1,203 @@ +/** + * @file + * Dialog for renaming layers. + */ +/* Author: + * Bryce W. Harrington + * Andrius R. + * Abhishek Sharma + * + * Copyright (C) 2004 Bryce Harrington + * Copyright (C) 2006 Andrius R. + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#include "lpe-powerstroke-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +PowerstrokePropertiesDialog::PowerstrokePropertiesDialog() +: _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + + _layout_table.set_spacings(4); + _layout_table.resize (2, 2); + + // Layer name widgets + _powerstroke_position_entry.set_activates_default(true); + _powerstroke_position_label.set_label(_("Position:")); + _powerstroke_position_label.set_alignment(1.0, 0.5); + + _powerstroke_width_entry.set_activates_default(true); + _powerstroke_width_label.set_label(_("Width:")); + _powerstroke_width_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_powerstroke_position_label, + 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_powerstroke_position_entry, + 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + _layout_table.attach(_powerstroke_width_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_powerstroke_width_entry, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + mainVBox->pack_start(_layout_table, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_apply)); + + signal_delete_event().connect( + sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)), + true + ) + ); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_powerstroke_width_entry); +} + +PowerstrokePropertiesDialog::~PowerstrokePropertiesDialog() { + + _setDesktop(NULL); +} + +void PowerstrokePropertiesDialog::showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt) +{ + PowerstrokePropertiesDialog *dialog = new PowerstrokePropertiesDialog(); + + dialog->_setDesktop(desktop); + dialog->_setKnotPoint(knotpoint); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Node Position")); + dialog->_apply_button.set_label(_("_Move")); + + dialog->set_modal(true); + desktop->setWindowTransient (dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void +PowerstrokePropertiesDialog::_apply() +{ + std::istringstream i_pos(_powerstroke_position_entry.get_text()); + std::istringstream i_width(_powerstroke_width_entry.get_text()); + double d_pos, d_width; + if ((i_pos >> d_pos) && i_width >> d_width) { + _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); + } + _close(); +} + +void +PowerstrokePropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + + /*switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: { + _apply(); + return true; + } + break; + }*/ + return false; +} + +void PowerstrokePropertiesDialog::_handleButtonEvent(GdkEventButton* event) +{ + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + _apply(); + } +} + +void PowerstrokePropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +{ + _powerstroke_position_entry.set_text(boost::lexical_cast(knotpoint.x())); + _powerstroke_width_entry.set_text(boost::lexical_cast(knotpoint.y())); +} + +void PowerstrokePropertiesDialog::_setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt) +{ + _knotpoint = const_cast(pt); +} + +void PowerstrokePropertiesDialog::_setDesktop(SPDesktop *desktop) { + if (desktop) { + Inkscape::GC::anchor (desktop); + } + if (_desktop) { + Inkscape::GC::release (_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + + +/* + 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 : diff --git a/src/ui/dialog/lpe-powerstroke-properties.h b/src/ui/dialog/lpe-powerstroke-properties.h new file mode 100644 index 000000000..c53eac0d9 --- /dev/null +++ b/src/ui/dialog/lpe-powerstroke-properties.h @@ -0,0 +1,99 @@ +/** @file + * @brief Dialog for renaming layers + */ +/* Author: + * Bryce W. Harrington + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H +#define INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H + +#include <2geom/point.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "live_effects/parameter/powerstrokepointarray.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class PowerstrokePropertiesDialog : public Gtk::Dialog { + public: + PowerstrokePropertiesDialog(); + virtual ~PowerstrokePropertiesDialog(); + + Glib::ustring getName() const { return "LayerPropertiesDialog"; } + + static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt); + +protected: + + SPDesktop *_desktop; + Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *_knotpoint; + + Gtk::Label _powerstroke_position_label; + Gtk::Entry _powerstroke_position_entry; + Gtk::Label _powerstroke_width_label; + Gtk::Entry _powerstroke_width_entry; + Gtk::Table _layout_table; + bool _position_visible; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static PowerstrokePropertiesDialog &_instance() { + static PowerstrokePropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt); + + void _apply(); + void _close(); + + void _setKnotPoint(Geom::Point knotpoint); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton* event); + + friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity; + +private: + PowerstrokePropertiesDialog(PowerstrokePropertiesDialog const &); // no copy + PowerstrokePropertiesDialog &operator=(PowerstrokePropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +/* + 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 : diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp new file mode 100644 index 000000000..31e73db29 --- /dev/null +++ b/src/ui/dialog/objects.cpp @@ -0,0 +1,2048 @@ +/* + * A simple panel for objects + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "objects.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/insertordericon.h" +#include "ui/widget/clipmaskicon.h" +#include "ui/widget/highlight-picker.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +//#include "event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "layer-manager.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +/** + * Gets an instance of the Objects panel + */ +ObjectsPanel& ObjectsPanel::getInstance() +{ + return *new ObjectsPanel(); +} + +/** + * Column enumeration + */ +enum { + COL_VISIBLE = 1, + COL_LOCKED, + COL_TYPE, + COL_INSERTORDER, + COL_CLIPMASK, + COL_HIGHLIGHT +}; + +/** + * Button enumeration + */ +enum { + BUTTON_NEW = 0, + BUTTON_RENAME, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DUPLICATE, + BUTTON_DELETE, + BUTTON_SOLO, + BUTTON_SHOW_ALL, + BUTTON_HIDE_ALL, + BUTTON_LOCK_OTHERS, + BUTTON_LOCK_ALL, + BUTTON_UNLOCK_ALL, + BUTTON_SETCLIP, + BUTTON_CLIPGROUP, + BUTTON_SETINVCLIP, + BUTTON_UNSETCLIP, + BUTTON_SETMASK, + BUTTON_UNSETMASK, + BUTTON_GROUP, + BUTTON_UNGROUP, + BUTTON_COLLAPSE_ALL, + DRAGNDROP +}; + +/** + * Xml node observer for observing objects in the document + */ +class ObjectsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + /** + * Creates a new object watcher + * @param pnl The panel to which the object watcher belongs + * @param obj The object to watch + */ + ObjectWatcher(ObjectsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _highlightAttr(g_quark_from_string("inkscape:highlight-color")), + _lockedAttr(g_quark_from_string("sodipodi:insensitive")), + _labelAttr(g_quark_from_string("inkscape:label")), + _groupAttr(g_quark_from_string("inkscape:groupmode")), + _styleAttr(g_quark_from_string("style")), + _clipAttr(g_quark_from_string("clip-path")), + _maskAttr(g_quark_from_string("mask")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _lockedAttr || name == _labelAttr || name == _highlightAttr || name == _groupAttr || name == _styleAttr || name == _clipAttr || name == _maskAttr ) { + _pnl->_updateObject(_obj, name == _highlightAttr); + if ( name == _styleAttr ) { + _pnl->_updateComposite(); + } + } + } + } + + /** + * Objects panel to which this watcher belongs + */ + ObjectsPanel* _pnl; + + /** + * The object that is being observed + */ + SPObject* _obj; + + /** + * The xml representation of the object that is being observed + */ + Inkscape::XML::Node* _repr; + + /* These are quarks which define the attributes that we are observing */ + GQuark _highlightAttr; + GQuark _lockedAttr; + GQuark _labelAttr; + GQuark _groupAttr; + GQuark _styleAttr; + GQuark _clipAttr; + GQuark _maskAttr; +}; + +class ObjectsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +class ObjectsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colObject); + add(_colVisible); + add(_colLocked); + add(_colLabel); + add(_colType); + add(_colHighlight); + add(_colClipMask); + add(_colInsertOrder); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colVisible; + Gtk::TreeModelColumn _colLocked; + Gtk::TreeModelColumn _colType; + Gtk::TreeModelColumn _colHighlight; + Gtk::TreeModelColumn _colClipMask; + Gtk::TreeModelColumn _colInsertOrder; +}; + +/** + * Stylizes a button using the given icon name and tooltip + */ +void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ) +{ + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + + btn.set_tooltip_text (tooltip); + +} + +/** + * Adds an item to the pop-up (right-click) menu + * @param desktop The active destktop + * @param code Action code + * @param iconName Icon name + * @param fallback Fallback text + * @param id Button id for callback function + * @return The generated menu item + */ +Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = Gtk::manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +/** + * Callback function for when an object changes. Essentially refreshes the entire tree + * @param obj Object which was changed (currently not used as the entire tree is recreated) + */ +void ObjectsPanel::_objectsChanged(SPObject */*obj*/) +{ + //First, unattach the watchers + while (!_objectWatchers.empty()) + { + ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + //Get the current document's root and use that to enumerate the tree + SPDocument* document = _desktop->doc(); + SPRoot* root = document->getRoot(); + if ( root ) { + _selectedConnection.block(); + //Clear the tree store + _store->clear(); + //Add all items recursively + _addObject( root, 0 ); + _selectedConnection.unblock(); + //Set the tree selection + _objectsSelected(_desktop->selection); + //Handle button sensitivity + _checkTreeSelection(); + } + } +} + +/** + * Recursively adds the children of the given item to the tree + * @param obj Root object to add to the tree + * @param parentRow Parent tree row (or NULL if adding to tree root) + */ +void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + + if (SP_IS_ITEM(child)) + { + SPItem * item = SP_ITEM(child); + SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0; + + //Add the item to the tree and set the column information + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = item; + row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + row[_model->_colVisible] = !item->isHidden(); + row[_model->_colLocked] = !item->isSensitive(); + row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; + row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; + row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); + row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + + //If our parent object is a group and it's expanded, expand the tree + if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) + { + _tree.expand_to_path( _store->get_path(iter) ); + } + + //Add an object watcher to the item + ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + + //If the item is a group, recursively add its children + if (group) + { + _addObject( child, &row ); + } + } + } + } +} + +/** + * Updates an item in the tree and optionally recursively updates the item's children + * @param obj The item to update in the tree + * @param recurse Whether to recurse through the item's children + */ +void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { + //Find the object in the tree store and update it + _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); + if (recurse) + { + for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) + { + _updateObject(iter, recurse); + } + } +} + +/** + * Checks items in the tree store and updates the given item + * @param iter Current item being looked at in the tree + * @param obj Object to update + * @return + */ +bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + //We found our item in the tree!! Update it! + SPItem * item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + SPGroup * group = SP_IS_GROUP(obj) ? SP_GROUP(obj) : 0; + + row[_model->_colLabel] = obj->label() ? obj->label() : obj->getId(); + row[_model->_colVisible] = item ? !item->isHidden() : false; + row[_model->_colLocked] = item ? !item->isSensitive() : false; + row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; + row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; + row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? (item->clip_ref->getObject()->inverse ? 3 : 1) : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; + row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + + return true; + } + + return false; +} + +/** + * Updates the composite controls for the selected item + */ +void ObjectsPanel::_updateComposite() { + if (!_blockCompositeUpdate) + { + //Set the default values + bool setValues = true; + + //Get/set the values + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_compositingChanged), &setValues)); + } +} + +/** + * Sets the compositing values for the first selected item in the tree + * @param iter Current tree item + * @param setValues Whether to set the compositing values + * @param blur Blur value to use + */ +void ObjectsPanel::_compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (*setValues) + { + _setCompositingValues(item); + *setValues = false; + } + } +} + +/** + * Occurs when the current desktop selection changes + * @param sel The current selection + */ +void ObjectsPanel::_objectsSelected( Selection *sel ) { + + bool setOpacity = true; + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + SPItem *item = NULL; + for (const GSList * iter = sel->itemList(); iter != NULL; iter = iter->next) + { + item = reinterpret_cast(iter->data); + if (setOpacity) + { + _setCompositingValues(item); + setOpacity = false; + } + _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, iter->next == NULL)); + } + if (!item) { + if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) { + item = SP_ITEM(_desktop->currentLayer()); + _setCompositingValues(item); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true)); + } + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +/** + * Helper function for setting the compositing values + * @param item Item to use for setting the compositing values + */ +void ObjectsPanel::_setCompositingValues(SPItem *item) +{ + //Block the connections to avoid interference + _opacityConnection.block(); + _blendConnection.block(); + _blurConnection.block(); + + //Set the opacity + _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper()); + SPFeBlend *spblend = NULL; + SPGaussianBlur *spblur = NULL; + if (item->style->getFilter()) + { + for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { + if(SP_IS_FEBLEND(primitive_obj) && !spblend) { + //Get the blend mode + spblend = SP_FEBLEND(primitive_obj); + } + + if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) { + //Get the blur value + spblur = SP_GAUSSIANBLUR(primitive_obj); + } + } + } + + //Set the blend mode + _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); + + //Set the blur value + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + if (bbox && spblur) { + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + _fe_blur.set_blur_value(spblur->stdDeviation.getNumber() * 400 / perimeter); + } else { + _fe_blur.set_blur_value(0); + } + + //Unblock connections + _blurConnection.unblock(); + _blendConnection.unblock(); + _opacityConnection.unblock(); +} + +/** + * Checks the tree and selects the specified item, optionally scrolling to the item + * @param path Current tree path + * @param iter Current tree item + * @param item Item to select in the tree + * @param scrollto Whether to scroll to the item + * @return Whether to continue searching the tree + */ +bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto) +{ + bool stopGoing = false; + + Gtk::TreeModel::Row row = *iter; + if ( item == row[_model->_colObject] ) + { + //We found the item! Expand to the path and select it in the tree. + _tree.expand_to_path( path ); + + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + if (scrollto) { + //Scroll to the item in the tree + _tree.scroll_to_row(path); + } + + stopGoing = true; + } + + return stopGoing; +} + +/** + * Pushes the current tree selection to the canvas + */ +void ObjectsPanel::_pushTreeSelectionToCurrent() +{ + if ( _desktop && _desktop->currentRoot() ) { + //block connections for selection and compositing values to prevent interference + _selectionChangedConnection.block(); + + //Clear the selection and then iterate over the tree selection, pushing each item to the desktop + _desktop->selection->clear(); + bool setOpacity = true; + _tree.get_selection()->selected_foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity)); + //unblock connections + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); + } +} + +/** + * Helper function for pushing the current tree selection to the current desktop + * @param iter Current tree item + * @param setCompositingValues Whether to set the compositing values + * @param blur + */ +void ObjectsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setCompositingValues ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) + { + //If the item is not a layer, then select it and set the current layer to its parent (if it's the first item) + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + else + { + //If the item is a layer, set the current layer + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); + } + if (*setCompositingValues) + { + //Only set the compositing values for the first item + _setCompositingValues(item); + *setCompositingValues = false; + } + } +} + +/** + * Handles button sensitivity + */ +void ObjectsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + //TODO: top/bottom sensitivity + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +/** + * Sets visibility of items in the tree + * @param iter Current item in the tree + * @param visible Whether the item should be visible or not + */ +void ObjectsPanel::_setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->setHidden( !visible ); + row[_model->_colVisible] = visible; + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Sets sensitivity of items in the tree + * @param iter Current item in the tree + * @param locked Whether the item should be locked + */ +void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->setLocked( locked ); + row[_model->_colLocked] = locked; + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Handles keyboard events + * @param event Keyboard event passed in from GDK + * @return Whether the event should be eaten (om nom nom) + */ +bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: + { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + //Rename item + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + break; + case GDK_Home: + { + //Move item(s) to top of containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT ); + } + return true; + } + case GDK_End: + { + //Move item(s) to bottom of containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK ); + } + return true; + } + case GDK_KEY_Page_Up: + { + //Move item(s) up in containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + if (event->state & GDK_SHIFT_MASK) { + _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); + } else { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + return true; + } + case GDK_KEY_Page_Down: + { + //Move item(s) down in containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + if (event->state & GDK_SHIFT_MASK) { + _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); + } else { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + return true; + } + //TODO: Handle Ctrl-A, etc. + } + return false; +} + +/** + * Handles mouse events + * @param event Mouse event from GDK + * @return whether to eat the event (om nom nom) + */ +bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + static bool overVisible = false; + + //Right mouse button was clicked, launch the pop-up menu + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + //Left mouse button was pressed! In order to handle multiple item drag & drop, + //we need to defer selection by setting the select function so that the tree doesn't + //automatically select anything. In order to handle multiple item icon clicking, + //we need to eat the event. There might be a better way to do both of these... + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + overVisible = false; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_VISIBLE-1)) { + //Click on visible column, eat this event to keep row selection + overVisible = true; + return true; + } else if (col == _tree.get_column(COL_LOCKED-1) || + col == _tree.get_column(COL_TYPE-1) || + col == _tree.get_column(COL_INSERTORDER - 1) || + col == _tree.get_column(COL_HIGHLIGHT-1)) { + //Click on an icon column, eat this event to keep row selection + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + //Click on a selected item with no modifiers, defer selection to the mouse-up by + //setting the select function to _noSelection + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_noSelection)); + _defer_target = path; + } + } + } + + //Restore the selection function to allow tree selection on mouse button release + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction)); + } + + //CellRenderers do not have good support for dealing with multiple items, so + //we handle all events on them here + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + //We had deferred a selection target, select it here (assuming no drag & drop) + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } + else { + if (event->state & GDK_SHIFT_MASK) { + // Shift left click on the visible/lock columns toggles "solo" mode + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _takeAction(BUTTON_SOLO); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _takeAction(BUTTON_LOCK_OTHERS); + } + } else if (event->state & GDK_MOD1_MASK) { + // Alt+left click on the visible/lock columns toggles "solo" mode and preserves selection + Gtk::TreeModel::iterator iter = _store->get_iter(path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _desktop->toggleLayerSolo( item ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _desktop->toggleLockOtherLayers( item ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + } + } + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPItem* item = row[_model->_colObject]; + + if (col == _tree.get_column(COL_VISIBLE - 1)) { + if (overVisible) { + //Toggle visibility + bool newValue = !row[_model->_colVisible]; + if (_tree.get_selection()->is_selected(path)) + { + //If the current row is selected, toggle the visibility + //for all selected items + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setVisibleIter), newValue)); + } + else + { + //If the current row is not selected, toggle just its visibility + row[_model->_colVisible] = newValue; + item->setHidden(!newValue); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Unhide objects") : _("Hide objects")); + overVisible = false; + } + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + //Toggle locking + bool newValue = !row[_model->_colLocked]; + if (_tree.get_selection()->is_selected(path)) + { + //If the current row is selected, toggle the sensitivity for + //all selected items + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setLockedIter), newValue)); + } + else + { + //If the current row is not selected, toggle just its sensitivity + row[_model->_colLocked] = newValue; + item->setLocked( newValue ); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Lock objects") : _("Unlock objects")); + + } else if (col == _tree.get_column(COL_TYPE - 1)) { + if (SP_IS_GROUP(item)) + { + //Toggle the current item between a group and a layer + SPGroup * g = SP_GROUP(item); + bool newValue = g->layerMode() == SPGroup::LAYER; + row[_model->_colType] = newValue ? 1: 2; + g->setLayerMode(newValue ? SPGroup::GROUP : SPGroup::LAYER); + g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Layer to group") : _("Group to layer")); + } + } else if (col == _tree.get_column(COL_INSERTORDER - 1)) { + if (SP_IS_GROUP(item)) + { + //Toggle the current item's insert order + SPGroup * g = SP_GROUP(item); + bool newValue = !g->insertBottom(); + row[_model->_colInsertOrder] = newValue ? 2: 1; + g->setInsertBottom(newValue); + g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Set insert mode bottom") : _("Set insert mode top")); + } + } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { + //Clear the highlight targets + _highlight_target.clear(); + if (_tree.get_selection()->is_selected(path)) + { + //If the current item is selected, store all selected items + //in the highlight source + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeHighlightTarget)); + } else { + //If the current item is not selected, store only it in the highlight source + _storeHighlightTarget(iter); + } + if (_colorSelector) + { + //Set up the color selector + SPColor color; + color.set( row[_model->_colHighlight] ); + _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); + } + //Show the color selector dialog + _colorSelectorDialog.show(); + } + } + } + } + } + + //Second mouse button press, set double click status for when the mouse is released + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + //Double click on mouse button release, if we're over the label column, edit + //the item name + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + + return false; +} + +/** + * Stores items in the highlight target vector to manipulate with the color selector + * @param iter Current tree item to store + */ +void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + _highlight_target.push_back(item); + } +} + +/* + * Drap and drop within the tree + */ +bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + //Set up our defaults and clear the source vector + _dnd_into = false; + _dnd_target = NULL; + _dnd_source.clear(); + + //Add all selected items to the source vector + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeDragSource)); + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/4) && cell_y <= (int)(cell_height * 3/4)); + if (cell_y > (int)(cell_height * 3/4)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = NULL; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + //Set the drop target. If we're not dropping into a group, we cannot + //drop into it, so set _dnd_into false. + _dnd_target = row[_model->_colObject]; + if (!(SP_IS_GROUP(_dnd_target))) _dnd_into = false; + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/** + * Stores all selected items as the drag source + * @param iter Current tree item + */ +void ObjectsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Move a layer in response to a drag & drop action + */ +void ObjectsPanel::_doTreeMove( ) +{ + g_assert(_desktop != NULL); + g_assert(_document != NULL); + + std::vector idvector; + + //Clear the desktop selection + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPItem *obj = _dnd_source.back(); + _dnd_source.pop_back(); + + if (obj != _dnd_target) { + //Store the object id (for selection later) and move the object + idvector.push_back(g_strdup(obj->getId())); + obj->moveTo(_dnd_target, _dnd_into); + } + } + + //Select items + while (!idvector.empty()) { + //Grab the id from the vector, get the item in the document and select it + gchar * id = idvector.back(); + idvector.pop_back(); + SPObject *obj = _document->getObjectById(id); + g_free(id); + if (obj && SP_IS_ITEM(obj)) { + SPItem *item = SP_ITEM(obj); + if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) + { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + else + { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); + } + } + } + + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Moved objects")); +} + +/** + * Fires the action verb + */ +void ObjectsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +/** + * Executes the given button action during the idle time + */ +void ObjectsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &ObjectsPanel::_executeAction), 0 ); + } +} + +/** + * Executes the pending button action + */ +bool ObjectsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _document && _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_LAYER_NEW ); + } + break; + case BUTTON_RENAME: + { + _fireAction( SP_VERB_LAYER_RENAME ); + } + break; + case BUTTON_TOP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT); + } + } + break; + case BUTTON_BOTTOM: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK); + } + } + break; + case BUTTON_UP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + break; + case BUTTON_DOWN: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + break; + case BUTTON_DUPLICATE: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_DUPLICATE ); + } + else + { + _fireAction( SP_VERB_EDIT_DUPLICATE ); + } + } + break; + case BUTTON_DELETE: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_DELETE ); + } + else + { + _fireAction( SP_VERB_EDIT_DELETE ); + } + } + break; + case BUTTON_SOLO: + { + _fireAction( SP_VERB_LAYER_SOLO ); + } + break; + case BUTTON_SHOW_ALL: + { + _fireAction( SP_VERB_LAYER_SHOW_ALL ); + } + break; + case BUTTON_HIDE_ALL: + { + _fireAction( SP_VERB_LAYER_HIDE_ALL ); + } + break; + case BUTTON_LOCK_OTHERS: + { + _fireAction( SP_VERB_LAYER_LOCK_OTHERS ); + } + break; + case BUTTON_LOCK_ALL: + { + _fireAction( SP_VERB_LAYER_LOCK_ALL ); + } + break; + case BUTTON_UNLOCK_ALL: + { + _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); + } + break; + case BUTTON_SETCLIP: + { + _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); + } + break; + case BUTTON_UNSETCLIP: + { + _fireAction( SP_VERB_OBJECT_UNSET_CLIPPATH ); + } + break; + case BUTTON_SETMASK: + { + _fireAction( SP_VERB_OBJECT_SET_MASK ); + } + break; + case BUTTON_UNSETMASK: + { + _fireAction( SP_VERB_OBJECT_UNSET_MASK ); + } + break; + case BUTTON_GROUP: + { + _fireAction( SP_VERB_SELECTION_GROUP ); + } + break; + case BUTTON_UNGROUP: + { + _fireAction( SP_VERB_SELECTION_UNGROUP ); + } + break; + case BUTTON_COLLAPSE_ALL: + { + for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) { + if (SP_IS_GROUP(obj)) { + _setCollapsed(SP_GROUP(obj)); + } + } + _objectsChanged(_document->getRoot()); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + +/** + * Handles an unsuccessful item label edit (escape pressed, etc.) + */ +void ObjectsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +/** + * Handle a successful item label edit + * @param path Tree path of the item currently being edited + * @param new_text New label text + */ +void ObjectsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +/** + * Renames an item in the tree + * @param row Tree row + * @param name New label to give to the item + */ +void ObjectsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPItem* item = row[_model->_colObject]; + if ( item ) { + gchar const* oldLabel = item->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + item->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } +} + +/** + * A row selection function used by the tree that doesn't allow any new items to be selected. + * Currently, this is used to allow multi-item drag & drop. + */ +bool ObjectsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) +{ + return false; +} + +/** + * Default row selection function taken from the layers dialog + */ +bool ObjectsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +/** + * Sets a group to be collapsed and recursively collapses its children + * @param group The group to collapse + */ +void ObjectsPanel::_setCollapsed(SPGroup * group) +{ + group->setExpanded(false); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + for (SPObject *iter = group->children; iter != NULL; iter = iter->next) + { + if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + } +} + +/** + * Sets a group to be expanded or collapsed + * @param iter Current tree item + * @param isexpanded Whether to expand or collapse + */ +void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPItem* item = row[_model->_colObject]; + if (item && SP_IS_GROUP(item)) + { + if (isexpanded) + { + //If we're expanding, simply perform the expansion + SP_GROUP(item)->setExpanded(isexpanded); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + else + { + //If we're collapsing, we need to recursively collapse, so call our helper function + _setCollapsed(SP_GROUP(item)); + } + } +} + +/** + * Callback for when the highlight color is changed + * @param csel Color selector + * @param cp Objects panel + */ +void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) +{ + SPColor color; + float alpha = 0; + csel->base->getColorAlpha(color, alpha); + guint32 rgba = color.toRGBA32( alpha ); + + ObjectsPanel *ptr = reinterpret_cast(cp); + + //Set the highlight color for all items in the _highlight_target (all selected items) + for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) + { + SPItem * target = *iter; + target->setHighlightColor(rgba); + target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); +} + +/** + * Callback for when the opacity value is changed + */ +void ObjectsPanel::_opacityValueChanged() +{ + _blockCompositeUpdate = true; + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_opacityChangedIter)); + DocumentUndo::maybeDone(_document, "opacity", SP_VERB_DIALOG_OBJECTS, _("Set object opacity")); + _blockCompositeUpdate = false; +} + +/** + * Change the opacity of the selected items in the tree + * @param iter Current tree item + */ +void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->style->opacity.set = TRUE; + item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper()); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Callback for when the blend mode is changed + */ +void ObjectsPanel::_blendValueChanged() +{ + _blockCompositeUpdate = true; + const Glib::ustring blendmode = _fe_cb.get_blend_mode(); + + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blendChangedIter), blendmode)); + DocumentUndo::done(_document, SP_VERB_DIALOG_OBJECTS, _("Set object blend mode")); + _blockCompositeUpdate = false; +} + +/** + * Sets the blend mode of the selected tree items + * @param iter Current tree item + * @param blendmode Blend mode to set + */ +void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + //Since blur and blend are both filters, we need to set both at the same time + SPStyle *style = item->style; + g_assert(style != NULL); + + if (blendmode != "normal") { + gdouble radius = 0; + if (item->style->getFilter()) { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_GAUSSIANBLUR(primitive)) { + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + if (bbox) { + radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber(); + } + } + } + } + SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); + sp_style_set_property_url(item, "filter", filter, false); + } else { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_FEBLEND(primitive)) { + primitive->deleteObject(); + break; + } + } + if (!item->style->getFilter()->children) { + remove_filter(item, false); + } + } + + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Callback for when the blur value has changed + */ +void ObjectsPanel::_blurValueChanged() +{ + _blockCompositeUpdate = true; + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blurChangedIter), _fe_blur.get_blur_value())); + DocumentUndo::maybeDone(_document, "blur", SP_VERB_DIALOG_OBJECTS, _("Set object blur")); + _blockCompositeUpdate = false; +} + +/** + * Sets the blur value for the selected items in the tree + * @param iter Current tree item + * @param blur Blur value to set + */ +void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + //Since blur and blend are both filters, we need to set both at the same time + SPStyle *style = item->style; + if (style) { + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + double radius; + if (bbox) { + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + radius = blur * perimeter / 400; + } else { + radius = 0; + } + + if (radius != 0) { + SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); + sp_style_set_property_url(item, "filter", filter, false); + } else if (item->style->filter.set && item->style->getFilter()) { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_GAUSSIANBLUR(primitive)) { + primitive->deleteObject(); + break; + } + } + if (!item->style->getFilter()->children) { + remove_filter(item, false); + } + } + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + } +} + +/** + * Constructor + */ +ObjectsPanel::ObjectsPanel() : + UI::Widget::Panel("", "/dialogs/objects", SP_VERB_DIALOG_OBJECTS), + _rootWatcher(0), + _deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + _composite_vbox(false, 0), + _opacity_vbox(false, 0), + _opacity_label(_("Opacity:")), + _opacity_label_unit(_("%")), +#if WITH_GTKMM_3_0 + _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)), +#else + _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), +#endif + _opacity_hscale(_opacity_adjustment), + _opacity_spin_button(_opacity_adjustment, 0.01, 1), + _fe_cb(UI::Widget::SimpleFilterModifier::BLEND), + _fe_vbox(false, 0), + _fe_alignment(1, 1, 1, 1), + _fe_blur(UI::Widget::SimpleFilterModifier::BLUR), + _blur_vbox(false, 0), + _blur_alignment(1, 1, 1, 1), + _colorSelectorDialog("dialogs.colorpickerwindow") +{ + //Create the tree model and store + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + //Set up the tree + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + //Create the column CellRenderers + //Visible + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); + int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; + eyeRenderer->property_activatable() = true; + Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); + if ( col ) { + col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); + } + + //Locked + Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); + int lockedColNum = _tree.append_column("lock", *renderer) - 1; + renderer->property_activatable() = true; + col = _tree.get_column(lockedColNum); + if ( col ) { + col->add_attribute( renderer->property_active(), _model->_colLocked ); + } + + //Type + Inkscape::UI::Widget::LayerTypeIcon * typeRenderer = Gtk::manage( new Inkscape::UI::Widget::LayerTypeIcon()); + int typeColNum = _tree.append_column("type", *typeRenderer) - 1; + typeRenderer->property_activatable() = true; + col = _tree.get_column(typeColNum); + if ( col ) { + col->add_attribute( typeRenderer->property_active(), _model->_colType ); + } + + //Insert order + Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); + int insertColNum = _tree.append_column("type", *insertRenderer) - 1; + col = _tree.get_column(insertColNum); + if ( col ) { + col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder ); + } + + //Clip/mask + Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); + int clipColNum = _tree.append_column("clipmask", *clipRenderer) - 1; + col = _tree.get_column(clipColNum); + if ( col ) { + col->add_attribute( clipRenderer->property_active(), _model->_colClipMask ); + } + + //Highlight + Inkscape::UI::Widget::HighlightPicker * highlightRenderer = Gtk::manage( new Inkscape::UI::Widget::HighlightPicker()); + int highlightColNum = _tree.append_column("highlight", *highlightRenderer) - 1; + col = _tree.get_column(highlightColNum); + if ( col ) { + col->add_attribute( highlightRenderer->property_active(), _model->_colHighlight ); + } + + //Label + _text_renderer = Gtk::manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + //Set the expander and search columns + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + _tree.set_search_column(_model->_colLabel); + + //Set up the tree selection + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &ObjectsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction) ); + + //Set up tree signals + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false ); + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleDragDrop), false); + _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), false)); + _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), true)); + + //Set up the label editing signals + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEditingCancelled) ); + + //Set up the scroller window and pack the page + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _page.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + //Set up the compositing items + //Blend mode filter effect + _composite_vbox.pack_start(_fe_vbox, false, false, 2); + _fe_alignment.set_padding(0, 0, 4, 0); + _fe_alignment.add(_fe_cb); + _fe_vbox.pack_start(_fe_alignment, false, false, 0); + _blendConnection = _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blendValueChanged)); + + //Blur filter effect + _composite_vbox.pack_start(_blur_vbox, false, false, 2); + _blur_alignment.set_padding(0, 0, 4, 0); + _blur_alignment.add(_fe_blur); + _blur_vbox.pack_start(_blur_alignment, false, false, 0); + _blurConnection = _fe_blur.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blurValueChanged)); + + //Opacity + _composite_vbox.pack_start(_opacity_vbox, false, false, 2); + _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); + _opacity_hbox.pack_start(_opacity_label, false, false, 3); + _opacity_vbox.pack_start(_opacity_hbox, false, false, 0); + _opacity_hbox.pack_start(_opacity_hscale, true, true, 0); + _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0); + _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); + _opacity_hscale.set_draw_value(false); +#if WITH_GTKMM_3_0 + _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); +#else + _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); +#endif + + //Keep the labels aligned + GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj())); + gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj())); + gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_blur.get_blur_label()->gobj())); + + //Pack the compositing functions and the button row + _page.pack_end(_composite_vbox, Gtk::PACK_SHRINK); + _page.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + //Pack into the panel contents + _getContents()->pack_start(_page, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + //Set up the button row + Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + _watching.push_back(&_composite_vbox); + + //Set up the pop-up menu + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_EDIT_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) ); + _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_GROUP, 0, "Group", (int)BUTTON_GROUP ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_UNGROUP, 0, "Ungroup", (int)BUTTON_UNGROUP ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); + //not implemented + //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); + + //will never be implemented + //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_CLIPPATH, 0, "Unset Clip", (int)BUTTON_UNSETCLIP ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_MASK, 0, "Set Mask", (int)BUTTON_SETMASK ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_MASK, 0, "Unset Mask", (int)BUTTON_UNSETMASK ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + //Set initial sensitivity of buttons + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + //Set up the color selection dialog + GtkWidget *dlg = GTK_WIDGET(_colorSelectorDialog.gobj()); + sp_transientize(dlg); + + _colorSelectorDialog.hide(); + _colorSelectorDialog.set_title (_("Select Highlight Color")); + _colorSelectorDialog.set_border_width (4); + _colorSelectorDialog.property_modal() = true; + _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); + _colorSelectorDialog.get_vbox()->pack_start ( + *Glib::wrap(&_colorSelector->vbox), true, true, 0); + + g_signal_connect(G_OBJECT(_colorSelector), "dragged", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + g_signal_connect(G_OBJECT(_colorSelector), "released", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + g_signal_connect(G_OBJECT(_colorSelector), "changed", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + + gtk_widget_show(GTK_WIDGET(_colorSelector)); + + setDesktop( targetDesktop ); + + show_all_children(); + + //Connect the desktop changed connection + desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectsPanel::setDesktop) ); + _deskTrack.connect(GTK_WIDGET(gobj())); +} + +/** + * Destructor + */ +ObjectsPanel::~ObjectsPanel() +{ + //Close the highlight selection dialog + _colorSelectorDialog.hide(); + _colorSelector = NULL; + + //Set the desktop to null, which will disconnect all object watchers + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + _deskTrack.disconnect(); +} + +/** + * Sets the current document + */ +void ObjectsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + //Clear all object watchers + while (!_objectWatchers.empty()) + { + ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + //Delete the root watcher + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getRoot() && document->getRoot()->getRepr()) + { + //Create a new root watcher for the document and then call _objectsChanged to fill the tree + _rootWatcher = new ObjectsPanel::ObjectWatcher(this, document->getRoot()); + document->getRoot()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getRoot()); + } +} + +/** + * Set the current panel desktop + */ +void ObjectsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //Connect desktop signals + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } else { + setDocument(NULL, NULL); + } + } + _deskTrack.setBase(desktop); +} +} //namespace Dialogs +} //namespace UI +} //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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h new file mode 100644 index 000000000..7b07afd63 --- /dev/null +++ b/src/ui/dialog/objects.h @@ -0,0 +1,255 @@ +/* + * A simple dialog for objects UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_OBJECTS_PANEL_H +#define SEEN_OBJECTS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPGroup; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays objects. + */ +class ObjectsPanel : public UI::Widget::Panel +{ +public: + ObjectsPanel(); + virtual ~ObjectsPanel(); + + static ObjectsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +private: + //Internal Classes: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + //Connections, Watchers, Trackers: + + //Document root watcher + ObjectsPanel::ObjectWatcher* _rootWatcher; + + //All object watchers + std::vector _objectWatchers; + + //Connection for when the desktop changes + sigc::connection desktopChangeConn; + + //Connection for when the document changes + sigc::connection _documentChangedConnection; + + //Connection for when the active selection in the document changes + sigc::connection _selectionChangedConnection; + + //Connection for when the selection in the dialog changes + sigc::connection _selectedConnection; + + //Connections for when the opacity/blend/blur of the active selection in the document changes + sigc::connection _opacityConnection; + sigc::connection _blendConnection; + sigc::connection _blurConnection; + + //Desktop tracker for grabbing the desktop changed connection + DesktopTracker _deskTrack; + + //Members: + + //The current desktop + SPDesktop* _desktop; + + //The current document + SPDocument* _document; + + //Tree data model + ModelColumns* _model; + + //Prevents the composite controls from updating + bool _blockCompositeUpdate; + + // + InternalUIBounce* _pending; + + //Whether the drag & drop was dragged into an item + gboolean _dnd_into; + + //List of drag & drop source items + std::vector _dnd_source; + + //Drag & drop target item + SPItem* _dnd_target; + + //List of items to change the highlight on + std::vector _highlight_target; + + //GUI Members: + + GdkEvent* _toggleEvent; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _page; + + /* Composite Settings */ + Gtk::VBox _composite_vbox; + Gtk::VBox _opacity_vbox; + Gtk::HBox _opacity_hbox; + Gtk::Label _opacity_label; + Gtk::Label _opacity_label_unit; +#if WITH_GTKMM_3_0 + Glib::RefPtr _opacity_adjustment; +#else + Gtk::Adjustment _opacity_adjustment; +#endif + Gtk::HScale _opacity_hscale; + Inkscape::UI::Widget::SpinButton _opacity_spin_button; + + Inkscape::UI::Widget::SimpleFilterModifier _fe_cb; + Gtk::VBox _fe_vbox; + Gtk::Alignment _fe_alignment; + Inkscape::UI::Widget::SimpleFilterModifier _fe_blur; + Gtk::VBox _blur_vbox; + Gtk::Alignment _blur_alignment; + + Gtk::Dialog _colorSelectorDialog; + SPColorSelector *_colorSelector; + + + //Methods: + + ObjectsPanel(ObjectsPanel const &); // no copy + ObjectsPanel &operator=(ObjectsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + void _setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ); + void _setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeHighlightTarget(const Gtk::TreeModel::iterator& iter); + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setOpacity ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + void _setCollapsed(SPGroup * group); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ); + void _updateComposite(); + void _setCompositingValues(SPItem *item); + + void _updateObject(SPObject *obj, bool recurse); + bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto); + + void _objectsChanged(SPObject *obj); + void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _opacityChangedIter(const Gtk::TreeIter& iter); + void _opacityValueChanged(); + + void _blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode); + void _blendValueChanged(); + + void _blurChangedIter(const Gtk::TreeIter& iter, double blur); + void _blurValueChanged(); + + + void setupDialog(const Glib::ustring &title); + + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + 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 : diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp new file mode 100644 index 000000000..f994b571f --- /dev/null +++ b/src/ui/dialog/tags.cpp @@ -0,0 +1,1182 @@ +/* + * A simple panel for tags + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tags.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "layer-fns.h" +#include "layer-manager.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/addtoicon.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +#include "event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-tag.h" +#include "sp-defs.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +TagsPanel& TagsPanel::getInstance() +{ + return *new TagsPanel(); +} + +enum { + COL_ADD = 1 +}; + +enum { + BUTTON_NEW = 0, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DELETE, + DRAGNDROP +}; + +class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : + _pnl(pnl), + _obj(obj), + _repr(repr), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + ObjectWatcher(TagsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _labelAttr ) { + _pnl->_updateObject( _obj); + } + } + } + + TagsPanel* _pnl; + SPObject* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; +}; + +class TagsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +{ + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } + } + } + + btn.set_tooltip_text (tooltip); +} + + +Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +void TagsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +void TagsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); + } +} + +bool TagsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_TAG_NEW ); + } + break; + case BUTTON_TOP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT); + } + } + break; + case BUTTON_BOTTOM: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK); + } + } + break; + case BUTTON_UP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + break; + case BUTTON_DOWN: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + break; + case BUTTON_DELETE: + { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + + +class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colParentObject); + add(_colObject); + add(_colLabel); + add(_colAddRemove); + add(_colAllowAddRemove); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colParentObject; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colAddRemove; + Gtk::TreeModelColumn _colAllowAddRemove; +}; + +void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) +{ + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && obj->parent) { + todelete->push_back(obj); + } +} + +void TagsPanel::_updateObject( SPObject *obj ) { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); +} + +bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + /* + * We get notified of layer update here (from layer->setLabel()) before layer->label() is set + * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which + * has the correct value (bug #168351) + */ + //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); + gchar const *label; + SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; + if (use && use->ref->isAttached()) { + label = use->ref->getObject()->getAttribute("inkscape:label"); + } else { + label = obj->getAttribute("inkscape:label"); + } + row[_model->_colLabel] = label ? label : obj->getId(); + row[_model->_colAddRemove] = SP_IS_TAG(obj); + } + + return false; +} + +void TagsPanel::_objectsSelected( Selection *sel ) { + + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) + { + SPObject *obj = reinterpret_cast(iter->data); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + SPObject * it = row[_model->_colObject]; + if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) + { + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + } + return false; +} + +void TagsPanel::_objectsChanged(SPObject* root) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + SPDocument* document = _desktop->doc(); + SPDefs* root = document->getDefs(); + if ( root ) { + _selectedConnection.block(); + _store->clear(); + _addObject( document, root, 0 ); + _selectedConnection.unblock(); + _objectsSelected(_desktop->selection); + _checkTreeSelection(); + } + } +} + +void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG(child)) + { + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colAddRemove] = true; + row[_model->_colAllowAddRemove] = true; + + _tree.expand_to_path( _store->get_path(iter) ); + + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + _addObject( doc, child, &row ); + } + } + if (SP_IS_TAG(obj) && obj->children) + { + Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row rowitems = *iteritems; + rowitems[_model->_colObject] = NULL; + rowitems[_model->_colParentObject] = obj; + rowitems[_model->_colLabel] = _("Items"); + rowitems[_model->_colAddRemove] = false; + rowitems[_model->_colAllowAddRemove] = false; + + _tree.expand_to_path( _store->get_path(iteritems) ); + + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child)) + { + SPItem *item = SP_TAG_USE(child)->ref->getObject(); + Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colAddRemove] = false; + row[_model->_colAllowAddRemove] = true; + + if (SP_TAG(obj)->expanded()) { + _tree.expand_to_path( _store->get_path(iter) ); + } + + if (item) { + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + item->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + } + } + } + } + } +} + +void TagsPanel::_select_tag( SPTag * tag ) +{ + for (SPObject * child = tag->children; child != NULL; child = child->next) + { + if (SP_IS_TAG(child)) { + _select_tag(SP_TAG(child)); + } else if (SP_IS_TAG_USE(child)) { + SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + if (obj) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); + _desktop->selection->add(obj); + } + } + } +} + +void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _select_tag(SP_TAG(obj)); + } else if (SP_IS_TAG_USE(obj)) { + SPObject * item = SP_TAG_USE(obj)->ref->getObject(); + if (item) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + } + } + } +} + +void TagsPanel::_pushTreeSelectionToCurrent() +{ + _selectionChangedConnection.block(); + // TODO hunt down the possible API abuse in getting NULL + if ( _desktop && _desktop->currentRoot() ) { + _desktop->selection->clear(); + _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); + } + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); +} + +void TagsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; +// if ( _tree.get_selection()->count_selected_rows() > 0 ) { +// sensitive = true; +// +// SPObject* inTree = _selectedLayer(); +// if ( inTree ) { +// +// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); +// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); +// +// } +// } + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +bool TagsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && SP_IS_TAG(obj)) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + } + case GDK_KEY_Delete: { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + return true; + } + break; + } + return false; +} + +bool TagsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + // Alt left click on the visible/lock columns - eat this event to keep row selection + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_ADD-1)) { + down_at_add = true; + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); + _defer_target = path; + } else { + down_at_add = false; + } + } else { + down_at_add = false; + } + } + + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); + } + + // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + + if (obj) { + if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { + if (SP_IS_TAG(obj)) { + bool wasadded = false; + for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) + { + SPObject *newobj = reinterpret_cast(iter->data); + bool addchild = true; + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + addchild = false; + } + } + if (addchild) { + Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); + obj->appendChild(clone); + wasadded = true; + } + } + if (wasadded) { + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to tag")); + } + } else { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * tobj = *iter; + if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { + tobj->parent->getRepr()->removeChild(tobj->getRepr()); + } + } + } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + } + } + } + } + } + + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + } + + return false; +} + +void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + _dnd_into = true; + _dnd_target = _document->getDefs(); + _dnd_source.clear(); + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); + + if (_dnd_source.empty()) { + return true; + } + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y > (int)(cell_height * 2/3)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = _document->getDefs(); + _dnd_into = true; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + SPObject *pobj = row[_model->_colParentObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _dnd_target = SP_TAG(obj); + } else if (SP_IS_TAG(obj->parent)) { + _dnd_target = SP_TAG(obj->parent); + _dnd_into = true; + } + } else if (pobj && SP_IS_TAG(pobj)) { + _dnd_target = SP_TAG(pobj); + _dnd_into = true; + } else { + return true; + } + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/* + * Move a layer in response to a drag & drop action + */ +void TagsPanel::_doTreeMove( ) +{ + if (_dnd_target) { + for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) + { + SPTag *src = *iter; + if (src != _dnd_target) { + src->moveTo(_dnd_target, _dnd_into); + } + } + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPTag *src = _dnd_source.back(); + _select_tag(src); + _dnd_source.pop_back(); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, + _("Moved tags")); + } +} + + +void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +void TagsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + if (SP_IS_TAG(obj)) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } + } +} + +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + return false; +} + +bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colParentObject]; + if (obj && SP_IS_TAG(obj)) + { + SP_TAG(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Constructor + */ +TagsPanel::TagsPanel() : + UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), + _rootWatcher(0), + deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + desktopChangeConn() +{ + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); + int addColNum = _tree.append_column("type", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _tree.get_column(addColNum); + if ( col ) { + col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); + col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); + } + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); + + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); + _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); + _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); + + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); + + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new tag") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button("Dup") ); +// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); +// _buttonsRow.add( *btn ); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Tag") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + setDesktop( targetDesktop ); + + show_all_children(); + + // restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); +} + +TagsPanel::~TagsPanel() +{ + + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + deskTrack.disconnect(); +} + +void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getDefs() && document->getDefs()->getRepr()) + { + _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); + document->getDefs()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getDefs()); + } +} + +void TagsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //setLabel( _desktop->doc()->name ); + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } + } +/* + GSList const *layers = _desktop->doc()->getResourceList( "layer" ); + g_message( "layers list starts at %p", layers ); + for ( GSList const *iter=layers ; iter ; iter = iter->next ) { + SPObject *layer=static_cast(iter->data); + g_message(" {%s} [%s]", layer->id, layer->label() ); + } +*/ + deskTrack.setBase(desktop); +} + + + + + +} //namespace Dialogs +} //namespace UI +} //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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h new file mode 100644 index 000000000..d35dfba01 --- /dev/null +++ b/src/ui/dialog/tags.h @@ -0,0 +1,181 @@ +/* + * A simple dialog for tags UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TAGS_PANEL_H +#define SEEN_TAGS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPTag; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays layers. + */ +class TagsPanel : public UI::Widget::Panel +{ +public: + TagsPanel(); + virtual ~TagsPanel(); + + //virtual void setOrientation( Gtk::AnchorType how ); + + static TagsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +protected: + //virtual void _handleAction( int setId, int itemId ); + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); +private: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + TagsPanel(TagsPanel const &); // no copy + TagsPanel &operator=(TagsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); + void _select_tag( SPTag * tag ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _updateObject(SPObject *obj); + bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); + + void _objectsChanged(SPObject *root); + void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); + +// std::vector groupConnections; + TagsPanel::ObjectWatcher* _rootWatcher; + std::vector _objectWatchers; + + // Hooked to the layer manager: + sigc::connection _documentChangedConnection; + sigc::connection _selectionChangedConnection; + + sigc::connection _changedConnection; + sigc::connection _addedConnection; + sigc::connection _removedConnection; + + // Internal + sigc::connection _selectedConnection; + sigc::connection _expandedConnection; + sigc::connection _collapsedConnection; + + DesktopTracker deskTrack; + SPDesktop* _desktop; + SPDocument* _document; + ModelColumns* _model; + InternalUIBounce* _pending; + gboolean _dnd_into; + std::vector _dnd_source; + SPObject* _dnd_target; + + GdkEvent* _toggleEvent; + bool down_at_add; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _layersPage; + + sigc::connection desktopChangeConn; + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + 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 : diff --git a/src/ui/widget/clipmaskicon.cpp b/src/ui/widget/clipmaskicon.cpp new file mode 100644 index 000000000..de7638bfe --- /dev/null +++ b/src/ui/widget/clipmaskicon.cpp @@ -0,0 +1,177 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/clipmaskicon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +ClipMaskIcon::ClipMaskIcon() : + Glib::ObjectBase(typeid(ClipMaskIcon)), + Gtk::CellRendererPixbuf(), + _pixClipName(INKSCAPE_ICON("path-intersection")), + _pixInverseName(INKSCAPE_ICON("path-difference")), + _pixMaskName(INKSCAPE_ICON("mask-intersection")), + _property_active(*this, "active", 0), + _property_pixbuf_clip(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_inverse(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_mask(*this, "pixbuf_off", Glib::RefPtr(0)) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); + + if (!icon_theme->has_icon(_pixClipName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixClipName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixInverseName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixInverseName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixMaskName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixMaskName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + + if (icon_theme->has_icon(_pixClipName)) { + _property_pixbuf_clip = icon_theme->load_icon(_pixClipName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixInverseName)) { + _property_pixbuf_inverse = icon_theme->load_icon(_pixInverseName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixMaskName)) { + _property_pixbuf_mask = icon_theme->load_icon(_pixMaskName, phys, (Gtk::IconLookupFlags)0); + } + + property_pixbuf() = Glib::RefPtr(0); +} + + +#if WITH_GTKMM_3_0 +void ClipMaskIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void ClipMaskIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void ClipMaskIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = phys;//+= (*width) >> 1; + } + if ( height ) { + *height =phys;//+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void ClipMaskIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void ClipMaskIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + switch (_property_active.get_value()) + { + case 1: + property_pixbuf() = _property_pixbuf_clip; + break; + case 2: + property_pixbuf() = _property_pixbuf_mask; + break; + case 3: + property_pixbuf() = _property_pixbuf_inverse; + break; + default: + property_pixbuf() = Glib::RefPtr(0); + break; + } +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +ClipMaskIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // 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:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/clipmaskicon.h b/src/ui/widget/clipmaskicon.h new file mode 100644 index 000000000..f1c1e7628 --- /dev/null +++ b/src/ui/widget/clipmaskicon.h @@ -0,0 +1,102 @@ +#ifndef __UI_DIALOG_CLIPMASKICON_H__ +#define __UI_DIALOG_CLIPMASKICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class ClipMaskIcon : public Gtk::CellRendererPixbuf { +public: + ClipMaskIcon(); + virtual ~ClipMaskIcon() {}; + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + int phys; + + Glib::ustring _pixClipName; + Glib::ustring _pixInverseName; + Glib::ustring _pixMaskName; + + Glib::Property _property_active; + Glib::Property< Glib::RefPtr > _property_pixbuf_clip; + Glib::Property< Glib::RefPtr > _property_pixbuf_inverse; + Glib::Property< Glib::RefPtr > _property_pixbuf_mask; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + 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 : diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp new file mode 100644 index 000000000..b799b5e29 --- /dev/null +++ b/src/ui/widget/highlight-picker.cpp @@ -0,0 +1,176 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "display/cairo-utils.h" + +#include + +#include "highlight-picker.h" +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +HighlightPicker::HighlightPicker() : + Glib::ObjectBase(typeid(HighlightPicker)), + Gtk::CellRendererPixbuf(), + _property_active(*this, "active", 0) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; +} + +HighlightPicker::~HighlightPicker() +{ +} + + +#if WITH_GTKMM_3_0 +void HighlightPicker::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void HighlightPicker::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void HighlightPicker::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = 10;//+= (*width) >> 1; + } + if ( height ) { + *height = 20; //cell_area ? cell_area->get_height() / 2 : 50; //+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void HighlightPicker::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void HighlightPicker::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + GdkRectangle carea; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 20); + cairo_t *ct = cairo_create(s); + + /* Transparent area */ + carea.x = 0; + carea.y = 0; + carea.width = 10; + carea.height = 20; + + cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard(); + + cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height / 2); + cairo_set_source(ct, checkers); + cairo_fill_preserve(ct); + ink_cairo_set_source_rgba32(ct, _property_active.get_value()); + cairo_fill(ct); + + cairo_pattern_destroy(checkers); + + cairo_rectangle(ct, carea.x, carea.y + carea.height / 2, carea.width, carea.height / 2); + ink_cairo_set_source_rgba32(ct, _property_active.get_value() | 0x000000ff); + cairo_fill(ct); + + cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height); + ink_cairo_set_source_rgba32(ct, 0x333333ff); + cairo_set_line_width(ct, 2); + cairo_stroke(ct); + + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), + GDK_COLORSPACE_RGB, TRUE, 8, + 10, 20, cairo_image_surface_get_stride(s), + ink_cairo_pixbuf_cleanup, s); + convert_pixbuf_argb32_to_normal(pixbuf); + + property_pixbuf() = Glib::wrap(pixbuf); +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +HighlightPicker::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // 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:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/highlight-picker.h b/src/ui/widget/highlight-picker.h new file mode 100644 index 000000000..2d7dbc14e --- /dev/null +++ b/src/ui/widget/highlight-picker.h @@ -0,0 +1,90 @@ +#ifndef __UI_DIALOG_HIGHLIGHT_PICKER_H__ +#define __UI_DIALOG_HIGHLIGHT_PICKER_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class HighlightPicker : public Gtk::CellRendererPixbuf { +public: + HighlightPicker(); + virtual ~HighlightPicker(); + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + +private: + + Glib::Property _property_active; +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + 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 : diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp new file mode 100644 index 000000000..9002a99c2 --- /dev/null +++ b/src/ui/widget/insertordericon.cpp @@ -0,0 +1,166 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/insertordericon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +InsertOrderIcon::InsertOrderIcon() : + Glib::ObjectBase(typeid(InsertOrderIcon)), + Gtk::CellRendererPixbuf(), + _pixTopName(INKSCAPE_ICON("insert-top")), + _pixBottomName(INKSCAPE_ICON("insert-bottom")), + _property_active(*this, "active", 0), + _property_pixbuf_top(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_bottom(*this, "pixbuf_on", Glib::RefPtr(0)) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); + + if (!icon_theme->has_icon(_pixTopName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixTopName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixBottomName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixBottomName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + + if (icon_theme->has_icon(_pixTopName)) { + _property_pixbuf_top = icon_theme->load_icon(_pixTopName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixBottomName)) { + _property_pixbuf_bottom = icon_theme->load_icon(_pixBottomName, phys, (Gtk::IconLookupFlags)0); + } + + property_pixbuf() = Glib::RefPtr(0); +} + + +#if WITH_GTKMM_3_0 +void InsertOrderIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void InsertOrderIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void InsertOrderIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = phys;//+= (*width) >> 1; + } + if ( height ) { + *height =phys;//+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void InsertOrderIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void InsertOrderIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + switch (_property_active.get_value()) + { + case 1: + property_pixbuf() = _property_pixbuf_top; + break; + case 2: + property_pixbuf() = _property_pixbuf_bottom; + break; + default: + property_pixbuf() = Glib::RefPtr(0); + break; + } +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +InsertOrderIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // 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:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/insertordericon.h b/src/ui/widget/insertordericon.h new file mode 100644 index 000000000..4b4b51de2 --- /dev/null +++ b/src/ui/widget/insertordericon.h @@ -0,0 +1,100 @@ +#ifndef __UI_DIALOG_INSERTORDERICON_H__ +#define __UI_DIALOG_INSERTORDERICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class InsertOrderIcon : public Gtk::CellRendererPixbuf { +public: + InsertOrderIcon(); + virtual ~InsertOrderIcon() {}; + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + int phys; + + Glib::ustring _pixTopName; + Glib::ustring _pixBottomName; + + Glib::Property _property_active; + Glib::Property< Glib::RefPtr > _property_pixbuf_top; + Glib::Property< Glib::RefPtr > _property_pixbuf_bottom; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + 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 : diff --git a/src/ui/widget/layertypeicon.cpp b/src/ui/widget/layertypeicon.cpp new file mode 100644 index 000000000..bfe855b28 --- /dev/null +++ b/src/ui/widget/layertypeicon.cpp @@ -0,0 +1,167 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/layertypeicon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +LayerTypeIcon::LayerTypeIcon() : + Glib::ObjectBase(typeid(LayerTypeIcon)), + Gtk::CellRendererPixbuf(), + _pixLayerName(INKSCAPE_ICON("dialog-layers")), + _pixGroupName(INKSCAPE_ICON("layer-duplicate")), + _pixPathName(INKSCAPE_ICON("layer-rename")), + _property_active(*this, "active", false), + _property_activatable(*this, "activatable", true), + _property_pixbuf_layer(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_group(*this, "pixbuf_off", Glib::RefPtr(0)), + _property_pixbuf_path(*this, "pixbuf_off", Glib::RefPtr(0)) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + int phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); + + if (!icon_theme->has_icon(_pixLayerName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixLayerName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixGroupName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixGroupName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixPathName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixPathName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + + if (icon_theme->has_icon(_pixLayerName)) { + _property_pixbuf_layer = icon_theme->load_icon(_pixLayerName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixGroupName)) { + _property_pixbuf_group = icon_theme->load_icon(_pixGroupName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixPathName)) { + _property_pixbuf_path = icon_theme->load_icon(_pixPathName, phys, (Gtk::IconLookupFlags)0); + } + + property_pixbuf() = _property_pixbuf_path.get_value(); +} + + +#if WITH_GTKMM_3_0 +void LayerTypeIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void LayerTypeIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void LayerTypeIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width += (*width) >> 1; + } + if ( height ) { + *height += (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void LayerTypeIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void LayerTypeIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + property_pixbuf() = _property_active.get_value() == 1 ? _property_pixbuf_group : (_property_active.get_value() == 2 ? _property_pixbuf_layer : _property_pixbuf_path); +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +LayerTypeIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + _signal_pre_toggle.emit(event); + _signal_toggled.emit(path); + + return false; +} + + +} // namespace Widget +} // namespace UI +} // 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:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/layertypeicon.h b/src/ui/widget/layertypeicon.h new file mode 100644 index 000000000..4ad3f16fb --- /dev/null +++ b/src/ui/widget/layertypeicon.h @@ -0,0 +1,108 @@ +#ifndef __UI_DIALOG_LAYERTYPEICON_H__ +#define __UI_DIALOG_LAYERTYPEICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class LayerTypeIcon : public Gtk::CellRendererPixbuf { +public: + LayerTypeIcon(); + virtual ~LayerTypeIcon() {}; + + sigc::signal signal_toggled() { return _signal_toggled;} + sigc::signal signal_pre_toggle() { return _signal_pre_toggle; } + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy property_activatable() { return _property_activatable.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + Glib::ustring _pixLayerName; + Glib::ustring _pixGroupName; + Glib::ustring _pixPathName; + + Glib::Property _property_active; + Glib::Property _property_activatable; + Glib::Property< Glib::RefPtr > _property_pixbuf_layer; + Glib::Property< Glib::RefPtr > _property_pixbuf_group; + Glib::Property< Glib::RefPtr > _property_pixbuf_path; + + sigc::signal _signal_toggled; + sigc::signal _signal_pre_toggle; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + 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 From 9bfba5c24a89f0d2ae75fc78a0aa21743a29e978 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 11:56:51 -0500 Subject: Experimental merge of Ponyscape features into trunk (will not compile) (bzr r13090.1.2) --- src/ui/dialog/objects.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 31e73db29..5023a8813 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -57,6 +57,8 @@ //#define DUMP_LAYERS 1 +guint get_group0_keyval(GdkEventKey *event); + namespace Inkscape { namespace UI { namespace Dialog { @@ -414,7 +416,7 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) row[_model->_colLocked] = item ? !item->isSensitive() : false; row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; - row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? (item->clip_ref->getObject()->inverse ? 3 : 1) : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; + row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; return true; @@ -2035,6 +2037,14 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) } //namespace UI } //namespace Inkscape +guint get_group0_keyval(GdkEventKey *event) { + guint keyval = 0; + gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( + gdk_display_get_default()), event->hardware_keycode, + (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, + NULL, NULL, NULL); + return keyval; +} /* Local Variables: -- cgit v1.2.3 From 05f60fa645caeda752fe6bffb33993f6485cadb6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 12:48:51 -0500 Subject: Experimental merge of Ponyscape to Inkscape trunk (does not compile) (bzr r13090.1.3) --- src/ui/widget/filter-effect-chooser.cpp | 2 ++ src/ui/widget/filter-effect-chooser.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 65706a9dc..3932bdfd4 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -23,6 +23,8 @@ namespace Widget { SimpleFilterModifier::SimpleFilterModifier(int flags) : _lb_blend(_("Blend mode:")), + _lb_blur(_("_Blur:")), + _lb_blur_unit(_("%")), _blend(BlendModeConverter, SP_ATTR_INVALID, false), _blur(_("Blur (%)"), 0, 0, 100, 1, 0.01, 1) { diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h index 6f0c2f26e..a467adcb1 100644 --- a/src/ui/widget/filter-effect-chooser.h +++ b/src/ui/widget/filter-effect-chooser.h @@ -54,11 +54,13 @@ public: double get_blur_value() const; void set_blur_value(const double); void set_blur_sensitive(const bool); + Gtk::Label *get_blur_label() { return &_lb_blur; }; private: int _flags; Gtk::HBox _hb_blend; - Gtk::Label _lb_blend; + Gtk::HBox _hb_blur; + Gtk::Label _lb_blend, _lb_blur, _lb_blur_unit; ComboBoxEnum _blend; SpinScale _blur; -- cgit v1.2.3 From ac167afb76ab4c730ac9dc945dc5dcd8efb8f5cf Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 12:59:13 -0500 Subject: Experimental Ponyscape to Inkscape merge (does not compile) (bzr r13090.1.4) --- src/ui/widget/Makefile_insert | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index 710b95c2b..e388b27f5 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -81,5 +81,10 @@ ink_common_sources += \ ui/widget/unit-menu.cpp \ ui/widget/unit-menu.h \ ui/widget/unit-tracker.h \ - ui/widget/unit-tracker.cpp - + ui/widget/unit-tracker.cpp \ + ui/widget/clipmaskicon.cpp \ + ui/widget/clipmaskicon.h \ + ui/widget/highlight-picker.cpp \ + ui/widget/highlight-picker.h \ + ui/widget/layertypeicon.cpp \ + ui/widget/layertypeicon.h -- cgit v1.2.3 From 8830d1ad5ab0693313d760cc99e2df0f35c9f6d9 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 16:29:52 -0500 Subject: Updated to include (non-functional) Objects dialogue (bzr r13090.1.6) --- src/ui/dialog/objects.cpp | 41 ++++++++++++++++++++++++++++++++++++++ src/ui/widget/Makefile_insert | 4 +++- src/ui/widget/highlight-picker.cpp | 32 ++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 5023a8813..ebfa16f02 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -37,6 +37,7 @@ #include "ui/widget/insertordericon.h" #include "ui/widget/clipmaskicon.h" #include "ui/widget/highlight-picker.h" +#include "ui/tools/node-tool.h" #include "verbs.h" #include "widgets/icon.h" #include "xml/node.h" @@ -54,6 +55,7 @@ #include "sp-clippath.h" #include "sp-mask.h" #include "layer-manager.h" +#include "tools-switch.h" //#define DUMP_LAYERS 1 @@ -2037,6 +2039,9 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) } //namespace UI } //namespace Inkscape +//should be okay to put these here because they are never referenced anywhere else +using namespace Inkscape::UI::Tools; + guint get_group0_keyval(GdkEventKey *event) { guint keyval = 0; gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( @@ -2046,6 +2051,42 @@ guint get_group0_keyval(GdkEventKey *event) { return keyval; } +void SPItem::setHighlightColor(guint32 const color) +{ + g_free(_highlightColor); + if (color & 0x000000ff) + { + _highlightColor = g_strdup_printf("%u", color); + } + else + { + _highlightColor = NULL; + } + + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(tool->desktop, TOOLS_NODES); + } + } +} + +void SPItem::unsetHighlightColor() +{ + g_free(_highlightColor); + _highlightColor = NULL; + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(tool->desktop, TOOLS_NODES); + } + } +} + /* Local Variables: mode:c++ diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index e388b27f5..2c543c5cc 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -87,4 +87,6 @@ ink_common_sources += \ ui/widget/highlight-picker.cpp \ ui/widget/highlight-picker.h \ ui/widget/layertypeicon.cpp \ - ui/widget/layertypeicon.h + ui/widget/layertypeicon.h \ + ui/widget/insertordericon.cpp \ + ui/widget/insertordericon.h diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index b799b5e29..bf93fa960 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -157,11 +157,41 @@ HighlightPicker::activate_vfunc(GdkEvent* event, return false; } - } // namespace Widget } // namespace UI } // namespace Inkscape +//should be okay to put this here +/** + * Converts GdkPixbuf's data to premultiplied ARGB. + * This function will convert a GdkPixbuf in place into Cairo's native pixel format. + * Note that this is a hack intended to save memory. When the pixbuf is in Cairo's format, + * using it with GTK will result in corrupted drawings. + */ +void +convert_pixbuf_normal_to_argb32(GdkPixbuf *pb) +{ + convert_pixels_pixbuf_to_argb32( + gdk_pixbuf_get_pixels(pb), + gdk_pixbuf_get_width(pb), + gdk_pixbuf_get_height(pb), + gdk_pixbuf_get_rowstride(pb)); +} + +/** + * Converts GdkPixbuf's data back to its native format. + * Once this is done, the pixbuf can be used with GTK again. + */ +void +convert_pixbuf_argb32_to_normal(GdkPixbuf *pb) +{ + convert_pixels_argb32_to_pixbuf( + gdk_pixbuf_get_pixels(pb), + gdk_pixbuf_get_width(pb), + gdk_pixbuf_get_height(pb), + gdk_pixbuf_get_rowstride(pb)); +} + /* Local Variables: mode:c++ -- cgit v1.2.3 From fc643d9de8b5b3faf6d43559a43308fbce56e592 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 17:39:47 -0500 Subject: Fix objects dialogue (bzr r13090.1.9) --- src/ui/dialog/dialog-manager.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 6d32e3aa8..bbb55ceee 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -54,6 +54,7 @@ #include "ui/dialog/xml-tree.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" +#include "ui/dialog/objects.h" namespace Inkscape { namespace UI { @@ -108,6 +109,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); + registerFactory("ObjectsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -142,6 +144,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); + registerFactory("ObjectsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); -- cgit v1.2.3 From fef7175272bbed79c874496c71092d3ba6e38d98 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 2 Mar 2014 23:50:04 +0100 Subject: Add new curve structure to show temporay item while draw on bspline and spiro, maybe the previous usage of the blue_curve give the strange errors in mac noticed by suv (bzr r11950.1.266) --- src/ui/tools/freehand-base.cpp | 22 ++++++++++++++++++++++ src/ui/tools/freehand-base.h | 4 ++++ src/ui/tools/pen-tool.cpp | 28 +++++++++++++++++++--------- 3 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 31d2f6191..cb6111bd5 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -82,6 +82,8 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , red_curve(NULL) , blue_bpath(NULL) , blue_curve(NULL) + , blue2_bpath(NULL) + , blue2_curve(NULL) , green_bpaths(NULL) , green_curve(NULL) , green_anchor(NULL) @@ -137,6 +139,13 @@ void FreehandBase::setup() { // Create blue curve this->blue_curve = new SPCurve(); + // Create blue2 bpath + this->blue2_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue2_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + + // Create blue2 curve + this->blue2_curve = new SPCurve(); + // Create green curve this->green_curve = new SPCurve(); @@ -483,6 +492,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); + // Blue2 + dc->blue2_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); + //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada //porque la modificamos al continuar por un anchor @@ -718,6 +731,15 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue_curve = dc->blue_curve->unref(); } + // Blue2 + if (dc->blue2_bpath) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->blue2_bpath)); + dc->blue2_bpath = NULL; + } + if (dc->blue2_curve) { + dc->blue2_curve = dc->blue2_curve->unref(); + } + // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index c8da9faed..d5c2fc9ba 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -57,6 +57,10 @@ public: SPCanvasItem *blue_bpath; SPCurve *blue_curve; + // Blue2 + SPCanvasItem *blue2_bpath; + SPCurve *blue2_curve; + // Green GSList *green_bpaths; SPCurve *green_curve; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 65823b642..5846c3cec 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1303,6 +1303,9 @@ void PenTool::_resetColors() { // Blue this->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), NULL); + // Blue2 + this->blue2_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue2_bpath), NULL); // Green while (this->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); @@ -1373,6 +1376,16 @@ void PenTool::_bspline_spiro_color() this->green_color = 0x00ff000; remake_green_bpaths = true; } + }else if(this->bspline){ + //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent + if(this->green_color != 0xff00007f){ + //since we are not im spiro mode, we assign the original colours + //to the red and the green curve, removing their transparency + this->red_color = 0xff00007f; + //Damos color rojo a la linea verde + this->green_color = 0xff00007f; + remake_green_bpaths = true; + } }else{ //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent if(this->green_color != 0x00ff007f){ @@ -1383,9 +1396,7 @@ void PenTool::_bspline_spiro_color() remake_green_bpaths = true; } //we hide the spiro/bspline rests - if(!this->bspline){ - sp_canvas_item_hide(this->blue_bpath); - } + sp_canvas_item_hide(this->blue2_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified @@ -1771,11 +1782,11 @@ void PenTool::_bspline_spiro_build() this->_spiro_doEffect(curve); } - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_item_show(this->blue_bpath); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue2_bpath), curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue2_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_item_show(this->blue2_bpath); curve->unref(); - this->blue_curve->reset(); + this->blue2_curve->reset(); //We hide the holders that doesn't contribute anything if(this->spiro){ sp_canvas_item_show(this->c1); @@ -1787,7 +1798,7 @@ void PenTool::_bspline_spiro_build() sp_canvas_item_hide(this->cl0); }else{ //if the curve is empty - sp_canvas_item_hide(this->blue_bpath); + sp_canvas_item_hide(this->blue2_bpath); } } @@ -2167,7 +2178,6 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - if(this->spiro || this->bspline) this->blue_curve->reset(); //spanish para cancelar linea sin un segmento creado this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); -- cgit v1.2.3 From 4eed716131afa00f3590b7d60600ef0c476c78e3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 20:24:50 -0500 Subject: Fixed path color when changed by Objects Dialog (bzr r13090.1.11) --- src/ui/tool/multi-path-manipulator.cpp | 6 +++--- src/ui/tool/multi-path-manipulator.h | 2 +- src/ui/tools/node-tool.cpp | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 65987ad52..b54b5ad07 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -182,7 +182,7 @@ void MultiPathManipulator::setItems(std::set const &s) ShapeRecord const &r = *i; if (!SP_IS_PATH(r.item) && !IS_LIVEPATHEFFECT(r.item)) continue; boost::shared_ptr newpm(new PathManipulator(*this, (SPPath*) r.item, - r.edit_transform, _getOutlineColor(r.role), r.lpe_key)); + r.edit_transform, _getOutlineColor(r.role, r.item), r.lpe_key)); newpm->showHandles(_show_handles); // always show outlines for clips and masks newpm->showOutline(_show_outline || r.role != SHAPE_ROLE_NORMAL); @@ -833,7 +833,7 @@ void MultiPathManipulator::_doneWithCleanup(gchar const *reason, bool alert_LPE) } /** Get an outline color based on the shape's role (normal, mask, LPE parameter, etc.). */ -guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role) +guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role, SPItem *item) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); switch(role) { @@ -845,7 +845,7 @@ guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role) return prefs->getColor("/tools/nodes/lpe_param_color", 0x009000ff); case SHAPE_ROLE_NORMAL: default: - return prefs->getColor("/tools/nodes/outline_color", 0xff0000ff); + return item->highlight_color(); } } diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index 1328372c6..d3746b878 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -106,7 +106,7 @@ private: void _commit(CommitEvent cps); void _done(gchar const *reason, bool alert_LPE = false); void _doneWithCleanup(gchar const *reason, bool alert_LPE = false); - guint32 _getOutlineColor(ShapeRole role); + guint32 _getOutlineColor(ShapeRole role, SPItem *item); MapType _mmap; public: diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..719b67108 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -473,7 +473,8 @@ bool NodeTool::root_handler(GdkEvent* event) { SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), - prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, + //prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, + over_item->highlight_color(), 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(flash), 0, SP_WIND_RULE_NONZERO); -- cgit v1.2.3 From 224de42669ff754155838d37c48a56fa70c9bc94 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 4 Mar 2014 12:38:20 +0100 Subject: Reduce a half the spiro distance to redraw (bzr r11950.1.273) --- src/ui/tools/pen-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 5846c3cec..0c97bd445 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -710,7 +710,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); }else{ - if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + if ( Geom::LInfty( event_w - pen_drag_origin_w ) > (tolerance/2) || mevent.time == 0) { this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); pen_drag_origin_w = event_w; -- cgit v1.2.3 From 3d7f15d8b4adc83c04a2ba5c654529beeeec0c3b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 4 Mar 2014 20:23:58 +0100 Subject: Change tooltip to one more explicit to make cusp nodes (bzr r11950.1.275) --- src/ui/tools/pen-tool.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 0c97bd445..ad77fcb53 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -642,7 +642,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { if(!this->spiro && !this->bspline){ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path.")); }else{ - this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path. Shift to cusp node")); + this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path. Shift+Click make a cusp node")); } this->anchor_statusbar = true; } else if (!anchor && this->anchor_statusbar) { @@ -656,7 +656,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { if(!this->spiro && !this->bspline){ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point.")); }else{ - this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point. Shift to cusp node")); + this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point. Shift+Click make a cusp node")); } this->anchor_statusbar = true; } else if (!anchor && this->anchor_statusbar) { @@ -2084,8 +2084,8 @@ void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint sta _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"); if(this->spiro || this->bspline){ message = is_curve ? - _("Curve segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path" ): - _("Line segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path"); + _("Curve segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter to finish the path" ): + _("Line segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter to finish the path"); } this->_setAngleDistanceStatusMessage(p, 0, message); } -- cgit v1.2.3 From dc1f7ce719d703d8dd4d7747d1967a3e8a1bfb18 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 16:53:56 -0500 Subject: Remove tag dialog temporarily (bzr r13090.1.13) --- src/ui/dialog/Makefile_insert | 2 -- src/ui/dialog/dialog-manager.cpp | 6 +++--- src/ui/dialog/swatches.cpp | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index bdb1abcda..1cf667f2a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -113,6 +113,4 @@ ink_common_sources += \ ui/dialog/lpe-powerstroke-properties.h \ ui/dialog/objects.cpp \ ui/dialog/objects.h \ - ui/dialog/tags.cpp \ - ui/dialog/tags.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index bbfea8cf0..1fddbf007 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -55,7 +55,7 @@ #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/objects.h" -#include "ui/dialog/tags.h" +//#include "ui/dialog/tags.h" namespace Inkscape { namespace UI { @@ -111,7 +111,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - registerFactory("TagsPanel", &create); + //registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -147,7 +147,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - registerFactory("TagsPanel", &create); + //registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 5e77a28ab..711bcfe2d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -20,6 +20,7 @@ #include "swatches.h" #include +#include #include #include @@ -57,6 +58,22 @@ #include "gradient-chemistry.h" #include "helper/action.h" #include "helper/action-context.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-pattern.h" +#include "icon-size.h" +#include "widgets/icon.h" +#include "filedialog.h" +#include "sp-stop.h" +#include "svg/svg-color.h" +#include "sp-radial-gradient.h" +#include "color-rgba.h" +#include "event-context.h" +#include +//sorry! +#ifdef WIN32 +#include +#endif namespace Inkscape { namespace UI { @@ -64,6 +81,7 @@ namespace Dialogs { #define VBLOCK 16 #define PREVIEW_PIXBUF_WIDTH 128 +#define SWATCHES_FILE_NAME "swatches.svg" void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); -- cgit v1.2.3 From 12971e975dae83c23e89cdbff99e990d3916b6ff Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 18:05:52 -0500 Subject: Added some basic swatch stuff (does not compile) (bzr r13090.1.14) --- src/ui/dialog/swatches.cpp | 2940 ++++++++++++++++++++++++++++++-------------- src/ui/dialog/swatches.h | 155 ++- 2 files changed, 2157 insertions(+), 938 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 711bcfe2d..a0c79b8ac 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -43,10 +43,10 @@ #include "path-prefix.h" #include "preferences.h" #include "sp-item.h" +#include "sp-gradient-fns.h" #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" -#include "ui/previewholder.h" #include "widgets/desktop-widget.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" @@ -57,7 +57,6 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" -#include "helper/action-context.h" #include "xml/node-observer.h" #include "xml/repr.h" #include "sp-pattern.h" @@ -68,1172 +67,2255 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" -#include "event-context.h" +#include "svg/css-ostringstream.h" +//#include "event-context.h" //no longer exists #include -//sorry! #ifdef WIN32 #include #endif +guint get_group0_keyval(GdkEventKey *event); +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); + namespace Inkscape { namespace UI { namespace Dialogs { -#define VBLOCK 16 -#define PREVIEW_PIXBUF_WIDTH 128 #define SWATCHES_FILE_NAME "swatches.svg" -void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); - -std::list userSwatchPages; -std::list systemSwatchPages; -static std::map docPalettes; -static std::vector docTrackings; -static std::map docPerPanel; - - -class SwatchesPanelHook : public SwatchesPanel -{ -public: - static void convertGradient( GtkMenuItem *menuitem, gpointer userData ); - static void deleteGradient( GtkMenuItem *menuitem, gpointer userData ); -}; +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; + } + ret = str; + while ( *str ) { + str++; + } + str--; + while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { + *str-- = 0; + } + return ret; +} -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); +static void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; } } -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); +static bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; } -static GtkWidget* popupMenu = 0; -static GtkWidget *popupSubHolder = 0; -static GtkWidget *popupSub = 0; -static std::vector popupItems; -static std::vector popupExtras; -static ColorItem* bounceTarget = 0; -static SwatchesPanel* bouncePanel = 0; +static char * SwatchFile; +static SPDocument * SwatchDocument; +static unsigned int page_suffix; -static void redirClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) +static void loadPalletFile() { - if ( bounceTarget ) { - handleClick( GTK_WIDGET(menuitem), bounceTarget ); + if (!SwatchDocument) { + SwatchFile=g_build_filename(INKSCAPE_PALETTESDIR, _("swatches.svg"), NULL); + SwatchDocument=SPDocument::createNewDoc (SwatchFile, TRUE); + if (!SwatchDocument) { + SwatchDocument = SPDocument::createNewDoc(NULL, TRUE, true); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } } } -static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) +static void addStop( Inkscape::XML::Node *parent, Glib::ustring const &color, gfloat opacity, gchar const *offset ) { - if ( bounceTarget ) { - handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget ); +#ifdef SP_GR_VERBOSE + g_message("addStop(%p, %s, %d, %s)", parent, color.c_str(), opacity, offset); +#endif + Inkscape::XML::Node *stop = parent->document()->createElement("svg:stop"); + { + gchar *tmp = g_strdup_printf( "stop-color:%s;stop-opacity:%f;", color.c_str(), opacity < 0.0 ? 0.0 : (opacity > 1.0 ? 1.0 : opacity) ); + stop->setAttribute( "style", tmp ); + g_free(tmp); } + + stop->setAttribute( "offset", offset ); + + parent->appendChild(stop); + Inkscape::GC::release(stop); } -static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) +static SPGroup* importGPL(SPDocument* doc, const gchar* full) { - if ( gr ) { - bool shown = false; - if ( desktop && desktop->doc() ) { - Inkscape::Selection *selection = sp_desktop_selection( desktop ); - GSList const *items = selection->itemList(); - if (items) { - SPStyle *query = sp_style_new( desktop->doc() ); - int result = objects_query_fillstroke(const_cast(items), query, true); - if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { - // could be pertinent - if (query->fill.isPaintserver()) { - SPPaintServer* server = query->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* grad = SP_GRADIENT(server); - if ( grad->isSwatch() && grad->getId() == gr->getId()) { - desktop->_dlg_mgr->showDialog("FillAndStroke"); - shown = true; + SPGroup* ret = NULL; + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + + /*Load the pallet file here*/ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( full, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + Inkscape::XML::Node * page = doc->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (doc->getObjectById(id)); + + page->setAttribute("id", id); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment + } else { + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + skipWhitespace(ptr); + if ( *ptr ) { + int r = 0; + int g = 0; + int b = 0; + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = g_dpgettext2(NULL, "Palette", n); + } + } + if ( !hasErr ) { + // Add the entry now + + Inkscape::XML::Node *grad = doc->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute("inkscape:label", name.c_str()); + grad->setAttribute( "osb:paint", "solid", 0 ); + SPColor color((float)r / 255, (float)g / 255, (float)b / 255); + addStop(grad, color.toString(), 1, "0"); + page->appendChild(grad); + Inkscape::GC::release(grad); + } + } else { + hasErr = true; + } + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; + } else { + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) + { + page->setAttribute("inkscape:label", val); + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } + } + } } } + } while ( result && !hasErr ); + if ( !hasErr ) { + doc->getDefs()->appendChild(page); + Inkscape::GC::release(page); + SPObject* obj = doc->getObjectByRepr(page); + if (SP_IS_GROUP(obj)) { + ret = SP_GROUP(obj); + } + #if ENABLE_MAGIC_COLORS + ColorItem::_wireMagicColors( onceMore ); + #endif // ENABLE_MAGIC_COLORS + } else { + delete page; } } - sp_style_unref(query); } - } - if (!shown) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) { - // Legacy gradient dialog - GtkWidget *dialog = sp_gradient_vector_editor_new( gr ); - gtk_widget_show( dialog ); - } else { - // Invoke the gradient tool - Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); - if ( verb ) { - SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); - if ( action ) { - sp_action_perform( action, NULL ); - } - } - } + fclose(f); } + /* end loading the pallet file*/ } + return ret; } -static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) +SwatchesPanel& SwatchesPanel::getInstance() { - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - SPDocument *doc = desktop ? desktop->doc() : 0; - if (doc) { - std::string targetName(bounceTarget->def.descr); - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - editGradientImpl( desktop, grad ); - break; + return *new SwatchesPanel(); +} + +class SwatchesPanel::StopWatcher : public Inkscape::XML::NodeObserver { +public: + StopWatcher(SwatchesPanel* pnl, SPStop* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()) + { + _repr->addObserver(*this); + } + + ~StopWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ){} + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj) { + _pnl->_defsChanged( ); + } + } + + SwatchesPanel* _pnl; + SPStop* _obj; + Inkscape::XML::Node* _repr; +}; + +class SwatchesPanel::GradientWatcher : public Inkscape::XML::NodeObserver { +public: + GradientWatcher(SwatchesPanel* pnl, SPGradient* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")), + _swatchAttr(g_quark_from_string("osb:paint")) + { + _repr->addObserver(*this); + } + + ~GradientWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch()) { + _pnl->_defsChanged( ); + } + } + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch() ) { + _pnl->_defsChanged( ); + } + } + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch() ) { + _pnl->_defsChanged( ); + } + } + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj && ((_obj->isSwatch() && name == _labelAttr) || name == _swatchAttr)) { + _pnl->_defsChanged( ); + } + } + + SwatchesPanel* _pnl; + SPGradient* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; + GQuark _swatchAttr; +}; + +class SwatchesPanel::SwatchWatcher : public Inkscape::XML::NodeObserver { +public: + SwatchWatcher(SwatchesPanel* pnl, SPObject* obj, bool builtIn) : + _pnl(pnl), + _obj(obj), + _builtIn(builtIn), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")), + _swatchAttr(g_quark_from_string("osb:paint")) + { + _repr->addObserver(*this); + } + + ~SwatchWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj) { + SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); + if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); } } } } -} - -void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData ) -{ - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - SPDocument *doc = desktop ? desktop->doc() : 0; - gint index = GPOINTER_TO_INT(userData); - if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { - Glib::ustring targetName = popupItems[index]; - - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - grad->setSwatch(); - DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, - _("Add gradient stop")); - break; + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); + } + } + } + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) + { + if ( _pnl && _obj) { + SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); + if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); } } } } -} + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj && name == _labelAttr) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); + } + } + } -void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*userData*/ ) + SwatchesPanel* _pnl; + SPObject* _obj; + bool _builtIn; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; + GQuark _swatchAttr; +}; + +class SwatchesPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord { - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - sp_gradient_unset_swatch(desktop, bounceTarget->def.descr); +public: + + ModelColumns() + { + add(_colObject); + add(_colLabel); } -} + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; +}; -static SwatchesPanel* findContainingPanel( GtkWidget *widget ) +class SwatchesPanel::ModelColumnsDoc : public Gtk::TreeModel::ColumnRecord { - SwatchesPanel *swp = 0; +public: - std::map rawObjects; - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - rawObjects[GTK_WIDGET(it->first->gobj())] = it->first; + ModelColumnsDoc() + { + add(_colObject); + add(_colLabel); + add(_colPixbuf); } + virtual ~ModelColumnsDoc() {} - for (GtkWidget* curr = widget; curr && !swp; curr = gtk_widget_get_parent(curr)) { - if (rawObjects.find(curr) != rawObjects.end()) { - swp = rawObjects[curr]; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn > _colPixbuf; +}; + +static void StripChildGroups(Inkscape::XML::Node * node, SPObject* addTo) +{ + for (Inkscape::XML::Node * it = node->firstChild(); it != NULL;) { + if (!strcmp(it->name(), "svg:g")) { + Inkscape::XML::Node * todel = it; + it = it->next(); + node->removeChild(todel); + } else { + it = it->next(); } } - - return swp; + addTo->appendChildRepr(node); } -static void removeit( GtkWidget *widget, gpointer data ) +static void BubbleChildGroups(Inkscape::XML::Node * node, SPObject* addTo) { - gtk_container_remove( GTK_CONTAINER(data), widget ); + std::queue groups; + for (Inkscape::XML::Node * it = node->firstChild(); it != NULL; ) { + if (!strcmp(it->name(), "svg:g")) { + groups.push(it->duplicate(addTo->document->getReprDoc())); + Inkscape::XML::Node * todel = it; + it = it->next(); + node->removeChild(todel); + } else { + it = it->next(); + } + } + addTo->appendChildRepr(node); + while (!groups.empty()) { + Inkscape::XML::Node * it = groups.front(); + groups.pop(); + BubbleChildGroups(it, addTo); + Inkscape::GC::release(it); + } } -/* extern'ed from colot-item.cpp */ -gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ); +void SwatchesPanel::_addSwatchButtonClicked(SPGroup* swatch, bool recurse) +{ + if (_currentDocument) { + if (swatch && SP_IS_GROUP(swatch) ) { + Inkscape::XML::Node * copy = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); + if (recurse) { + BubbleChildGroups(copy, _currentDocument->getDefs()); + } else { + StripChildGroups(copy, _currentDocument->getDefs()); + } + Inkscape::GC::release(copy); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); + } + } +} -gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ) +void SwatchesPanel::_importButtonClicked(bool addToDoc, bool addToBI) { - gboolean handled = FALSE; - - if ( event && (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) { - SwatchesPanel* swp = findContainingPanel( widget ); - - if ( !popupMenu ) { - popupMenu = gtk_menu_new(); - GtkWidget* child = 0; - - //TRANSLATORS: An item in context menu on a colour in the swatches - child = gtk_menu_item_new_with_label(_("Set fill")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(redirClick), - user_data); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - - //TRANSLATORS: An item in context menu on a colour in the swatches - child = gtk_menu_item_new_with_label(_("Set stroke")); - - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(redirSecondaryClick), - user_data); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - - child = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_menu_item_new_with_label(_("Delete")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(SwatchesPanelHook::deleteGradient), - user_data ); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - gtk_widget_set_sensitive( child, FALSE ); - - child = gtk_menu_item_new_with_label(_("Edit...")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(editGradient), - user_data ); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_menu_item_new_with_label(_("Convert")); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - //popupExtras.push_back(child); - //gtk_widget_set_sensitive( child, FALSE ); + if (addToDoc || addToBI) { + //# Get the current directory for finding files + static Glib::ustring open_path; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if(open_path.empty()) + { + Glib::ustring attr = prefs->getString("/dialogs/open/path"); + if (!attr.empty()) open_path = attr; + } + + //# Test if the open_path directory exists + if (!Inkscape::IO::file_test(open_path.c_str(), + (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) + open_path = ""; + + #ifdef WIN32 + //# If no open path, default to our win32 documents folder + if (open_path.empty()) + { + // The path to the My Documents folder is read from the + // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" + HKEY key = NULL; + if(RegOpenKeyExA(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { - popupSubHolder = child; - popupSub = gtk_menu_new(); - gtk_menu_item_set_submenu( GTK_MENU_ITEM(child), popupSub ); + WCHAR utf16path[_MAX_PATH]; + DWORD value_type; + DWORD data_size = sizeof(utf16path); + if(RegQueryValueExW(key, L"Personal", NULL, &value_type, + (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) + { + g_assert(value_type == REG_SZ); + gchar *utf8path = g_utf16_to_utf8( + (const gunichar2*)utf16path, -1, NULL, NULL, NULL); + if(utf8path) + { + open_path = Glib::ustring(utf8path); + g_free(utf8path); + } + } } + } + #endif - gtk_widget_show_all(popupMenu); + //# If no open path, default to our home directory + if (open_path.empty()) + { + open_path = g_get_home_dir(); + open_path.append(G_DIR_SEPARATOR_S); } - if ( user_data ) { - ColorItem* item = reinterpret_cast(user_data); - bool show = swp && (swp->getSelectedIndex() == 0); - for ( std::vector::iterator it = popupExtras.begin(); it != popupExtras.end(); ++ it) { - gtk_widget_set_sensitive(*it, show); - } + Gtk::Window * parent = SP_ACTIVE_DESKTOP->getToplevel(); + //# Create a dialog + Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = + Inkscape::UI::Dialog::FileOpenDialog::create( + *parent, open_path, + Inkscape::UI::Dialog::SWATCH_TYPES, + _("Select file to open")); - bounceTarget = item; - bouncePanel = swp; - popupItems.clear(); - if ( popupMenu ) { - gtk_container_foreach(GTK_CONTAINER(popupSub), removeit, popupSub); - bool processed = false; - GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); - if ( wdgt ) { - SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); - if ( dtw && dtw->desktop ) { - // Pick up all gradients with vectors - const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); - gint index = 0; - for (const GSList *curr = gradients; curr; curr = curr->next) { - SPGradient* grad = SP_GRADIENT(curr->data); - if ( grad->hasStops() && !grad->isSwatch() ) { - //gl = g_slist_prepend(gl, curr->data); - processed = true; - GtkWidget *child = gtk_menu_item_new_with_label(grad->getId()); - gtk_menu_shell_append(GTK_MENU_SHELL(popupSub), child); - - popupItems.push_back(grad->getId()); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(SwatchesPanelHook::convertGradient), - GINT_TO_POINTER(index) ); - index++; - } - } + //# Show the dialog + bool const success = openDialogInstance->show(); - gtk_widget_show_all(popupSub); - } - } - gtk_widget_set_sensitive( popupSubHolder, processed ); + //# Save the folder the user selected for later + open_path = openDialogInstance->getCurrentDirectory(); - gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time); - handled = TRUE; - } + if (!success) + { + delete openDialogInstance; + return; } - } - return handled; -} + //# User selected something. Get name and type + Glib::ustring fileName = openDialogInstance->getFilename(); + //# We no longer need the file dialog object - delete it + delete openDialogInstance; + openDialogInstance = NULL; -static char* trim( char* str ) { - char* ret = str; - while ( *str && (*str == ' ' || *str == '\t') ) { - str++; - } - ret = str; - while ( *str ) { - str++; - } - str--; - while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { - *str-- = 0; - } - return ret; -} -static void skipWhitespace( char*& str ) { - while ( *str == ' ' || *str == '\t' ) { - str++; + if (!fileName.empty()) + { + Glib::ustring newFileName = Glib::filename_to_utf8(fileName); + + if ( newFileName.size() > 0) + fileName = newFileName; + else + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + + open_path = Glib::path_get_dirname (fileName); + open_path.append(G_DIR_SEPARATOR_S); + prefs->setString("/dialogs/open/path", open_path); + + SPDocument* importdoc = SPDocument::createNewDoc(fileName.c_str(), true); + Inkscape::XML::Node * page = NULL; + if (importdoc && importdoc->getDefs()) { + if (addToBI) { + page = SwatchDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (SwatchDocument->getObjectById(id)); + + page->setAttribute("id", id); + gchar* name = g_path_get_basename(importdoc->getName()); + page->setAttribute("inkscape:label", name); + g_free(name); + } + + for (SPObject* it = importdoc->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GROUP(it)) { + if (page) { + Inkscape::XML::Node * copy = it->getRepr()->duplicate(SwatchDocument->getReprDoc()); + page->appendChild(copy); + } + if (addToDoc) { + _addSwatchButtonClicked(SP_GROUP(it), false); + } + } + } + if (page) { + SwatchDocument->getDefs()->appendChildRepr(page); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } + + importdoc->doUnref(); + } else { + SPGroup* g = importGPL(addToBI ? SwatchDocument : _currentDocument, fileName.c_str()); + if (addToBI) { + if (addToDoc) { + _addSwatchButtonClicked(g, false); + } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } else { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); + } + } + } } } -static bool parseNum( char*& str, int& val ) { - val = 0; - while ( '0' <= *str && *str <= '9' ) { - val = val * 10 + (*str - '0'); - str++; +void SwatchesPanel::SetSelectedFill(SPGradient* swatch) +{ + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->fill.isSet()) { + if (it->style->fill.isPaintserver()) { + SPPaintServer * server = it->style->getFillPaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = swatch->getRepr(); + if (repr != drepr && grad != swatch) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { + Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); + swatch->appendChildRepr(clone); + Inkscape::GC::release(clone); + } + swatch->setSwatch(); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); + } + } + } else if (it->style->fill.isColor()) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + addStop(swatch->getRepr(), it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); + swatch->setSwatch(); + if (!_noLink.get_active()) { + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + } + } + } } - bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); - return retval; } - -void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +void SwatchesPanel::SetSelectedStroke(SPGradient* swatch) { - char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); - if ( f ) { - char* result = fgets( block, sizeof(block), f ); - if ( result ) { - if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { - bool inHeader = true; - bool hasErr = false; - - SwatchPage *onceMore = new SwatchPage(); - - do { - result = fgets( block, sizeof(block), f ); - block[sizeof(block) - 1] = 0; - if ( result ) { - if ( block[0] == '#' ) { - // ignore comment - } else { - char *ptr = block; - // very simple check for header versus entry - while ( *ptr == ' ' || *ptr == '\t' ) { - ptr++; + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->stroke.isSet()) { + if (it->style->stroke.isPaintserver()) { + SPPaintServer * server = it->style->getStrokePaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = swatch->getRepr(); + if (repr != drepr && grad != swatch) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); } - if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { - // blank line. skip it. - } else if ( '0' <= *ptr && *ptr <= '9' ) { - // should be an entry link - inHeader = false; - ptr = block; - Glib::ustring name(""); - skipWhitespace(ptr); - if ( *ptr ) { - int r = 0; - int g = 0; - int b = 0; - hasErr = parseNum(ptr, r); - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, g); - } - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, b); - } - if ( !hasErr && *ptr ) { - char* n = trim(ptr); - if (n != NULL) { - name = g_dpgettext2(NULL, "Palette", n); - } - } - if ( !hasErr ) { - // Add the entry now - Glib::ustring nameStr(name); - ColorItem* item = new ColorItem( r, g, b, nameStr ); - onceMore->_colors.push_back(item); - } - } else { - hasErr = true; - } - } else { - if ( !inHeader ) { - // Hmmm... probably bad. Not quite the format we want? - hasErr = true; - } else { - char* sep = strchr(result, ':'); - if ( sep ) { - *sep = 0; - char* val = trim(sep + 1); - char* name = trim(result); - if ( *name ) { - if ( strcmp( "Name", name ) == 0 ) - { - onceMore->_name = val; - } - else if ( strcmp( "Columns", name ) == 0 ) - { - gchar* endPtr = 0; - guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == val) ) { - // failed conversion - } else { - onceMore->_prefWidth = numVal; - } - } - } else { - // error - hasErr = true; - } - } else { - // error - hasErr = true; - } - } + for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { + Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); + swatch->appendChildRepr(clone); + Inkscape::GC::release(clone); + } + swatch->setSwatch(); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); } } - } while ( result && !hasErr ); - if ( !hasErr ) { - if (user) - userSwatchPages.push_back(onceMore); - else - systemSwatchPages.push_back(onceMore); -#if ENABLE_MAGIC_COLORS - ColorItem::_wireMagicColors( onceMore ); -#endif // ENABLE_MAGIC_COLORS - } else { - delete onceMore; + } else if (it->style->stroke.isColor()) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + addStop(swatch->getRepr(), it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); + swatch->setSwatch(); + if (!_noLink.get_active()) { + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); } } } + } +} - fclose(f); +void SwatchesPanel::MoveSwatchDown(SPGradient* swatch) +{ + if (_currentDocument && swatch) { + SPObject* next = swatch->next; + while (next && (!SP_IS_GRADIENT(next) || !(SP_GRADIENT(next)->isSwatch()))) { + next = next->next; + } + if (next) { + Inkscape::XML::Node* repr = swatch->getRepr(); + repr->parent()->changeOrder(repr, next->getRepr()); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Right")); + } } } -static bool -compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { +void SwatchesPanel::MoveSwatchUp(SPGradient* swatch) +{ + if (_currentDocument && swatch) { + SPObject* g = NULL; + SPObject* next = swatch->parent->firstChild(); + while (next && next != swatch) { + if (SP_IS_GRADIENT(next) && SP_GRADIENT(next)->isSwatch()) { + g = next; + } + next = next->next; + } + if (g) { + g = g->getPrev(); + Inkscape::XML::Node* repr = swatch->getRepr(); + repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Left")); + } + } +} - return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0; +void SwatchesPanel::RemoveSwatch(SPGradient* swatch) +{ + if (_currentDocument) { + if (swatch->isReferenced()) { + Inkscape::XML::Node * repr = swatch->getRepr(); + repr->parent()->removeChild(repr); + _currentDocument->getDefs()->getRepr()->appendChild(repr); + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); + } else { + swatch->deleteObject(false); + } + } } -static void loadEmUp() +void SwatchesPanel::_setSelectionSwatch(SPGradient* swatch, bool isStroke) { - static bool beenHere = false; - gboolean userPalete = true; - if ( !beenHere ) { - beenHere = true; - - std::list sources; - sources.push_back( profile_path("palettes") ); - sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); - sources.push_back( g_strdup(CREATE_PALETTESDIR) ); - - // Use this loop to iterate through a list of possible document locations. - while (!sources.empty()) { - gchar *dirname = sources.front(); - if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) - && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { - GError *err = 0; - GDir *directory = g_dir_open(dirname, 0, &err); - if (!directory) { - gchar *safeDir = Inkscape::IO::sanitizeString(dirname); - g_warning(_("Palettes directory (%s) is unavailable."), safeDir); - g_free(safeDir); + if (_currentDocument) { + if (swatch) { + if (_noLink.get_active()) { + if (swatch->isSolid()) { + ColorRGBA rgba(swatch->getFirstStop()->getEffectiveColor().toRGBA32(swatch->getFirstStop()->opacity)); + sp_desktop_set_color(_currentDesktop, rgba, false, !isStroke); } else { - gchar *filename = 0; - while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { - gchar* lower = g_ascii_strdown( filename, -1 ); -// if ( g_str_has_suffix(lower, ".gpl") ) { - if ( !g_str_has_suffix(lower, "~") ) { - gchar* full = g_build_filename(dirname, filename, NULL); - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - _loadPaletteFile(full, userPalete); - } - g_free(full); - } -// } - g_free(lower); - } - g_dir_close(directory); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); + + Inkscape::XML::Node * clone = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); + _currentDocument->getDefs()->appendChildRepr(clone); + SPGradient* grad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + Inkscape::GC::release(clone); + grad->setSwatch(false); + SPGradient* normalized = sp_gradient_ensure_vector_normalized(grad); +// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { +// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); +// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); +// } + sp_desktop_set_style(_currentDesktop, css); + sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); + sp_repr_css_attr_unref (css); } + } else { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); + + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); +// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { +// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); +// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); +// } + sp_desktop_set_style(_currentDesktop, css); + sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); + sp_repr_css_attr_unref (css); } - - // toss the dirname - g_free(dirname); - sources.pop_front(); - userPalete = false; + } else { + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, isStroke ? "stroke" : "fill", "none"); + sp_desktop_set_style(_currentDesktop, css); + } + if (isStroke) { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item stroke swatch")); + } else { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item fill swatch")); } } +} - // Sort the list of swatches by name, grouped by user/system - userSwatchPages.sort(compare_swatch_names); - systemSwatchPages.sort(compare_swatch_names); +void SwatchesPanel::_swatchClicked(GdkEventButton* event, SPGradient* swatch) +{ + if (_currentDesktop) { + if (event->button == 3) { + Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi; + + Glib::ustring us = Glib::ustring::compose("%1", swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]")); + mi = Gtk::manage(new Gtk::MenuItem(swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]"))); + Gtk::Label* namelbl = dynamic_cast(mi->get_child()); + if (namelbl) { + namelbl->set_markup(us); + } + mi->show(); + mi->set_sensitive(false); + menu->append(*mi); + + Gtk::SeparatorMenuItem* sep; + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, false)); + mi->show(); + mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, true)); + mi->show(); + mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); + menu->append(*mi); + + if (swatch) { + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedFill), swatch)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedStroke), swatch)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Left"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchUp), swatch)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Right"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchDown), swatch)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::RemoveSwatch), swatch)); + mi->show(); + menu->append(*mi); + } + menu->popup(event->button, event->time); + } else if (!_currentDesktop->selection->isEmpty()) { + _setSelectionSwatch(swatch, event->state & GDK_SHIFT_MASK); + } + } } +void SwatchesPanel::MoveDown(SPGroup* page) +{ + if (_currentDocument && page) { + SPObject* next = page->next; + while (next && !SP_IS_GROUP(next)) { + next = next->next; + } + if (next) { + Inkscape::XML::Node* repr = page->getRepr(); + repr->parent()->changeOrder(repr, next->getRepr()); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Down")); + } + } +} - -SwatchesPanel& SwatchesPanel::getInstance() +void SwatchesPanel::MoveUp(SPGroup* page) { - return *new SwatchesPanel(); + if (_currentDocument && page) { + SPObject* g = NULL; + SPObject* next = page->parent->firstChild(); + while (next && next != page) { + if (SP_IS_GROUP(next)) { + g = next; + } + next = next->next; + } + if (g) { + g = g->getPrev(); + Inkscape::XML::Node* repr = page->getRepr(); + repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Up")); + } + } } +void SwatchesPanel::Remove(SPGroup* page) +{ + if (_currentDocument && page) { + std::vector toMove; + for(SPObject* obj = page->firstChild(); obj != NULL; obj = obj->next) { + if (SP_IS_GRADIENT(obj)) { + SPGradient* grad = SP_GRADIENT(obj); + if (grad->isReferenced()) { + toMove.push_back(grad->getRepr()); + } + } + } + while (!toMove.empty()) { + Inkscape::XML::Node * repr = toMove.back(); + toMove.pop_back(); + repr->parent()->removeChild(repr); + _currentDocument->getDefs()->getRepr()->appendChild(repr); + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); + } + page->deleteObject(false); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Remove Swatch Group")); + } +} -/** - * Constructor - */ -SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : - Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true), - _holder(0), - _clear(0), - _remove(0), - _currentIndex(0), - _currentDesktop(0), - _currentDocument(0) +void SwatchesPanel::AddSelectedFill(SPGroup* page) { - Gtk::RadioMenuItem* hotItem = 0; - _holder = new PreviewHolder(); - _clear = new ColorItem( ege::PaintDef::CLEAR ); - _remove = new ColorItem( ege::PaintDef::NONE ); - if (docPalettes.empty()) { - SwatchPage *docPalette = new SwatchPage(); - - docPalette->_name = "Auto"; - docPalettes[0] = docPalette; - } - - loadEmUp(); - if ( !systemSwatchPages.empty() ) { - SwatchPage* first = 0; - int index = 0; - Glib::ustring targetName; - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - targetName = prefs->getString(_prefs_path + "/palette"); - if (!targetName.empty()) { - if (targetName == "Auto") { - first = docPalettes[0]; - } else { - //index++; - std::vector pages = _getSwatchSets(); - for ( std::vector::iterator iter = pages.begin(); iter != pages.end(); ++iter ) { - if ( (*iter)->_name == targetName ) { - first = *iter; - break; + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->fill.isSet()) { + if (it->style->fill.isPaintserver()) { + SPPaintServer * server = it->style->getFillPaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + if (_noLink.get_active()) { + Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + clone->setAttribute( "osb:paint", "gradient", 0 ); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else if (grad->isSwatch()) { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); + if (repr->parent() != drepr) { + repr->parent()->removeChild(repr); + drepr->appendChild(repr); + } + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); } - index++; } + } else if (it->style->fill.isColor()) { + Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute( "osb:paint", "solid", 0 ); + addStop(grad, it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); + if (page) { + page->appendChild(grad); + } else { + _currentDocument->getDefs()->appendChild(grad); + } + SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); + Inkscape::GC::release(grad); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); } } } + } +} - if ( !first ) { - first = docPalettes[0]; - _currentIndex = 0; - } else { - _currentIndex = index; - } - - _rebuild(); - - Gtk::RadioMenuItem::Group groupOne; - - int i = 0; - std::vector swatchSets = _getSwatchSets(); - for ( std::vector::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { - SwatchPage* curr = *it; - Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); - if ( curr == first ) { - hotItem = single; +void SwatchesPanel::AddSelectedStroke(SPGroup* page) +{ + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->stroke.isSet()) { + if (it->style->stroke.isPaintserver()) { + SPPaintServer * server = it->style->getStrokePaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + if (_noLink.get_active()) { + Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + clone->setAttribute( "osb:paint", "gradient", 0 ); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else if (grad->isSwatch()) { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); + if (repr->parent() != drepr) { + repr->parent()->removeChild(repr); + drepr->appendChild(repr); + } + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } + } + } else if (it->style->stroke.isColor()) { + Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute( "osb:paint", "solid", 0 ); + addStop(grad, it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); + if (page) { + page->appendChild(grad); + } else { + _currentDocument->getDefs()->appendChild(grad); + } + SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); + Inkscape::GC::release(grad); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); + } } - _regItem( single, 3, i ); - - i++; } } +} - if (Glib::ustring(prefsPath) == "/dialogs/swatches") { - Gtk::Requisition sreq; -#if WITH_GTKMM_3_0 - Gtk::Requisition sreq_natural; - get_preferred_size(sreq_natural, sreq); -#else - sreq = size_request(); -#endif - int minHeight = 60; - if (sreq.height < minHeight) { - set_size_request(70, minHeight); - } +void SwatchesPanel::_addBIButtonClicked(GdkEventButton* event) +{ + if (popUpImportMenu) { + popUpImportMenu->popup(event->button, event->time); } +} - _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); - _setTargetFillable(_holder); - - show_all_children(); - - restorePanelPrefs(); - if ( hotItem ) { - hotItem->set_active(); +void SwatchesPanel::NewGroupBI() +{ + if (_currentDocument) { + Inkscape::XML::Node * page = SwatchDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (SwatchDocument->getObjectById(id)); + + page->setAttribute("id", id); + + SwatchDocument->getDefs()->appendChild(page); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } -SwatchesPanel::~SwatchesPanel() +void SwatchesPanel::NewGroup() { - _trackDocument( this, 0 ); - - _documentConnection.disconnect(); - _selChanged.disconnect(); - - if ( _clear ) { - delete _clear; - } - if ( _remove ) { - delete _remove; - } - if ( _holder ) { - delete _holder; + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("New Swatch Group")); } } -void SwatchesPanel::setOrientation(SPAnchorType how) +void SwatchesPanel::SaveAs() { - // Must call the parent class or bad things might happen - Inkscape::UI::Widget::Panel::setOrientation( how ); - - if ( _holder ) - { - _holder->setOrientation(SP_ANCHOR_SOUTH); + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + + std::vector toMove; + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->isSwatch()) { + toMove.push_back(grad->getRepr()); + } + } + } + while (!toMove.empty()) { + Inkscape::XML::Node* repr = toMove.back(); + toMove.pop_back(); + repr->parent()->removeChild(repr); + page->appendChild(repr); + } + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Save Swatch Group")); } } -void SwatchesPanel::setDesktop( SPDesktop* desktop ) +void SwatchesPanel::Duplicate(SPGroup* oldpage) { - if ( desktop != _currentDesktop ) { - if ( _currentDesktop ) { - _documentConnection.disconnect(); - _selChanged.disconnect(); + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + if (oldpage->label()) page->setAttribute("inkscape:label", oldpage->label()); + + for (SPObject *it = oldpage->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->isSwatch()) { + Inkscape::XML::Node * copy = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + page->appendChild(copy); + Inkscape::GC::release(copy); + } + } } + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Duplicate Swatch Group")); + } +} - _currentDesktop = desktop; +void SwatchesPanel::_lblClick(GdkEventButton* event, SPGroup* page) +{ + Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi; + Glib::ustring us = Glib::ustring::compose("%1", page ? (page->label() ? page->label() : page->getId()) : _("[Base]")); + mi = Gtk::manage(new Gtk::MenuItem(page ? (page->label() ? page->label() : page->getId()) : _("[Base]"))); + Gtk::Label* namelbl = dynamic_cast(mi->get_child()); + if (namelbl) { + namelbl->set_markup(us); + } + mi->show(); + mi->set_sensitive(false); + menu->append(*mi); + + Gtk::SeparatorMenuItem* sep; + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedFill), page)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedStroke), page)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + if (page) { + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Up"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveUp), page)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Down"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveDown), page)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Duplicate"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Duplicate), page)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Remove), page)); + mi->show(); + menu->append(*mi); + } else { + mi = Gtk::manage(new Gtk::MenuItem(_("Create New Group"))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Save As New Group"))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::SaveAs)); + mi->show(); + menu->append(*mi); + } + + menu->popup(event->button, event->time); +} - if ( desktop ) { - _currentDesktop->selection->connectChanged( - sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); +void SwatchesPanel::_defsChanged() +{ + if (_storeDoc) { + _storeDoc->clear(); + } + + while (!docWatchers.empty()) { + Inkscape::XML::NodeObserver* w = docWatchers.back(); + docWatchers.pop_back(); + delete w; + } + + std::vector tableChildren = _insideTable.get_children(); + for (std::vector::iterator c = tableChildren.begin(); c != tableChildren.end(); ++c) { + _insideTable.remove(**c); + } + + if (_currentDocument) { + Gtk::EventBox* eb; + Gtk::Label* lbl; + if (_showlabels) { + eb = Gtk::manage(new Gtk::EventBox()); + eb->add_events(Gdk::BUTTON_PRESS_MASK); + eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), NULL)); + + lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); + eb->add(*lbl); + _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + } + Glib::ustring str1 = Glib::ustring(_("[None]")); + ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); + //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->setName(_("[None]")); + _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + + unsigned int i = 1; + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->hasStops()) { + + GradientWatcher* w = new GradientWatcher(this, grad); + docWatchers.push_back(w); + + if (grad->isSwatch()) { + + for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { + StopWatcher* sw = new StopWatcher(this, s); + docWatchers.push_back(sw); + } - _currentDesktop->selection->connectModified( - sigc::hide(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection)))); + if (_storeDoc) { + Gtk::TreeModel::iterator iter = _storeDoc->append(); + Gtk::TreeModel::Row row = *iter; + row[_modelDoc->_colObject] = grad; + row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); + GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); + row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); + } + Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); + item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); + item->setGradient(grad); + //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->setName(it->label() ? it->label() : it->getId()); + if (_showlabels) { + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } else { + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } - _currentDesktop->connectToolSubselectionChanged( - sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + i++; + } + } + } + } + + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GROUP(it)) { + SwatchWatcher* w = new SwatchWatcher(this, it, false); + docWatchers.push_back(w); + + if (_showlabels) { + i += 20 - (i % 20); + eb = Gtk::manage(new Gtk::EventBox()); + eb->add_events(Gdk::BUTTON_PRESS_MASK); + eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); + lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); + eb->add(*lbl); + _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + } + + Gtk::TreeModel::iterator rowiter; + + if (_storeDoc) { + rowiter = _storeDoc->append(); + Gtk::TreeModel::Row row = *rowiter; + row[_modelDoc->_colObject] = it; + row[_modelDoc->_colLabel] = it->label() ? it->label() : it->getId(); + } + + for (SPObject *cit = it->firstChild(); cit != NULL; cit = cit->next) { + if (SP_IS_GRADIENT(cit)) { + SPGradient* grad = SP_GRADIENT(cit); + + if (grad->hasStops()) { + + GradientWatcher* w = new GradientWatcher(this, grad); + docWatchers.push_back(w); + + if (grad->isSwatch()) { + + for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { + StopWatcher* sw = new StopWatcher(this, s); + docWatchers.push_back(sw); + } - sigc::bound_mem_functor1 first = sigc::mem_fun(*this, &SwatchesPanel::_setDocument); - sigc::slot base2 = first; - sigc::slot slot2 = sigc::hide<0>( base2 ); - _documentConnection = desktop->connectDocumentReplaced( slot2 ); + if (_storeDoc && rowiter) { + Gtk::TreeModel::iterator iter = _storeDoc->append(rowiter->children()); + Gtk::TreeModel::Row row = *iter; + row[_modelDoc->_colObject] = grad; + row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); + GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); + row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - _setDocument( desktop->doc() ); - } else { - _setDocument(0); + _editDoc.expand_to_path(_storeDoc->get_path(iter)); + } + Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); + item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); + item->setGradient(grad); + //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->setName(cit->label() ? cit->label() : cit->getId()); + if (_showlabels) { + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } else { + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } + i++; + } + } + } + } + } } } + + _scroller.show_all_children(); + _scroller.queue_draw(); } - -class DocTrack +Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) { -public: - DocTrack(SPDocument *doc, sigc::connection &docDestroy, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : - doc(doc), - updatePending(false), - lastGradientUpdate(0.0), - docDestroy(docDestroy), - gradientRsrcChanged(gradientRsrcChanged), - defsChanged(defsChanged), - defsModified(defsModified) - { - if ( !timer ) { - timer = new Glib::Timer(); - refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); + Gtk::MenuItem* mi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId(),1)); + Gtk::Menu* m = NULL; + + Gtk::TreeModel::Row* r; + if (_store) { + Gtk::TreeModel::iterator iter = parentRow ? _store->append(parentRow->children()) : _store->append(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = group; + row[_model->_colLabel] = group->label() ? group->label() : group->getId(); + + if (SP_IS_GROUP(group->parent) && SP_GROUP(group->parent)->expanded()) { + _editBI.expand_to_path(_store->get_path(iter)); } - timerRefCount++; + r = &row; + } else { + r = NULL; } - - ~DocTrack() + + bool hasswatches = false; + for (SPObject * obj = group->firstChild(); obj != NULL; obj = obj->next) { - timerRefCount--; - if ( timerRefCount <= 0 ) { - refreshTimer.disconnect(); - timerRefCount = 0; - if ( timer ) { - timer->stop(); - delete timer; - timer = 0; + if (SP_IS_GROUP(obj)) { + if (!m) { + m = manage(new Gtk::Menu()); + m->show_all(); + mi->set_submenu(*m); + + Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(_("[All]"))); + basemi->show(); + Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); + if (namelbl) { + namelbl->set_markup(_("[All]")); + } + basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, true)); + m->append(*basemi); + + Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + m->append(*sep); } + SwatchWatcher* w = new SwatchWatcher(this, obj, true); + rootWatchers.push_back(w); + m->append(*_addSwatchGroup(SP_GROUP(obj), r)); + } else if (SP_IS_GRADIENT(obj)) { + hasswatches = true; } - if (doc) { - docDestroy.disconnect(); - gradientRsrcChanged.disconnect(); - defsChanged.disconnect(); - defsModified.disconnect(); - doc = NULL; + } + if (!m) { + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); + } else if (hasswatches) { + Glib::ustring us = Glib::ustring::compose("%1", group->label() ? group->label() : group->getId()); + Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId())); + basemi->show(); + Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); + if (namelbl) { + namelbl->set_markup(us); } + basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); + m->prepend(*basemi); } + mi->show(); + return mi; +} - static bool handleTimerCB(); - - /** - * Checks if update should be queued or executed immediately. - * - * @return true if the update was queued and should not be immediately executed. - */ - static bool queueUpdateIfNeeded(SPDocument *doc); - - static Glib::Timer *timer; - static int timerRefCount; - static sigc::connection refreshTimer; - - SPDocument *doc; - bool updatePending; - double lastGradientUpdate; - sigc::connection docDestroy; - sigc::connection gradientRsrcChanged; - sigc::connection defsChanged; - sigc::connection defsModified; - -private: - DocTrack(DocTrack const &); // no copy - DocTrack &operator=(DocTrack const &); // no assign -}; - -Glib::Timer *DocTrack::timer = 0; -int DocTrack::timerRefCount = 0; -sigc::connection DocTrack::refreshTimer; +void SwatchesPanel::_swatchesChanged() +{ + while (!rootWatchers.empty()) { + Inkscape::XML::NodeObserver* w = rootWatchers.back(); + rootWatchers.pop_back(); + delete w; + } -static const double DOC_UPDATE_THREASHOLD = 0.090; + std::vector menuChildren = popUpMenu->get_children(); + for (std::vector::iterator c = menuChildren.begin(); c != menuChildren.end(); ++c) { + popUpMenu->remove(**c); + } + + if (_store) { + _store->clear(); + } + + Gtk::MenuItem* mi; + + for (SPObject * obj = SwatchDocument->getDefs()->firstChild(); obj != NULL; obj = obj->next) + { + if (SP_IS_GROUP(obj)) { + SwatchWatcher* w = new SwatchWatcher(this, obj, true); + rootWatchers.push_back(w); + popUpMenu->append(*_addSwatchGroup(SP_GROUP(obj), NULL)); + + } + } + Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + popUpMenu->append(*sep); + + mi = manage(new Gtk::MenuItem(_("New Swatch Group..."),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); + mi->show(); + popUpMenu->append(*mi); + + mi = manage(new Gtk::MenuItem(_("Add Swatch File..."),1)); + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, false)); + mi->show(); + popUpMenu->append(*mi); + + mi = manage(new Gtk::MenuItem(_("Import Swatch File..."),1)); + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, true)); + mi->show(); + popUpMenu->append(*mi); +} -bool DocTrack::handleTimerCB() +void SwatchesPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) { - double now = timer->elapsed(); + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } - std::vector needCallback; - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { - DocTrack *track = *it; - if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { - needCallback.push_back(track); + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } } } + + btn.set_tooltip_text (fallback); + + if ( !set ) { + btn.set_label( fallback ); + } +} - for (std::vector::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { - DocTrack *track = *it; - if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping - // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. - SwatchesPanel::handleDefsModified(track->doc); +void SwatchesPanel::_addButtonClicked(GdkEventButton* event) { + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) { + if (popUpMenu) { + popUpMenu->popup(event->button, event->time); } } +} - return true; +void SwatchesPanel::NoLinkToggled() { + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring nolink = Glib::ustring::compose("%1/nolink", _prefs_path); + prefs->setBool(nolink, _noLink.get_active()); } -bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) +bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) { - bool deferProcessing = false; - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { - DocTrack *track = *it; - if ( track->doc == doc ) { - double now = timer->elapsed(); - double elapsed = now - track->lastGradientUpdate; - - if ( elapsed < DOC_UPDATE_THREASHOLD ) { - deferProcessing = true; - track->updatePending = true; - } else { - track->lastGradientUpdate = now; - track->updatePending = false; - } + static unsigned doubleclick = 0; + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } - break; + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _editBI.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnBI) { + // Double click on the Layer name, enable editing + _text_rendererBI->property_editable() = true; + _editBI.set_cursor (path, *_name_columnBI, true); + grab_focus(); } } - return deferProcessing; + + return false; } -void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) +bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - SPDocument *oldDoc = NULL; - if (docPerPanel.find(panel) != docPerPanel.end()) { - oldDoc = docPerPanel[panel]; - if (!oldDoc) { - docPerPanel.erase(panel); // Should not be needed, but clean up just in case. - } - } - if (oldDoc != document) { - if (oldDoc) { - docPerPanel[panel] = NULL; - bool found = false; - for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { - found = (it->second == document); - } - if (!found) { - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ - if ((*it)->doc == oldDoc) { - delete *it; - docTrackings.erase(it); - break; - } + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter && !_text_rendererBI->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_rendererBI->property_editable() = true; + _editBI.set_cursor(*path, *_name_columnBI, true); + grab_focus(); + return true; } } } - - if (document) { - bool found = false; - for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { - found = (it->second == document); - } - docPerPanel[panel] = document; - if (!found) { - sigc::connection conn0 = document->connectDestroy(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDocumentDestroy), document)); - sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); - sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); - sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); - - DocTrack *dt = new DocTrack(document, conn0, conn1, conn2, conn3); - docTrackings.push_back(dt); - - if (docPalettes.find(document) == docPalettes.end()) { - SwatchPage *docPalette = new SwatchPage(); - docPalette->_name = "Auto"; - docPalettes[document] = docPalette; + case GDK_KEY_Delete: { + + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj) { + obj->deleteObject(false); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } + return true; } + break; } + return false; } -void SwatchesPanel::_setDocument( SPDocument *document ) +void SwatchesPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) { - if ( document != _currentDocument ) { - _trackDocument(this, document); - _currentDocument = document; - handleGradientsChange( document ); - } + Gtk::TreeModel::iterator iter = _editBI.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_rendererBI->property_editable() = false; } -static void recalcSwatchContents(SPDocument* doc, - boost::ptr_vector &tmpColors, - std::map &previewMappings, - std::map &gradMappings) +void SwatchesPanel::_handleEditingCancelled() { - std::vector newList; - - if (doc) { - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( grad->isSwatch() ) { - newList.push_back(SP_GRADIENT(item->data)); + _text_rendererBI->property_editable() = false; +} + +void SwatchesPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && SwatchDocument) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } } +} - if ( !newList.empty() ) { - std::reverse(newList.begin(), newList.end()); - for ( std::vector::iterator it = newList.begin(); it != newList.end(); ++it ) - { - SPGradient* grad = *it; - - cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - PREVIEW_PIXBUF_WIDTH, VBLOCK); - cairo_t *ct = cairo_create(preview); - - Glib::ustring name( grad->getId() ); - ColorItem* item = new ColorItem( 0, 0, 0, name ); - - cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); - cairo_set_source(ct, check); - cairo_paint(ct); - cairo_set_source(ct, gradient); - cairo_paint(ct); - - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_pattern_destroy(check); - - cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); - cairo_surface_destroy(preview); +void SwatchesPanel::_setCollapsed(SPGroup * group) +{ + group->setExpanded(false); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + for (SPObject *iter = group->children; iter != NULL; iter = iter->next) + { + if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + } +} - previewMappings[item] = prevpat; +void SwatchesPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; - tmpColors.push_back(item); - gradMappings[item] = grad; + SPObject* obj = row[_model->_colObject]; + if (obj && SP_IS_GROUP(obj)) + { + if (isexpanded) + { + SP_GROUP(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + else + { + _setCollapsed(SP_GROUP(obj)); } } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } -void SwatchesPanel::handleDocumentDestroy(SPDocument *document) +void SwatchesPanel::_deleteButtonClicked() { - if (document) { - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ - if ((*it)->doc == document) { - delete *it; - docTrackings.erase(it); - break; - } + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + if (obj) { + obj->deleteObject(false); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } + } +} - if (docPalettes.find(document) != docPalettes.end()) { - docPalettes.erase(document); +bool SwatchesPanel::_handleButtonEventDoc(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _editDoc.get_path_at_pos( x, y, path ) ) { + Gtk::TreeModel::Children::iterator iter = _editDoc.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_modelDoc->_colObject]; + if (SP_IS_GRADIENT(obj)) { + _swatchClicked(event, SP_GRADIENT(obj)); + } else if (SP_IS_GROUP(obj)) { + _lblClick(event, SP_GROUP(obj)); + } else { + _lblClick(event, NULL); + } + } else { + _lblClick(event, NULL); } + } + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - if (it->second == document) { - SwatchesPanel* swp = it->first; - std::vector pages = swp->_getSwatchSets(); - if ((swp->_currentIndex >= static_cast(pages.size())) && (pages.size() > 0)) - { - swp->_setSelectedIndex(swp->_getSwatchSets().size() - 1); - } - swp->_rebuild(); - docPerPanel.erase(it); - break; - } + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _editDoc.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnDoc) { + // Double click on the Layer name, enable editing + _text_rendererDoc->property_editable() = true; + _editDoc.set_cursor (path, *_name_columnDoc, true); + grab_focus(); } } + + return false; } -void SwatchesPanel::handleGradientsChange(SPDocument *document) +void SwatchesPanel::_deleteButtonClickedDoc() { - SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette) { - boost::ptr_vector tmpColors; - std::map tmpPrevs; - std::map tmpGrads; - recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - - for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - it->first->setPattern(it->second); - cairo_pattern_destroy(it->second); + Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); + if (iter) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_modelDoc->_colObject]; + if (SP_IS_GRADIENT(obj)) { + RemoveSwatch(SP_GRADIENT(obj)); + } else if (SP_IS_GROUP(obj)) { + Remove(SP_GROUP(obj)); } + } +} - for (std::map::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { - it->first->setGradient(it->second); - } - - docPalette->_colors.swap(tmpColors); - - // Figure out which SwatchesPanel instances are affected and update them. - - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - if (it->second == document) { - SwatchesPanel* swp = it->first; - std::vector pages = swp->_getSwatchSets(); - SwatchPage* curr = pages[swp->_currentIndex]; - if (curr == docPalette) { - swp->_rebuild(); +bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) +{ + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); + if (iter && !_text_rendererDoc->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_modelDoc->_colObject]; + if (obj) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_rendererDoc->property_editable() = true; + _editDoc.set_cursor(*path, *_name_columnDoc, true); + grab_focus(); + return true; } } } + case GDK_KEY_Delete: { + + _deleteButtonClickedDoc(); + return true; + } + break; } + return false; } -void SwatchesPanel::handleDefsModified(SPDocument *document) +void SwatchesPanel::_renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name) { - SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { - boost::ptr_vector tmpColors; - std::map tmpPrevs; - std::map tmpGrads; - recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - - if ( tmpColors.size() != docPalette->_colors.size() ) { - handleGradientsChange(document); - } else { - int cap = std::min(docPalette->_colors.size(), tmpColors.size()); - for (int i = 0; i < cap; i++) { - ColorItem *newColor = &tmpColors[i]; - ColorItem *oldColor = &docPalette->_colors[i]; - if ( (newColor->def.getType() != oldColor->def.getType()) || - (newColor->def.getR() != oldColor->def.getR()) || - (newColor->def.getG() != oldColor->def.getG()) || - (newColor->def.getB() != oldColor->def.getB()) ) { - oldColor->def.setRGB(newColor->def.getR(), newColor->def.getG(), newColor->def.getB()); - } - if (tmpGrads.find(newColor) != tmpGrads.end()) { - oldColor->setGradient(tmpGrads[newColor]); - } - if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { - oldColor->setPattern(tmpPrevs[newColor]); - } + if ( row && SwatchDocument) { + SPObject* obj = row[_modelDoc->_colObject]; + if ( obj ) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); } } - - for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - cairo_pattern_destroy(it->second); - } } } +void SwatchesPanel::_handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _editDoc.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObjectDoc(row, new_text); + _text_rendererDoc->property_editable() = false; +} + +void SwatchesPanel::_handleEditingCancelledDoc() +{ + _text_rendererDoc->property_editable() = false; +} -std::vector SwatchesPanel::_getSwatchSets() const +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool SwatchesPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) { - std::vector tmp; - if (docPalettes.find(_currentDocument) != docPalettes.end()) { - tmp.push_back(docPalettes[_currentDocument]); + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + bool _dnd_top = false; + _dnd_into = false; + _dnd_target = SwatchDocument->getDefs()->lastChild(); + Gtk::TreeModel::iterator itersel = _editBI.get_selection()->get_selected(); + if (!itersel) { + return true; } + Gtk::TreeModel::Row rowsel = *itersel; + _dnd_source = rowsel[_model->_colObject]; - tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end()); - tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end()); + if (!_dnd_source) { + return true; + } + + if (_editBI.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _editBI.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y < (int)(cell_height * 1/3)) { + Gtk::TreeModel::Path next_path = target_path; + if (next_path.prev()) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + _dnd_top = true; + // Drop into the top level + _dnd_target = NULL; + } + } + } + if (!_dnd_top) { + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + _dnd_target = obj; + } + } + } + } + + if (_dnd_source != _dnd_target) { + + Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; + Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); + + if (target_ref != our_ref) { + if (!target_ref) { + target_ref = SwatchDocument->getDefs()->getRepr(); + if (target_ref != our_ref->parent()) { + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else { + our_ref->parent()->changeOrder(our_ref, NULL); + } + } else if (_dnd_into) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } + } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } - return tmp; + return true; } -void SwatchesPanel::_updateFromSelection() +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time) { - SwatchPage *docPalette = (docPalettes.find(_currentDocument) != docPalettes.end()) ? docPalettes[_currentDocument] : 0; - if ( docPalette ) { - Glib::ustring fillId; - Glib::ustring strokeId; - - SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); - int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); - switch (result) { - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - { - if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { - SPPaintServer* server = tmpStyle->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* target = 0; - SPGradient* grad = SP_GRADIENT(server); - - if ( grad->isSwatch() ) { - target = grad; - } else if ( grad->ref ) { - SPGradient *tmp = grad->ref->getObject(); - if ( tmp && tmp->isSwatch() ) { - target = tmp; - } - } - if ( target ) { - //XML Tree being used directly here while it shouldn't be - gchar const* id = target->getRepr()->attribute("id"); - if ( id ) { - fillId = id; - } - } - } + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + bool _dnd_top = false; + _dnd_into = false; + _dnd_target = _currentDocument->getDefs()->lastChild(); + Gtk::TreeModel::iterator itersel = _editDoc.get_selection()->get_selected(); + if (!itersel) { + return true; + } + Gtk::TreeModel::Row rowsel = *itersel; + _dnd_source = rowsel[_modelDoc->_colObject]; + + if (!_dnd_source) { + return true; + } + + if (_editDoc.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _editDoc.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y < (int)(cell_height * 1/3)) { + Gtk::TreeModel::Path next_path = target_path; + if (next_path.prev()) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_storeDoc->iter_is_valid(_storeDoc->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + _dnd_top = true; + // Drop into the top level + _dnd_target = NULL; } - break; } } - - result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); - switch (result) { - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - { - if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { - SPPaintServer* server = tmpStyle->getStrokePaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* target = 0; - SPGradient* grad = SP_GRADIENT(server); - if ( grad->isSwatch() ) { - target = grad; - } else if ( grad->ref ) { - SPGradient *tmp = grad->ref->getObject(); - if ( tmp && tmp->isSwatch() ) { - target = tmp; - } - } - if ( target ) { - //XML Tree being used directly here while it shouldn't be - gchar const* id = target->getRepr()->attribute("id"); - if ( id ) { - strokeId = id; - } + if (!_dnd_top) { + Gtk::TreeModel::iterator iter = _storeDoc->get_iter(target_path); + if (_storeDoc->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_modelDoc->_colObject]; + if (obj) { + _dnd_target = obj; + if (SP_IS_GRADIENT(obj)) { + _dnd_into = false; + if (SP_IS_GROUP(_dnd_source)) { + _dnd_target = obj->parent; } + } else if (SP_IS_GROUP(_dnd_source)) { + _dnd_into = false; } } - break; } } - sp_style_unref(tmpStyle); - - for ( boost::ptr_vector::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { - ColorItem* item = &*it; - bool isFill = (fillId == item->def.descr); - bool isStroke = (strokeId == item->def.descr); - item->setState( isFill, isStroke ); + } + + if (_dnd_source != _dnd_target) { + + Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; + Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); + + if (target_ref != our_ref) { + if (!target_ref) { + target_ref = _currentDocument->getDefs()->getRepr(); + if (target_ref != our_ref->parent()) { + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else { + our_ref->parent()->changeOrder(our_ref, NULL); + } + } else if (_dnd_into) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } } + DocumentUndo::done( _currentDocument , SP_VERB_DIALOG_SWATCHES, + _("Moved Swatches")); } + + return true; } -void SwatchesPanel::_handleAction( int setId, int itemId ) + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : + Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), + _scroller(), + _insideTable(1, 2), + _insideV(), + _insideH(), + _buttonsRow(), + _outsideV(), + _noLink(_("Don't Link")), + _showlabels(showLabels), + _store(0), + _scrollerBI(), + _editBI(), + _buttonsRowBI(), + _editBIV(), + _storeDoc(0), + _scrollerDoc(), + _editDoc(), + _buttonsRowDoc(), + _editDocV(), + _notebook(), + rootWatcher(0), + docWatcher(0), + _currentDesktop(0), + _currentDocument(0) { - switch( setId ) { - case 3: + _insideH.pack_start(_insideTable, Gtk::PACK_SHRINK); + if (_showlabels) { + _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); + _scroller.add(_insideV); + } else { + _scroller.property_height_request() = 45; + _scroller.add(_insideH); + } + + popUpMenu = manage( new Gtk::Menu() ); + popUpMenu->show_all_children(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Add Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked) ); + _buttonsRow.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button() ); +// _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_DISCONNECT, C_("Unlink", "New") ); +// _buttonsRow.pack_end(*btn, Gtk::PACK_SHRINK); + + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring nolink = Glib::ustring::compose("%1/nolink", prefsPath); + _noLink.set_tooltip_text(_("Don't link swatches")); + _noLink.set_active(prefs->getBool(nolink, false)); + _noLink.signal_toggled().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NoLinkToggled)); + _buttonsRow.pack_end(_noLink, Gtk::PACK_SHRINK); + + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_NONE); + + if (_showlabels) { + _outsideV.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + _outsideV.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); + + _notebook.append_page(_outsideV, "Use"); + + { + ModelColumnsDoc *zoop = new ModelColumnsDoc(); + _modelDoc = zoop; + + _storeDoc = Gtk::TreeStore::create( *zoop ); + + _editDoc.set_model( _storeDoc ); + _editDoc.set_headers_visible(false); + _editDoc.set_reorderable(true); + _editDoc.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked)); + _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClickedDoc))); + _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + + _pixbuf_rendererDoc = manage(new Gtk::CellRendererPixbuf()); + int pixbufColNum = _editDoc.append_column("Pixbuf", *_pixbuf_rendererDoc) - 1; + _pixbuf_columnDoc = _editDoc.get_column(pixbufColNum); + _pixbuf_columnDoc->add_attribute(_pixbuf_rendererDoc->property_pixbuf(), _modelDoc->_colPixbuf); + + _text_rendererDoc = manage(new Gtk::CellRendererText()); + int nameColNum = _editDoc.append_column("Name", *_text_rendererDoc) - 1; + _name_columnDoc = _editDoc.get_column(nameColNum); + _name_columnDoc->add_attribute(_text_rendererDoc->property_text(), _modelDoc->_colLabel); + + _text_rendererDoc->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditedDoc) ); + _text_rendererDoc->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelledDoc) ); + + _editDoc.set_expander_column( *_editDoc.get_column(nameColNum) ); + + _editDoc.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); + _editDoc.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); + _editDoc.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEventDoc), false ); + + _editDoc.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDropDoc), false); + + _scrollerDoc.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scrollerDoc.set_shadow_type(Gtk::SHADOW_IN); + _scrollerDoc.add(_editDoc); + + _editDocV.pack_start(_scrollerDoc, Gtk::PACK_EXPAND_WIDGET); + _editDocV.pack_end(_buttonsRowDoc, Gtk::PACK_SHRINK); + + _notebook.append_page(_editDocV, "Edit"); + } + { - _setSelectedIndex(itemId); + popUpImportMenu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("New Swatch Group..."))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroupBI)); + mi->show(); + popUpImportMenu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Import Swatch File..."))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), false, true)); + mi->show(); + popUpImportMenu->append(*mi); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _editBI.set_model( _store ); + _editBI.set_headers_visible(false); + _editBI.set_reorderable(true); + _editBI.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); + btn->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::_addBIButtonClicked)); + _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClicked))); + _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); + + _text_rendererBI = manage(new Gtk::CellRendererText()); + int nameColNum = _editBI.append_column("Name", *_text_rendererBI) - 1; + _name_columnBI = _editBI.get_column(nameColNum); + _name_columnBI->add_attribute(_text_rendererBI->property_text(), _model->_colLabel); + + _text_rendererBI->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEdited) ); + _text_rendererBI->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelled) ); + + _editBI.set_expander_column( *_editBI.get_column(nameColNum) ); + + _editBI.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); + _editBI.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); + _editBI.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEvent), false ); + + _editBI.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDrop), false); + _editBI.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), false)); + _editBI.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), true)); + + _scrollerBI.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scrollerBI.set_shadow_type(Gtk::SHADOW_IN); + _scrollerBI.add(_editBI); + + _editBIV.pack_start(_scrollerBI, Gtk::PACK_EXPAND_WIDGET); + _editBIV.pack_end(_buttonsRowBI, Gtk::PACK_SHRINK); + + _notebook.append_page(_editBIV, "Edit Built-In"); } - break; + + _getContents()->pack_end(_notebook, Gtk::PACK_EXPAND_WIDGET); + } else { + //_outsideV.pack_end(_scroller, Gtk::PACK_SHRINK); + _buttonsRow.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); + //_getContents()->pack_end(_outsideV, Gtk::PACK_SHRINK); + _getContents()->pack_end(_buttonsRow, Gtk::PACK_SHRINK); } + + loadPalletFile(); + + rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); + SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); + _swatchesChanged(); } -void SwatchesPanel::_setSelectedIndex( int index ) +SwatchesPanel::~SwatchesPanel() { - std::vector pages = _getSwatchSets(); - if ( index >= 0 && index < static_cast(pages.size()) ) { - _currentIndex = index; + if (rootWatcher) { + rootWatcher->_repr->removeObserver(*rootWatcher); + delete rootWatcher; + } + + if (docWatcher) { + docWatcher->_repr->removeObserver(*docWatcher); + delete docWatcher; + } + + _documentConnection.disconnect(); + _selChanged.disconnect(); +} - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); +void SwatchesPanel::setDesktop( SPDesktop* desktop ) +{ + Inkscape::UI::Widget::Panel::setDesktop(desktop); + if ( desktop != _currentDesktop ) { + if ( _currentDesktop ) { + _documentConnection.disconnect(); + _selChanged.disconnect(); } - _rebuild(); + _currentDesktop = desktop; + + if ( desktop ) { + //_currentDesktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + _documentConnection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &SwatchesPanel::_setDocument)); + + _setDocument( desktop, desktop->doc() ); + } else { + _setDocument(0, 0); + } } } -void SwatchesPanel::_rebuild() +void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) { - std::vector pages = _getSwatchSets(); - if (_currentIndex < static_cast(pages.size())) { - SwatchPage* curr = pages[_currentIndex]; - _holder->clear(); - - if ( curr->_prefWidth > 0 ) { - _holder->setColumnPref( curr->_prefWidth ); + if ( document != _currentDocument ) { + if (docWatcher) { + docWatcher->_repr->removeObserver(*docWatcher); + delete docWatcher; + docWatcher = NULL; } - _holder->freezeUpdates(); - // TODO restore once 'clear' works _holder->addPreview(_clear); - _holder->addPreview(_remove); - for ( boost::ptr_vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { - _holder->addPreview(&*it); + _currentDocument = document; + + if (_currentDocument) { + docWatcher = new SwatchWatcher(this, _currentDocument->getDefs(), false); + _currentDocument->getDefs()->getRepr()->addObserver(*docWatcher); } - _holder->thawUpdates(); + _defsChanged(); } } @@ -1241,6 +2323,48 @@ void SwatchesPanel::_rebuild() } //namespace UI } //namespace Inkscape +//should be okay to add this here +guint get_group0_keyval(GdkEventKey *event) { + guint keyval = 0; + gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( + gdk_display_get_default()), event->hardware_keycode, + (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, + NULL, NULL, NULL); + return keyval; +} + +void +sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +{ + + bool intercepted = false; + + if (gradient->isSolid()) { + ColorRGBA color(gradient->getFirstStop()->getEffectiveColor().toRGBA32(gradient->getFirstStop()->opacity)); + guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); + gchar b[64]; + sp_svg_write_color(b, sizeof(b), rgba); + SPCSSAttr *css = sp_repr_css_attr_new(); + if (fill) { + sp_repr_css_set_property(css, "fill", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); + } else { + sp_repr_css_set_property(css, "stroke", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); + } + intercepted = desktop->_set_style_signal.emit(css); + } + + if (!intercepted) { + for (const GSList *it = desktop->selection->itemList(); it != NULL; it = it->next) { + sp_item_set_gradient(SP_ITEM(it->data), gradient, SP_IS_RADIALGRADIENT(gradient) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, !fill ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); + } + } +} /* Local Variables: diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index 3abb81d98..cb8f87962 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -12,66 +12,161 @@ #include "ui/widget/panel.h" #include "enums.h" +#include "sp-object.h" +#include "sp-item-group.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sp-gradient.h" +#include "xml/node-observer.h" namespace Inkscape { namespace UI { -class PreviewHolder; - namespace Dialogs { -class ColorItem; -class SwatchPage; -class DocTrack; - /** * A panel that displays paint swatches. */ class SwatchesPanel : public Inkscape::UI::Widget::Panel { public: - SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches"); + SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches", bool showLabels = true); virtual ~SwatchesPanel(); - + static SwatchesPanel& getInstance(); - virtual void setOrientation(SPAnchorType how); - virtual void setDesktop( SPDesktop* desktop ); virtual SPDesktop* getDesktop() {return _currentDesktop;} - virtual int getSelectedIndex() {return _currentIndex;} // temporary - protected: - static void handleDocumentDestroy(SPDocument *document); - static void handleGradientsChange(SPDocument *document); - - virtual void _updateFromSelection(); - virtual void _handleAction( int setId, int itemId ); - virtual void _setDocument( SPDocument *document ); - virtual void _setSelectedIndex( int index ); - virtual void _rebuild(); - virtual std::vector _getSwatchSets() const; + virtual void _setDocument( SPDesktop* desktop, SPDocument *document ); private: + class ModelColumns; + class ModelColumnsDoc; + + class StopWatcher; + class GradientWatcher; + class SwatchWatcher; + SwatchesPanel(SwatchesPanel const &); // no copy SwatchesPanel &operator=(SwatchesPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ); + + void _setSelectionSwatch(SPGradient* swatchItem, bool isStroke); + + void NoLinkToggled(); + void NewGroup(); + void NewGroupBI(); + void _addBIButtonClicked(GdkEventButton* event); + void Duplicate(SPGroup* page); + void SaveAs(); + void AddSelectedFill(SPGroup* page); + void AddSelectedStroke(SPGroup* page); + void MoveUp(SPGroup* page); + void MoveDown(SPGroup* page); + void Remove(SPGroup* page); + + void SetSelectedFill(SPGradient* swatch); + void SetSelectedStroke(SPGradient* swatch); + void MoveSwatchUp(SPGradient* swatch); + void MoveSwatchDown(SPGradient* swatch); + void RemoveSwatch(SPGradient* swatch); + + void _lblClick(GdkEventButton* event, SPGroup* page); + void _addSwatchButtonClicked(SPGroup* swatch, bool recurse); + void _defsChanged(); + void _importButtonClicked(bool addToDoc, bool addToBI); + void _deleteButtonClicked(); + void _addButtonClicked(GdkEventButton* event); + void _swatchClicked(GdkEventButton* event, SPGradient* swatchItem); + + Gtk::MenuItem* _addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow); + void _swatchesChanged(); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _setCollapsed(SPGroup * group); + void _setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded); + + void _deleteButtonClickedDoc(); + bool _handleButtonEventDoc(GdkEventButton* event); + bool _handleKeyEventDoc(GdkEventKey *event); + + void _handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelledDoc(); + void _renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name); + + bool _handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + + Gtk::Menu *popUpMenu; + Gtk::Menu *popUpImportMenu; + + Gtk::ScrolledWindow _scroller; + Gtk::Table _insideTable; + Gtk::VBox _insideV; + Gtk::HBox _insideH; + Gtk::HBox _buttonsRow; + Gtk::VBox _outsideV; + Gtk::CheckButton _noLink; + bool _showlabels; + + SwatchesPanel::ModelColumns* _model; + Glib::RefPtr _store; + + Gtk::CellRendererText *_text_rendererBI; + Gtk::TreeView::Column *_name_columnBI; + Gtk::ScrolledWindow _scrollerBI; + Gtk::TreeView _editBI; + Gtk::HBox _buttonsRowBI; + Gtk::VBox _editBIV; + + SwatchesPanel::ModelColumnsDoc* _modelDoc; + Glib::RefPtr _storeDoc; + + Gtk::CellRendererText *_text_rendererDoc; + Gtk::CellRendererPixbuf *_pixbuf_rendererDoc; + Gtk::TreeView::Column *_name_columnDoc; + Gtk::TreeView::Column *_pixbuf_columnDoc; + Gtk::ScrolledWindow _scrollerDoc; + Gtk::TreeView _editDoc; + Gtk::HBox _buttonsRowDoc; + Gtk::VBox _editDocV; + + Gtk::Notebook _notebook; + + SwatchWatcher* rootWatcher; + std::vector rootWatchers; + + std::vector docWatchers; + SwatchWatcher* docWatcher; - static void _trackDocument( SwatchesPanel *panel, SPDocument *document ); - static void handleDefsModified(SPDocument *document); - - PreviewHolder* _holder; - ColorItem* _clear; - ColorItem* _remove; - int _currentIndex; SPDesktop* _currentDesktop; SPDocument* _currentDocument; + + bool _dnd_into; + SPObject* _dnd_source; + SPObject* _dnd_target; sigc::connection _documentConnection; sigc::connection _selChanged; - - friend class DocTrack; }; } //namespace Dialogs -- cgit v1.2.3 From 3093434e177d4bb7ccc57c1339fad00d47431c17 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 21:24:03 -0500 Subject: Added a few swatch related functions (does not compile) (bzr r13090.1.15) --- src/ui/dialog/swatches.cpp | 2 +- src/ui/widget/addtoicon.cpp | 149 ++++++++++++++++++++++++++++++++++++++++++++ src/ui/widget/addtoicon.h | 98 +++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 src/ui/widget/addtoicon.cpp create mode 100644 src/ui/widget/addtoicon.h (limited to 'src/ui') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index a0c79b8ac..2956c6d17 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -68,7 +68,7 @@ #include "sp-radial-gradient.h" #include "color-rgba.h" #include "svg/css-ostringstream.h" -//#include "event-context.h" //no longer exists +#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include diff --git a/src/ui/widget/addtoicon.cpp b/src/ui/widget/addtoicon.cpp new file mode 100644 index 000000000..3d6091f70 --- /dev/null +++ b/src/ui/widget/addtoicon.cpp @@ -0,0 +1,149 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/addtoicon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" +#include "addtoicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +AddToIcon::AddToIcon() : + Glib::ObjectBase(typeid(AddToIcon)), + Gtk::CellRendererPixbuf(), +// _pixAddName(INKSCAPE_ICON("layer-new")), + _property_active(*this, "active", false) +// _property_pixbuf_add(*this, "pixbuf_on", Glib::RefPtr(0)) +{ + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_BUTTON); +// Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); +// +// if (!icon_theme->has_icon(_pixAddName)) { +// Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixAddName.data()), Inkscape::ICON_SIZE_DECORATION ); +// } +// if (icon_theme->has_icon(_pixAddName)) { +// _property_pixbuf_add = icon_theme->load_icon(_pixAddName, phys, (Gtk::IconLookupFlags)0); +// } +// +// _property_pixbuf_add = Gtk::Widget:: + + property_stock_id() = GTK_STOCK_ADD; +} + + +#if WITH_GTKMM_3_0 +void AddToIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void AddToIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void AddToIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = phys;//+= (*width) >> 1; + } + if ( height ) { + *height =phys;//+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void AddToIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void AddToIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + property_stock_id() = property_active().get_value() ? GTK_STOCK_ADD : GTK_STOCK_DELETE; + +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +AddToIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // 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:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/addtoicon.h b/src/ui/widget/addtoicon.h new file mode 100644 index 000000000..aa8b4148e --- /dev/null +++ b/src/ui/widget/addtoicon.h @@ -0,0 +1,98 @@ +#ifndef __UI_DIALOG_ADDTOICON_H__ +#define __UI_DIALOG_ADDTOICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class AddToIcon : public Gtk::CellRendererPixbuf { +public: + AddToIcon(); + virtual ~AddToIcon() {}; + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + int phys; + +// Glib::ustring _pixAddName; + + Glib::Property _property_active; +// Glib::Property< Glib::RefPtr > _property_pixbuf_add; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + 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 From 9ae7e81723f4ea4e2640ed01d55d94e73874804f Mon Sep 17 00:00:00 2001 From: Guiu Rocafort Date: Wed, 5 Mar 2014 12:37:27 +0100 Subject: translations from spanish to english done, it might need a little review, but everything seems ok (bzr r11950.5.1) --- src/ui/tool/curve-drag-point.cpp | 5 ++- src/ui/tool/multi-path-manipulator.cpp | 5 ++- src/ui/tool/node.cpp | 64 ++++++++++++++++---------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 14 +++---- src/ui/tools/freehand-base.cpp | 23 ++++++------ src/ui/tools/node-tool.h | 3 +- src/ui/tools/pen-tool.cpp | 67 ++++++++++++++++------------------ src/ui/tools/pen-tool.h | 26 ++++++------- src/ui/tools/pencil-tool.cpp | 4 +- 10 files changed, 106 insertions(+), 107 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index e5412fdc2..ad03cf75d 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,7 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - //spanish: solo actualizamos los nodos si no es bspline + // only update the nodes if the mode is bspline if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -89,7 +89,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT + + //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index b7f3ac29b..68aaa77a5 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,9 +671,10 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: si es trazado bspline (mode 2) + + //if the trace is bspline ( mode 2) if(mode==2){ - //spanish: ¿correcto? + // is this correct ? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 78d8fe833..73460a313 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -184,7 +184,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -210,7 +210,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + // moves the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -292,7 +292,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo + // new double click event to set the handlers of a node to the default proportion, 0.3334% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -303,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 +//this function moves the handler and its oposite to the default proportion of 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -359,8 +359,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el - //parametro "steps whith control" del efecto en vivo BSpline + // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" + // by default in live BSpline if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -370,7 +370,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - //spanish: si está activado el ajuste (snap) y no es bspline + //if the snap adjustment is activated and it is not bspline if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -411,8 +411,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - //spanish: si es bspline pero no está presionado SHIFT o CONTROL - //lo fija en la posición original + //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -432,7 +431,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //spanish: marca la fuerza del bspline como 0.0000 + //sets the bspline strength to 0.0000 if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } @@ -478,9 +477,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - //spanish: un truco para, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + // a trick to mark as bspline if the node has no strength, we are going to use it later + // to show the appropiate messages. We cannot do it in any different way becasue the function is constant + bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -622,8 +621,8 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + + // save the previous node strength to apply it again once the node is moved double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline(false)){ @@ -638,8 +637,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the affected handlers. First the node ones, later the adjoining ones. if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -649,8 +648,7 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + // save the previous node strength to apply it again later when the node is moved double oldPos = 0.0000; if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; @@ -663,8 +661,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the involved handlers, first the node ones, later the adjoining ones if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -755,9 +753,11 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. - //Cada vez que actuemos sobre dichos tiradores en un trazado - //bspline esta fuerza se tiene que actualizar + + // define the node strength, depending on being or not bspline traced. + // every time we operate over these handlers in a trace bspline + // that strength needs to be updated. + this->bsplineWeight = 0.0000; if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { @@ -868,9 +868,8 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - //spanish: en los cambios de tipo de nodo, sobre trazados bspline, - //o bien los mantenemos con potencia 0.0000 en modo esquina - //o les damos la potencia por defecto en modo de curva + /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, + or we give them the default power in curve mode */ if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1123,7 +1122,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //spanish: esto muestra los tiradores al seleccionar los nodos + //this shows the handlers when selecting the nodes if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); @@ -1389,9 +1388,10 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - //spanish: un truco par, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + + /* if the node doesnt have strength, it marks it as bspline, we'll use it later + to show the appropiate messages. We cannot do it in any other way, because the + function is constant */ bool isBSpline = false; if( this->bsplineWeight != 0.0000) isBSpline = true; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index b7d6951d0..4393446d9 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,7 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //spanish: creamos valor de potencia bspline asociado a cada nodo + //strength value for each node double bsplineWeight; /** diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index a6689d93d..1cc075603 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -663,7 +663,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - //spanish: si se borra, reajustamos los tiradores + // if we are removing, we readjust the handlers if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ @@ -1182,7 +1182,7 @@ void PathManipulator::_createControlPointsFromGeometry() } } -//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza +//determines if the trace has a bspline effect and the number of steps that it takes int PathManipulator::BSplineGetSteps(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1200,7 +1200,7 @@ int PathManipulator::BSplineGetSteps(){ return steps; } -//spanish: determina si el trazado tiene efecto bspline +// determines if the trace has bspline effect bool PathManipulator::isBSpline(bool recalculate){ static int BSplineSteps = this->BSplineGetSteps(); if(recalculate){ @@ -1213,7 +1213,7 @@ bool PathManipulator::isBSpline(bool recalculate){ return isBSpline; } -//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador +// returns the corresponding strength to the position of a handler double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1231,13 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } -//spanish: mueve el tirador a la posición que le corresponda +// moves the handler to the corresponding position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } -//spanish: mueve el tirador a una posición específica +// moves the handler to the specified position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1263,7 +1263,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } -//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos +//moves the node handlers and its oposite handlers to the strength of its nodes void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index cb6111bd5..40a257de9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -252,7 +252,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //spanish: añadimos el modo bspline a los efectos en espera + //add the bspline node in the waiting effects if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -496,9 +496,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente - //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada - //porque la modificamos al continuar por un anchor + /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. + if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because + we modify it when continuing through an anchor. */ if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -527,8 +527,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor - //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes + + /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. + this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and + close incorrectly one of the parts */ if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { @@ -547,8 +549,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); } - //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white - //pasándole la curva de inicio necesaria + + //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); @@ -679,9 +681,8 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. - //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en - //la que cerramos el trazado. + /* modify the anchoring curve so it is equal to the starting curve. + this curve is modified when it's modified and we need them to be equal to the closing curve */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 168ec995a..42f89cd1c 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,7 +14,8 @@ #include #include #include "ui/tools/tool-base.h" -//spanish: lo necesitamos para llamarlo desde el Live Effect + +// we need it to call it from Live Effect #include "selection.h" namespace Inkscape { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 5846c3cec..bb1a03b7c 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//spanish: incluimos los archivos necesarios para las BSpline y Spiro +// we include the necessary files for BSpline & Spiro #include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -166,7 +166,7 @@ PenTool::~PenTool() { void PenTool::setPolylineMode() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: cambiamos los modos para dar cabida al modo bspline + // change the nodes to make space for bspline mode this->polylines_only = (mode == 3 || mode == 4); this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -178,7 +178,7 @@ void PenTool::setPolylineMode() { *.Set the mode of draw spiro, and bsplines */ void PenTool::_pen_context_set_mode(guint mode) { - //spanish: definimos los modos + // define the nodes this->spiro = (mode == 1); this->bspline = (mode == 2); } @@ -386,7 +386,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ - //spanish Borrar siguiente linea para evitar un nodo encima de otro + //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); _finish( FALSE); return TRUE; @@ -512,7 +512,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { } } - //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar + // avoid the creation of a control point so a node is created in the release event this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -705,7 +705,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { default: break; } - //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. + // calls the function "bspline_spiro_motion" when the mouse starts or stops moving if(this->bspline){ this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); @@ -743,9 +743,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(this, event_w); - //with this we avoid creating a new point over the existing one - //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. - + // if we try to create a node in the same place as another node, we skip if((!anchor || anchor == this->sa) && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ return TRUE; } @@ -760,7 +758,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { p = anchor->dp; } this->sa = anchor; - //spanish: continuamos una curva existente + // continue the existing curve if (anchor) { if(this->bspline || this->spiro){ this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; @@ -790,7 +788,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { this->_endpointSnap(p, revent.state); } this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hude the guide of the penultimate node when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -817,7 +815,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::CLOSE: this->_endpointSnap(p, revent.state); this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hide the penultimate node guide when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -908,7 +906,7 @@ void PenTool::_redrawAll() { sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); // handles - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if (this->p[0] != this->p[1] && !this->spiro && !this->bspline) { SP_CTRL(this->c1)->moveto(this->p[1]); this->cl1->setCoords(this->p[0], this->p[1]); @@ -922,7 +920,7 @@ void PenTool::_redrawAll() { Geom::Curve const * last_seg = this->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if ( cubic && (*cubic)[2] != this->p[0] && !this->spiro && !this->bspline ) { @@ -937,9 +935,8 @@ void PenTool::_redrawAll() { } } - //spanish: simplemente redibujamos la spiro. - //como es un redibujo simplemente no llamamos a la función global sino al final de esta - //Lanzamos solamente el redibujado + // simply redraw the spiro. because its a redrawing, we don't call the global function, + // but we call the redrawing at the ending. this->_bspline_spiro_build(); } @@ -969,12 +966,12 @@ void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) { } void PenTool::_lastpointToCurve() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. if (this->npoints != 5 && !this->spiro && !this->bspline) return; Geom::CubicBezier const * cubic; this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //modificate the last segment of the green curve so it creates the type of node we need if(this->spiro||this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1012,7 +1009,7 @@ void PenTool::_lastpointToCurve() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + //if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(false); } @@ -1023,11 +1020,11 @@ void PenTool::_lastpointToCurve() { void PenTool::_lastpointToLine() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect) it doesn't stop here. if (this->npoints != 5 && !this->bspline) return; - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + // modify the last segment of the green curve so the type of node we want is created. if(this->spiro || this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1059,7 +1056,7 @@ void PenTool::_lastpointToLine() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + // if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(true); } @@ -1248,7 +1245,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0]; } - //spanish: asignamos el valor a un tercio de distancia del último segmento. + // asign the value in a third of the distance of the last segment. if(this->bspline){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } @@ -1258,7 +1255,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { : this->p[3])); this->npoints = 2; - //spanish: eliminamos el último segmento de la curva verde + // delete the last segment of the green curve if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { @@ -1270,7 +1267,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { }else{ this->green_curve->backspace(); } - //spanish: asignamos el valor de this->p[1] a el opuesto de el ultimo segmento de la línea verde + // assign the value of this->p[1] to the oposite of the green line last segment if(this->spiro){ cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { @@ -1285,7 +1282,8 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->state = PenTool::POINT; this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //spanish: redibujamos + + //redraw this->_bspline_spiro_build(); ret = TRUE; } @@ -1360,9 +1358,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t g_string_free(dist, FALSE); } - - -//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +// this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; @@ -1736,8 +1732,7 @@ void PenTool::_bspline_spiro_end_anchor_off() } } - -//spanish: preparates the curves for its trasformation into BSline curves. +//prepares the curves for its transformation into BSpline curve. void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) @@ -1766,7 +1761,7 @@ void PenTool::_bspline_spiro_build() } if(!curve->is_empty()){ - //spanish: cerramos la curva si estan cerca los puntos finales de la curva + // close the curve if the final points of the curve are close enough if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1805,7 +1800,7 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { - //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp + // commenting the function doEffect in src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -1945,7 +1940,7 @@ void PenTool::_bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp -//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp +// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; @@ -2178,7 +2173,7 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - //spanish para cancelar linea sin un segmento creado + // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); this->sa = NULL; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 88e528b22..95565abc9 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -49,7 +49,7 @@ public: bool polylines_only; bool polylines_paraxial; - //spanish: propiedad que guarda si el modo Spiro está activo o no + // propiety which saves if Spiro mode is active or not bool spiro; bool bspline; int num_clicks; @@ -88,29 +88,29 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - //spanish: añade los modos spiro y bspline + //adds spiro & bspline modes void _pen_context_set_mode(guint mode); - //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro + //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro void _bspline_spiro_color(); - //spanish: crea un nodo en modo bspline o spiro + //creates a node in bspline or spiro modes void _bspline_spiro(bool shift); - //spanish: crea un nodo de modo spiro o bspline + //creates a node in bspline or spiro modes void _bspline_spiro_on(); - //spanish: crea un nodo de tipo CUSP + //creates a CUSP node void _bspline_spiro_off(); - //spanish: continua una curva existente en modo bspline o spiro + //continues the existing curve in bspline or spiro mode void _bspline_spiro_start_anchor(bool shift); - //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro + //continues the existing curve with the union node in bspline or spiro modes void _bspline_spiro_start_anchor_on(); - //spanish: continua una curva existente con el nodo de union en modo CUSP + //continues an existing curve with the union node in CUSP mode void _bspline_spiro_start_anchor_off(); - //spanish: modifica la "red_curve" cuando se detecta movimiento + //modifies the "red_curve" when it detects movement void _bspline_spiro_motion(bool shift); - //spanish: cierra la curva con el último nodo en modo bspline o spiro + //closes the curve with the last node in bspline or spiro mode void _bspline_spiro_end_anchor_on(); - //spanish: cierra la curva con el último nodo en modo CUSP + //closes the curve with the last node in CUSP mode void _bspline_spiro_end_anchor_off(); - //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. + //CHECK: join all the curves "in game" and we call doEffect function void _bspline_spiro_build(); //function bspline cloned from lpe-bspline.cpp void _bspline_doEffect(SPCurve * curve); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index bd50672af..1ccdee637 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -685,7 +685,7 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -835,7 +835,7 @@ void PencilTool::_fitAndSplit() { this->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From a9eea1cea2a13f129bcb30f175cea82ffcbcee29 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Mar 2014 20:03:46 +0100 Subject: Translations (bzr r11950.1.279) --- src/ui/tool/curve-drag-point.cpp | 5 +-- src/ui/tool/multi-path-manipulator.cpp | 5 +-- src/ui/tool/node.cpp | 64 ++++++++++++++++---------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 14 +++---- src/ui/tools/freehand-base.cpp | 23 ++++++------ src/ui/tools/node-tool.h | 3 +- src/ui/tools/pen-tool.cpp | 67 ++++++++++++++++++---------------- src/ui/tools/pen-tool.h | 26 ++++++------- src/ui/tools/pencil-tool.cpp | 4 +- 10 files changed, 107 insertions(+), 106 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index ad03cf75d..e5412fdc2 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,7 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - // only update the nodes if the mode is bspline + //spanish: solo actualizamos los nodos si no es bspline if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -89,8 +89,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - - //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed + //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 68aaa77a5..b7f3ac29b 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,10 +671,9 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - - //if the trace is bspline ( mode 2) + //spanish: si es trazado bspline (mode 2) if(mode==2){ - // is this correct ? + //spanish: ¿correcto? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 73460a313..78d8fe833 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //move the handler and its oposite the same proportion + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -184,7 +184,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //move the handler and its oposite the same proportion + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -210,7 +210,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - // moves the handler and its oposite the same proportion + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -292,7 +292,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - // new double click event to set the handlers of a node to the default proportion, 0.3334% + //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -303,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//this function moves the handler and its oposite to the default proportion of 0.3334 +//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -359,8 +359,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" - // by default in live BSpline + //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el + //parametro "steps whith control" del efecto en vivo BSpline if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -370,7 +370,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - //if the snap adjustment is activated and it is not bspline + //spanish: si está activado el ajuste (snap) y no es bspline if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -411,7 +411,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position + //spanish: si es bspline pero no está presionado SHIFT o CONTROL + //lo fija en la posición original if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -431,7 +432,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //sets the bspline strength to 0.0000 + //spanish: marca la fuerza del bspline como 0.0000 if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } @@ -477,9 +478,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - // a trick to mark as bspline if the node has no strength, we are going to use it later - // to show the appropiate messages. We cannot do it in any different way becasue the function is constant - + //spanish: un truco para, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -621,8 +622,8 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - - // save the previous node strength to apply it again once the node is moved + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline(false)){ @@ -637,8 +638,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - - // move the affected handlers. First the node ones, later the adjoining ones. + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -648,7 +649,8 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { - // save the previous node strength to apply it again later when the node is moved + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; @@ -661,8 +663,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - - // move the involved handlers, first the node ones, later the adjoining ones + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -753,11 +755,9 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - - // define the node strength, depending on being or not bspline traced. - // every time we operate over these handlers in a trace bspline - // that strength needs to be updated. - + //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. + //Cada vez que actuemos sobre dichos tiradores en un trazado + //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { @@ -868,8 +868,9 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, - or we give them the default power in curve mode */ + //spanish: en los cambios de tipo de nodo, sobre trazados bspline, + //o bien los mantenemos con potencia 0.0000 en modo esquina + //o les damos la potencia por defecto en modo de curva if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1122,7 +1123,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //this shows the handlers when selecting the nodes + //spanish: esto muestra los tiradores al seleccionar los nodos if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); @@ -1388,10 +1389,9 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - - /* if the node doesnt have strength, it marks it as bspline, we'll use it later - to show the appropiate messages. We cannot do it in any other way, because the - function is constant */ + //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; if( this->bsplineWeight != 0.0000) isBSpline = true; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 4393446d9..b7d6951d0 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,7 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //strength value for each node + //spanish: creamos valor de potencia bspline asociado a cada nodo double bsplineWeight; /** diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1cc075603..a6689d93d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -663,7 +663,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - // if we are removing, we readjust the handlers + //spanish: si se borra, reajustamos los tiradores if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ @@ -1182,7 +1182,7 @@ void PathManipulator::_createControlPointsFromGeometry() } } -//determines if the trace has a bspline effect and the number of steps that it takes +//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza int PathManipulator::BSplineGetSteps(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1200,7 +1200,7 @@ int PathManipulator::BSplineGetSteps(){ return steps; } -// determines if the trace has bspline effect +//spanish: determina si el trazado tiene efecto bspline bool PathManipulator::isBSpline(bool recalculate){ static int BSplineSteps = this->BSplineGetSteps(); if(recalculate){ @@ -1213,7 +1213,7 @@ bool PathManipulator::isBSpline(bool recalculate){ return isBSpline; } -// returns the corresponding strength to the position of a handler +//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1231,13 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } -// moves the handler to the corresponding position +//spanish: mueve el tirador a la posición que le corresponda Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } -// moves the handler to the specified position +//spanish: mueve el tirador a una posición específica Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1263,7 +1263,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } -//moves the node handlers and its oposite handlers to the strength of its nodes +//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 40a257de9..cb6111bd5 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -252,7 +252,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //add the bspline node in the waiting effects + //spanish: añadimos el modo bspline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -496,9 +496,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. - if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because - we modify it when continuing through an anchor. */ + //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente + //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada + //porque la modificamos al continuar por un anchor if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -527,10 +527,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - - /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. - this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and - close incorrectly one of the parts */ + //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor + //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { @@ -549,8 +547,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); } - - //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. + //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white + //pasándole la curva de inicio necesaria if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); @@ -681,8 +679,9 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - /* modify the anchoring curve so it is equal to the starting curve. - this curve is modified when it's modified and we need them to be equal to the closing curve */ + //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. + //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en + //la que cerramos el trazado. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 42f89cd1c..168ec995a 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,8 +14,7 @@ #include #include #include "ui/tools/tool-base.h" - -// we need it to call it from Live Effect +//spanish: lo necesitamos para llamarlo desde el Live Effect #include "selection.h" namespace Inkscape { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index e3bbc72b1..ad77fcb53 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -// we include the necessary files for BSpline & Spiro +//spanish: incluimos los archivos necesarios para las BSpline y Spiro #include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -166,7 +166,7 @@ PenTool::~PenTool() { void PenTool::setPolylineMode() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - // change the nodes to make space for bspline mode + //spanish: cambiamos los modos para dar cabida al modo bspline this->polylines_only = (mode == 3 || mode == 4); this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -178,7 +178,7 @@ void PenTool::setPolylineMode() { *.Set the mode of draw spiro, and bsplines */ void PenTool::_pen_context_set_mode(guint mode) { - // define the nodes + //spanish: definimos los modos this->spiro = (mode == 1); this->bspline = (mode == 2); } @@ -386,7 +386,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ - //remove the following line to avoid having one node on top of another + //spanish Borrar siguiente linea para evitar un nodo encima de otro _finishSegment(event_dt, bevent.state); _finish( FALSE); return TRUE; @@ -512,7 +512,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { } } - // avoid the creation of a control point so a node is created in the release event + //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -705,7 +705,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { default: break; } - // calls the function "bspline_spiro_motion" when the mouse starts or stops moving + //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(this->bspline){ this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); @@ -743,7 +743,9 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(this, event_w); - // if we try to create a node in the same place as another node, we skip + //with this we avoid creating a new point over the existing one + //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. + if((!anchor || anchor == this->sa) && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ return TRUE; } @@ -758,7 +760,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { p = anchor->dp; } this->sa = anchor; - // continue the existing curve + //spanish: continuamos una curva existente if (anchor) { if(this->bspline || this->spiro){ this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; @@ -788,7 +790,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { this->_endpointSnap(p, revent.state); } this->_finishSegment(p, revent.state); - // hude the guide of the penultimate node when closing the curve + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -815,7 +817,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::CLOSE: this->_endpointSnap(p, revent.state); this->_finishSegment(p, revent.state); - // hide the penultimate node guide when closing the curve + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -906,7 +908,7 @@ void PenTool::_redrawAll() { sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); // handles - // hide the handlers in bspline and spiro modes + //spanish: ocultamos los tiradores en modo bspline y spiro if (this->p[0] != this->p[1] && !this->spiro && !this->bspline) { SP_CTRL(this->c1)->moveto(this->p[1]); this->cl1->setCoords(this->p[0], this->p[1]); @@ -920,7 +922,7 @@ void PenTool::_redrawAll() { Geom::Curve const * last_seg = this->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - // hide the handlers in bspline and spiro modes + //spanish: ocultamos los tiradores en modo bspline y spiro if ( cubic && (*cubic)[2] != this->p[0] && !this->spiro && !this->bspline ) { @@ -935,8 +937,9 @@ void PenTool::_redrawAll() { } } - // simply redraw the spiro. because its a redrawing, we don't call the global function, - // but we call the redrawing at the ending. + //spanish: simplemente redibujamos la spiro. + //como es un redibujo simplemente no llamamos a la función global sino al final de esta + //Lanzamos solamente el redibujado this->_bspline_spiro_build(); } @@ -966,12 +969,12 @@ void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) { } void PenTool::_lastpointToCurve() { - // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (this->npoints != 5 && !this->spiro && !this->bspline) return; Geom::CubicBezier const * cubic; this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); - //modificate the last segment of the green curve so it creates the type of node we need + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(this->spiro||this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1009,7 +1012,7 @@ void PenTool::_lastpointToCurve() { this->green_curve->append_continuous(previous, 0.0625); } } - //if the last node is an union with another curve + //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(false); } @@ -1020,11 +1023,11 @@ void PenTool::_lastpointToCurve() { void PenTool::_lastpointToLine() { - // avoid that if the "red_curve" contains only two points ( rect) it doesn't stop here. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (this->npoints != 5 && !this->bspline) return; - // modify the last segment of the green curve so the type of node we want is created. + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(this->spiro || this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1056,7 +1059,7 @@ void PenTool::_lastpointToLine() { this->green_curve->append_continuous(previous, 0.0625); } } - // if the last node is an union with another curve + //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(true); } @@ -1245,7 +1248,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0]; } - // asign the value in a third of the distance of the last segment. + //spanish: asignamos el valor a un tercio de distancia del último segmento. if(this->bspline){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } @@ -1255,7 +1258,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { : this->p[3])); this->npoints = 2; - // delete the last segment of the green curve + //spanish: eliminamos el último segmento de la curva verde if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { @@ -1267,7 +1270,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { }else{ this->green_curve->backspace(); } - // assign the value of this->p[1] to the oposite of the green line last segment + //spanish: asignamos el valor de this->p[1] a el opuesto de el ultimo segmento de la línea verde if(this->spiro){ cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { @@ -1282,8 +1285,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->state = PenTool::POINT; this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - - //redraw + //spanish: redibujamos this->_bspline_spiro_build(); ret = TRUE; } @@ -1358,7 +1360,9 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t g_string_free(dist, FALSE); } -// this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. + + +//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; @@ -1732,7 +1736,8 @@ void PenTool::_bspline_spiro_end_anchor_off() } } -//prepares the curves for its transformation into BSpline curve. + +//spanish: preparates the curves for its trasformation into BSline curves. void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) @@ -1761,7 +1766,7 @@ void PenTool::_bspline_spiro_build() } if(!curve->is_empty()){ - // close the curve if the final points of the curve are close enough + //spanish: cerramos la curva si estan cerca los puntos finales de la curva if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1800,7 +1805,7 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { - // commenting the function doEffect in src/live_effects/lpe-bspline.cpp + //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -1940,7 +1945,7 @@ void PenTool::_bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp -// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp +//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; @@ -2173,7 +2178,7 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - // cancelate line without a created segment + //spanish para cancelar linea sin un segmento creado this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); this->sa = NULL; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 95565abc9..88e528b22 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -49,7 +49,7 @@ public: bool polylines_only; bool polylines_paraxial; - // propiety which saves if Spiro mode is active or not + //spanish: propiedad que guarda si el modo Spiro está activo o no bool spiro; bool bspline; int num_clicks; @@ -88,29 +88,29 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - //adds spiro & bspline modes + //spanish: añade los modos spiro y bspline void _pen_context_set_mode(guint mode); - //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro + //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro void _bspline_spiro_color(); - //creates a node in bspline or spiro modes + //spanish: crea un nodo en modo bspline o spiro void _bspline_spiro(bool shift); - //creates a node in bspline or spiro modes + //spanish: crea un nodo de modo spiro o bspline void _bspline_spiro_on(); - //creates a CUSP node + //spanish: crea un nodo de tipo CUSP void _bspline_spiro_off(); - //continues the existing curve in bspline or spiro mode + //spanish: continua una curva existente en modo bspline o spiro void _bspline_spiro_start_anchor(bool shift); - //continues the existing curve with the union node in bspline or spiro modes + //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro void _bspline_spiro_start_anchor_on(); - //continues an existing curve with the union node in CUSP mode + //spanish: continua una curva existente con el nodo de union en modo CUSP void _bspline_spiro_start_anchor_off(); - //modifies the "red_curve" when it detects movement + //spanish: modifica la "red_curve" cuando se detecta movimiento void _bspline_spiro_motion(bool shift); - //closes the curve with the last node in bspline or spiro mode + //spanish: cierra la curva con el último nodo en modo bspline o spiro void _bspline_spiro_end_anchor_on(); - //closes the curve with the last node in CUSP mode + //spanish: cierra la curva con el último nodo en modo CUSP void _bspline_spiro_end_anchor_off(); - //CHECK: join all the curves "in game" and we call doEffect function + //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. void _bspline_spiro_build(); //function bspline cloned from lpe-bspline.cpp void _bspline_doEffect(SPCurve * curve); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 1ccdee637..bd50672af 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -685,7 +685,7 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - // if we are in BSpline we modify the trace to create adhoc nodes + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -835,7 +835,7 @@ void PencilTool::_fitAndSplit() { this->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - // if we are in BSpline we modify the trace to create adhoc nodes + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From 2aca4771b38314e62530f398222f02d4b9c17be5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Mar 2014 20:09:26 +0100 Subject: Fixing branch problems (bzr r11950.1.280) --- src/ui/dialog/export.cpp | 502 ++++++++++++++++++++++++----------------------- src/ui/dialog/export.h | 48 +++-- 2 files changed, 282 insertions(+), 268 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 340a3dad0..f0a5f1bf5 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -144,11 +144,13 @@ namespace Dialog { /** A list of strings that is used both in the preferences, and in the data fields to describe the various values of \c selection_type. */ static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; + "page", "drawing", "selection", "custom" +}; /** The names on the buttons for the various selection types. */ static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom") +}; Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), @@ -201,7 +203,7 @@ Export::Export (void) : /* gets added to the vbox later, but the unit selector is needed earlier than that */ unit_selector.setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { unit_selector.setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); @@ -232,28 +234,28 @@ Export::Export (void) : #endif x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaX0Change); + t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaX0Change); x1_adj = createSpinbutton ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaX1Change); + t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaX1Change); width_adj = createSpinbutton ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaWidthChange); + t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaWidthChange); y0_adj = createSpinbutton ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaY0Change); + t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaY0Change); y1_adj = createSpinbutton ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaY1Change); + t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaY1Change); height_adj = createSpinbutton ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaHeightChange); + t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaHeightChange); area_box.pack_start(togglebox, false, false, 3); area_box.pack_start(*t, false, false, 0); @@ -284,27 +286,27 @@ Export::Export (void) : size_box.pack_start(*t); bmwidth_adj = createSpinbutton ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0, - t, 0, 0, - _("_Width:"), _("pixels at"), 0, 1, - &Export::onBitmapWidthChange); + t, 0, 0, + _("_Width:"), _("pixels at"), 0, 1, + &Export::onBitmapWidthChange); xdpi_adj = createSpinbutton ( "xdpi", - prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), - 0.01, 100000.0, 0.1, 1.0, t, 3, 0, - "", _("dp_i"), 2, 1, - &Export::onExportXdpiChange); + prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), + 0.01, 100000.0, 0.1, 1.0, t, 3, 0, + "", _("dp_i"), 2, 1, + &Export::onExportXdpiChange); bmheight_adj = createSpinbutton ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0, - t, 0, 1, - _("_Height:"), _("pixels at"), 0, 1, - &Export::onBitmapHeightChange); + t, 0, 1, + _("_Height:"), _("pixels at"), 0, 1, + &Export::onBitmapHeightChange); /** TODO * There's no way to set ydpi currently, so we use the defaultxdpi value here, too... */ ydpi_adj = createSpinbutton ( "ydpi", prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), - 0.01, 100000.0, 0.1, 1.0, t, 3, 1, - "", _("dpi"), 2, 0, NULL ); + 0.01, 100000.0, 0.1, 1.0, t, 3, 1, + "", _("dpi"), 2, 0, NULL ); singleexport_box.pack_start(size_box); } @@ -482,18 +484,18 @@ void Export::set_default_filename () { #if WITH_GTKMM_3_0 Glib::RefPtr Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max, - float step, float page, - Gtk::Grid *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ) + float step, float page, + Gtk::Grid *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ) #else Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max, - float step, float page, - Gtk::Table *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ) + float step, float page, + Gtk::Table *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ) #endif { #if WITH_GTKMM_3_0 @@ -535,7 +537,9 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl sb->set_sensitive (sensitive); pos++; - if (!ll.empty()) { l->set_mnemonic_widget(*sb);} + if (!ll.empty()) { + l->set_mnemonic_widget(*sb); + } if (!lr.empty()) { l = new Gtk::Label(lr,true); @@ -565,7 +569,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl Glib::ustring Export::create_filepath_from_id (Glib::ustring id, const Glib::ustring &file_entry_text) { if (id.empty()) - { /* This should never happen */ + { /* This should never happen */ id = "bitmap"; } @@ -678,35 +682,35 @@ void Export::onSelectionModified ( guint /*flags*/ ) { Inkscape::Selection * Sel; switch (current_key) { - case SELECTION_DRAWING: - if ( SP_ACTIVE_DESKTOP ) { - SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); - if (bbox) { - setArea ( bbox->left(), - bbox->top(), - bbox->right(), - bbox->bottom()); - } + case SELECTION_DRAWING: + if ( SP_ACTIVE_DESKTOP ) { + SPDocument *doc; + doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); + if (bbox) { + setArea ( bbox->left(), + bbox->top(), + bbox->right(), + bbox->bottom()); } - break; - case SELECTION_SELECTION: - Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); - if (Sel->isEmpty() == false) { - Geom::OptRect bbox = Sel->visualBounds(); - if (bbox) - { - setArea ( bbox->left(), - bbox->top(), - bbox->right(), - bbox->bottom()); - } + } + break; + case SELECTION_SELECTION: + Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); + if (Sel->isEmpty() == false) { + Geom::OptRect bbox = Sel->visualBounds(); + if (bbox) + { + setArea ( bbox->left(), + bbox->top(), + bbox->right(), + bbox->bottom()); } - break; - default: - /* Do nothing for page or for custom */ - break; + } + break; + default: + /* Do nothing for page or for custom */ + break; } return; @@ -738,39 +742,39 @@ void Export::onAreaToggled () various backups. If you modify this without noticing you'll probabaly screw something up. */ switch (key) { - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) - { - bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); - /* Only if there is a selection that we can set - do we break, otherwise we fall through to the - drawing */ - // std::cout << "Using selection: SELECTION" << std::endl; - key = SELECTION_SELECTION; - break; - } - case SELECTION_DRAWING: - /** \todo - * This returns wrong values if the document has a viewBox. - */ - bbox = doc->getRoot()->desktopVisualBounds(); - /* If the drawing is valid, then we'll use it and break - otherwise we drop through to the page settings */ - if (bbox) { - // std::cout << "Using selection: DRAWING" << std::endl; - key = SELECTION_DRAWING; - break; - } - case SELECTION_PAGE: - bbox = Geom::Rect(Geom::Point(0.0, 0.0), - Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); - - // std::cout << "Using selection: PAGE" << std::endl; - key = SELECTION_PAGE; + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) + { + bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); + /* Only if there is a selection that we can set + do we break, otherwise we fall through to the + drawing */ + // std::cout << "Using selection: SELECTION" << std::endl; + key = SELECTION_SELECTION; break; - case SELECTION_CUSTOM: - default: + } + case SELECTION_DRAWING: + /** \todo + * This returns wrong values if the document has a viewBox. + */ + bbox = doc->getRoot()->desktopVisualBounds(); + /* If the drawing is valid, then we'll use it and break + otherwise we drop through to the page settings */ + if (bbox) { + // std::cout << "Using selection: DRAWING" << std::endl; + key = SELECTION_DRAWING; break; + } + case SELECTION_PAGE: + bbox = Geom::Rect(Geom::Point(0.0, 0.0), + Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); + + // std::cout << "Using selection: PAGE" << std::endl; + key = SELECTION_PAGE; + break; + case SELECTION_CUSTOM: + default: + break; } // switch current_key = key; @@ -780,9 +784,9 @@ void Export::onAreaToggled () if ( key != SELECTION_CUSTOM && bbox ) { setArea ( bbox->min()[Geom::X], - bbox->min()[Geom::Y], - bbox->max()[Geom::X], - bbox->max()[Geom::Y]); + bbox->min()[Geom::Y], + bbox->max()[Geom::X], + bbox->max()[Geom::Y]); } } // end of if ( SP_ACTIVE_DESKTOP ) @@ -793,43 +797,43 @@ void Export::onAreaToggled () float xdpi = 0.0, ydpi = 0.0; switch (key) { - case SELECTION_PAGE: - case SELECTION_DRAWING: { - SPDocument * doc = SP_ACTIVE_DOCUMENT; - sp_document_get_export_hints (doc, filename, &xdpi, &ydpi); - - if (filename.empty()) { - if (!doc_export_name.empty()) { - filename = doc_export_name; - } + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + sp_document_get_export_hints (doc, filename, &xdpi, &ydpi); + + if (filename.empty()) { + if (!doc_export_name.empty()) { + filename = doc_export_name; } - break; } - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - - sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi); - - /* If we still don't have a filename -- let's build - one that's nice */ - if (filename.empty()) { - const gchar * id = "object"; - const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); - for(; reprlst != NULL; reprlst = reprlst->next) { - Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; - if (repr->attribute("id")) { - id = repr->attribute("id"); - break; - } - } + break; + } + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - filename = create_filepath_from_id (id, filename_entry.get_text()); + sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi); + + /* If we still don't have a filename -- let's build + one that's nice */ + if (filename.empty()) { + const gchar * id = "object"; + const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; + if (repr->attribute("id")) { + id = repr->attribute("id"); + break; + } } + + filename = create_filepath_from_id (id, filename_entry.get_text()); } - break; - case SELECTION_CUSTOM: - default: - break; + } + break; + case SELECTION_CUSTOM: + default: + break; } if (!filename.empty()) { @@ -895,8 +899,8 @@ unsigned int Export::onProgressCallback(float value, void *dlg) int evtcount = 0; while ((evtcount < 16) && gdk_events_pending()) { - gtk_main_iteration_do(FALSE); - evtcount += 1; + gtk_main_iteration_do(FALSE); + evtcount += 1; } gtk_main_iteration_do(FALSE); @@ -960,7 +964,7 @@ Glib::ustring Export::filename_add_extension (Glib::ustring filename, Glib::ustr } else { - return filename = filename + "." + extension; + return filename = filename + "." + extension; } } } @@ -1057,9 +1061,9 @@ void Export::onExport () // Do export gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); MessageCleaner msgCleanup(desktop->messageStack()->pushF(Inkscape::IMMEDIATE_MESSAGE, - _("Exporting file %s..."), safeFile), desktop); + _("Exporting file %s..."), safeFile), desktop); MessageCleaner msgFlashCleanup(desktop->messageStack()->flashF(Inkscape::IMMEDIATE_MESSAGE, - _("Exporting file %s..."), safeFile), desktop); + _("Exporting file %s..."), safeFile), desktop); if (!sp_export_png_file (doc, path.c_str(), *area, width, height, dpi, dpi, @@ -1067,7 +1071,7 @@ void Export::onExport () onProgressCallback, (void*)prog_dlg, TRUE, // overwrite without asking hide ? const_cast(sp_desktop_selection(desktop)->itemList()) : NULL - )) { + )) { gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); desktop->messageStack()->flashF(Inkscape::ERROR_MESSAGE, @@ -1096,7 +1100,7 @@ void Export::onExport () } else { Glib::ustring filename = filename_entry.get_text(); - if (filename.empty()){ + if (filename.empty()) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename.")); sp_ui_error_dialog(_("You have to enter a filename")); return; @@ -1125,7 +1129,7 @@ void Export::onExport () Glib::ustring dirname = Glib::path_get_dirname(path); if ( dirname.empty() - || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) + || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) { gchar *safeDir = Inkscape::IO::sanitizeString(dirname.c_str()); gchar *error = g_strdup_printf(_("Directory %s does not exist or is not a directory.\n"), @@ -1151,12 +1155,12 @@ void Export::onExport () /* Do export */ ExportResult status = sp_export_png_file(sp_desktop_document(desktop), path.c_str(), - Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, - nv->pagecolor, - onProgressCallback, (void*)prog_dlg, - FALSE, - hide ? const_cast(sp_desktop_selection(desktop)->itemList()) : NULL - ); + Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, + nv->pagecolor, + onProgressCallback, (void*)prog_dlg, + FALSE, + hide ? const_cast(sp_desktop_selection(desktop)->itemList()) : NULL + ); if (status == EXPORT_ERROR) { gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1189,19 +1193,65 @@ void Export::onExport () /* Setup the values in the document */ switch (current_key) { - case SELECTION_PAGE: - case SELECTION_DRAWING: { - SPDocument * doc = SP_ACTIVE_DOCUMENT; - Inkscape::XML::Node * repr = doc->getReprRoot(); - bool modified = false; - - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); - - gchar const *temp_string = repr->attribute("inkscape:export-filename"); - if (temp_string == NULL || (filename_ext != temp_string)) { - repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); - modified = true; + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node * repr = doc->getReprRoot(); + bool modified = false; + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + + gchar const *temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || (filename_ext != temp_string)) { + repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); + modified = true; + } + temp_string = repr->attribute("inkscape:export-xdpi"); + if (temp_string == NULL || xdpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi); + modified = true; + } + temp_string = repr->attribute("inkscape:export-ydpi"); + if (temp_string == NULL || ydpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); + modified = true; + } + DocumentUndo::setUndoSensitive(doc, saved); + + if (modified) { + doc->setModifiedSinceSave(); + } + break; + } + case SELECTION_SELECTION: { + const GSList * reprlst; + SPDocument * doc = SP_ACTIVE_DOCUMENT; + bool modified = false; + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + reprlst = sp_desktop_selection(desktop)->reprList(); + + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = static_cast(reprlst->data); + const gchar * temp_string; + Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); + const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI(); + Glib::ustring docdir; + if (docURI) + { + docdir = Glib::path_get_dirname(docURI); + } + if (repr->attribute("id") == NULL || + !(filename_ext.find_last_of(repr->attribute("id")) && + ( !docURI || + (dir == docdir)))) { + temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || (filename_ext != temp_string)) { + repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); + modified = true; + } } temp_string = repr->attribute("inkscape:export-xdpi"); if (temp_string == NULL || xdpi != atof(temp_string)) { @@ -1213,62 +1263,16 @@ void Export::onExport () sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); modified = true; } - DocumentUndo::setUndoSensitive(doc, saved); - - if (modified) { - doc->setModifiedSinceSave(); - } - break; } - case SELECTION_SELECTION: { - const GSList * reprlst; - SPDocument * doc = SP_ACTIVE_DOCUMENT; - bool modified = false; - - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); - reprlst = sp_desktop_selection(desktop)->reprList(); - - for(; reprlst != NULL; reprlst = reprlst->next) { - Inkscape::XML::Node * repr = static_cast(reprlst->data); - const gchar * temp_string; - Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); - const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI(); - Glib::ustring docdir; - if (docURI) - { - docdir = Glib::path_get_dirname(docURI); - } - if (repr->attribute("id") == NULL || - !(filename_ext.find_last_of(repr->attribute("id")) && - ( !docURI || - (dir == docdir)))) { - temp_string = repr->attribute("inkscape:export-filename"); - if (temp_string == NULL || (filename_ext != temp_string)) { - repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); - modified = true; - } - } - temp_string = repr->attribute("inkscape:export-xdpi"); - if (temp_string == NULL || xdpi != atof(temp_string)) { - sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi); - modified = true; - } - temp_string = repr->attribute("inkscape:export-ydpi"); - if (temp_string == NULL || ydpi != atof(temp_string)) { - sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); - modified = true; - } - } - DocumentUndo::setUndoSensitive(doc, saved); + DocumentUndo::setUndoSensitive(doc, saved); - if (modified) { - doc->setModifiedSinceSave(); - } - break; + if (modified) { + doc->setModifiedSinceSave(); } - default: - break; + break; + } + default: + break; } } @@ -1331,8 +1335,8 @@ void Export::onBrowse () // Copy the selected file name, converting from UTF-8 to UTF-16 std::string dirname = Glib::path_get_dirname(filename.raw()); if ( !Glib::file_test(dirname, Glib::FILE_TEST_EXISTS) || - Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || - dirname.empty() ) + Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || + dirname.empty() ) { Glib::ustring tmp; filename = create_filepath_from_id(tmp, tmp); @@ -1407,11 +1411,11 @@ bool Export::bbox_equal(Geom::Rect const &one, Geom::Rect const &two) { double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION); return ( - (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) && - (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) && - (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) && - (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon) - ); + (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) && + (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) && + (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) && + (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon) + ); } /** @@ -1454,48 +1458,48 @@ void Export::detectSize() { for (int i = 0; i < SELECTION_NUMBER_OF + 1 && - key == SELECTION_NUMBER_OF && - SP_ACTIVE_DESKTOP != NULL; + key == SELECTION_NUMBER_OF && + SP_ACTIVE_DESKTOP != NULL; i++) { switch (this_test[i]) { - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); - if ( bbox && bbox_equal(*bbox,current_bbox)) { - key = SELECTION_SELECTION; - } + if ( bbox && bbox_equal(*bbox,current_bbox)) { + key = SELECTION_SELECTION; } - break; - case SELECTION_DRAWING: { - SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + } + break; + case SELECTION_DRAWING: { + SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); + Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); - if ( bbox && bbox_equal(*bbox,current_bbox) ) { - key = SELECTION_DRAWING; - } - break; + if ( bbox && bbox_equal(*bbox,current_bbox) ) { + key = SELECTION_DRAWING; } + break; + } - case SELECTION_PAGE: { - SPDocument *doc; + case SELECTION_PAGE: { + SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::Point x(0.0, 0.0); - Geom::Point y(doc->getWidth().value("px"), - doc->getHeight().value("px")); - Geom::Rect bbox(x, y); + Geom::Point x(0.0, 0.0); + Geom::Point y(doc->getWidth().value("px"), + doc->getHeight().value("px")); + Geom::Rect bbox(x, y); - if (bbox_equal(bbox,current_bbox)) { - key = SELECTION_PAGE; - } + if (bbox_equal(bbox,current_bbox)) { + key = SELECTION_PAGE; + } - break; - } + break; + } default: - break; + break; } } // std::cout << std::endl; @@ -1579,7 +1583,7 @@ void Export::areaYChange (Gtk::Adjustment *adj) height = SP_EXPORT_MIN_SIZE; //key = (const gchar *)g_object_get_data(G_OBJECT (adj), "key"); if (adj == y1_adj) { - //if (!strcmp (key, "y0")) { + //if (!strcmp (key, "y0")) { y1 = y0 + height * DPI_BASE / ydpi; setValuePx(y1_adj, y1); } else { diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 79e597414..6f3c0dfac 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -56,7 +56,9 @@ public: Export (); ~Export (); - static Export &getInstance() { return *new Export(); } + static Export &getInstance() { + return *new Export(); + } private: @@ -97,7 +99,7 @@ private: float getValue (Gtk::Adjustment *adj); float getValuePx (Gtk::Adjustment *adj); #endif - + /** * Helper function to create, style and pack spinbuttons for the export dialog. * @@ -121,20 +123,20 @@ private: */ #if WITH_GTKMM_3_0 Glib::RefPtr createSpinbutton( gchar const *key, float val, float min, float max, - float step, float page, - Gtk::Grid *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ); + float step, float page, + Gtk::Grid *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ); #else Gtk::Adjustment * createSpinbutton( gchar const *key, float val, float min, float max, - float step, float page, - Gtk::Table *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ); + float step, float page, + Gtk::Table *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ); #endif - + /** * One of the area select radio buttons was pressed */ @@ -153,8 +155,12 @@ private: /** * Area X value changed callback */ - void onAreaX0Change() {areaXChange(x0_adj);} ; - void onAreaX1Change() {areaXChange(x1_adj);} ; + void onAreaX0Change() { + areaXChange(x0_adj); + } ; + void onAreaX1Change() { + areaXChange(x1_adj); + } ; #if WITH_GTKMM_3_0 void areaXChange(Glib::RefPtr& adj); #else @@ -164,8 +170,12 @@ private: /** * Area Y value changed callback */ - void onAreaY0Change() {areaYChange(y0_adj);} ; - void onAreaY1Change() {areaYChange(y1_adj);} ; + void onAreaY0Change() { + areaYChange(y0_adj); + } ; + void onAreaY1Change() { + areaYChange(y1_adj); + } ; #if WITH_GTKMM_3_0 void areaYChange(Glib::RefPtr& adj); #else @@ -235,14 +245,14 @@ private: /** * Creates progress dialog for batch exporting. - * + * * @param progress_text Text to be shown in the progress bar */ Gtk::Dialog * create_progress_dialog (Glib::ustring progress_text); /** * Callback to be used in for loop to update the progress bar. - * + * * @param value number between 0 and 1 indicating the fraction of progress (0.17 = 17 % progress) * @param dlg void pointer to the Gtk::Dialog progress dialog */ -- cgit v1.2.3 From c15e77cc2670408ab725ba60c064743a9b61a375 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Mar 2014 20:18:54 +0100 Subject: Fixing branch problems (bzr r11950.1.281) --- src/ui/tool/curve-drag-point.cpp | 5 ++- src/ui/tool/multi-path-manipulator.cpp | 5 ++- src/ui/tool/node.cpp | 64 ++++++++++++++++---------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 14 +++---- src/ui/tools/freehand-base.cpp | 23 ++++++------ src/ui/tools/node-tool.h | 3 +- src/ui/tools/pen-tool.cpp | 67 ++++++++++++++++------------------ src/ui/tools/pen-tool.h | 26 ++++++------- src/ui/tools/pencil-tool.cpp | 4 +- 10 files changed, 106 insertions(+), 107 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index e5412fdc2..ad03cf75d 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,7 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - //spanish: solo actualizamos los nodos si no es bspline + // only update the nodes if the mode is bspline if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -89,7 +89,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT + + //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index b7f3ac29b..68aaa77a5 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,9 +671,10 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: si es trazado bspline (mode 2) + + //if the trace is bspline ( mode 2) if(mode==2){ - //spanish: ¿correcto? + // is this correct ? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 78d8fe833..73460a313 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -184,7 +184,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -210,7 +210,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + // moves the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -292,7 +292,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo + // new double click event to set the handlers of a node to the default proportion, 0.3334% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -303,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 +//this function moves the handler and its oposite to the default proportion of 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -359,8 +359,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el - //parametro "steps whith control" del efecto en vivo BSpline + // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" + // by default in live BSpline if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -370,7 +370,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - //spanish: si está activado el ajuste (snap) y no es bspline + //if the snap adjustment is activated and it is not bspline if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -411,8 +411,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - //spanish: si es bspline pero no está presionado SHIFT o CONTROL - //lo fija en la posición original + //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -432,7 +431,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //spanish: marca la fuerza del bspline como 0.0000 + //sets the bspline strength to 0.0000 if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } @@ -478,9 +477,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - //spanish: un truco para, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + // a trick to mark as bspline if the node has no strength, we are going to use it later + // to show the appropiate messages. We cannot do it in any different way becasue the function is constant + bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -622,8 +621,8 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + + // save the previous node strength to apply it again once the node is moved double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline(false)){ @@ -638,8 +637,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the affected handlers. First the node ones, later the adjoining ones. if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -649,8 +648,7 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + // save the previous node strength to apply it again later when the node is moved double oldPos = 0.0000; if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; @@ -663,8 +661,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the involved handlers, first the node ones, later the adjoining ones if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -755,9 +753,11 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. - //Cada vez que actuemos sobre dichos tiradores en un trazado - //bspline esta fuerza se tiene que actualizar + + // define the node strength, depending on being or not bspline traced. + // every time we operate over these handlers in a trace bspline + // that strength needs to be updated. + this->bsplineWeight = 0.0000; if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { @@ -868,9 +868,8 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - //spanish: en los cambios de tipo de nodo, sobre trazados bspline, - //o bien los mantenemos con potencia 0.0000 en modo esquina - //o les damos la potencia por defecto en modo de curva + /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, + or we give them the default power in curve mode */ if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1123,7 +1122,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //spanish: esto muestra los tiradores al seleccionar los nodos + //this shows the handlers when selecting the nodes if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); @@ -1389,9 +1388,10 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - //spanish: un truco par, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + + /* if the node doesnt have strength, it marks it as bspline, we'll use it later + to show the appropiate messages. We cannot do it in any other way, because the + function is constant */ bool isBSpline = false; if( this->bsplineWeight != 0.0000) isBSpline = true; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index b7d6951d0..4393446d9 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,7 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //spanish: creamos valor de potencia bspline asociado a cada nodo + //strength value for each node double bsplineWeight; /** diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index a6689d93d..1cc075603 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -663,7 +663,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - //spanish: si se borra, reajustamos los tiradores + // if we are removing, we readjust the handlers if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ @@ -1182,7 +1182,7 @@ void PathManipulator::_createControlPointsFromGeometry() } } -//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza +//determines if the trace has a bspline effect and the number of steps that it takes int PathManipulator::BSplineGetSteps(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1200,7 +1200,7 @@ int PathManipulator::BSplineGetSteps(){ return steps; } -//spanish: determina si el trazado tiene efecto bspline +// determines if the trace has bspline effect bool PathManipulator::isBSpline(bool recalculate){ static int BSplineSteps = this->BSplineGetSteps(); if(recalculate){ @@ -1213,7 +1213,7 @@ bool PathManipulator::isBSpline(bool recalculate){ return isBSpline; } -//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador +// returns the corresponding strength to the position of a handler double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1231,13 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } -//spanish: mueve el tirador a la posición que le corresponda +// moves the handler to the corresponding position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } -//spanish: mueve el tirador a una posición específica +// moves the handler to the specified position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1263,7 +1263,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } -//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos +//moves the node handlers and its oposite handlers to the strength of its nodes void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index cb6111bd5..40a257de9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -252,7 +252,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //spanish: añadimos el modo bspline a los efectos en espera + //add the bspline node in the waiting effects if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -496,9 +496,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente - //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada - //porque la modificamos al continuar por un anchor + /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. + if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because + we modify it when continuing through an anchor. */ if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -527,8 +527,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor - //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes + + /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. + this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and + close incorrectly one of the parts */ if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { @@ -547,8 +549,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); } - //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white - //pasándole la curva de inicio necesaria + + //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); @@ -679,9 +681,8 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. - //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en - //la que cerramos el trazado. + /* modify the anchoring curve so it is equal to the starting curve. + this curve is modified when it's modified and we need them to be equal to the closing curve */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 168ec995a..42f89cd1c 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,7 +14,8 @@ #include #include #include "ui/tools/tool-base.h" -//spanish: lo necesitamos para llamarlo desde el Live Effect + +// we need it to call it from Live Effect #include "selection.h" namespace Inkscape { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index ad77fcb53..e3bbc72b1 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//spanish: incluimos los archivos necesarios para las BSpline y Spiro +// we include the necessary files for BSpline & Spiro #include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -166,7 +166,7 @@ PenTool::~PenTool() { void PenTool::setPolylineMode() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: cambiamos los modos para dar cabida al modo bspline + // change the nodes to make space for bspline mode this->polylines_only = (mode == 3 || mode == 4); this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -178,7 +178,7 @@ void PenTool::setPolylineMode() { *.Set the mode of draw spiro, and bsplines */ void PenTool::_pen_context_set_mode(guint mode) { - //spanish: definimos los modos + // define the nodes this->spiro = (mode == 1); this->bspline = (mode == 2); } @@ -386,7 +386,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ - //spanish Borrar siguiente linea para evitar un nodo encima de otro + //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); _finish( FALSE); return TRUE; @@ -512,7 +512,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { } } - //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar + // avoid the creation of a control point so a node is created in the release event this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -705,7 +705,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { default: break; } - //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. + // calls the function "bspline_spiro_motion" when the mouse starts or stops moving if(this->bspline){ this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); @@ -743,9 +743,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(this, event_w); - //with this we avoid creating a new point over the existing one - //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. - + // if we try to create a node in the same place as another node, we skip if((!anchor || anchor == this->sa) && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ return TRUE; } @@ -760,7 +758,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { p = anchor->dp; } this->sa = anchor; - //spanish: continuamos una curva existente + // continue the existing curve if (anchor) { if(this->bspline || this->spiro){ this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; @@ -790,7 +788,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { this->_endpointSnap(p, revent.state); } this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hude the guide of the penultimate node when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -817,7 +815,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::CLOSE: this->_endpointSnap(p, revent.state); this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hide the penultimate node guide when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -908,7 +906,7 @@ void PenTool::_redrawAll() { sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); // handles - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if (this->p[0] != this->p[1] && !this->spiro && !this->bspline) { SP_CTRL(this->c1)->moveto(this->p[1]); this->cl1->setCoords(this->p[0], this->p[1]); @@ -922,7 +920,7 @@ void PenTool::_redrawAll() { Geom::Curve const * last_seg = this->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if ( cubic && (*cubic)[2] != this->p[0] && !this->spiro && !this->bspline ) { @@ -937,9 +935,8 @@ void PenTool::_redrawAll() { } } - //spanish: simplemente redibujamos la spiro. - //como es un redibujo simplemente no llamamos a la función global sino al final de esta - //Lanzamos solamente el redibujado + // simply redraw the spiro. because its a redrawing, we don't call the global function, + // but we call the redrawing at the ending. this->_bspline_spiro_build(); } @@ -969,12 +966,12 @@ void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) { } void PenTool::_lastpointToCurve() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. if (this->npoints != 5 && !this->spiro && !this->bspline) return; Geom::CubicBezier const * cubic; this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //modificate the last segment of the green curve so it creates the type of node we need if(this->spiro||this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1012,7 +1009,7 @@ void PenTool::_lastpointToCurve() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + //if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(false); } @@ -1023,11 +1020,11 @@ void PenTool::_lastpointToCurve() { void PenTool::_lastpointToLine() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect) it doesn't stop here. if (this->npoints != 5 && !this->bspline) return; - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + // modify the last segment of the green curve so the type of node we want is created. if(this->spiro || this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1059,7 +1056,7 @@ void PenTool::_lastpointToLine() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + // if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(true); } @@ -1248,7 +1245,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0]; } - //spanish: asignamos el valor a un tercio de distancia del último segmento. + // asign the value in a third of the distance of the last segment. if(this->bspline){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } @@ -1258,7 +1255,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { : this->p[3])); this->npoints = 2; - //spanish: eliminamos el último segmento de la curva verde + // delete the last segment of the green curve if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { @@ -1270,7 +1267,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { }else{ this->green_curve->backspace(); } - //spanish: asignamos el valor de this->p[1] a el opuesto de el ultimo segmento de la línea verde + // assign the value of this->p[1] to the oposite of the green line last segment if(this->spiro){ cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { @@ -1285,7 +1282,8 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->state = PenTool::POINT; this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //spanish: redibujamos + + //redraw this->_bspline_spiro_build(); ret = TRUE; } @@ -1360,9 +1358,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t g_string_free(dist, FALSE); } - - -//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +// this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; @@ -1736,8 +1732,7 @@ void PenTool::_bspline_spiro_end_anchor_off() } } - -//spanish: preparates the curves for its trasformation into BSline curves. +//prepares the curves for its transformation into BSpline curve. void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) @@ -1766,7 +1761,7 @@ void PenTool::_bspline_spiro_build() } if(!curve->is_empty()){ - //spanish: cerramos la curva si estan cerca los puntos finales de la curva + // close the curve if the final points of the curve are close enough if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1805,7 +1800,7 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { - //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp + // commenting the function doEffect in src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -1945,7 +1940,7 @@ void PenTool::_bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp -//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp +// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; @@ -2178,7 +2173,7 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - //spanish para cancelar linea sin un segmento creado + // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); this->sa = NULL; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 88e528b22..95565abc9 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -49,7 +49,7 @@ public: bool polylines_only; bool polylines_paraxial; - //spanish: propiedad que guarda si el modo Spiro está activo o no + // propiety which saves if Spiro mode is active or not bool spiro; bool bspline; int num_clicks; @@ -88,29 +88,29 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - //spanish: añade los modos spiro y bspline + //adds spiro & bspline modes void _pen_context_set_mode(guint mode); - //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro + //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro void _bspline_spiro_color(); - //spanish: crea un nodo en modo bspline o spiro + //creates a node in bspline or spiro modes void _bspline_spiro(bool shift); - //spanish: crea un nodo de modo spiro o bspline + //creates a node in bspline or spiro modes void _bspline_spiro_on(); - //spanish: crea un nodo de tipo CUSP + //creates a CUSP node void _bspline_spiro_off(); - //spanish: continua una curva existente en modo bspline o spiro + //continues the existing curve in bspline or spiro mode void _bspline_spiro_start_anchor(bool shift); - //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro + //continues the existing curve with the union node in bspline or spiro modes void _bspline_spiro_start_anchor_on(); - //spanish: continua una curva existente con el nodo de union en modo CUSP + //continues an existing curve with the union node in CUSP mode void _bspline_spiro_start_anchor_off(); - //spanish: modifica la "red_curve" cuando se detecta movimiento + //modifies the "red_curve" when it detects movement void _bspline_spiro_motion(bool shift); - //spanish: cierra la curva con el último nodo en modo bspline o spiro + //closes the curve with the last node in bspline or spiro mode void _bspline_spiro_end_anchor_on(); - //spanish: cierra la curva con el último nodo en modo CUSP + //closes the curve with the last node in CUSP mode void _bspline_spiro_end_anchor_off(); - //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. + //CHECK: join all the curves "in game" and we call doEffect function void _bspline_spiro_build(); //function bspline cloned from lpe-bspline.cpp void _bspline_doEffect(SPCurve * curve); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index bd50672af..1ccdee637 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -685,7 +685,7 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -835,7 +835,7 @@ void PencilTool::_fitAndSplit() { this->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From fcffbecabedd7c6bca1312918c918d57fee3cf8c Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 15:24:04 -0500 Subject: Added new swatches dialog (bzr r13090.1.16) --- src/ui/dialog/color-item.cpp | 860 ++++++++----------------------------------- src/ui/dialog/color-item.h | 108 ++---- src/ui/dialog/filedialog.h | 1 + src/ui/dialog/swatches.cpp | 48 +-- 4 files changed, 203 insertions(+), 814 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 7940c28ae..6eece0c17 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,18 +11,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - -#include #include +#include #include #include @@ -45,6 +36,7 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" +#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE @@ -53,756 +45,206 @@ namespace Inkscape { namespace UI { namespace Dialogs { -static std::vector mimeStrings; -static std::map mimeToInt; - -#if ENABLE_MAGIC_COLORS -// TODO remove this soon: -extern std::vector possible; -#endif // ENABLE_MAGIC_COLORS - - -#if ENABLE_MAGIC_COLORS -static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) +bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) { - bool changed = false; - - if ( node ) { - gchar const * val = node->attribute("inkscape:x-fill-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "fill", c ); - - sp_desktop_apply_css_recursive( obj, css, true ); - static_cast(obj)->updateRepr(); - - changed = true; - } - - val = node->attribute("inkscape:x-stroke-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "stroke", c ); - - sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); - ((SPItem*)obj)->updateRepr(); - - changed = true; - } - - Inkscape::XML::Node* first = node->firstChild(); - changed |= bruteForce( document, first, match, r, g, b ); - - changed |= bruteForce( document, node->next(), match, r, g, b ); - } - - return changed; -} -#endif // ENABLE_MAGIC_COLORS - -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); - } -} - -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); - } -} - -static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), - item->def.descr.c_str()); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); - } - } - return FALSE; -} - -static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); } - return FALSE; + return Gtk::Widget::on_enter_notify_event(event); } -static void dieDieDie( GObject *obj, gpointer user_data ) +bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) { - g_message("die die die %p %p", obj, user_data ); -} - -static bool getBlock( std::string& dst, guchar ch, std::string const & str ) -{ - bool good = false; - std::string::size_type pos = str.find(ch); - if ( pos != std::string::npos ) - { - std::string::size_type pos2 = str.find( '(', pos ); - if ( pos2 != std::string::npos ) { - std::string::size_type endPos = str.find( ')', pos2 ); - if ( endPos != std::string::npos ) { - dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); - good = true; - } - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); } - return good; + return Gtk::Widget::on_leave_notify_event(event); } -static bool popVal( guint64& numVal, std::string& str ) +void ColorItem::selection_modified(Selection* selection, guint flags) { - bool good = false; - std::string::size_type endPos = str.find(','); - if ( endPos == std::string::npos ) { - endPos = str.length(); - } - - if ( endPos != std::string::npos && endPos > 0 ) { - std::string xxx = str.substr( 0, endPos ); - const gchar* ptr = xxx.c_str(); - gchar* endPtr = 0; - numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == ptr) ) { - // failed conversion - } else { - good = true; - str.erase( 0, endPos + 1 ); - } - } - - return good; + selection_changed(selection); } -// TODO resolve this more cleanly: -extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); - -static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) +void ColorItem::selection_changed(Selection* selection) { - ColorItem* item = reinterpret_cast(data); - if ( item ) + SPItem* item = selection->singleItem(); + SPPaintServer* grad; + if (item && + ( + (item->style->fill.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) + && SP_GRADIENT(grad)->getVector() == gradient) || + + (item->style->stroke.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && + SP_GRADIENT(grad)->getVector() == gradient) + ) + ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - int width = 32; - int height = 24; - - if (item->def.getType() != ege::PaintDef::RGB){ - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); - g_free(localFilename); - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); - } else { - GdkPixbuf* pixbuf = 0; - if ( item->getGradient() ){ - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, gradient); - cairo_paint(ct); - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_surface_flush(s); - - pixbuf = ink_pixbuf_create_from_cairo_surface(s); - } else { - Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); - guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) - | (0x00ff0000 & (item->def.getG() << 16)) - | (0x0000ff00 & (item->def.getB() << 8)); - thumb->fill( fillWith ); - pixbuf = thumb->gobj(); - g_object_ref(G_OBJECT(pixbuf)); - } - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + if (!_isSelected) { + _isSelected = true; + queue_draw(); } + } else if (_isSelected) { + _isSelected = false; + queue_draw(); } - -} - -//"drag-drop" -// gboolean dragDropColorData( GtkWidget *widget, -// GdkDragContext *drag_context, -// gint x, -// gint y, -// guint time, -// gpointer user_data) -// { -// // TODO finish - -// return TRUE; -// } - - -SwatchPage::SwatchPage() - : _prefWidth(0) -{ -} - -SwatchPage::~SwatchPage() -{ -} - - -ColorItem::ColorItem(ege::PaintDef::ColorType type) : - def(type), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : - def( r, g, b, name ), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::~ColorItem() -{ - if (_pattern != NULL) { - cairo_pattern_destroy(_pattern); - } -} - -ColorItem::ColorItem(ColorItem const &other) : - Inkscape::UI::Previewable() -{ - if ( this != &other ) { - *this = other; - } -} - -ColorItem &ColorItem::operator=(ColorItem const &other) -{ - if ( this != &other ) { - def = other.def; - - // TODO - correct linkage - _linkSrc = other._linkSrc; - g_message("Erk!"); - } - return *this; } -void ColorItem::setState( bool fill, bool stroke ) +ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : + Glib::ObjectBase("coloritem"), + Gtk::Widget(), + def( name ), + gradient(grad), + _isSelected(false) { - if ( (_isFill != fill) || (_isStroke != stroke) ) { - _isFill = fill; - _isStroke = stroke; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - int val = eek_preview_get_linked( preview ); - val &= ~(PREVIEW_FILL | PREVIEW_STROKE); - if ( _isFill ) { - val |= PREVIEW_FILL; - } - if ( _isStroke ) { - val |= PREVIEW_STROKE; - } - eek_preview_set_linked( preview, static_cast(val) ); - } - } - } + set_has_window(true); + add_events(Gdk::BUTTON_PRESS_MASK); + add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); + mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); + selection_changed(desktop->selection); } -void ColorItem::setGradient(SPGradient *grad) +void ColorItem::on_size_request(Gtk::Requisition* requisition) { - if (_grad != grad) { - _grad = grad; - // TODO regen and push to listeners - } - - setName( gr_prepare_label(_grad) ); + requisition->height = 20; + requisition->width = 20; } -void ColorItem::setName(const Glib::ustring name) +void ColorItem::on_size_allocate(Gtk::Allocation& allocation) { - //def.descr = name; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str()); - } - else if ( GTK_IS_LABEL(widget->gobj()) ) { - gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str()); - } + set_allocation(allocation); + if (m_refGdkWindow) + { + m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); } } -void ColorItem::setPattern(cairo_pattern_t *pattern) +void ColorItem::on_map() { - if (pattern) { - cairo_pattern_reference(pattern); - } - if (_pattern) { - cairo_pattern_destroy(_pattern); - } - _pattern = pattern; - - _updatePreviews(); + Gtk::Widget::on_map(); } -void ColorItem::_dragGetColorData( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - GtkSelectionData *data, - guint info, - guint /*time*/, - gpointer user_data) +void ColorItem::on_unmap() { - ColorItem* item = reinterpret_cast(user_data); - std::string key; - if ( info < mimeStrings.size() ) { - key = mimeStrings[info]; - } else { - g_warning("ERROR: unknown value (%d)", info); - } - - if ( !key.empty() ) { - char* tmp = 0; - int len = 0; - int format = 0; - item->def.getMIMEData(key, tmp, len, format); - if ( tmp ) { - GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); - gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); - delete[] tmp; - } - } + Gtk::Widget::on_unmap(); } -void ColorItem::_dropDataIn( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - gint /*x*/, gint /*y*/, - GtkSelectionData */*data*/, - guint /*info*/, - guint /*event_time*/, - gpointer /*user_data*/) +void ColorItem::on_realize() { + set_realized(); + ensure_style(); + + if(!m_refGdkWindow) + { + //Create the GdkWindow: + + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); + + Gtk::Allocation allocation = get_allocation(); + + //Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + + m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, + GDK_WA_X | GDK_WA_Y); + set_window(m_refGdkWindow); + + //Attach this widget's style to its Gdk::Window. + style_attach(); + + //make the widget receive expose events + m_refGdkWindow->set_user_data(gobj()); + } } -void ColorItem::_colorDefChanged(void* data) +void ColorItem::on_unrealize() { - ColorItem* item = reinterpret_cast(data); - if ( item ) { - item->_updatePreviews(); - } + m_refGdkWindow.reset(); + + Gtk::Widget::on_unrealize(); } -void ColorItem::_updatePreviews() +bool ColorItem::on_expose_event(GdkEventExpose* event) { - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - _regenPreview(preview); - - widget->queue_draw(); - } - } - - for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { - guint r = def.getR(); - guint g = def.getG(); - guint b = def.getB(); - - if ( (*it)->_linkIsTone ) { - r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } else { - r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } - - (*it)->def.setRGB( r, g, b ); - } - - -#if ENABLE_MAGIC_COLORS - // Look for objects using this color + if(m_refGdkWindow) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - SPDocument* document = sp_desktop_document( desktop ); - Inkscape::XML::Node *rroot = document->getReprRoot(); - if ( rroot ) { - - // Find where this thing came from - Glib::ustring paletteName; - bool found = false; - int index = 0; - for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { - SwatchPage* curr = *it2; - index = 0; - for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { - if ( this == &*zz ) { - found = true; - paletteName = curr->_name; - break; - } else { - index++; - } - } - } - - if ( !paletteName.empty() ) { - gchar* str = g_strdup_printf("%d|", index); - paletteName.insert( 0, str ); - g_free(str); - str = 0; - - if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { - SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, - _("Change color definition")); - } - } - } - } - } -#endif // ENABLE_MAGIC_COLORS - -} - -void ColorItem::_regenPreview(EekPreview * preview) -{ - if ( def.getType() != ege::PaintDef::RGB ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); - if (!pixbuf) { - g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); - } - g_free(localFilename); - - eek_preview_set_pixbuf( preview, pixbuf ); - } - else if ( !_pattern ){ - eek_preview_set_color( preview, - (def.getR() << 8) | def.getR(), - (def.getG() << 8) | def.getG(), - (def.getB() << 8) | def.getB() ); - } else { - // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp - // TODO: the pattern to draw should be in the widget that draws the preview, - // so the preview can be scalable - int w = 128; - int h = 16; - - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, _pattern); - cairo_paint(ct); - cairo_destroy(ct); - cairo_surface_flush(s); - - GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); - eek_preview_set_pixbuf( preview, pixbuf ); - } - - eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) - | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) - | (_isLive ? PREVIEW_LINK_OTHER:0)) ); -} - -Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) -{ - Gtk::Widget* widget = 0; - if ( style == PREVIEW_STYLE_BLURB) { - Gtk::Label *lbl = new Gtk::Label(def.descr); - lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - widget = lbl; - } else { - GtkWidget* eekWidget = eek_preview_new(); - EekPreview * preview = EEK_PREVIEW(eekWidget); - Gtk::Widget* newBlot = Glib::wrap(eekWidget); - _regenPreview(preview); - - eek_preview_set_details( preview, - (::ViewType)view, - (::PreviewSize)size, - ratio, - border ); - - def.addCallback( _colorDefChanged, this ); - eek_preview_set_focus_on_click(preview, FALSE); - newBlot->set_tooltip_text(def.descr); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "clicked", - G_CALLBACK(handleClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "alt-clicked", - G_CALLBACK(handleSecondaryClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "button-press-event", - G_CALLBACK(colorItemHandleButtonPress), - this); - + Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); + if(event) { - std::vector listing = def.getMIMETypes(); - int entryCount = listing.size(); - GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; - GtkTargetEntry* curr = entries; - for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { - curr->target = g_strdup(it->c_str()); - curr->flags = 0; - if ( mimeToInt.find(*it) == mimeToInt.end() ){ - // these next lines are order-dependent: - mimeToInt[*it] = mimeStrings.size(); - mimeStrings.push_back(*it); - } - curr->info = mimeToInt[curr->target]; - curr++; - } - gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), - GDK_BUTTON1_MASK, - entries, entryCount, - GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); - for ( int i = 0; i < entryCount; i++ ) { - g_free(entries[i].target); - } - delete[] entries; + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); + cr->clip(); } - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-data-get", - G_CALLBACK(ColorItem::_dragGetColorData), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-begin", - G_CALLBACK(colorItemDragBegin), - this ); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "enter-notify-event", - G_CALLBACK(handleEnterNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "leave-notify-event", - G_CALLBACK(handleLeaveNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "destroy", - G_CALLBACK(dieDieDie), - this); - - - widget = newBlot; - } - - _previews.push_back( widget ); - - return widget; -} - -void ColorItem::buttonClicked(bool secondary) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - char const * attrName = secondary ? "stroke" : "fill"; - - SPCSSAttr *css = sp_repr_css_attr_new(); - Glib::ustring descr; - switch (def.getType()) { - case ege::PaintDef::CLEAR: { - // TODO actually make this clear - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Remove stroke color") : _("Remove fill color"); - break; - } - case ege::PaintDef::NONE: { - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); - break; - } - case ege::PaintDef::RGB: { - Glib::ustring colorspec; - if ( _grad ){ - colorspec = "url(#"; - colorspec += _grad->getId(); - colorspec += ")"; - } else { - gchar c[64]; - guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; - sp_svg_write_color(c, sizeof(c), rgba); - colorspec = c; - } - sp_repr_css_set_property( css, attrName, colorspec.c_str() ); - descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); - break; - } - } - sp_desktop_set_style(desktop, css); - sp_repr_css_attr_unref(css); - - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); - } -} - -void ColorItem::_wireMagicColors( SwatchPage *colorSet ) -{ - if ( colorSet ) - { - for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) - { - std::string::size_type pos = it->def.descr.find("*{"); - if ( pos != std::string::npos ) - { - std::string subby = it->def.descr.substr( pos + 2 ); - std::string::size_type endPos = subby.find("}*"); - if ( endPos != std::string::npos ) - { - subby.erase( endPos ); - //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); - //g_message(" '%s'", subby.c_str()); - - if ( subby.find('E') != std::string::npos ) - { - it->def.setEditable( true ); - } - - if ( subby.find('L') != std::string::npos ) - { - it->_isLive = true; - } - - std::string part; - // Tint. index + 1 more val. - if ( getBlock( part, 'T', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - it->_linkTint( colorSet->_colors[colorIndex], percent ); - } - } - } - - // Shade/tone. index + 1 or 2 more val. - if ( getBlock( part, 'S', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - guint64 grayLevel = 0; - if ( !popVal( grayLevel, part ) ) { - grayLevel = 0; - } - it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); - } - } - } - - } + if (gradient) { + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + + Cairo::RefPtr checkpat(new Cairo::Pattern(check)); + + cr->set_source(checkpat); + cr->paint(); + + cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); + Cairo::RefPtr gpat(new Cairo::Pattern(g)); + cr->set_source(gpat); + cr->paint(); + gpat.clear(); + cairo_pattern_destroy(g); + + checkpat.clear(); + + cairo_pattern_destroy(check); + + if (_isSelected) { + cr->set_source_rgb(0, 0, 0); + cr->set_line_width(3); + cr->move_to(0, get_allocation().get_height()); + cr->line_to(0,0); + cr->line_to(get_allocation().get_width(), 0); + cr->stroke(); + cr->move_to(get_allocation().get_width(), 0); + cr->set_source_rgb(1, 1, 1); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->line_to(0, get_allocation().get_height()); + //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); + cr->stroke(); } + } else { + cr->set_source_rgb(1, 1, 1); + cr->paint(); + cr->set_source_rgb(1, 0, 0); + cr->set_line_width(3); + cr->move_to(0,0); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->move_to(get_allocation().get_width(), 0); + cr->line_to(0, get_allocation().get_height()); + cr->stroke(); } } + return true; } - -void ColorItem::_linkTint( ColorItem& other, int percent ) -{ - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = false; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = 0; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } -} - -void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) +ColorItem::~ColorItem() { - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = true; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = grayLevel; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } + sel_connection.disconnect(); + mod_connection.disconnect(); } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 3a0b33193..5d97d8803 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,7 +15,11 @@ #include #include "widgets/ege-paint-def.h" -#include "ui/previewable.h" +#include "widgets/eek-preview.h" +#include +#include +#include "desktop.h" +#include "selection.h" class SPGradient; @@ -23,89 +27,43 @@ namespace Inkscape { namespace UI { namespace Dialogs { -class ColorItem; - -class SwatchPage -{ -public: - SwatchPage(); - ~SwatchPage(); - - Glib::ustring _name; - int _prefWidth; - boost::ptr_vector _colors; -}; - /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Inkscape::UI::Previewable +class ColorItem : public Gtk::Widget { - friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( ege::PaintDef::ColorType type ); - ColorItem( unsigned int r, unsigned int g, unsigned int b, - Glib::ustring& name ); + ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); virtual ~ColorItem(); - ColorItem(ColorItem const &other); - virtual ColorItem &operator=(ColorItem const &other); - virtual Gtk::Widget* getPreview(PreviewStyle style, - ViewType view, - ::PreviewSize size, - guint ratio, - guint border); - void buttonClicked(bool secondary = false); - - void setGradient(SPGradient *grad); - SPGradient * getGradient() const { return _grad; } - void setPattern(cairo_pattern_t *pattern); - void setName(const Glib::ustring name); - - void setState( bool fill, bool stroke ); - bool isFill() { return _isFill; } - bool isStroke() { return _isStroke; } - - ege::PaintDef def; - + + SPGradient * getGradient() { return gradient; } + +protected: + + const gchar* def; + SPGradient * gradient; + virtual bool on_enter_notify_event(GdkEventCrossing* event); + virtual bool on_leave_notify_event(GdkEventCrossing* event); + + virtual void on_size_request(Gtk::Requisition* requisition); + virtual void on_size_allocate(Gtk::Allocation& allocation); + virtual void on_map(); + virtual void on_unmap(); + virtual void on_realize(); + virtual void on_unrealize(); + virtual bool on_expose_event(GdkEventExpose* event); + + Glib::RefPtr m_refGdkWindow; + + private: + void selection_changed(Selection* selection); + void selection_modified(Selection* selection, guint flags); - static void _dropDataIn( GtkWidget *widget, - GdkDragContext *drag_context, - gint x, gint y, - GtkSelectionData *data, - guint info, - guint event_time, - gpointer user_data); - - static void _dragGetColorData( GtkWidget *widget, - GdkDragContext *drag_context, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data); - - static void _wireMagicColors( SwatchPage *colorSet ); - static void _colorDefChanged(void* data); - - void _updatePreviews(); - void _regenPreview(EekPreview * preview); - - void _linkTint( ColorItem& other, int percent ); - void _linkTone( ColorItem& other, int percent, int grayLevel ); - - std::vector _previews; - - bool _isFill; - bool _isStroke; - bool _isLive; - bool _linkIsTone; - int _linkPercent; - int _linkGray; - ColorItem* _linkSrc; - SPGradient* _grad; - cairo_pattern_t *_pattern; - std::vector _listeners; + sigc::connection sel_connection; + sigc::connection mod_connection; + bool _isSelected; }; } // namespace Dialogs diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 8dfcf5dce..175031bcf 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -48,6 +48,7 @@ typedef enum { IMPORT_TYPES, EXPORT_TYPES, EXE_TYPES, + SWATCH_TYPES, CUSTOM_TYPE } FileDialogType; diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2956c6d17..efea4b869 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -67,14 +67,14 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" +#include "ui/tools/tool-base.h" #include "svg/css-ostringstream.h" -#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include #endif -guint get_group0_keyval(GdkEventKey *event); +//lazy! void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); namespace Inkscape { @@ -1335,10 +1335,10 @@ void SwatchesPanel::_defsChanged() eb->add(*lbl); _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); } - Glib::ustring str1 = Glib::ustring(_("[None]")); - ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->setName(_("[None]")); + + ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->set_tooltip_text(_("[None]")); _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); unsigned int i = 1; @@ -1365,11 +1365,10 @@ void SwatchesPanel::_defsChanged() GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); } - Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); - item->setGradient(grad); - //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(it->label() ? it->label() : it->getId()); + + item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1432,11 +1431,10 @@ void SwatchesPanel::_defsChanged() _editDoc.expand_to_path(_storeDoc->get_path(iter)); } - Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); - item->setGradient(grad); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(cit->label() ? cit->label() : cit->getId()); + + item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1643,7 +1641,7 @@ bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -1815,7 +1813,7 @@ void SwatchesPanel::_deleteButtonClickedDoc() bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -2323,18 +2321,8 @@ void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) } //namespace UI } //namespace Inkscape -//should be okay to add this here -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - -void -sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +//really lazy! +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) { bool intercepted = false; -- cgit v1.2.3 From a13fdaaa6335ad69b59750a3a9c6b978b921881b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 16:21:29 -0500 Subject: Fixed some swatch sizes (what about the table?) (bzr r13090.1.17) --- src/ui/dialog/swatches.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index efea4b869..91d859f90 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -1333,13 +1333,13 @@ void SwatchesPanel::_defsChanged() lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); } ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); item->set_tooltip_text(_("[None]")); - _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); unsigned int i = 1; for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { @@ -1370,9 +1370,9 @@ void SwatchesPanel::_defsChanged() item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } i++; @@ -1393,7 +1393,7 @@ void SwatchesPanel::_defsChanged() eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); } Gtk::TreeModel::iterator rowiter; @@ -1436,9 +1436,9 @@ void SwatchesPanel::_defsChanged() item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } i++; } @@ -2072,7 +2072,7 @@ bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& con SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), _scroller(), - _insideTable(1, 2), + _insideTable(1, 1), _insideV(), _insideH(), _buttonsRow(), -- cgit v1.2.3 From 8db893813e5974793db85bad0eb6b32468d29c45 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 19:31:15 -0500 Subject: Makefile fix (bzr r13090.1.18) --- src/ui/dialog/swatches.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 91d859f90..ceda27885 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -1448,9 +1448,11 @@ void SwatchesPanel::_defsChanged() } } } - + //_scroller.resize(1,1); + _insideTable.resize(1,1); _scroller.show_all_children(); _scroller.queue_draw(); + } Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) @@ -2258,6 +2260,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); _swatchesChanged(); + _insideTable.resize(1,1); } SwatchesPanel::~SwatchesPanel() -- cgit v1.2.3 From 50a5b62b327c55b8038b5031d35bf6ae48705485 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 21:08:09 -0500 Subject: Fixed size of swatches widget (bzr r13090.1.19) --- src/ui/dialog/swatches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index ceda27885..c3889db46 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -2102,7 +2102,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); _scroller.add(_insideV); } else { - _scroller.property_height_request() = 45; + _scroller.property_height_request() = 20; _scroller.add(_insideH); } -- cgit v1.2.3 From eb7c3f5dc2737bb22388b040f857117c3a25da6f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 6 Mar 2014 15:21:30 +0100 Subject: Fixed a bug when click over the previuos node in bspline/spiro mode (bzr r11950.1.285) --- src/ui/tools/pen-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index e3bbc72b1..d79803644 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -384,7 +384,6 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { //with this we avoid creating a new point over the existing one if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ - this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); -- cgit v1.2.3 From c3edf2beebfdf0cbb505d2accbddc4fec17dff7d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 6 Mar 2014 21:05:19 -0500 Subject: Start cleanup for merge into trunk (bzr r13090.1.20) --- src/ui/dialog/color-item.cpp | 2 +- src/ui/dialog/dialog-manager.cpp | 4 +- src/ui/dialog/lpe-powerstroke-properties.cpp | 8 + src/ui/dialog/swatches.cpp | 1 - src/ui/dialog/tags.cpp | 1182 -------------------------- src/ui/dialog/tags.h | 181 ---- src/ui/widget/addtoicon.h | 2 +- src/ui/widget/clipmaskicon.h | 2 +- src/ui/widget/highlight-picker.cpp | 10 +- src/ui/widget/highlight-picker.h | 2 +- src/ui/widget/insertordericon.cpp | 7 + src/ui/widget/layertypeicon.h | 2 +- 12 files changed, 31 insertions(+), 1372 deletions(-) delete mode 100644 src/ui/dialog/tags.cpp delete mode 100644 src/ui/dialog/tags.h (limited to 'src/ui') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 6eece0c17..a1951ec48 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -40,6 +39,7 @@ #include "color.h" // for SP_RGBA32_U_COMPOSE +#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 1fddbf007..ddf41e0c8 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -111,7 +111,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - //registerFactory("TagsPanel", &create); +// registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -147,7 +147,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - //registerFactory("TagsPanel", &create); +// registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index cef6f494e..c34351511 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -13,6 +13,14 @@ * Released under GNU GPL. Read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include "lpe-powerstroke-properties.h" #include #include diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index c3889db46..34885a971 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -43,7 +43,6 @@ #include "path-prefix.h" #include "preferences.h" #include "sp-item.h" -#include "sp-gradient-fns.h" #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp deleted file mode 100644 index 116f9eb0b..000000000 --- a/src/ui/dialog/tags.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * A simple panel for tags - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "tags.h" -#include -#include -#include -#include - -#include - -#include "desktop.h" -#include "desktop-style.h" -#include "document.h" -#include "document-undo.h" -#include "helper/action.h" -#include "inkscape.h" -#include "layer-fns.h" -#include "layer-manager.h" -#include "preferences.h" -#include "sp-item.h" -#include "sp-object.h" -#include "sp-shape.h" -#include "svg/css-ostringstream.h" -#include "ui/icon-names.h" -#include "ui/widget/layertypeicon.h" -#include "ui/widget/addtoicon.h" -#include "verbs.h" -#include "widgets/icon.h" -#include "xml/node.h" -#include "xml/node-observer.h" -#include "xml/repr.h" -#include "sp-root.h" -//#include "event-context.h" -#include "selection.h" -#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" -#include "style.h" -#include "filter-chemistry.h" -#include "filters/blend.h" -#include "filters/gaussian-blur.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "sp-tag.h" -#include "sp-defs.h" -#include "sp-tag-use.h" -#include "sp-tag-use-reference.h" - -//#define DUMP_LAYERS 1 - -namespace Inkscape { -namespace UI { -namespace Dialog { - -using Inkscape::XML::Node; - -TagsPanel& TagsPanel::getInstance() -{ - return *new TagsPanel(); -} - -enum { - COL_ADD = 1 -}; - -enum { - BUTTON_NEW = 0, - BUTTON_TOP, - BUTTON_BOTTOM, - BUTTON_UP, - BUTTON_DOWN, - BUTTON_DELETE, - DRAGNDROP -}; - -class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { -public: - ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : - _pnl(pnl), - _obj(obj), - _repr(repr), - _labelAttr(g_quark_from_string("inkscape:label")) - {} - - ObjectWatcher(TagsPanel* pnl, SPObject* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")) - {} - - virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if ( _pnl && _obj ) { - if ( name == _labelAttr ) { - _pnl->_updateObject( _obj); - } - } - } - - TagsPanel* _pnl; - SPObject* _obj; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; -}; - -class TagsPanel::InternalUIBounce -{ -public: - int _actionCode; -}; - -void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) -{ - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; - } - } - } - - btn.set_tooltip_text (tooltip); -} - - -Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) -{ - GtkWidget* iconWidget = 0; - const char* label = 0; - - if ( iconName ) { - iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !iconWidget && action && action->image ) { - iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); - } - - if ( action ) { - label = action->name; - } - } - } - - if ( !label && fallback ) { - label = fallback; - } - - Gtk::Widget* wrapped = 0; - if ( iconWidget ) { - wrapped = manage(Glib::wrap(iconWidget)); - wrapped->show(); - } - - - Gtk::MenuItem* item = 0; - - if (wrapped) { - item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); - } else { - item = Gtk::manage(new Gtk::MenuItem(label, true)); - } - - item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); - _popupMenu.append(*item); - - return *item; -} - -void TagsPanel::_fireAction( unsigned int code ) -{ - if ( _desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(_desktop); - if ( action ) { - sp_action_perform( action, NULL ); - } - } - } -} - -void TagsPanel::_takeAction( int val ) -{ - if ( !_pending ) { - _pending = new InternalUIBounce(); - _pending->_actionCode = val; - Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); - } -} - -bool TagsPanel::_executeAction() -{ - // Make sure selected layer hasn't changed since the action was triggered - if ( _pending) - { - int val = _pending->_actionCode; -// SPObject* target = _pending->_target; - - switch ( val ) { - case BUTTON_NEW: - { - _fireAction( SP_VERB_TAG_NEW ); - } - break; - case BUTTON_TOP: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_FRONT); - } - } - break; - case BUTTON_BOTTOM: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_BACK); - } - } - break; - case BUTTON_UP: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - else - { - _fireAction( SP_VERB_SELECTION_RAISE ); - } - } - break; - case BUTTON_DOWN: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - else - { - _fireAction( SP_VERB_SELECTION_LOWER ); - } - } - break; - case BUTTON_DELETE: - { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * obj = *iter; - if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - break; - case DRAGNDROP: - { - _doTreeMove( ); - } - break; - } - - delete _pending; - _pending = 0; - } - - return false; -} - - -class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - - ModelColumns() - { - add(_colParentObject); - add(_colObject); - add(_colLabel); - add(_colAddRemove); - add(_colAllowAddRemove); - } - virtual ~ModelColumns() {} - - Gtk::TreeModelColumn _colParentObject; - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; - Gtk::TreeModelColumn _colAddRemove; - Gtk::TreeModelColumn _colAllowAddRemove; -}; - -void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) -{ - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj && obj->parent) { - todelete->push_back(obj); - } -} - -void TagsPanel::_updateObject( SPObject *obj ) { - _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); -} - -bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) -{ - Gtk::TreeModel::Row row = *iter; - if ( obj == row[_model->_colObject] ) - { - /* - * We get notified of layer update here (from layer->setLabel()) before layer->label() is set - * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which - * has the correct value (bug #168351) - */ - //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); - gchar const *label; - SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; - if (use && use->ref->isAttached()) { - label = use->ref->getObject()->getAttribute("inkscape:label"); - } else { - label = obj->getAttribute("inkscape:label"); - } - row[_model->_colLabel] = label ? label : obj->getId(); - row[_model->_colAddRemove] = SP_IS_TAG(obj); - } - - return false; -} - -void TagsPanel::_objectsSelected( Selection *sel ) { - - _selectedConnection.block(); - _tree.get_selection()->unselect_all(); - for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) - { - SPObject *obj = reinterpret_cast(iter->data); - _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); - } - _selectedConnection.unblock(); - _checkTreeSelection(); -} - -bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) -{ - Gtk::TreeModel::Row row = *iter; - SPObject * it = row[_model->_colObject]; - if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) - { - Glib::RefPtr select = _tree.get_selection(); - - select->select(iter); - } - return false; -} - -void TagsPanel::_objectsChanged(SPObject* root) -{ - while (!_objectWatchers.empty()) - { - TagsPanel::ObjectWatcher *w = _objectWatchers.back(); - w->_repr->removeObserver(*w); - _objectWatchers.pop_back(); - delete w; - } - - if (_desktop) { - SPDocument* document = _desktop->doc(); - SPDefs* root = document->getDefs(); - if ( root ) { - _selectedConnection.block(); - _store->clear(); - _addObject( document, root, 0 ); - _selectedConnection.unblock(); - _objectsSelected(_desktop->selection); - _checkTreeSelection(); - } - } -} - -void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) -{ - if ( _desktop && obj ) { - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG(child)) - { - Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; - row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = child->label() ? child->label() : child->getId(); - row[_model->_colAddRemove] = true; - row[_model->_colAllowAddRemove] = true; - - _tree.expand_to_path( _store->get_path(iter) ); - - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); - child->getRepr()->addObserver(*w); - _objectWatchers.push_back(w); - _addObject( doc, child, &row ); - } - } - if (SP_IS_TAG(obj) && obj->children) - { - Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); - Gtk::TreeModel::Row rowitems = *iteritems; - rowitems[_model->_colObject] = NULL; - rowitems[_model->_colParentObject] = obj; - rowitems[_model->_colLabel] = _("Items"); - rowitems[_model->_colAddRemove] = false; - rowitems[_model->_colAllowAddRemove] = false; - - _tree.expand_to_path( _store->get_path(iteritems) ); - - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child)) - { - SPItem *item = SP_TAG_USE(child)->ref->getObject(); - Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; - row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; - row[_model->_colAddRemove] = false; - row[_model->_colAllowAddRemove] = true; - - if (SP_TAG(obj)->expanded()) { - _tree.expand_to_path( _store->get_path(iter) ); - } - - if (item) { - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); - item->getRepr()->addObserver(*w); - _objectWatchers.push_back(w); - } - } - } - } - } -} - -void TagsPanel::_select_tag( SPTag * tag ) -{ - for (SPObject * child = tag->children; child != NULL; child = child->next) - { - if (SP_IS_TAG(child)) { - _select_tag(SP_TAG(child)); - } else if (SP_IS_TAG_USE(child)) { - SPObject * obj = SP_TAG_USE(child)->ref->getObject(); - if (obj) { - if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); - _desktop->selection->add(obj); - } - } - } -} - -void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) -{ - if (iter) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - if (obj) { - if (SP_IS_TAG(obj)) { - _select_tag(SP_TAG(obj)); - } else if (SP_IS_TAG_USE(obj)) { - SPObject * item = SP_TAG_USE(obj)->ref->getObject(); - if (item) { - if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); - _desktop->selection->add(item); - } - } - } - } -} - -void TagsPanel::_pushTreeSelectionToCurrent() -{ - _selectionChangedConnection.block(); - // TODO hunt down the possible API abuse in getting NULL - if ( _desktop && _desktop->currentRoot() ) { - _desktop->selection->clear(); - _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); - } - _selectionChangedConnection.unblock(); - - _checkTreeSelection(); -} - -void TagsPanel::_checkTreeSelection() -{ - bool sensitive = _tree.get_selection()->count_selected_rows() > 0; - bool sensitiveNonTop = true; - bool sensitiveNonBottom = true; -// if ( _tree.get_selection()->count_selected_rows() > 0 ) { -// sensitive = true; -// -// SPObject* inTree = _selectedLayer(); -// if ( inTree ) { -// -// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); -// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); -// -// } -// } - - - for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { - (*it)->set_sensitive( sensitive ); - } - for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { - (*it)->set_sensitive( sensitiveNonTop ); - } - for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { - (*it)->set_sensitive( sensitiveNonBottom ); - } -} - -bool TagsPanel::_handleKeyEvent(GdkEventKey *event) -{ - - switch (get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); - if (iter && !_text_renderer->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj && SP_IS_TAG(obj)) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_renderer->property_editable() = true; - _tree.set_cursor(*path, *_name_column, true); - grab_focus(); - return true; - } - } - } - case GDK_KEY_Delete: { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - if (!todelete.empty()) { - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * obj = *iter; - if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - return true; - } - break; - } - return false; -} - -bool TagsPanel::_handleButtonEvent(GdkEventButton* event) -{ - static unsigned doubleclick = 0; - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { - // TODO - fix to a better is-popup function - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - if ( _tree.get_path_at_pos( x, y, path ) ) { - _checkTreeSelection(); - _popupMenu.popup(event->button, event->time); - if (_tree.get_selection()->is_selected(path)) { - return true; - } - } - } - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { - // Alt left click on the visible/lock columns - eat this event to keep row selection - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { - if (col == _tree.get_column(COL_ADD-1)) { - down_at_add = true; - return true; - } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { - _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); - _defer_target = path; - } else { - down_at_add = false; - } - } else { - down_at_add = false; - } - } - - if ( event->type == GDK_BUTTON_RELEASE) { - _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); - } - - // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. - if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { - - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { - if (_defer_target) { - if (_defer_target == path && !(event->x == 0 && event->y == 0)) - { - _tree.set_cursor(path, *col, false); - } - _defer_target = Gtk::TreeModel::Path(); - } else { - Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colObject]; - - if (obj) { - if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { - if (SP_IS_TAG(obj)) { - bool wasadded = false; - for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) - { - SPObject *newobj = reinterpret_cast(iter->data); - bool addchild = true; - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { - addchild = false; - } - } - if (addchild) { - Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); - obj->appendChild(clone); - wasadded = true; - } - } - if (wasadded) { - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to tag")); - } - } else { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - if (!todelete.empty()) { - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * tobj = *iter; - if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { - tobj->parent->getRepr()->removeChild(tobj->getRepr()); - } - } - } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - } - } - } - } - } - - - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } - - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { - Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colObject]; - if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { - // Double click on the Layer name, enable editing - _text_renderer->property_editable() = true; - _tree.set_cursor (path, *_name_column, true); - grab_focus(); - } - } - } - - return false; -} - -void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) -{ - Gtk::TreeModel::Row row = *iter; - SPObject* obj = row[_model->_colObject]; - SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; - if (item) - { - _dnd_source.push_back(item); - } -} - -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) -{ - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - _dnd_into = true; - _dnd_target = _document->getDefs(); - _dnd_source.clear(); - _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); - - if (_dnd_source.empty()) { - return true; - } - - if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _tree.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y > (int)(cell_height * 2/3)) { - Gtk::TreeModel::Path next_path = target_path; - next_path.next(); - if (_store->iter_is_valid(_store->get_iter(next_path))) { - target_path = next_path; - } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_store->iter_is_valid(_store->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - // Drop into the top level - _dnd_target = _document->getDefs(); - _dnd_into = true; - } - } - } - Gtk::TreeModel::iterator iter = _store->get_iter(target_path); - if (_store->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - SPObject *pobj = row[_model->_colParentObject]; - if (obj) { - if (SP_IS_TAG(obj)) { - _dnd_target = SP_TAG(obj); - } else if (SP_IS_TAG(obj->parent)) { - _dnd_target = SP_TAG(obj->parent); - _dnd_into = true; - } - } else if (pobj && SP_IS_TAG(pobj)) { - _dnd_target = SP_TAG(pobj); - _dnd_into = true; - } else { - return true; - } - } - } - - _takeAction(DRAGNDROP); - - return false; -} - -/* - * Move a layer in response to a drag & drop action - */ -void TagsPanel::_doTreeMove( ) -{ - if (_dnd_target) { - for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) - { - SPTag *src = *iter; - if (src != _dnd_target) { - src->moveTo(_dnd_target, _dnd_into); - } - } - _desktop->selection->clear(); - while (!_dnd_source.empty()) - { - SPTag *src = _dnd_source.back(); - _select_tag(src); - _dnd_source.pop_back(); - } - DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, - _("Moved tags")); - } -} - - -void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - _renameObject(row, new_text); - _text_renderer->property_editable() = false; -} - -void TagsPanel::_handleEditingCancelled() -{ - _text_renderer->property_editable() = false; -} - -void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && _desktop) { - SPObject* obj = row[_model->_colObject]; - if ( obj ) { - if (SP_IS_TAG(obj)) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, - _("Rename object")); - } - } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, - _("Rename object")); - } - } - } - } -} - -bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -{ - return false; -} - -bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -{ - bool val = true; - if ( !currentlySelected && _toggleEvent ) - { - GdkEvent* event = gtk_get_current_event(); - if ( event ) { - // (keep these checks separate, so we know when to call gdk_event_free() - if ( event->type == GDK_BUTTON_PRESS ) { - GdkEventButton const* target = reinterpret_cast(_toggleEvent); - GdkEventButton const* evtb = reinterpret_cast(event); - - if ( (evtb->window == target->window) - && (evtb->send_event == target->send_event) - && (evtb->time == target->time) - && (evtb->state == target->state) - ) - { - // Ooooh! It's a magic one - val = false; - } - } - gdk_event_free(event); - } - } - return val; -} - -void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) -{ - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colParentObject]; - if (obj && SP_IS_TAG(obj)) - { - SP_TAG(obj)->setExpanded(isexpanded); - obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - } -} - -/** - * Constructor - */ -TagsPanel::TagsPanel() : - UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), - _rootWatcher(0), - deskTrack(), - _desktop(0), - _document(0), - _model(0), - _pending(0), - _toggleEvent(0), - _defer_target(), - desktopChangeConn() -{ - //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - ModelColumns *zoop = new ModelColumns(); - _model = zoop; - - _store = Gtk::TreeStore::create( *zoop ); - - _tree.set_model( _store ); - _tree.set_headers_visible(false); - _tree.set_reorderable(true); - _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); - - Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); - int addColNum = _tree.append_column("type", *addRenderer) - 1; - Gtk::TreeViewColumn *col = _tree.get_column(addColNum); - if ( col ) { - col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); - col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); - } - - _text_renderer = manage(new Gtk::CellRendererText()); - int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; - _name_column = _tree.get_column(nameColNum); - _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); - - _tree.set_expander_column( *_tree.get_column(nameColNum) ); - - _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); - _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); - _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); - - _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); - _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); - _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); - - _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); - _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); - - _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); - _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); - _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); - - _scroller.add( _tree ); - _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_IN); - Gtk::Requisition sreq; -#if WITH_GTKMM_3_0 - Gtk::Requisition sreq_natural; - _scroller.get_preferred_size(sreq_natural, sreq); -#else - sreq = _scroller.size_request(); -#endif - int minHeight = 70; - if (sreq.height < minHeight) { - // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar - _scroller.set_size_request(sreq.width, minHeight); - } - - _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); - - _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); - - _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); - - SPDesktop* targetDesktop = getDesktop(); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new tag") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); - _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - -// btn = manage( new Gtk::Button("Dup") ); -// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); -// _buttonsRow.add( *btn ); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Tag") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); - _watching.push_back( btn ); - _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - - _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); - _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); - - // ------------------------------------------------------- - { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); - - _popupMenu.show_all_children(); - } - // ------------------------------------------------------- - - - - for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { - (*it)->set_sensitive( false ); - } - for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { - (*it)->set_sensitive( false ); - } - for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { - (*it)->set_sensitive( false ); - } - - setDesktop( targetDesktop ); - - show_all_children(); - - // restorePanelPrefs(); - - // Connect this up last - desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); - deskTrack.connect(GTK_WIDGET(gobj())); -} - -TagsPanel::~TagsPanel() -{ - - setDesktop(NULL); - - if ( _model ) - { - delete _model; - _model = 0; - } - - if (_pending) { - delete _pending; - _pending = 0; - } - - if ( _toggleEvent ) - { - gdk_event_free( _toggleEvent ); - _toggleEvent = 0; - } - - desktopChangeConn.disconnect(); - deskTrack.disconnect(); -} - -void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) -{ - while (!_objectWatchers.empty()) - { - TagsPanel::ObjectWatcher *w = _objectWatchers.back(); - w->_repr->removeObserver(*w); - _objectWatchers.pop_back(); - delete w; - } - - if (_rootWatcher) - { - _rootWatcher->_repr->removeObserver(*_rootWatcher); - delete _rootWatcher; - _rootWatcher = NULL; - } - - _document = document; - - if (document && document->getDefs() && document->getDefs()->getRepr()) - { - _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); - document->getDefs()->getRepr()->addObserver(*_rootWatcher); - _objectsChanged(document->getDefs()); - } -} - -void TagsPanel::setDesktop( SPDesktop* desktop ) -{ - Panel::setDesktop(desktop); - - if ( desktop != _desktop ) { - _documentChangedConnection.disconnect(); - _selectionChangedConnection.disconnect(); - if ( _desktop ) { - _desktop = 0; - } - - _desktop = Panel::getDesktop(); - if ( _desktop ) { - //setLabel( _desktop->doc()->name ); - _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); - _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); - - setDocument(_desktop, _desktop->doc()); - } - } -/* - GSList const *layers = _desktop->doc()->getResourceList( "layer" ); - g_message( "layers list starts at %p", layers ); - for ( GSList const *iter=layers ; iter ; iter = iter->next ) { - SPObject *layer=static_cast(iter->data); - g_message(" {%s} [%s]", layer->id, layer->label() ); - } -*/ - deskTrack.setBase(desktop); -} - - - - - -} //namespace Dialogs -} //namespace UI -} //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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h deleted file mode 100644 index d35dfba01..000000000 --- a/src/ui/dialog/tags.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * A simple dialog for tags UI. - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef SEEN_TAGS_PANEL_H -#define SEEN_TAGS_PANEL_H - -#include -#include -#include -#include -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/panel.h" -#include "ui/widget/object-composite-settings.h" -#include "desktop-tracker.h" -#include "ui/widget/style-subject.h" -#include "selection.h" -#include "ui/widget/filter-effect-chooser.h" - -class SPObject; -class SPTag; -struct SPColorSelector; - -namespace Inkscape { - -namespace UI { -namespace Dialog { - - -/** - * A panel that displays layers. - */ -class TagsPanel : public UI::Widget::Panel -{ -public: - TagsPanel(); - virtual ~TagsPanel(); - - //virtual void setOrientation( Gtk::AnchorType how ); - - static TagsPanel& getInstance(); - - void setDesktop( SPDesktop* desktop ); - void setDocument( SPDesktop* desktop, SPDocument* document); - -protected: - //virtual void _handleAction( int setId, int itemId ); - friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); -private: - class ModelColumns; - class InternalUIBounce; - class ObjectWatcher; - - TagsPanel(TagsPanel const &); // no copy - TagsPanel &operator=(TagsPanel const &); // no assign - - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); - void _fireAction( unsigned int code ); - Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); - - bool _handleButtonEvent(GdkEventButton *event); - bool _handleKeyEvent(GdkEventKey *event); - - void _storeDragSource(const Gtk::TreeModel::iterator& iter); - bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); - void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelled(); - - void _doTreeMove(); - void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); - - void _pushTreeSelectionToCurrent(); - void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); - void _select_tag( SPTag * tag ); - - void _checkTreeSelection(); - - void _takeAction( int val ); - bool _executeAction(); - - void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); - - bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); - bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); - - void _updateObject(SPObject *obj); - bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); - - void _objectsSelected(Selection *sel); - bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); - - void _objectsChanged(SPObject *root); - void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); - - void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); - -// std::vector groupConnections; - TagsPanel::ObjectWatcher* _rootWatcher; - std::vector _objectWatchers; - - // Hooked to the layer manager: - sigc::connection _documentChangedConnection; - sigc::connection _selectionChangedConnection; - - sigc::connection _changedConnection; - sigc::connection _addedConnection; - sigc::connection _removedConnection; - - // Internal - sigc::connection _selectedConnection; - sigc::connection _expandedConnection; - sigc::connection _collapsedConnection; - - DesktopTracker deskTrack; - SPDesktop* _desktop; - SPDocument* _document; - ModelColumns* _model; - InternalUIBounce* _pending; - gboolean _dnd_into; - std::vector _dnd_source; - SPObject* _dnd_target; - - GdkEvent* _toggleEvent; - bool down_at_add; - - Gtk::TreeModel::Path _defer_target; - - Glib::RefPtr _store; - std::vector _watching; - std::vector _watchingNonTop; - std::vector _watchingNonBottom; - - Gtk::TreeView _tree; - Gtk::CellRendererText *_text_renderer; - Gtk::TreeView::Column *_name_column; -#if WITH_GTKMM_3_0 - Gtk::Box _buttonsRow; - Gtk::Box _buttonsPrimary; - Gtk::Box _buttonsSecondary; -#else - Gtk::HBox _buttonsRow; - Gtk::HBox _buttonsPrimary; - Gtk::HBox _buttonsSecondary; -#endif - Gtk::ScrolledWindow _scroller; - Gtk::Menu _popupMenu; - Inkscape::UI::Widget::SpinButton _spinBtn; - Gtk::VBox _layersPage; - - sigc::connection desktopChangeConn; - -}; - - - -} //namespace Dialogs -} //namespace UI -} //namespace Inkscape - - - -#endif // SEEN_OBJECTS_PANEL_H - -/* - 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 : diff --git a/src/ui/widget/addtoicon.h b/src/ui/widget/addtoicon.h index aa8b4148e..9c134d231 100644 --- a/src/ui/widget/addtoicon.h +++ b/src/ui/widget/addtoicon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/clipmaskicon.h b/src/ui/widget/clipmaskicon.h index f1c1e7628..eca852a83 100644 --- a/src/ui/widget/clipmaskicon.h +++ b/src/ui/widget/clipmaskicon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index bf93fa960..2afdc02a6 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -7,7 +7,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include "display/cairo-utils.h" #include @@ -16,6 +23,7 @@ #include "widgets/icon.h" #include "widgets/toolbox.h" #include "ui/icon-names.h" +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/highlight-picker.h b/src/ui/widget/highlight-picker.h index 2d7dbc14e..c5fe4c02c 100644 --- a/src/ui/widget/highlight-picker.h +++ b/src/ui/widget/highlight-picker.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp index 9002a99c2..2f06225bc 100644 --- a/src/ui/widget/insertordericon.cpp +++ b/src/ui/widget/insertordericon.cpp @@ -7,6 +7,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif #include "ui/widget/insertordericon.h" diff --git a/src/ui/widget/layertypeicon.h b/src/ui/widget/layertypeicon.h index 4ad3f16fb..6c71ce361 100644 --- a/src/ui/widget/layertypeicon.h +++ b/src/ui/widget/layertypeicon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { -- cgit v1.2.3 From fd36e8d406b5ca3bfdc575a949351c6ae4a45c57 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 8 Mar 2014 20:52:27 -0500 Subject: Remove all trace of the Tags dialog Fixed Attach Path and Fill Between Many LPEs Enabled Gradient Meshes (bzr r13090.1.21) --- src/ui/dialog/swatches.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 34885a971..2a8471b55 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -6,6 +6,7 @@ * Jon A. Cruz * John Bintz * Abhishek Sharma + * Theodore Janezcko * * Copyright (C) 2005 Jon A. Cruz * Copyright (C) 2008 John Bintz -- cgit v1.2.3 From 9e33a22a12381e538c26580798934eb418f62bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Sun, 9 Mar 2014 22:06:46 -0300 Subject: Shortening code through removal of variable declaration used only at one place. (bzr r11950.6.1) --- src/ui/tools/freehand-base.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 40a257de9..4b7a310e3 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -501,8 +501,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) we modify it when continuing through an anchor. */ if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - SPDesktop *desktop = dc->desktop; - spdc_selection_modified(sp_desktop_selection(desktop), 0, dc); + spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); } c->unref(); return; -- cgit v1.2.3 From 4b8c6b64ba7ac54955cc68aa6ad18c67b57ef5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Sun, 9 Mar 2014 23:20:18 -0300 Subject: Removing repeated condition logical test to make the code more readable and easier to follow. (bzr r11950.6.2) --- src/ui/tools/freehand-base.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 4b7a310e3..3f74a5147 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -540,6 +540,11 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if(Geom::are_near(dc->sa->curve->first_path()->initialPoint(), dc->ea->dp)){ dc->sa->curve->closepath_current(); } + + // if the curve has an bspline or spiro LPE, we execute + // spdc_flush_white, passing the necessary starting curve. + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + spdc_flush_white(dc, dc->sa->curve); }else{ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { c = reverse_then_unref(c); @@ -547,16 +552,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - } - - //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - spdc_flush_white(dc, dc->sa->curve); - }else{ spdc_flush_white(dc, NULL); } + return; } -- cgit v1.2.3 From 13c192e2fa564c0a743e13e30b1cf6de9b1a39a6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 12 Mar 2014 08:56:04 -0400 Subject: Reverted swatches Removed a toy effect (not ready yet) Fixed a bug with Livarot General cleanup (bzr r13090.1.23) --- src/ui/dialog/color-item.cpp | 862 ++++++++-- src/ui/dialog/color-item.h | 108 +- src/ui/dialog/object-properties.cpp | 1 + src/ui/dialog/objects.cpp | 227 +-- src/ui/dialog/swatches.cpp | 2944 +++++++++++------------------------ src/ui/dialog/swatches.h | 153 +- 6 files changed, 1825 insertions(+), 2470 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index a1951ec48..bab7e18e1 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,8 +11,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include +#include #include #include @@ -35,216 +45,766 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" -#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE -#include namespace Inkscape { namespace UI { namespace Dialogs { +static std::vector mimeStrings; +static std::map mimeToInt; + -bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) +#if ENABLE_MAGIC_COLORS +// TODO remove this soon: +extern std::vector possible; +#endif // ENABLE_MAGIC_COLORS + + +#if ENABLE_MAGIC_COLORS +static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); + bool changed = false; + + if ( node ) { + gchar const * val = node->attribute("inkscape:x-fill-tag"); + if ( val && (match == val) ) { + SPObject *obj = document->getObjectByRepr( node ); + + gchar c[64] = {0}; + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, "fill", c ); + + sp_desktop_apply_css_recursive( obj, css, true ); + static_cast(obj)->updateRepr(); + + changed = true; + } + + val = node->attribute("inkscape:x-stroke-tag"); + if ( val && (match == val) ) { + SPObject *obj = document->getObjectByRepr( node ); + + gchar c[64] = {0}; + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, "stroke", c ); + + sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); + ((SPItem*)obj)->updateRepr(); + + changed = true; + } + + Inkscape::XML::Node* first = node->firstChild(); + changed |= bruteForce( document, first, match, r, g, b ); + + changed |= bruteForce( document, node->next(), match, r, g, b ); } - return Gtk::Widget::on_enter_notify_event(event); + + return changed; +} +#endif // ENABLE_MAGIC_COLORS + +static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); + } +} + +static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); + } +} + +static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), + item->def.descr.c_str()); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); + } + } + return FALSE; +} + +static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); + } + } + return FALSE; } -bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) +static void dieDieDie( GObject *obj, gpointer user_data ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); + g_message("die die die %p %p", obj, user_data ); +} + +static bool getBlock( std::string& dst, guchar ch, std::string const & str ) +{ + bool good = false; + std::string::size_type pos = str.find(ch); + if ( pos != std::string::npos ) + { + std::string::size_type pos2 = str.find( '(', pos ); + if ( pos2 != std::string::npos ) { + std::string::size_type endPos = str.find( ')', pos2 ); + if ( endPos != std::string::npos ) { + dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); + good = true; + } + } } - return Gtk::Widget::on_leave_notify_event(event); + return good; } -void ColorItem::selection_modified(Selection* selection, guint flags) +static bool popVal( guint64& numVal, std::string& str ) { - selection_changed(selection); + bool good = false; + std::string::size_type endPos = str.find(','); + if ( endPos == std::string::npos ) { + endPos = str.length(); + } + + if ( endPos != std::string::npos && endPos > 0 ) { + std::string xxx = str.substr( 0, endPos ); + const gchar* ptr = xxx.c_str(); + gchar* endPtr = 0; + numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); + if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { + // overflow + } else if ( (numVal == 0) && (endPtr == ptr) ) { + // failed conversion + } else { + good = true; + str.erase( 0, endPos + 1 ); + } + } + + return good; } -void ColorItem::selection_changed(Selection* selection) +// TODO resolve this more cleanly: +extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); + +static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) { - SPItem* item = selection->singleItem(); - SPPaintServer* grad; - if (item && - ( - (item->style->fill.isPaintserver() && - SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) - && SP_GRADIENT(grad)->getVector() == gradient) || - - (item->style->stroke.isPaintserver() && - SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && - SP_GRADIENT(grad)->getVector() == gradient) - ) - ) + ColorItem* item = reinterpret_cast(data); + if ( item ) { - if (!_isSelected) { - _isSelected = true; - queue_draw(); + using Inkscape::IO::Resource::get_path; + using Inkscape::IO::Resource::ICONS; + using Inkscape::IO::Resource::SYSTEM; + int width = 32; + int height = 24; + + if (item->def.getType() != ege::PaintDef::RGB){ + GError *error = NULL; + gsize bytesRead = 0; + gsize bytesWritten = 0; + gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), + -1, + &bytesRead, + &bytesWritten, + &error); + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); + g_free(localFilename); + gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + } else { + GdkPixbuf* pixbuf = 0; + if ( item->getGradient() ){ + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, gradient); + cairo_paint(ct); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_surface_flush(s); + + pixbuf = ink_pixbuf_create_from_cairo_surface(s); + } else { + Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); + guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) + | (0x00ff0000 & (item->def.getG() << 16)) + | (0x0000ff00 & (item->def.getB() << 8)); + thumb->fill( fillWith ); + pixbuf = thumb->gobj(); + g_object_ref(G_OBJECT(pixbuf)); + } + gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); } - } else if (_isSelected) { - _isSelected = false; - queue_draw(); } + +} + +//"drag-drop" +// gboolean dragDropColorData( GtkWidget *widget, +// GdkDragContext *drag_context, +// gint x, +// gint y, +// guint time, +// gpointer user_data) +// { +// // TODO finish + +// return TRUE; +// } + + +SwatchPage::SwatchPage() + : _prefWidth(0) +{ } -ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : - Glib::ObjectBase("coloritem"), - Gtk::Widget(), - def( name ), - gradient(grad), - _isSelected(false) +SwatchPage::~SwatchPage() { - set_has_window(true); - add_events(Gdk::BUTTON_PRESS_MASK); - add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); - sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); - mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); - selection_changed(desktop->selection); } -void ColorItem::on_size_request(Gtk::Requisition* requisition) + +ColorItem::ColorItem(ege::PaintDef::ColorType type) : + def(type), + _isFill(false), + _isStroke(false), + _isLive(false), + _linkIsTone(false), + _linkPercent(0), + _linkGray(0), + _linkSrc(0), + _grad(0), + _pattern(0) { - requisition->height = 20; - requisition->width = 20; } -void ColorItem::on_size_allocate(Gtk::Allocation& allocation) +ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : + def( r, g, b, name ), + _isFill(false), + _isStroke(false), + _isLive(false), + _linkIsTone(false), + _linkPercent(0), + _linkGray(0), + _linkSrc(0), + _grad(0), + _pattern(0) { - set_allocation(allocation); - if (m_refGdkWindow) - { - m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); +} + +ColorItem::~ColorItem() +{ + if (_pattern != NULL) { + cairo_pattern_destroy(_pattern); + } +} + +ColorItem::ColorItem(ColorItem const &other) : + Inkscape::UI::Previewable() +{ + if ( this != &other ) { + *this = other; + } +} + +ColorItem &ColorItem::operator=(ColorItem const &other) +{ + if ( this != &other ) { + def = other.def; + + // TODO - correct linkage + _linkSrc = other._linkSrc; + g_message("Erk!"); + } + return *this; +} + +void ColorItem::setState( bool fill, bool stroke ) +{ + if ( (_isFill != fill) || (_isStroke != stroke) ) { + _isFill = fill; + _isStroke = stroke; + + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + EekPreview * preview = EEK_PREVIEW(widget->gobj()); + + int val = eek_preview_get_linked( preview ); + val &= ~(PREVIEW_FILL | PREVIEW_STROKE); + if ( _isFill ) { + val |= PREVIEW_FILL; + } + if ( _isStroke ) { + val |= PREVIEW_STROKE; + } + eek_preview_set_linked( preview, static_cast(val) ); + } + } + } +} + +void ColorItem::setGradient(SPGradient *grad) +{ + if (_grad != grad) { + _grad = grad; + // TODO regen and push to listeners } + + setName( gr_prepare_label(_grad) ); } -void ColorItem::on_map() +void ColorItem::setName(const Glib::ustring name) { - Gtk::Widget::on_map(); + //def.descr = name; + + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str()); + } + else if ( GTK_IS_LABEL(widget->gobj()) ) { + gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str()); + } + } } -void ColorItem::on_unmap() +void ColorItem::setPattern(cairo_pattern_t *pattern) { - Gtk::Widget::on_unmap(); + if (pattern) { + cairo_pattern_reference(pattern); + } + if (_pattern) { + cairo_pattern_destroy(_pattern); + } + _pattern = pattern; + + _updatePreviews(); } -void ColorItem::on_realize() +void ColorItem::_dragGetColorData( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + GtkSelectionData *data, + guint info, + guint /*time*/, + gpointer user_data) +{ + ColorItem* item = reinterpret_cast(user_data); + std::string key; + if ( info < mimeStrings.size() ) { + key = mimeStrings[info]; + } else { + g_warning("ERROR: unknown value (%d)", info); + } + + if ( !key.empty() ) { + char* tmp = 0; + int len = 0; + int format = 0; + item->def.getMIMEData(key, tmp, len, format); + if ( tmp ) { + GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); + gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); + delete[] tmp; + } + } +} + +void ColorItem::_dropDataIn( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, + GtkSelectionData */*data*/, + guint /*info*/, + guint /*event_time*/, + gpointer /*user_data*/) { - set_realized(); - ensure_style(); - - if(!m_refGdkWindow) - { - //Create the GdkWindow: - - GdkWindowAttr attributes; - memset(&attributes, 0, sizeof(attributes)); - - Gtk::Allocation allocation = get_allocation(); - - //Set initial position and size of the Gdk::Window: - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); - - attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - - m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, - GDK_WA_X | GDK_WA_Y); - set_window(m_refGdkWindow); - - //Attach this widget's style to its Gdk::Window. - style_attach(); - - //make the widget receive expose events - m_refGdkWindow->set_user_data(gobj()); - } } -void ColorItem::on_unrealize() +void ColorItem::_colorDefChanged(void* data) { - m_refGdkWindow.reset(); - - Gtk::Widget::on_unrealize(); + ColorItem* item = reinterpret_cast(data); + if ( item ) { + item->_updatePreviews(); + } } -bool ColorItem::on_expose_event(GdkEventExpose* event) +void ColorItem::_updatePreviews() { - if(m_refGdkWindow) + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + EekPreview * preview = EEK_PREVIEW(widget->gobj()); + + _regenPreview(preview); + + widget->queue_draw(); + } + } + + for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { + guint r = def.getR(); + guint g = def.getG(); + guint b = def.getB(); + + if ( (*it)->_linkIsTone ) { + r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; + g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; + b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; + } else { + r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; + g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; + b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; + } + + (*it)->def.setRGB( r, g, b ); + } + + +#if ENABLE_MAGIC_COLORS + // Look for objects using this color { - Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); - if(event) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + SPDocument* document = sp_desktop_document( desktop ); + Inkscape::XML::Node *rroot = document->getReprRoot(); + if ( rroot ) { + + // Find where this thing came from + Glib::ustring paletteName; + bool found = false; + int index = 0; + for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { + SwatchPage* curr = *it2; + index = 0; + for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { + if ( this == &*zz ) { + found = true; + paletteName = curr->_name; + break; + } else { + index++; + } + } + } + + if ( !paletteName.empty() ) { + gchar* str = g_strdup_printf("%d|", index); + paletteName.insert( 0, str ); + g_free(str); + str = 0; + + if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { + SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, + _("Change color definition")); + } + } + } + } + } +#endif // ENABLE_MAGIC_COLORS + +} + +void ColorItem::_regenPreview(EekPreview * preview) +{ + if ( def.getType() != ege::PaintDef::RGB ) { + using Inkscape::IO::Resource::get_path; + using Inkscape::IO::Resource::ICONS; + using Inkscape::IO::Resource::SYSTEM; + GError *error = NULL; + gsize bytesRead = 0; + gsize bytesWritten = 0; + gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), + -1, + &bytesRead, + &bytesWritten, + &error); + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); + if (!pixbuf) { + g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); + } + g_free(localFilename); + + eek_preview_set_pixbuf( preview, pixbuf ); + } + else if ( !_pattern ){ + eek_preview_set_color( preview, + (def.getR() << 8) | def.getR(), + (def.getG() << 8) | def.getG(), + (def.getB() << 8) | def.getB() ); + } else { + // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp + // TODO: the pattern to draw should be in the widget that draws the preview, + // so the preview can be scalable + int w = 128; + int h = 16; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, _pattern); + cairo_paint(ct); + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); + eek_preview_set_pixbuf( preview, pixbuf ); + } + + eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) + | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) + | (_isLive ? PREVIEW_LINK_OTHER:0)) ); +} + +Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) +{ + Gtk::Widget* widget = 0; + if ( style == PREVIEW_STYLE_BLURB) { + Gtk::Label *lbl = new Gtk::Label(def.descr); + lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + widget = lbl; + } else { + GtkWidget* eekWidget = eek_preview_new(); + EekPreview * preview = EEK_PREVIEW(eekWidget); + Gtk::Widget* newBlot = Glib::wrap(eekWidget); + _regenPreview(preview); + + eek_preview_set_details( preview, + (::ViewType)view, + (::PreviewSize)size, + ratio, + border ); + + def.addCallback( _colorDefChanged, this ); + eek_preview_set_focus_on_click(preview, FALSE); + newBlot->set_tooltip_text(def.descr); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "clicked", + G_CALLBACK(handleClick), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "alt-clicked", + G_CALLBACK(handleSecondaryClick), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "button-press-event", + G_CALLBACK(colorItemHandleButtonPress), + this); + { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); - cr->clip(); + std::vector listing = def.getMIMETypes(); + int entryCount = listing.size(); + GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; + GtkTargetEntry* curr = entries; + for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { + curr->target = g_strdup(it->c_str()); + curr->flags = 0; + if ( mimeToInt.find(*it) == mimeToInt.end() ){ + // these next lines are order-dependent: + mimeToInt[*it] = mimeStrings.size(); + mimeStrings.push_back(*it); + } + curr->info = mimeToInt[curr->target]; + curr++; + } + gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), + GDK_BUTTON1_MASK, + entries, entryCount, + GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); + for ( int i = 0; i < entryCount; i++ ) { + g_free(entries[i].target); + } + delete[] entries; } - if (gradient) { - cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); - - Cairo::RefPtr checkpat(new Cairo::Pattern(check)); - - cr->set_source(checkpat); - cr->paint(); - - cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); - Cairo::RefPtr gpat(new Cairo::Pattern(g)); - cr->set_source(gpat); - cr->paint(); - gpat.clear(); - cairo_pattern_destroy(g); - - checkpat.clear(); - - cairo_pattern_destroy(check); - - if (_isSelected) { - cr->set_source_rgb(0, 0, 0); - cr->set_line_width(3); - cr->move_to(0, get_allocation().get_height()); - cr->line_to(0,0); - cr->line_to(get_allocation().get_width(), 0); - cr->stroke(); - cr->move_to(get_allocation().get_width(), 0); - cr->set_source_rgb(1, 1, 1); - cr->line_to(get_allocation().get_width(), get_allocation().get_height()); - cr->line_to(0, get_allocation().get_height()); - //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); - cr->stroke(); + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-data-get", + G_CALLBACK(ColorItem::_dragGetColorData), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-begin", + G_CALLBACK(colorItemDragBegin), + this ); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "enter-notify-event", + G_CALLBACK(handleEnterNotify), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "leave-notify-event", + G_CALLBACK(handleLeaveNotify), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "destroy", + G_CALLBACK(dieDieDie), + this); + + + widget = newBlot; + } + + _previews.push_back( widget ); + + return widget; +} + +void ColorItem::buttonClicked(bool secondary) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + char const * attrName = secondary ? "stroke" : "fill"; + + SPCSSAttr *css = sp_repr_css_attr_new(); + Glib::ustring descr; + switch (def.getType()) { + case ege::PaintDef::CLEAR: { + // TODO actually make this clear + sp_repr_css_set_property( css, attrName, "none" ); + descr = secondary? _("Remove stroke color") : _("Remove fill color"); + break; + } + case ege::PaintDef::NONE: { + sp_repr_css_set_property( css, attrName, "none" ); + descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); + break; + } +//mark + case ege::PaintDef::RGB: { + Glib::ustring colorspec; + if ( _grad ){ + colorspec = "url(#"; + colorspec += _grad->getId(); + colorspec += ")"; + } else { + gchar c[64]; + guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; + sp_svg_write_color(c, sizeof(c), rgba); + colorspec = c; + } +//end mark + sp_repr_css_set_property( css, attrName, colorspec.c_str() ); + descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); + break; } - } else { - cr->set_source_rgb(1, 1, 1); - cr->paint(); - cr->set_source_rgb(1, 0, 0); - cr->set_line_width(3); - cr->move_to(0,0); - cr->line_to(get_allocation().get_width(), get_allocation().get_height()); - cr->move_to(get_allocation().get_width(), 0); - cr->line_to(0, get_allocation().get_height()); - cr->stroke(); } + sp_desktop_set_style(desktop, css); + sp_repr_css_attr_unref(css); + + DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); } - return true; } -ColorItem::~ColorItem() +void ColorItem::_wireMagicColors( SwatchPage *colorSet ) +{ + if ( colorSet ) + { + for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) + { + std::string::size_type pos = it->def.descr.find("*{"); + if ( pos != std::string::npos ) + { + std::string subby = it->def.descr.substr( pos + 2 ); + std::string::size_type endPos = subby.find("}*"); + if ( endPos != std::string::npos ) + { + subby.erase( endPos ); + //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); + //g_message(" '%s'", subby.c_str()); + + if ( subby.find('E') != std::string::npos ) + { + it->def.setEditable( true ); + } + + if ( subby.find('L') != std::string::npos ) + { + it->_isLive = true; + } + + std::string part; + // Tint. index + 1 more val. + if ( getBlock( part, 'T', subby ) ) { + guint64 colorIndex = 0; + if ( popVal( colorIndex, part ) ) { + guint64 percent = 0; + if ( popVal( percent, part ) ) { + it->_linkTint( colorSet->_colors[colorIndex], percent ); + } + } + } + + // Shade/tone. index + 1 or 2 more val. + if ( getBlock( part, 'S', subby ) ) { + guint64 colorIndex = 0; + if ( popVal( colorIndex, part ) ) { + guint64 percent = 0; + if ( popVal( percent, part ) ) { + guint64 grayLevel = 0; + if ( !popVal( grayLevel, part ) ) { + grayLevel = 0; + } + it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); + } + } + } + + } + } + } + } +} + + +void ColorItem::_linkTint( ColorItem& other, int percent ) +{ + if ( !_linkSrc ) + { + other._listeners.push_back(this); + _linkIsTone = false; + _linkPercent = percent; + if ( _linkPercent > 100 ) + _linkPercent = 100; + if ( _linkPercent < 0 ) + _linkPercent = 0; + _linkGray = 0; + _linkSrc = &other; + + ColorItem::_colorDefChanged(&other); + } +} + +void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) { - sel_connection.disconnect(); - mod_connection.disconnect(); + if ( !_linkSrc ) + { + other._listeners.push_back(this); + _linkIsTone = true; + _linkPercent = percent; + if ( _linkPercent > 100 ) + _linkPercent = 100; + if ( _linkPercent < 0 ) + _linkPercent = 0; + _linkGray = grayLevel; + _linkSrc = &other; + + ColorItem::_colorDefChanged(&other); + } } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 5d97d8803..3a0b33193 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,11 +15,7 @@ #include #include "widgets/ege-paint-def.h" -#include "widgets/eek-preview.h" -#include -#include -#include "desktop.h" -#include "selection.h" +#include "ui/previewable.h" class SPGradient; @@ -27,43 +23,89 @@ namespace Inkscape { namespace UI { namespace Dialogs { +class ColorItem; + +class SwatchPage +{ +public: + SwatchPage(); + ~SwatchPage(); + + Glib::ustring _name; + int _prefWidth; + boost::ptr_vector _colors; +}; + /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Gtk::Widget +class ColorItem : public Inkscape::UI::Previewable { + friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); + ColorItem( ege::PaintDef::ColorType type ); + ColorItem( unsigned int r, unsigned int g, unsigned int b, + Glib::ustring& name ); virtual ~ColorItem(); - - SPGradient * getGradient() { return gradient; } - -protected: - - const gchar* def; - SPGradient * gradient; - virtual bool on_enter_notify_event(GdkEventCrossing* event); - virtual bool on_leave_notify_event(GdkEventCrossing* event); - - virtual void on_size_request(Gtk::Requisition* requisition); - virtual void on_size_allocate(Gtk::Allocation& allocation); - virtual void on_map(); - virtual void on_unmap(); - virtual void on_realize(); - virtual void on_unrealize(); - virtual bool on_expose_event(GdkEventExpose* event); - - Glib::RefPtr m_refGdkWindow; - - + ColorItem(ColorItem const &other); + virtual ColorItem &operator=(ColorItem const &other); + virtual Gtk::Widget* getPreview(PreviewStyle style, + ViewType view, + ::PreviewSize size, + guint ratio, + guint border); + void buttonClicked(bool secondary = false); + + void setGradient(SPGradient *grad); + SPGradient * getGradient() const { return _grad; } + void setPattern(cairo_pattern_t *pattern); + void setName(const Glib::ustring name); + + void setState( bool fill, bool stroke ); + bool isFill() { return _isFill; } + bool isStroke() { return _isStroke; } + + ege::PaintDef def; + private: - void selection_changed(Selection* selection); - void selection_modified(Selection* selection, guint flags); - sigc::connection sel_connection; - sigc::connection mod_connection; - bool _isSelected; + static void _dropDataIn( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data); + + static void _dragGetColorData( GtkWidget *widget, + GdkDragContext *drag_context, + GtkSelectionData *data, + guint info, + guint time, + gpointer user_data); + + static void _wireMagicColors( SwatchPage *colorSet ); + static void _colorDefChanged(void* data); + + void _updatePreviews(); + void _regenPreview(EekPreview * preview); + + void _linkTint( ColorItem& other, int percent ); + void _linkTone( ColorItem& other, int percent, int grayLevel ); + + std::vector _previews; + + bool _isFill; + bool _isStroke; + bool _isLive; + bool _linkIsTone; + int _linkPercent; + int _linkGray; + ColorItem* _linkSrc; + SPGradient* _grad; + cairo_pattern_t *_pattern; + std::vector _listeners; }; } // namespace Dialogs diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 82b2cf6b1..8f36cba43 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -467,6 +467,7 @@ void ObjectProperties::label_changed(void) blocked = true; /* Retrieve the label widget for the object's id */ + //bug 1290573: getId() crashes after undo (cannot create string from NULL ptr) gchar *id = g_strdup(EntryID.get_text().c_str()); g_strcanon (id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); if (!strcmp (id, item->getId())) { diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index ebfa16f02..2095546fb 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -3,6 +3,7 @@ * * Authors: * Theodore Janeczko + * Tweaked by Liam P White for use in Inkscape * * Copyright (C) Theodore Janeczko 2012 * @@ -17,20 +18,31 @@ #include #include #include +#include #include #include "desktop.h" #include "desktop-style.h" +#include "dialogs/dialog-events.h" #include "document.h" #include "document-undo.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" #include "helper/action.h" #include "inkscape.h" +#include "layer-manager.h" #include "preferences.h" +#include "selection.h" +#include "sp-clippath.h" +#include "sp-mask.h" #include "sp-item.h" #include "sp-object.h" +#include "sp-root.h" #include "sp-shape.h" -#include "svg/css-ostringstream.h" +#include "style.h" +#include "tools-switch.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" @@ -38,29 +50,16 @@ #include "ui/widget/clipmaskicon.h" #include "ui/widget/highlight-picker.h" #include "ui/tools/node-tool.h" +#include "ui/tools/tool-base.h" #include "verbs.h" +#include "widgets/sp-color-notebook.h" #include "widgets/icon.h" #include "xml/node.h" #include "xml/node-observer.h" #include "xml/repr.h" -#include "sp-root.h" -//#include "event-context.h" -#include "selection.h" -#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" -#include "style.h" -#include "filter-chemistry.h" -#include "filters/blend.h" -#include "filters/gaussian-blur.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "layer-manager.h" -#include "tools-switch.h" //#define DUMP_LAYERS 1 -guint get_group0_keyval(GdkEventKey *event); - namespace Inkscape { namespace UI { namespace Dialog { @@ -82,7 +81,7 @@ enum { COL_VISIBLE = 1, COL_LOCKED, COL_TYPE, - COL_INSERTORDER, +// COL_INSERTORDER, COL_CLIPMASK, COL_HIGHLIGHT }; @@ -106,8 +105,8 @@ enum { BUTTON_LOCK_ALL, BUTTON_UNLOCK_ALL, BUTTON_SETCLIP, - BUTTON_CLIPGROUP, - BUTTON_SETINVCLIP, +// BUTTON_CLIPGROUP, +// BUTTON_SETINVCLIP, BUTTON_UNSETCLIP, BUTTON_SETMASK, BUTTON_UNSETMASK, @@ -214,7 +213,7 @@ public: add(_colType); add(_colHighlight); add(_colClipMask); - add(_colInsertOrder); + //add(_colInsertOrder); } virtual ~ModelColumns() {} @@ -225,7 +224,7 @@ public: Gtk::TreeModelColumn _colType; Gtk::TreeModelColumn _colHighlight; Gtk::TreeModelColumn _colClipMask; - Gtk::TreeModelColumn _colInsertOrder; + //Gtk::TreeModelColumn _colInsertOrder; }; /** @@ -352,13 +351,19 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); Gtk::TreeModel::Row row = *iter; row[_model->_colObject] = item; - row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + //this seems to crash on convert stroke to path then undo (probably no ID?) + try { + row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + } catch (...) { + row[_model->_colLabel] = Glib::ustring("getId_failure"); + g_critical("item->getId() failed, using \"getId_failure\""); + } row[_model->_colVisible] = !item->isHidden(); row[_model->_colLocked] = !item->isSensitive(); row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); - row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; //If our parent object is a group and it's expanded, expand the tree if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) @@ -388,7 +393,10 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) */ void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { //Find the object in the tree store and update it + + //mark _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); + //end mark if (recurse) { for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) @@ -419,7 +427,7 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; - row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; return true; } @@ -685,7 +693,9 @@ void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const b bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + bool empty = _desktop->selection->isEmpty(); + + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: @@ -702,68 +712,33 @@ bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) } break; case GDK_Home: - { //Move item(s) to top of containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_FRONT ); - } - return true; - } + _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT ); + break; case GDK_End: - { //Move item(s) to bottom of containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_BACK ); - } - return true; - } + _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); + break; case GDK_KEY_Page_Up: { //Move item(s) up in containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - else - { - if (event->state & GDK_SHIFT_MASK) { - _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); - } else { - _fireAction( SP_VERB_SELECTION_RAISE ); - } - } - return true; + int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_RAISE; + _fireAction( empty ? SP_VERB_LAYER_RAISE : ch ); + break; } case GDK_KEY_Page_Down: { //Move item(s) down in containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - else - { - if (event->state & GDK_SHIFT_MASK) { - _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); - } else { - _fireAction( SP_VERB_SELECTION_LOWER ); - } - } - return true; + int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_LOWER; + _fireAction( empty ? SP_VERB_LAYER_LOWER : ch ); + break; } + //TODO: Handle Ctrl-A, etc. + default: + return false; } - return false; + return true; } /** @@ -809,7 +784,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) return true; } else if (col == _tree.get_column(COL_LOCKED-1) || col == _tree.get_column(COL_TYPE-1) || - col == _tree.get_column(COL_INSERTORDER - 1) || + //col == _tree.get_column(COL_INSERTORDER - 1) || col == _tree.get_column(COL_HIGHLIGHT-1)) { //Click on an icon column, eat this event to keep row selection return true; @@ -926,7 +901,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, newValue? _("Layer to group") : _("Group to layer")); } - } else if (col == _tree.get_column(COL_INSERTORDER - 1)) { + } /*else if (col == _tree.get_column(COL_INSERTORDER - 1)) { if (SP_IS_GROUP(item)) { //Toggle the current item's insert order @@ -938,7 +913,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, newValue? _("Set insert mode bottom") : _("Set insert mode top")); } - } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { + }*/ else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { //Clear the highlight targets _highlight_target.clear(); if (_tree.get_selection()->is_selected(path)) @@ -1474,7 +1449,7 @@ void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) target->setHighlightColor(rgba); target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); } - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); + DocumentUndo::maybeDone(SP_ACTIVE_DOCUMENT, "highlight", SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); } /** @@ -1689,13 +1664,13 @@ ObjectsPanel::ObjectsPanel() : col->add_attribute( typeRenderer->property_active(), _model->_colType ); } - //Insert order - Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); + //Insert order (LiamW: unused) + /*Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); int insertColNum = _tree.append_column("type", *insertRenderer) - 1; col = _tree.get_column(insertColNum); if ( col ) { col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder ); - } + }*/ //Clip/mask Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); @@ -1807,43 +1782,102 @@ ObjectsPanel::ObjectsPanel() : SPDesktop* targetDesktop = getDesktop(); //Set up the button row + + + //Add object/layer Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); + btn->set_tooltip_text(_("Add layer...")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + Gtk::Image *image_add = Gtk::manage(new Gtk::Image()); + image_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_add); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + //Remove object btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); + btn->set_tooltip_text(_("Remove object")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + Gtk::Image *image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + //Move to bottom btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); + btn->set_tooltip_text(_("Move To Bottom")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - + + //Move down btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); + btn->set_tooltip_text(_("Move Down")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + //Move up btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); + btn->set_tooltip_text(_("Move Up")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + //Move to top btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); + btn->set_tooltip_text(_("Move To Top")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); + //Collapse all + btn = Gtk::manage( new Gtk::Button(Gtk::Stock::UNINDENT) ); + btn->set_tooltip_text(_("Collapse All")); + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); @@ -2042,15 +2076,6 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) //should be okay to put these here because they are never referenced anywhere else using namespace Inkscape::UI::Tools; -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - void SPItem::setHighlightColor(guint32 const color) { g_free(_highlightColor); @@ -2065,7 +2090,7 @@ void SPItem::setHighlightColor(guint32 const color) NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { - ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); tools_switch(tool->desktop, TOOLS_NODES); @@ -2079,7 +2104,7 @@ void SPItem::unsetHighlightColor() _highlightColor = NULL; NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { - ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); tools_switch(tool->desktop, TOOLS_NODES); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2a8471b55..807618b4d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -6,7 +6,6 @@ * Jon A. Cruz * John Bintz * Abhishek Sharma - * Theodore Janezcko * * Copyright (C) 2005 Jon A. Cruz * Copyright (C) 2008 John Bintz @@ -21,7 +20,6 @@ #include "swatches.h" #include -#include #include #include @@ -47,6 +45,7 @@ #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" +#include "ui/previewholder.h" #include "widgets/desktop-widget.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" @@ -57,2305 +56,1130 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" -#include "xml/node-observer.h" -#include "xml/repr.h" -#include "sp-pattern.h" -#include "icon-size.h" -#include "widgets/icon.h" -#include "filedialog.h" -#include "sp-stop.h" -#include "svg/svg-color.h" -#include "sp-radial-gradient.h" -#include "color-rgba.h" -#include "ui/tools/tool-base.h" -#include "svg/css-ostringstream.h" -#include -#ifdef WIN32 -#include -#endif - -//lazy! -void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); +#include "helper/action-context.h" namespace Inkscape { namespace UI { namespace Dialogs { -#define SWATCHES_FILE_NAME "swatches.svg" - -static char* trim( char* str ) { - char* ret = str; - while ( *str && (*str == ' ' || *str == '\t') ) { - str++; - } - ret = str; - while ( *str ) { - str++; - } - str--; - while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { - *str-- = 0; - } - return ret; -} - -static void skipWhitespace( char*& str ) { - while ( *str == ' ' || *str == '\t' ) { - str++; - } -} - -static bool parseNum( char*& str, int& val ) { - val = 0; - while ( '0' <= *str && *str <= '9' ) { - val = val * 10 + (*str - '0'); - str++; - } - bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); - return retval; -} - -static char * SwatchFile; -static SPDocument * SwatchDocument; -static unsigned int page_suffix; - -static void loadPalletFile() -{ - if (!SwatchDocument) { - SwatchFile=g_build_filename(INKSCAPE_PALETTESDIR, _("swatches.svg"), NULL); - SwatchDocument=SPDocument::createNewDoc (SwatchFile, TRUE); - if (!SwatchDocument) { - SwatchDocument = SPDocument::createNewDoc(NULL, TRUE, true); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - } -} - -static void addStop( Inkscape::XML::Node *parent, Glib::ustring const &color, gfloat opacity, gchar const *offset ) -{ -#ifdef SP_GR_VERBOSE - g_message("addStop(%p, %s, %d, %s)", parent, color.c_str(), opacity, offset); -#endif - Inkscape::XML::Node *stop = parent->document()->createElement("svg:stop"); - { - gchar *tmp = g_strdup_printf( "stop-color:%s;stop-opacity:%f;", color.c_str(), opacity < 0.0 ? 0.0 : (opacity > 1.0 ? 1.0 : opacity) ); - stop->setAttribute( "style", tmp ); - g_free(tmp); - } - - stop->setAttribute( "offset", offset ); - - parent->appendChild(stop); - Inkscape::GC::release(stop); -} - -static SPGroup* importGPL(SPDocument* doc, const gchar* full) -{ - SPGroup* ret = NULL; - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - - /*Load the pallet file here*/ - char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( full, "r" ); - if ( f ) { - char* result = fgets( block, sizeof(block), f ); - if ( result ) { - if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { - bool inHeader = true; - bool hasErr = false; - - Inkscape::XML::Node * page = doc->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (doc->getObjectById(id)); - - page->setAttribute("id", id); - - do { - result = fgets( block, sizeof(block), f ); - block[sizeof(block) - 1] = 0; - if ( result ) { - if ( block[0] == '#' ) { - // ignore comment - } else { - char *ptr = block; - // very simple check for header versus entry - while ( *ptr == ' ' || *ptr == '\t' ) { - ptr++; - } - if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { - // blank line. skip it. - } else if ( '0' <= *ptr && *ptr <= '9' ) { - // should be an entry link - inHeader = false; - ptr = block; - Glib::ustring name(""); - skipWhitespace(ptr); - if ( *ptr ) { - int r = 0; - int g = 0; - int b = 0; - hasErr = parseNum(ptr, r); - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, g); - } - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, b); - } - if ( !hasErr && *ptr ) { - char* n = trim(ptr); - if (n != NULL) { - name = g_dpgettext2(NULL, "Palette", n); - } - } - if ( !hasErr ) { - // Add the entry now - - Inkscape::XML::Node *grad = doc->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute("inkscape:label", name.c_str()); - grad->setAttribute( "osb:paint", "solid", 0 ); - SPColor color((float)r / 255, (float)g / 255, (float)b / 255); - addStop(grad, color.toString(), 1, "0"); - page->appendChild(grad); - Inkscape::GC::release(grad); - } - } else { - hasErr = true; - } - } else { - if ( !inHeader ) { - // Hmmm... probably bad. Not quite the format we want? - hasErr = true; - } else { - char* sep = strchr(result, ':'); - if ( sep ) { - *sep = 0; - char* val = trim(sep + 1); - char* name = trim(result); - if ( *name ) { - if ( strcmp( "Name", name ) == 0 ) - { - page->setAttribute("inkscape:label", val); - } - } else { - // error - hasErr = true; - } - } else { - // error - hasErr = true; - } - } - } - } - } - } while ( result && !hasErr ); - if ( !hasErr ) { - doc->getDefs()->appendChild(page); - Inkscape::GC::release(page); - SPObject* obj = doc->getObjectByRepr(page); - if (SP_IS_GROUP(obj)) { - ret = SP_GROUP(obj); - } - #if ENABLE_MAGIC_COLORS - ColorItem::_wireMagicColors( onceMore ); - #endif // ENABLE_MAGIC_COLORS - } else { - delete page; - } - } - } - - fclose(f); - } - /* end loading the pallet file*/ - } - return ret; -} - -SwatchesPanel& SwatchesPanel::getInstance() -{ - return *new SwatchesPanel(); -} - -class SwatchesPanel::StopWatcher : public Inkscape::XML::NodeObserver { -public: - StopWatcher(SwatchesPanel* pnl, SPStop* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()) - { - _repr->addObserver(*this); - } - - ~StopWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ){} - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj) { - _pnl->_defsChanged( ); - } - } +#define VBLOCK 16 +#define PREVIEW_PIXBUF_WIDTH 128 - SwatchesPanel* _pnl; - SPStop* _obj; - Inkscape::XML::Node* _repr; -}; +void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); -class SwatchesPanel::GradientWatcher : public Inkscape::XML::NodeObserver { -public: - GradientWatcher(SwatchesPanel* pnl, SPGradient* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")), - _swatchAttr(g_quark_from_string("osb:paint")) - { - _repr->addObserver(*this); - } - - ~GradientWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch()) { - _pnl->_defsChanged( ); - } - } - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch() ) { - _pnl->_defsChanged( ); - } - } - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch() ) { - _pnl->_defsChanged( ); - } - } - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj && ((_obj->isSwatch() && name == _labelAttr) || name == _swatchAttr)) { - _pnl->_defsChanged( ); - } - } - - SwatchesPanel* _pnl; - SPGradient* _obj; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; - GQuark _swatchAttr; -}; - -class SwatchesPanel::SwatchWatcher : public Inkscape::XML::NodeObserver { -public: - SwatchWatcher(SwatchesPanel* pnl, SPObject* obj, bool builtIn) : - _pnl(pnl), - _obj(obj), - _builtIn(builtIn), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")), - _swatchAttr(g_quark_from_string("osb:paint")) - { - _repr->addObserver(*this); - } - - ~SwatchWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj) { - SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); - if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - } - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) - { - if ( _pnl && _obj) { - SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); - if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - } - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj && name == _labelAttr) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } +std::list userSwatchPages; +std::list systemSwatchPages; +static std::map docPalettes; +static std::vector docTrackings; +static std::map docPerPanel; - SwatchesPanel* _pnl; - SPObject* _obj; - bool _builtIn; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; - GQuark _swatchAttr; -}; -class SwatchesPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +class SwatchesPanelHook : public SwatchesPanel { public: - - ModelColumns() - { - add(_colObject); - add(_colLabel); - } - virtual ~ModelColumns() {} - - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; + static void convertGradient( GtkMenuItem *menuitem, gpointer userData ); + static void deleteGradient( GtkMenuItem *menuitem, gpointer userData ); }; -class SwatchesPanel::ModelColumnsDoc : public Gtk::TreeModel::ColumnRecord -{ -public: - - ModelColumnsDoc() - { - add(_colObject); - add(_colLabel); - add(_colPixbuf); +static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); } - virtual ~ModelColumnsDoc() {} - - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; - Gtk::TreeModelColumn > _colPixbuf; -}; +} -static void StripChildGroups(Inkscape::XML::Node * node, SPObject* addTo) -{ - for (Inkscape::XML::Node * it = node->firstChild(); it != NULL;) { - if (!strcmp(it->name(), "svg:g")) { - Inkscape::XML::Node * todel = it; - it = it->next(); - node->removeChild(todel); - } else { - it = it->next(); - } +static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); } - addTo->appendChildRepr(node); } -static void BubbleChildGroups(Inkscape::XML::Node * node, SPObject* addTo) +static GtkWidget* popupMenu = 0; +static GtkWidget *popupSubHolder = 0; +static GtkWidget *popupSub = 0; +static std::vector popupItems; +static std::vector popupExtras; +static ColorItem* bounceTarget = 0; +static SwatchesPanel* bouncePanel = 0; + +static void redirClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) { - std::queue groups; - for (Inkscape::XML::Node * it = node->firstChild(); it != NULL; ) { - if (!strcmp(it->name(), "svg:g")) { - groups.push(it->duplicate(addTo->document->getReprDoc())); - Inkscape::XML::Node * todel = it; - it = it->next(); - node->removeChild(todel); - } else { - it = it->next(); - } - } - addTo->appendChildRepr(node); - while (!groups.empty()) { - Inkscape::XML::Node * it = groups.front(); - groups.pop(); - BubbleChildGroups(it, addTo); - Inkscape::GC::release(it); + if ( bounceTarget ) { + handleClick( GTK_WIDGET(menuitem), bounceTarget ); } } -void SwatchesPanel::_addSwatchButtonClicked(SPGroup* swatch, bool recurse) +static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) { - if (_currentDocument) { - if (swatch && SP_IS_GROUP(swatch) ) { - Inkscape::XML::Node * copy = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); - if (recurse) { - BubbleChildGroups(copy, _currentDocument->getDefs()); - } else { - StripChildGroups(copy, _currentDocument->getDefs()); - } - Inkscape::GC::release(copy); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); - } + if ( bounceTarget ) { + handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget ); } } -void SwatchesPanel::_importButtonClicked(bool addToDoc, bool addToBI) +static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) { - if (addToDoc || addToBI) { - //# Get the current directory for finding files - static Glib::ustring open_path; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if(open_path.empty()) - { - Glib::ustring attr = prefs->getString("/dialogs/open/path"); - if (!attr.empty()) open_path = attr; - } - - //# Test if the open_path directory exists - if (!Inkscape::IO::file_test(open_path.c_str(), - (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - open_path = ""; - - #ifdef WIN32 - //# If no open path, default to our win32 documents folder - if (open_path.empty()) - { - // The path to the My Documents folder is read from the - // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" - HKEY key = NULL; - if(RegOpenKeyExA(HKEY_CURRENT_USER, - "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", - 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) - { - WCHAR utf16path[_MAX_PATH]; - DWORD value_type; - DWORD data_size = sizeof(utf16path); - if(RegQueryValueExW(key, L"Personal", NULL, &value_type, - (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) - { - g_assert(value_type == REG_SZ); - gchar *utf8path = g_utf16_to_utf8( - (const gunichar2*)utf16path, -1, NULL, NULL, NULL); - if(utf8path) - { - open_path = Glib::ustring(utf8path); - g_free(utf8path); + if ( gr ) { + bool shown = false; + if ( desktop && desktop->doc() ) { + Inkscape::Selection *selection = sp_desktop_selection( desktop ); + GSList const *items = selection->itemList(); + if (items) { + SPStyle *query = sp_style_new( desktop->doc() ); + int result = objects_query_fillstroke(const_cast(items), query, true); + if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { + // could be pertinent + if (query->fill.isPaintserver()) { + SPPaintServer* server = query->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* grad = SP_GRADIENT(server); + if ( grad->isSwatch() && grad->getId() == gr->getId()) { + desktop->_dlg_mgr->showDialog("FillAndStroke"); + shown = true; + } + } } } + sp_style_unref(query); } } - #endif - - //# If no open path, default to our home directory - if (open_path.empty()) - { - open_path = g_get_home_dir(); - open_path.append(G_DIR_SEPARATOR_S); - } - Gtk::Window * parent = SP_ACTIVE_DESKTOP->getToplevel(); - //# Create a dialog - Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = - Inkscape::UI::Dialog::FileOpenDialog::create( - *parent, open_path, - Inkscape::UI::Dialog::SWATCH_TYPES, - _("Select file to open")); - - //# Show the dialog - bool const success = openDialogInstance->show(); - - //# Save the folder the user selected for later - open_path = openDialogInstance->getCurrentDirectory(); - - if (!success) - { - delete openDialogInstance; - return; - } - - //# User selected something. Get name and type - Glib::ustring fileName = openDialogInstance->getFilename(); - - //# We no longer need the file dialog object - delete it - delete openDialogInstance; - openDialogInstance = NULL; - - - if (!fileName.empty()) - { - Glib::ustring newFileName = Glib::filename_to_utf8(fileName); - - if ( newFileName.size() > 0) - fileName = newFileName; - else - g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); - - open_path = Glib::path_get_dirname (fileName); - open_path.append(G_DIR_SEPARATOR_S); - prefs->setString("/dialogs/open/path", open_path); - - SPDocument* importdoc = SPDocument::createNewDoc(fileName.c_str(), true); - Inkscape::XML::Node * page = NULL; - if (importdoc && importdoc->getDefs()) { - if (addToBI) { - page = SwatchDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (SwatchDocument->getObjectById(id)); - - page->setAttribute("id", id); - gchar* name = g_path_get_basename(importdoc->getName()); - page->setAttribute("inkscape:label", name); - g_free(name); - } - - for (SPObject* it = importdoc->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GROUP(it)) { - if (page) { - Inkscape::XML::Node * copy = it->getRepr()->duplicate(SwatchDocument->getReprDoc()); - page->appendChild(copy); - } - if (addToDoc) { - _addSwatchButtonClicked(SP_GROUP(it), false); - } - } - } - if (page) { - SwatchDocument->getDefs()->appendChildRepr(page); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - - importdoc->doUnref(); + if (!shown) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) { + // Legacy gradient dialog + GtkWidget *dialog = sp_gradient_vector_editor_new( gr ); + gtk_widget_show( dialog ); } else { - SPGroup* g = importGPL(addToBI ? SwatchDocument : _currentDocument, fileName.c_str()); - if (addToBI) { - if (addToDoc) { - _addSwatchButtonClicked(g, false); + // Invoke the gradient tool + Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); + if ( verb ) { + SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); + if ( action ) { + sp_action_perform( action, NULL ); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } else { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); } } } } } -void SwatchesPanel::SetSelectedFill(SPGradient* swatch) +static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) { - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->fill.isSet()) { - if (it->style->fill.isPaintserver()) { - SPPaintServer * server = it->style->getFillPaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = swatch->getRepr(); - if (repr != drepr && grad != swatch) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { - Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); - swatch->appendChildRepr(clone); - Inkscape::GC::release(clone); - } - swatch->setSwatch(); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); - } - } - } else if (it->style->fill.isColor()) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - addStop(swatch->getRepr(), it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); - swatch->setSwatch(); - if (!_noLink.get_active()) { - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + SPDocument *doc = desktop ? desktop->doc() : 0; + if (doc) { + std::string targetName(bounceTarget->def.descr); + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + editGradientImpl( desktop, grad ); + break; } } } } } -void SwatchesPanel::SetSelectedStroke(SPGradient* swatch) +void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData ) { - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->stroke.isSet()) { - if (it->style->stroke.isPaintserver()) { - SPPaintServer * server = it->style->getStrokePaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = swatch->getRepr(); - if (repr != drepr && grad != swatch) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { - Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); - swatch->appendChildRepr(clone); - Inkscape::GC::release(clone); - } - swatch->setSwatch(); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); - } - } - } else if (it->style->stroke.isColor()) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - addStop(swatch->getRepr(), it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); - swatch->setSwatch(); - if (!_noLink.get_active()) { - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + SPDocument *doc = desktop ? desktop->doc() : 0; + gint index = GPOINTER_TO_INT(userData); + if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { + Glib::ustring targetName = popupItems[index]; + + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + grad->setSwatch(); + DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, + _("Add gradient stop")); + break; } } } } } -void SwatchesPanel::MoveSwatchDown(SPGradient* swatch) +void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*userData*/ ) { - if (_currentDocument && swatch) { - SPObject* next = swatch->next; - while (next && (!SP_IS_GRADIENT(next) || !(SP_GRADIENT(next)->isSwatch()))) { - next = next->next; - } - if (next) { - Inkscape::XML::Node* repr = swatch->getRepr(); - repr->parent()->changeOrder(repr, next->getRepr()); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Right")); - } + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + sp_gradient_unset_swatch(desktop, bounceTarget->def.descr); } } -void SwatchesPanel::MoveSwatchUp(SPGradient* swatch) +static SwatchesPanel* findContainingPanel( GtkWidget *widget ) { - if (_currentDocument && swatch) { - SPObject* g = NULL; - SPObject* next = swatch->parent->firstChild(); - while (next && next != swatch) { - if (SP_IS_GRADIENT(next) && SP_GRADIENT(next)->isSwatch()) { - g = next; - } - next = next->next; - } - if (g) { - g = g->getPrev(); - Inkscape::XML::Node* repr = swatch->getRepr(); - repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Left")); - } - } -} + SwatchesPanel *swp = 0; -void SwatchesPanel::RemoveSwatch(SPGradient* swatch) -{ - if (_currentDocument) { - if (swatch->isReferenced()) { - Inkscape::XML::Node * repr = swatch->getRepr(); - repr->parent()->removeChild(repr); - _currentDocument->getDefs()->getRepr()->appendChild(repr); - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); - } else { - swatch->deleteObject(false); - } + std::map rawObjects; + for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + rawObjects[GTK_WIDGET(it->first->gobj())] = it->first; } -} -void SwatchesPanel::_setSelectionSwatch(SPGradient* swatch, bool isStroke) -{ - if (_currentDocument) { - if (swatch) { - if (_noLink.get_active()) { - if (swatch->isSolid()) { - ColorRGBA rgba(swatch->getFirstStop()->getEffectiveColor().toRGBA32(swatch->getFirstStop()->opacity)); - sp_desktop_set_color(_currentDesktop, rgba, false, !isStroke); - } else { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); - - Inkscape::XML::Node * clone = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); - _currentDocument->getDefs()->appendChildRepr(clone); - SPGradient* grad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - Inkscape::GC::release(clone); - grad->setSwatch(false); - SPGradient* normalized = sp_gradient_ensure_vector_normalized(grad); -// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { -// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); -// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); -// } - sp_desktop_set_style(_currentDesktop, css); - sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); - sp_repr_css_attr_unref (css); - } - } else { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); - - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); -// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { -// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); -// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); -// } - sp_desktop_set_style(_currentDesktop, css); - sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); - sp_repr_css_attr_unref (css); - } - } else { - SPCSSAttr *css = sp_repr_css_attr_new (); - sp_repr_css_set_property (css, isStroke ? "stroke" : "fill", "none"); - sp_desktop_set_style(_currentDesktop, css); - } - if (isStroke) { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item stroke swatch")); - } else { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item fill swatch")); + for (GtkWidget* curr = widget; curr && !swp; curr = gtk_widget_get_parent(curr)) { + if (rawObjects.find(curr) != rawObjects.end()) { + swp = rawObjects[curr]; } } -} - -void SwatchesPanel::_swatchClicked(GdkEventButton* event, SPGradient* swatch) -{ - if (_currentDesktop) { - if (event->button == 3) { - Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi; - - Glib::ustring us = Glib::ustring::compose("%1", swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]")); - mi = Gtk::manage(new Gtk::MenuItem(swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]"))); - Gtk::Label* namelbl = dynamic_cast(mi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - mi->show(); - mi->set_sensitive(false); - menu->append(*mi); - - Gtk::SeparatorMenuItem* sep; - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, false)); - mi->show(); - mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, true)); - mi->show(); - mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); - menu->append(*mi); - - if (swatch) { - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedFill), swatch)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedStroke), swatch)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Left"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchUp), swatch)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Right"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchDown), swatch)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::RemoveSwatch), swatch)); - mi->show(); - menu->append(*mi); - } - menu->popup(event->button, event->time); - } else if (!_currentDesktop->selection->isEmpty()) { - _setSelectionSwatch(swatch, event->state & GDK_SHIFT_MASK); - } - } + return swp; } -void SwatchesPanel::MoveDown(SPGroup* page) +static void removeit( GtkWidget *widget, gpointer data ) { - if (_currentDocument && page) { - SPObject* next = page->next; - while (next && !SP_IS_GROUP(next)) { - next = next->next; - } - if (next) { - Inkscape::XML::Node* repr = page->getRepr(); - repr->parent()->changeOrder(repr, next->getRepr()); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Down")); - } - } + gtk_container_remove( GTK_CONTAINER(data), widget ); } -void SwatchesPanel::MoveUp(SPGroup* page) -{ - if (_currentDocument && page) { - SPObject* g = NULL; - SPObject* next = page->parent->firstChild(); - while (next && next != page) { - if (SP_IS_GROUP(next)) { - g = next; - } - next = next->next; - } - if (g) { - g = g->getPrev(); - Inkscape::XML::Node* repr = page->getRepr(); - repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Up")); - } - } -} +/* extern'ed from colot-item.cpp */ +gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ); -void SwatchesPanel::Remove(SPGroup* page) +gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ) { - if (_currentDocument && page) { - std::vector toMove; - for(SPObject* obj = page->firstChild(); obj != NULL; obj = obj->next) { - if (SP_IS_GRADIENT(obj)) { - SPGradient* grad = SP_GRADIENT(obj); - if (grad->isReferenced()) { - toMove.push_back(grad->getRepr()); - } + gboolean handled = FALSE; + + if ( event && (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) { + SwatchesPanel* swp = findContainingPanel( widget ); + + if ( !popupMenu ) { + popupMenu = gtk_menu_new(); + GtkWidget* child = 0; + + //TRANSLATORS: An item in context menu on a colour in the swatches + child = gtk_menu_item_new_with_label(_("Set fill")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(redirClick), + user_data); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + + //TRANSLATORS: An item in context menu on a colour in the swatches + child = gtk_menu_item_new_with_label(_("Set stroke")); + + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(redirSecondaryClick), + user_data); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + + child = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_menu_item_new_with_label(_("Delete")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(SwatchesPanelHook::deleteGradient), + user_data ); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + gtk_widget_set_sensitive( child, FALSE ); + + child = gtk_menu_item_new_with_label(_("Edit...")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(editGradient), + user_data ); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_menu_item_new_with_label(_("Convert")); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + //popupExtras.push_back(child); + //gtk_widget_set_sensitive( child, FALSE ); + { + popupSubHolder = child; + popupSub = gtk_menu_new(); + gtk_menu_item_set_submenu( GTK_MENU_ITEM(child), popupSub ); } + + gtk_widget_show_all(popupMenu); } - while (!toMove.empty()) { - Inkscape::XML::Node * repr = toMove.back(); - toMove.pop_back(); - repr->parent()->removeChild(repr); - _currentDocument->getDefs()->getRepr()->appendChild(repr); - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); - } - page->deleteObject(false); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Remove Swatch Group")); - } -} -void SwatchesPanel::AddSelectedFill(SPGroup* page) -{ - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->fill.isSet()) { - if (it->style->fill.isPaintserver()) { - SPPaintServer * server = it->style->getFillPaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - if (_noLink.get_active()) { - Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - clone->setAttribute( "osb:paint", "gradient", 0 ); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else if (grad->isSwatch()) { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); - if (repr->parent() != drepr) { - repr->parent()->removeChild(repr); - drepr->appendChild(repr); - } - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } - } - } else if (it->style->fill.isColor()) { - Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute( "osb:paint", "solid", 0 ); - addStop(grad, it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); - if (page) { - page->appendChild(grad); - } else { - _currentDocument->getDefs()->appendChild(grad); - } - SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); - Inkscape::GC::release(grad); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); - } + if ( user_data ) { + ColorItem* item = reinterpret_cast(user_data); + bool show = swp && (swp->getSelectedIndex() == 0); + for ( std::vector::iterator it = popupExtras.begin(); it != popupExtras.end(); ++ it) { + gtk_widget_set_sensitive(*it, show); } - } - } -} -void SwatchesPanel::AddSelectedStroke(SPGroup* page) -{ - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->stroke.isSet()) { - if (it->style->stroke.isPaintserver()) { - SPPaintServer * server = it->style->getStrokePaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - if (_noLink.get_active()) { - Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - clone->setAttribute( "osb:paint", "gradient", 0 ); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); + bounceTarget = item; + bouncePanel = swp; + popupItems.clear(); + if ( popupMenu ) { + gtk_container_foreach(GTK_CONTAINER(popupSub), removeit, popupSub); + bool processed = false; + GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); + if ( wdgt ) { + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); + if ( dtw && dtw->desktop ) { + // Pick up all gradients with vectors + const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); + gint index = 0; + for (const GSList *curr = gradients; curr; curr = curr->next) { + SPGradient* grad = SP_GRADIENT(curr->data); + if ( grad->hasStops() && !grad->isSwatch() ) { + //gl = g_slist_prepend(gl, curr->data); + processed = true; + GtkWidget *child = gtk_menu_item_new_with_label(grad->getId()); + gtk_menu_shell_append(GTK_MENU_SHELL(popupSub), child); + + popupItems.push_back(grad->getId()); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(SwatchesPanelHook::convertGradient), + GINT_TO_POINTER(index) ); + index++; } - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else if (grad->isSwatch()) { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); - if (repr->parent() != drepr) { - repr->parent()->removeChild(repr); - drepr->appendChild(repr); - } - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); } + + gtk_widget_show_all(popupSub); } - } else if (it->style->stroke.isColor()) { - Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute( "osb:paint", "solid", 0 ); - addStop(grad, it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); - if (page) { - page->appendChild(grad); - } else { - _currentDocument->getDefs()->appendChild(grad); - } - SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); - Inkscape::GC::release(grad); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); } + gtk_widget_set_sensitive( popupSubHolder, processed ); + + gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time); + handled = TRUE; } } } -} -void SwatchesPanel::_addBIButtonClicked(GdkEventButton* event) -{ - if (popUpImportMenu) { - popUpImportMenu->popup(event->button, event->time); - } + return handled; } -void SwatchesPanel::NewGroupBI() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = SwatchDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (SwatchDocument->getObjectById(id)); - - page->setAttribute("id", id); - - SwatchDocument->getDefs()->appendChild(page); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } -} -void SwatchesPanel::NewGroup() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("New Swatch Group")); +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; } -} - -void SwatchesPanel::SaveAs() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - - std::vector toMove; - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->isSwatch()) { - toMove.push_back(grad->getRepr()); - } - } - } - while (!toMove.empty()) { - Inkscape::XML::Node* repr = toMove.back(); - toMove.pop_back(); - repr->parent()->removeChild(repr); - page->appendChild(repr); - } - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Save Swatch Group")); + ret = str; + while ( *str ) { + str++; } -} - -void SwatchesPanel::Duplicate(SPGroup* oldpage) -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - if (oldpage->label()) page->setAttribute("inkscape:label", oldpage->label()); - - for (SPObject *it = oldpage->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->isSwatch()) { - Inkscape::XML::Node * copy = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - page->appendChild(copy); - Inkscape::GC::release(copy); - } - } - } - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Duplicate Swatch Group")); + str--; + while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { + *str-- = 0; } + return ret; } -void SwatchesPanel::_lblClick(GdkEventButton* event, SPGroup* page) -{ - Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi; - Glib::ustring us = Glib::ustring::compose("%1", page ? (page->label() ? page->label() : page->getId()) : _("[Base]")); - mi = Gtk::manage(new Gtk::MenuItem(page ? (page->label() ? page->label() : page->getId()) : _("[Base]"))); - Gtk::Label* namelbl = dynamic_cast(mi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - mi->show(); - mi->set_sensitive(false); - menu->append(*mi); - - Gtk::SeparatorMenuItem* sep; - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedFill), page)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedStroke), page)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - if (page) { - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Up"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveUp), page)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Down"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveDown), page)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Duplicate"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Duplicate), page)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Remove), page)); - mi->show(); - menu->append(*mi); - } else { - mi = Gtk::manage(new Gtk::MenuItem(_("Create New Group"))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Save As New Group"))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::SaveAs)); - mi->show(); - menu->append(*mi); +static void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; } - - menu->popup(event->button, event->time); } -void SwatchesPanel::_defsChanged() -{ - if (_storeDoc) { - _storeDoc->clear(); - } - - while (!docWatchers.empty()) { - Inkscape::XML::NodeObserver* w = docWatchers.back(); - docWatchers.pop_back(); - delete w; - } - - std::vector tableChildren = _insideTable.get_children(); - for (std::vector::iterator c = tableChildren.begin(); c != tableChildren.end(); ++c) { - _insideTable.remove(**c); +static bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; } - - if (_currentDocument) { - Gtk::EventBox* eb; - Gtk::Label* lbl; - if (_showlabels) { - eb = Gtk::manage(new Gtk::EventBox()); - eb->add_events(Gdk::BUTTON_PRESS_MASK); - eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), NULL)); - - lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); - eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); - } - - ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->set_tooltip_text(_("[None]")); - _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); - - unsigned int i = 1; - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->hasStops()) { - - GradientWatcher* w = new GradientWatcher(this, grad); - docWatchers.push_back(w); - - if (grad->isSwatch()) { - - for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { - StopWatcher* sw = new StopWatcher(this, s); - docWatchers.push_back(sw); - } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; +} - if (_storeDoc) { - Gtk::TreeModel::iterator iter = _storeDoc->append(); - Gtk::TreeModel::Row row = *iter; - row[_modelDoc->_colObject] = grad; - row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); - GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); - row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - } - item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->set_tooltip_text(it->label() ? it->label() : it->getId()); - if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); +void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +{ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + SwatchPage *onceMore = new SwatchPage(); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); - } - - i++; - } - } - } - } - - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GROUP(it)) { - SwatchWatcher* w = new SwatchWatcher(this, it, false); - docWatchers.push_back(w); - - if (_showlabels) { - i += 20 - (i % 20); - eb = Gtk::manage(new Gtk::EventBox()); - eb->add_events(Gdk::BUTTON_PRESS_MASK); - eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); - lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); - eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); - } - - Gtk::TreeModel::iterator rowiter; - - if (_storeDoc) { - rowiter = _storeDoc->append(); - Gtk::TreeModel::Row row = *rowiter; - row[_modelDoc->_colObject] = it; - row[_modelDoc->_colLabel] = it->label() ? it->label() : it->getId(); - } - - for (SPObject *cit = it->firstChild(); cit != NULL; cit = cit->next) { - if (SP_IS_GRADIENT(cit)) { - SPGradient* grad = SP_GRADIENT(cit); - - if (grad->hasStops()) { - - GradientWatcher* w = new GradientWatcher(this, grad); - docWatchers.push_back(w); - - if (grad->isSwatch()) { - - for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { - StopWatcher* sw = new StopWatcher(this, s); - docWatchers.push_back(sw); - } - - if (_storeDoc && rowiter) { - Gtk::TreeModel::iterator iter = _storeDoc->append(rowiter->children()); - Gtk::TreeModel::Row row = *iter; - row[_modelDoc->_colObject] = grad; - row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); - GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); - row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - - _editDoc.expand_to_path(_storeDoc->get_path(iter)); + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + skipWhitespace(ptr); + if ( *ptr ) { + int r = 0; + int g = 0; + int b = 0; + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = g_dpgettext2(NULL, "Palette", n); + } + } + if ( !hasErr ) { + // Add the entry now + Glib::ustring nameStr(name); + ColorItem* item = new ColorItem( r, g, b, nameStr ); + onceMore->_colors.push_back(item); + } + } else { + hasErr = true; } - - item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); - if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) + { + onceMore->_name = val; + } + else if ( strcmp( "Columns", name ) == 0 ) + { + gchar* endPtr = 0; + guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 ); + if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { + // overflow + } else if ( (numVal == 0) && (endPtr == val) ) { + // failed conversion + } else { + onceMore->_prefWidth = numVal; + } + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } } - i++; } } } + } while ( result && !hasErr ); + if ( !hasErr ) { + if (user) + userSwatchPages.push_back(onceMore); + else + systemSwatchPages.push_back(onceMore); +#if ENABLE_MAGIC_COLORS + ColorItem::_wireMagicColors( onceMore ); +#endif // ENABLE_MAGIC_COLORS + } else { + delete onceMore; } } } - } - //_scroller.resize(1,1); - _insideTable.resize(1,1); - _scroller.show_all_children(); - _scroller.queue_draw(); - -} -Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) -{ - Gtk::MenuItem* mi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId(),1)); - Gtk::Menu* m = NULL; - - Gtk::TreeModel::Row* r; - if (_store) { - Gtk::TreeModel::iterator iter = parentRow ? _store->append(parentRow->children()) : _store->append(); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = group; - row[_model->_colLabel] = group->label() ? group->label() : group->getId(); - - if (SP_IS_GROUP(group->parent) && SP_GROUP(group->parent)->expanded()) { - _editBI.expand_to_path(_store->get_path(iter)); - } - r = &row; - } else { - r = NULL; - } - - bool hasswatches = false; - for (SPObject * obj = group->firstChild(); obj != NULL; obj = obj->next) - { - if (SP_IS_GROUP(obj)) { - if (!m) { - m = manage(new Gtk::Menu()); - m->show_all(); - mi->set_submenu(*m); - - Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(_("[All]"))); - basemi->show(); - Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); - if (namelbl) { - namelbl->set_markup(_("[All]")); - } - basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, true)); - m->append(*basemi); - - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - m->append(*sep); - } - SwatchWatcher* w = new SwatchWatcher(this, obj, true); - rootWatchers.push_back(w); - m->append(*_addSwatchGroup(SP_GROUP(obj), r)); - } else if (SP_IS_GRADIENT(obj)) { - hasswatches = true; - } + fclose(f); } - if (!m) { - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); - } else if (hasswatches) { - Glib::ustring us = Glib::ustring::compose("%1", group->label() ? group->label() : group->getId()); - Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId())); - basemi->show(); - Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); - m->prepend(*basemi); - } - mi->show(); - return mi; } -void SwatchesPanel::_swatchesChanged() -{ - while (!rootWatchers.empty()) { - Inkscape::XML::NodeObserver* w = rootWatchers.back(); - rootWatchers.pop_back(); - delete w; - } +static bool +compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { - std::vector menuChildren = popUpMenu->get_children(); - for (std::vector::iterator c = menuChildren.begin(); c != menuChildren.end(); ++c) { - popUpMenu->remove(**c); - } - - if (_store) { - _store->clear(); - } - - Gtk::MenuItem* mi; - - for (SPObject * obj = SwatchDocument->getDefs()->firstChild(); obj != NULL; obj = obj->next) - { - if (SP_IS_GROUP(obj)) { - SwatchWatcher* w = new SwatchWatcher(this, obj, true); - rootWatchers.push_back(w); - popUpMenu->append(*_addSwatchGroup(SP_GROUP(obj), NULL)); - - } - } - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - popUpMenu->append(*sep); - - mi = manage(new Gtk::MenuItem(_("New Swatch Group..."),1)); - mi->signal_activate().connect(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); - mi->show(); - popUpMenu->append(*mi); - - mi = manage(new Gtk::MenuItem(_("Add Swatch File..."),1)); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, false)); - mi->show(); - popUpMenu->append(*mi); - - mi = manage(new Gtk::MenuItem(_("Import Swatch File..."),1)); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, true)); - mi->show(); - popUpMenu->append(*mi); + return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0; } -void SwatchesPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) +static void loadEmUp() { - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; + static bool beenHere = false; + gboolean userPalete = true; + if ( !beenHere ) { + beenHere = true; + + std::list sources; + sources.push_back( profile_path("palettes") ); + sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); + sources.push_back( g_strdup(CREATE_PALETTESDIR) ); + + // Use this loop to iterate through a list of possible document locations. + while (!sources.empty()) { + gchar *dirname = sources.front(); + if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) + && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { + GError *err = 0; + GDir *directory = g_dir_open(dirname, 0, &err); + if (!directory) { + gchar *safeDir = Inkscape::IO::sanitizeString(dirname); + g_warning(_("Palettes directory (%s) is unavailable."), safeDir); + g_free(safeDir); + } else { + gchar *filename = 0; + while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { + gchar* lower = g_ascii_strdown( filename, -1 ); +// if ( g_str_has_suffix(lower, ".gpl") ) { + if ( !g_str_has_suffix(lower, "~") ) { + gchar* full = g_build_filename(dirname, filename, NULL); + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + _loadPaletteFile(full, userPalete); + } + g_free(full); + } +// } + g_free(lower); + } + g_dir_close(directory); + } } + + // toss the dirname + g_free(dirname); + sources.pop_front(); + userPalete = false; } } - - btn.set_tooltip_text (fallback); - if ( !set ) { - btn.set_label( fallback ); - } -} + // Sort the list of swatches by name, grouped by user/system + userSwatchPages.sort(compare_swatch_names); + systemSwatchPages.sort(compare_swatch_names); -void SwatchesPanel::_addButtonClicked(GdkEventButton* event) { - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) { - if (popUpMenu) { - popUpMenu->popup(event->button, event->time); - } - } } -void SwatchesPanel::NoLinkToggled() { - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring nolink = Glib::ustring::compose("%1/nolink", _prefs_path); - prefs->setBool(nolink, _noLink.get_active()); -} -bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) -{ - static unsigned doubleclick = 0; - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _editBI.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnBI) { - // Double click on the Layer name, enable editing - _text_rendererBI->property_editable() = true; - _editBI.set_cursor (path, *_name_columnBI, true); - grab_focus(); - } - } - - return false; +SwatchesPanel& SwatchesPanel::getInstance() +{ + return *new SwatchesPanel(); } -bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : + Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true), + _holder(0), + _clear(0), + _remove(0), + _currentIndex(0), + _currentDesktop(0), + _currentDocument(0) { - switch (Inkscape::UI::Tools::get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter && !_text_rendererBI->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_rendererBI->property_editable() = true; - _editBI.set_cursor(*path, *_name_columnBI, true); - grab_focus(); - return true; + Gtk::RadioMenuItem* hotItem = 0; + _holder = new PreviewHolder(); + _clear = new ColorItem( ege::PaintDef::CLEAR ); + _remove = new ColorItem( ege::PaintDef::NONE ); + if (docPalettes.empty()) { + SwatchPage *docPalette = new SwatchPage(); + + docPalette->_name = "Auto"; + docPalettes[0] = docPalette; + } + + loadEmUp(); + if ( !systemSwatchPages.empty() ) { + SwatchPage* first = 0; + int index = 0; + Glib::ustring targetName; + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + targetName = prefs->getString(_prefs_path + "/palette"); + if (!targetName.empty()) { + if (targetName == "Auto") { + first = docPalettes[0]; + } else { + //index++; + std::vector pages = _getSwatchSets(); + for ( std::vector::iterator iter = pages.begin(); iter != pages.end(); ++iter ) { + if ( (*iter)->_name == targetName ) { + first = *iter; + break; + } + index++; + } } } } - case GDK_KEY_Delete: { - - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj) { - obj->deleteObject(false); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } + + if ( !first ) { + first = docPalettes[0]; + _currentIndex = 0; + } else { + _currentIndex = index; + } + + _rebuild(); + + Gtk::RadioMenuItem::Group groupOne; + + int i = 0; + std::vector swatchSets = _getSwatchSets(); + for ( std::vector::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { + SwatchPage* curr = *it; + Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); + if ( curr == first ) { + hotItem = single; } - return true; + _regItem( single, 3, i ); + + i++; } - break; } - return false; -} -void SwatchesPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _editBI.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; + if (Glib::ustring(prefsPath) == "/dialogs/swatches") { + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + get_preferred_size(sreq_natural, sreq); +#else + sreq = size_request(); +#endif + int minHeight = 60; + if (sreq.height < minHeight) { + set_size_request(70, minHeight); + } + } - _renameObject(row, new_text); - _text_rendererBI->property_editable() = false; -} + _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); + _setTargetFillable(_holder); -void SwatchesPanel::_handleEditingCancelled() -{ - _text_rendererBI->property_editable() = false; -} + show_all_children(); -void SwatchesPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && SwatchDocument) { - SPObject* obj = row[_model->_colObject]; - if ( obj ) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - } + restorePanelPrefs(); + if ( hotItem ) { + hotItem->set_active(); } } -void SwatchesPanel::_setCollapsed(SPGroup * group) +SwatchesPanel::~SwatchesPanel() { - group->setExpanded(false); - group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - for (SPObject *iter = group->children; iter != NULL; iter = iter->next) - { - if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + _trackDocument( this, 0 ); + + _documentConnection.disconnect(); + _selChanged.disconnect(); + + if ( _clear ) { + delete _clear; + } + if ( _remove ) { + delete _remove; + } + if ( _holder ) { + delete _holder; } } -void SwatchesPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +void SwatchesPanel::setOrientation(SPAnchorType how) { - Gtk::TreeModel::Row row = *iter; + // Must call the parent class or bad things might happen + Inkscape::UI::Widget::Panel::setOrientation( how ); - SPObject* obj = row[_model->_colObject]; - if (obj && SP_IS_GROUP(obj)) + if ( _holder ) { - if (isexpanded) - { - SP_GROUP(obj)->setExpanded(isexpanded); - obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - } - else - { - _setCollapsed(SP_GROUP(obj)); - } + _holder->setOrientation(SP_ANCHOR_SOUTH); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } -void SwatchesPanel::_deleteButtonClicked() +void SwatchesPanel::setDesktop( SPDesktop* desktop ) { - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter) { - Gtk::TreeModel::Row row = *iter; - SPObject* obj = row[_model->_colObject]; - if (obj) { - obj->deleteObject(false); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + if ( desktop != _currentDesktop ) { + if ( _currentDesktop ) { + _documentConnection.disconnect(); + _selChanged.disconnect(); } - } -} -bool SwatchesPanel::_handleButtonEventDoc(GdkEventButton* event) -{ - static unsigned doubleclick = 0; - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { - // TODO - fix to a better is-popup function - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - if ( _editDoc.get_path_at_pos( x, y, path ) ) { - Gtk::TreeModel::Children::iterator iter = _editDoc.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_modelDoc->_colObject]; - if (SP_IS_GRADIENT(obj)) { - _swatchClicked(event, SP_GRADIENT(obj)); - } else if (SP_IS_GROUP(obj)) { - _lblClick(event, SP_GROUP(obj)); - } else { - _lblClick(event, NULL); - } - } else { - _lblClick(event, NULL); - } - } - - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } + _currentDesktop = desktop; - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _editDoc.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnDoc) { - // Double click on the Layer name, enable editing - _text_rendererDoc->property_editable() = true; - _editDoc.set_cursor (path, *_name_columnDoc, true); - grab_focus(); + if ( desktop ) { + _currentDesktop->selection->connectChanged( + sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + _currentDesktop->selection->connectModified( + sigc::hide(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection)))); + + _currentDesktop->connectToolSubselectionChanged( + sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + sigc::bound_mem_functor1 first = sigc::mem_fun(*this, &SwatchesPanel::_setDocument); + sigc::slot base2 = first; + sigc::slot slot2 = sigc::hide<0>( base2 ); + _documentConnection = desktop->connectDocumentReplaced( slot2 ); + + _setDocument( desktop->doc() ); + } else { + _setDocument(0); } } - - return false; } -void SwatchesPanel::_deleteButtonClickedDoc() + +class DocTrack { - Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); - if (iter) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_modelDoc->_colObject]; - if (SP_IS_GRADIENT(obj)) { - RemoveSwatch(SP_GRADIENT(obj)); - } else if (SP_IS_GROUP(obj)) { - Remove(SP_GROUP(obj)); +public: + DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : + doc(doc->doRef()), + updatePending(false), + lastGradientUpdate(0.0), + gradientRsrcChanged(gradientRsrcChanged), + defsChanged(defsChanged), + defsModified(defsModified) + { + if ( !timer ) { + timer = new Glib::Timer(); + refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); } + timerRefCount++; } -} -bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) -{ - switch (Inkscape::UI::Tools::get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); - if (iter && !_text_rendererDoc->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_modelDoc->_colObject]; - if (obj) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_rendererDoc->property_editable() = true; - _editDoc.set_cursor(*path, *_name_columnDoc, true); - grab_focus(); - return true; - } + ~DocTrack() + { + timerRefCount--; + if ( timerRefCount <= 0 ) { + refreshTimer.disconnect(); + timerRefCount = 0; + if ( timer ) { + timer->stop(); + delete timer; + timer = 0; } } - case GDK_KEY_Delete: { - - _deleteButtonClickedDoc(); - return true; + if (doc) { + gradientRsrcChanged.disconnect(); + defsChanged.disconnect(); + defsModified.disconnect(); + doc->doUnref(); + doc = NULL; } - break; } - return false; -} -void SwatchesPanel::_renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && SwatchDocument) { - SPObject* obj = row[_modelDoc->_colObject]; - if ( obj ) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - } - } - } -} + static bool handleTimerCB(); -void SwatchesPanel::_handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _editDoc.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; + /** + * Checks if update should be queued or executed immediately. + * + * @return true if the update was queued and should not be immediately executed. + */ + static bool queueUpdateIfNeeded(SPDocument *doc); - _renameObjectDoc(row, new_text); - _text_rendererDoc->property_editable() = false; -} + static Glib::Timer *timer; + static int timerRefCount; + static sigc::connection refreshTimer; -void SwatchesPanel::_handleEditingCancelledDoc() -{ - _text_rendererDoc->property_editable() = false; -} + SPDocument *doc; + bool updatePending; + double lastGradientUpdate; + sigc::connection gradientRsrcChanged; + sigc::connection defsChanged; + sigc::connection defsModified; -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool SwatchesPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +private: + DocTrack(DocTrack const &); // no copy + DocTrack &operator=(DocTrack const &); // no assign +}; + +Glib::Timer *DocTrack::timer = 0; +int DocTrack::timerRefCount = 0; +sigc::connection DocTrack::refreshTimer; + +static const double DOC_UPDATE_THREASHOLD = 0.090; + +bool DocTrack::handleTimerCB() { - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - bool _dnd_top = false; - _dnd_into = false; - _dnd_target = SwatchDocument->getDefs()->lastChild(); - Gtk::TreeModel::iterator itersel = _editBI.get_selection()->get_selected(); - if (!itersel) { - return true; - } - Gtk::TreeModel::Row rowsel = *itersel; - _dnd_source = rowsel[_model->_colObject]; + double now = timer->elapsed(); - if (!_dnd_source) { - return true; - } - - if (_editBI.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _editBI.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y < (int)(cell_height * 1/3)) { - Gtk::TreeModel::Path next_path = target_path; - if (next_path.prev()) { - target_path = next_path; - } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_store->iter_is_valid(_store->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - _dnd_top = true; - // Drop into the top level - _dnd_target = NULL; - } - } - } - if (!_dnd_top) { - Gtk::TreeModel::iterator iter = _store->get_iter(target_path); - if (_store->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - if (obj) { - _dnd_target = obj; - } - } + std::vector needCallback; + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { + needCallback.push_back(track); } } - - if (_dnd_source != _dnd_target) { - - Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; - Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); - - if (target_ref != our_ref) { - if (!target_ref) { - target_ref = SwatchDocument->getDefs()->getRepr(); - if (target_ref != our_ref->parent()) { - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else { - our_ref->parent()->changeOrder(our_ref, NULL); - } - } else if (_dnd_into) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); - } + + for (std::vector::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { + DocTrack *track = *it; + if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping + // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. + SwatchesPanel::handleDefsModified(track->doc); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } return true; } -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time) +bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) { - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - bool _dnd_top = false; - _dnd_into = false; - _dnd_target = _currentDocument->getDefs()->lastChild(); - Gtk::TreeModel::iterator itersel = _editDoc.get_selection()->get_selected(); - if (!itersel) { - return true; - } - Gtk::TreeModel::Row rowsel = *itersel; - _dnd_source = rowsel[_modelDoc->_colObject]; - - if (!_dnd_source) { - return true; - } - - if (_editDoc.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _editDoc.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y < (int)(cell_height * 1/3)) { - Gtk::TreeModel::Path next_path = target_path; - if (next_path.prev()) { - target_path = next_path; + bool deferProcessing = false; + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->doc == doc ) { + double now = timer->elapsed(); + double elapsed = now - track->lastGradientUpdate; + + if ( elapsed < DOC_UPDATE_THREASHOLD ) { + deferProcessing = true; + track->updatePending = true; } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_storeDoc->iter_is_valid(_storeDoc->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - _dnd_top = true; - // Drop into the top level - _dnd_target = NULL; - } + track->lastGradientUpdate = now; + track->updatePending = false; } + + break; } - if (!_dnd_top) { - Gtk::TreeModel::iterator iter = _storeDoc->get_iter(target_path); - if (_storeDoc->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_modelDoc->_colObject]; - if (obj) { - _dnd_target = obj; - if (SP_IS_GRADIENT(obj)) { - _dnd_into = false; - if (SP_IS_GROUP(_dnd_source)) { - _dnd_target = obj->parent; - } - } else if (SP_IS_GROUP(_dnd_source)) { - _dnd_into = false; + } + return deferProcessing; +} + +void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) +{ + SPDocument *oldDoc = NULL; + if (docPerPanel.find(panel) != docPerPanel.end()) { + oldDoc = docPerPanel[panel]; + if (!oldDoc) { + docPerPanel.erase(panel); // Should not be needed, but clean up just in case. + } + } + if (oldDoc != document) { + if (oldDoc) { + docPerPanel[panel] = NULL; + bool found = false; + for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { + found = (it->second == document); + } + if (!found) { + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ + if ((*it)->doc == oldDoc) { + delete *it; + docTrackings.erase(it); + break; } } } } - } - - if (_dnd_source != _dnd_target) { - - Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; - Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); - - if (target_ref != our_ref) { - if (!target_ref) { - target_ref = _currentDocument->getDefs()->getRepr(); - if (target_ref != our_ref->parent()) { - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else { - our_ref->parent()->changeOrder(our_ref, NULL); + + if (document) { + bool found = false; + for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { + found = (it->second == document); + } + docPerPanel[panel] = document; + if (!found) { + sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); + sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); + sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); + + DocTrack *dt = new DocTrack(document, conn1, conn2, conn3); + docTrackings.push_back(dt); + + if (docPalettes.find(document) == docPalettes.end()) { + SwatchPage *docPalette = new SwatchPage(); + docPalette->_name = "Auto"; + docPalettes[document] = docPalette; } - } else if (_dnd_into) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); } } - DocumentUndo::done( _currentDocument , SP_VERB_DIALOG_SWATCHES, - _("Moved Swatches")); } - - return true; } +void SwatchesPanel::_setDocument( SPDocument *document ) +{ + if ( document != _currentDocument ) { + _trackDocument(this, document); + _currentDocument = document; + handleGradientsChange( document ); + } +} -/** - * Constructor - */ -SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : - Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), - _scroller(), - _insideTable(1, 1), - _insideV(), - _insideH(), - _buttonsRow(), - _outsideV(), - _noLink(_("Don't Link")), - _showlabels(showLabels), - _store(0), - _scrollerBI(), - _editBI(), - _buttonsRowBI(), - _editBIV(), - _storeDoc(0), - _scrollerDoc(), - _editDoc(), - _buttonsRowDoc(), - _editDocV(), - _notebook(), - rootWatcher(0), - docWatcher(0), - _currentDesktop(0), - _currentDocument(0) +static void recalcSwatchContents(SPDocument* doc, + boost::ptr_vector &tmpColors, + std::map &previewMappings, + std::map &gradMappings) { - _insideH.pack_start(_insideTable, Gtk::PACK_SHRINK); - if (_showlabels) { - _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); - _scroller.add(_insideV); - } else { - _scroller.property_height_request() = 20; - _scroller.add(_insideH); + std::vector newList; + + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( grad->isSwatch() ) { + newList.push_back(SP_GRADIENT(item->data)); + } } - - popUpMenu = manage( new Gtk::Menu() ); - popUpMenu->show_all_children(); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Add Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked) ); - _buttonsRow.pack_start(*btn, Gtk::PACK_SHRINK); - -// btn = manage( new Gtk::Button() ); -// _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_DISCONNECT, C_("Unlink", "New") ); -// _buttonsRow.pack_end(*btn, Gtk::PACK_SHRINK); - - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring nolink = Glib::ustring::compose("%1/nolink", prefsPath); - _noLink.set_tooltip_text(_("Don't link swatches")); - _noLink.set_active(prefs->getBool(nolink, false)); - _noLink.signal_toggled().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NoLinkToggled)); - _buttonsRow.pack_end(_noLink, Gtk::PACK_SHRINK); - - _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_NONE); - - if (_showlabels) { - _outsideV.pack_end(_buttonsRow, Gtk::PACK_SHRINK); - _outsideV.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); - - _notebook.append_page(_outsideV, "Use"); - + + if ( !newList.empty() ) { + std::reverse(newList.begin(), newList.end()); + for ( std::vector::iterator it = newList.begin(); it != newList.end(); ++it ) { - ModelColumnsDoc *zoop = new ModelColumnsDoc(); - _modelDoc = zoop; + SPGradient* grad = *it; - _storeDoc = Gtk::TreeStore::create( *zoop ); + cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + PREVIEW_PIXBUF_WIDTH, VBLOCK); + cairo_t *ct = cairo_create(preview); - _editDoc.set_model( _storeDoc ); - _editDoc.set_headers_visible(false); - _editDoc.set_reorderable(true); - _editDoc.enable_model_drag_dest (Gdk::ACTION_MOVE); + Glib::ustring name( grad->getId() ); + ColorItem* item = new ColorItem( 0, 0, 0, name ); - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked)); - _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); + cairo_set_source(ct, check); + cairo_paint(ct); + cairo_set_source(ct, gradient); + cairo_paint(ct); - btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClickedDoc))); - _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_pattern_destroy(check); - _pixbuf_rendererDoc = manage(new Gtk::CellRendererPixbuf()); - int pixbufColNum = _editDoc.append_column("Pixbuf", *_pixbuf_rendererDoc) - 1; - _pixbuf_columnDoc = _editDoc.get_column(pixbufColNum); - _pixbuf_columnDoc->add_attribute(_pixbuf_rendererDoc->property_pixbuf(), _modelDoc->_colPixbuf); - - _text_rendererDoc = manage(new Gtk::CellRendererText()); - int nameColNum = _editDoc.append_column("Name", *_text_rendererDoc) - 1; - _name_columnDoc = _editDoc.get_column(nameColNum); - _name_columnDoc->add_attribute(_text_rendererDoc->property_text(), _modelDoc->_colLabel); + cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); + cairo_surface_destroy(preview); - _text_rendererDoc->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditedDoc) ); - _text_rendererDoc->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelledDoc) ); + previewMappings[item] = prevpat; + + tmpColors.push_back(item); + gradMappings[item] = grad; + } + } +} - _editDoc.set_expander_column( *_editDoc.get_column(nameColNum) ); +void SwatchesPanel::handleGradientsChange(SPDocument *document) +{ + SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; + if (docPalette) { + boost::ptr_vector tmpColors; + std::map tmpPrevs; + std::map tmpGrads; + recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - _editDoc.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); - _editDoc.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); - _editDoc.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEventDoc), false ); + for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + it->first->setPattern(it->second); + cairo_pattern_destroy(it->second); + } - _editDoc.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDropDoc), false); + for (std::map::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { + it->first->setGradient(it->second); + } - _scrollerDoc.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scrollerDoc.set_shadow_type(Gtk::SHADOW_IN); - _scrollerDoc.add(_editDoc); + docPalette->_colors.swap(tmpColors); - _editDocV.pack_start(_scrollerDoc, Gtk::PACK_EXPAND_WIDGET); - _editDocV.pack_end(_buttonsRowDoc, Gtk::PACK_SHRINK); + // Figure out which SwatchesPanel instances are affected and update them. - _notebook.append_page(_editDocV, "Edit"); - } - - { - popUpImportMenu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("New Swatch Group..."))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroupBI)); - mi->show(); - popUpImportMenu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Import Swatch File..."))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), false, true)); - mi->show(); - popUpImportMenu->append(*mi); - - ModelColumns *zoop = new ModelColumns(); - _model = zoop; - - _store = Gtk::TreeStore::create( *zoop ); - - _editBI.set_model( _store ); - _editBI.set_headers_visible(false); - _editBI.set_reorderable(true); - _editBI.enable_model_drag_dest (Gdk::ACTION_MOVE); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); - btn->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::_addBIButtonClicked)); - _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClicked))); - _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); - - _text_rendererBI = manage(new Gtk::CellRendererText()); - int nameColNum = _editBI.append_column("Name", *_text_rendererBI) - 1; - _name_columnBI = _editBI.get_column(nameColNum); - _name_columnBI->add_attribute(_text_rendererBI->property_text(), _model->_colLabel); - - _text_rendererBI->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEdited) ); - _text_rendererBI->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelled) ); - - _editBI.set_expander_column( *_editBI.get_column(nameColNum) ); - - _editBI.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); - _editBI.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); - _editBI.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEvent), false ); - - _editBI.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDrop), false); - _editBI.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), false)); - _editBI.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), true)); - - _scrollerBI.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scrollerBI.set_shadow_type(Gtk::SHADOW_IN); - _scrollerBI.add(_editBI); - - _editBIV.pack_start(_scrollerBI, Gtk::PACK_EXPAND_WIDGET); - _editBIV.pack_end(_buttonsRowBI, Gtk::PACK_SHRINK); - - _notebook.append_page(_editBIV, "Edit Built-In"); + for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + if (it->second == document) { + SwatchesPanel* swp = it->first; + std::vector pages = swp->_getSwatchSets(); + SwatchPage* curr = pages[swp->_currentIndex]; + if (curr == docPalette) { + swp->_rebuild(); + } + } } - - _getContents()->pack_end(_notebook, Gtk::PACK_EXPAND_WIDGET); - } else { - //_outsideV.pack_end(_scroller, Gtk::PACK_SHRINK); - _buttonsRow.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); - //_getContents()->pack_end(_outsideV, Gtk::PACK_SHRINK); - _getContents()->pack_end(_buttonsRow, Gtk::PACK_SHRINK); } - - loadPalletFile(); - - rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); - SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); - _swatchesChanged(); - _insideTable.resize(1,1); } -SwatchesPanel::~SwatchesPanel() +void SwatchesPanel::handleDefsModified(SPDocument *document) { - if (rootWatcher) { - rootWatcher->_repr->removeObserver(*rootWatcher); - delete rootWatcher; + SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; + if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { + boost::ptr_vector tmpColors; + std::map tmpPrevs; + std::map tmpGrads; + recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); + + if ( tmpColors.size() != docPalette->_colors.size() ) { + handleGradientsChange(document); + } else { + int cap = std::min(docPalette->_colors.size(), tmpColors.size()); + for (int i = 0; i < cap; i++) { + ColorItem *newColor = &tmpColors[i]; + ColorItem *oldColor = &docPalette->_colors[i]; + if ( (newColor->def.getType() != oldColor->def.getType()) || + (newColor->def.getR() != oldColor->def.getR()) || + (newColor->def.getG() != oldColor->def.getG()) || + (newColor->def.getB() != oldColor->def.getB()) ) { + oldColor->def.setRGB(newColor->def.getR(), newColor->def.getG(), newColor->def.getB()); + } + if (tmpGrads.find(newColor) != tmpGrads.end()) { + oldColor->setGradient(tmpGrads[newColor]); + } + if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { + oldColor->setPattern(tmpPrevs[newColor]); + } + } + } + + for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + cairo_pattern_destroy(it->second); + } } - - if (docWatcher) { - docWatcher->_repr->removeObserver(*docWatcher); - delete docWatcher; +} + + +std::vector SwatchesPanel::_getSwatchSets() const +{ + std::vector tmp; + if (docPalettes.find(_currentDocument) != docPalettes.end()) { + tmp.push_back(docPalettes[_currentDocument]); } - _documentConnection.disconnect(); - _selChanged.disconnect(); + tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end()); + tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end()); + + return tmp; } -void SwatchesPanel::setDesktop( SPDesktop* desktop ) +void SwatchesPanel::_updateFromSelection() { - Inkscape::UI::Widget::Panel::setDesktop(desktop); - if ( desktop != _currentDesktop ) { - if ( _currentDesktop ) { - _documentConnection.disconnect(); - _selChanged.disconnect(); + SwatchPage *docPalette = (docPalettes.find(_currentDocument) != docPalettes.end()) ? docPalettes[_currentDocument] : 0; + if ( docPalette ) { + Glib::ustring fillId; + Glib::ustring strokeId; + + SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); + int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); + switch (result) { + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + { + if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { + SPPaintServer* server = tmpStyle->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* target = 0; + SPGradient* grad = SP_GRADIENT(server); + + if ( grad->isSwatch() ) { + target = grad; + } else if ( grad->ref ) { + SPGradient *tmp = grad->ref->getObject(); + if ( tmp && tmp->isSwatch() ) { + target = tmp; + } + } + if ( target ) { + //XML Tree being used directly here while it shouldn't be + gchar const* id = target->getRepr()->attribute("id"); + if ( id ) { + fillId = id; + } + } + } + } + break; + } } - _currentDesktop = desktop; + result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); + switch (result) { + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + { + if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { + SPPaintServer* server = tmpStyle->getStrokePaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* target = 0; + SPGradient* grad = SP_GRADIENT(server); + if ( grad->isSwatch() ) { + target = grad; + } else if ( grad->ref ) { + SPGradient *tmp = grad->ref->getObject(); + if ( tmp && tmp->isSwatch() ) { + target = tmp; + } + } + if ( target ) { + //XML Tree being used directly here while it shouldn't be + gchar const* id = target->getRepr()->attribute("id"); + if ( id ) { + strokeId = id; + } + } + } + } + break; + } + } + sp_style_unref(tmpStyle); - if ( desktop ) { - //_currentDesktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + for ( boost::ptr_vector::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { + ColorItem* item = &*it; + bool isFill = (fillId == item->def.descr); + bool isStroke = (strokeId == item->def.descr); + item->setState( isFill, isStroke ); + } + } +} - _documentConnection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &SwatchesPanel::_setDocument)); +void SwatchesPanel::_handleAction( int setId, int itemId ) +{ + switch( setId ) { + case 3: + { + std::vector pages = _getSwatchSets(); + if ( itemId >= 0 && itemId < static_cast(pages.size()) ) { + _currentIndex = itemId; - _setDocument( desktop, desktop->doc() ); - } else { - _setDocument(0, 0); + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); + } + + _rebuild(); + } } + break; } } -void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) +void SwatchesPanel::_rebuild() { - if ( document != _currentDocument ) { - if (docWatcher) { - docWatcher->_repr->removeObserver(*docWatcher); - delete docWatcher; - docWatcher = NULL; - } - _currentDocument = document; - - if (_currentDocument) { - docWatcher = new SwatchWatcher(this, _currentDocument->getDefs(), false); - _currentDocument->getDefs()->getRepr()->addObserver(*docWatcher); - } - _defsChanged(); + std::vector pages = _getSwatchSets(); + SwatchPage* curr = pages[_currentIndex]; + _holder->clear(); + + if ( curr->_prefWidth > 0 ) { + _holder->setColumnPref( curr->_prefWidth ); } + _holder->freezeUpdates(); + // TODO restore once 'clear' works _holder->addPreview(_clear); + _holder->addPreview(_remove); + for ( boost::ptr_vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { + _holder->addPreview(&*it); + } + _holder->thawUpdates(); } } //namespace Dialogs } //namespace UI } //namespace Inkscape -//really lazy! -void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) -{ - - bool intercepted = false; - - if (gradient->isSolid()) { - ColorRGBA color(gradient->getFirstStop()->getEffectiveColor().toRGBA32(gradient->getFirstStop()->opacity)); - guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); - gchar b[64]; - sp_svg_write_color(b, sizeof(b), rgba); - SPCSSAttr *css = sp_repr_css_attr_new(); - if (fill) { - sp_repr_css_set_property(css, "fill", b); - Inkscape::CSSOStringStream osalpha; - osalpha << color[3]; - sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); - } else { - sp_repr_css_set_property(css, "stroke", b); - Inkscape::CSSOStringStream osalpha; - osalpha << color[3]; - sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); - } - intercepted = desktop->_set_style_signal.emit(css); - } - - if (!intercepted) { - for (const GSList *it = desktop->selection->itemList(); it != NULL; it = it->next) { - sp_item_set_gradient(SP_ITEM(it->data), gradient, SP_IS_RADIALGRADIENT(gradient) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, !fill ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); - } - } -} /* Local Variables: diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index cb8f87962..ca4c1687d 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -12,161 +12,64 @@ #include "ui/widget/panel.h" #include "enums.h" -#include "sp-object.h" -#include "sp-item-group.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sp-gradient.h" -#include "xml/node-observer.h" namespace Inkscape { namespace UI { +class PreviewHolder; + namespace Dialogs { +class ColorItem; +class SwatchPage; +class DocTrack; + /** * A panel that displays paint swatches. */ class SwatchesPanel : public Inkscape::UI::Widget::Panel { public: - SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches", bool showLabels = true); + SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches"); virtual ~SwatchesPanel(); - + static SwatchesPanel& getInstance(); + virtual void setOrientation(SPAnchorType how); + virtual void setDesktop( SPDesktop* desktop ); virtual SPDesktop* getDesktop() {return _currentDesktop;} + virtual int getSelectedIndex() {return _currentIndex;} // temporary + protected: + static void handleGradientsChange(SPDocument *document); + + virtual void _updateFromSelection(); + virtual void _handleAction( int setId, int itemId ); + virtual void _setDocument( SPDocument *document ); + virtual void _rebuild(); - virtual void _setDocument( SPDesktop* desktop, SPDocument *document ); + virtual std::vector _getSwatchSets() const; private: - class ModelColumns; - class ModelColumnsDoc; - - class StopWatcher; - class GradientWatcher; - class SwatchWatcher; - SwatchesPanel(SwatchesPanel const &); // no copy SwatchesPanel &operator=(SwatchesPanel const &); // no assign - - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ); - - void _setSelectionSwatch(SPGradient* swatchItem, bool isStroke); - - void NoLinkToggled(); - void NewGroup(); - void NewGroupBI(); - void _addBIButtonClicked(GdkEventButton* event); - void Duplicate(SPGroup* page); - void SaveAs(); - void AddSelectedFill(SPGroup* page); - void AddSelectedStroke(SPGroup* page); - void MoveUp(SPGroup* page); - void MoveDown(SPGroup* page); - void Remove(SPGroup* page); - - void SetSelectedFill(SPGradient* swatch); - void SetSelectedStroke(SPGradient* swatch); - void MoveSwatchUp(SPGradient* swatch); - void MoveSwatchDown(SPGradient* swatch); - void RemoveSwatch(SPGradient* swatch); - - void _lblClick(GdkEventButton* event, SPGroup* page); - void _addSwatchButtonClicked(SPGroup* swatch, bool recurse); - void _defsChanged(); - void _importButtonClicked(bool addToDoc, bool addToBI); - void _deleteButtonClicked(); - void _addButtonClicked(GdkEventButton* event); - void _swatchClicked(GdkEventButton* event, SPGradient* swatchItem); - - Gtk::MenuItem* _addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow); - void _swatchesChanged(); - - bool _handleButtonEvent(GdkEventButton *event); - bool _handleKeyEvent(GdkEventKey *event); - - void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelled(); - void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); - - void _setCollapsed(SPGroup * group); - void _setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded); - - void _deleteButtonClickedDoc(); - bool _handleButtonEventDoc(GdkEventButton* event); - bool _handleKeyEventDoc(GdkEventKey *event); - - void _handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelledDoc(); - void _renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name); - - bool _handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time); - bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); - - Gtk::Menu *popUpMenu; - Gtk::Menu *popUpImportMenu; - - Gtk::ScrolledWindow _scroller; - Gtk::Table _insideTable; - Gtk::VBox _insideV; - Gtk::HBox _insideH; - Gtk::HBox _buttonsRow; - Gtk::VBox _outsideV; - Gtk::CheckButton _noLink; - bool _showlabels; - - SwatchesPanel::ModelColumns* _model; - Glib::RefPtr _store; - - Gtk::CellRendererText *_text_rendererBI; - Gtk::TreeView::Column *_name_columnBI; - Gtk::ScrolledWindow _scrollerBI; - Gtk::TreeView _editBI; - Gtk::HBox _buttonsRowBI; - Gtk::VBox _editBIV; - - SwatchesPanel::ModelColumnsDoc* _modelDoc; - Glib::RefPtr _storeDoc; - - Gtk::CellRendererText *_text_rendererDoc; - Gtk::CellRendererPixbuf *_pixbuf_rendererDoc; - Gtk::TreeView::Column *_name_columnDoc; - Gtk::TreeView::Column *_pixbuf_columnDoc; - Gtk::ScrolledWindow _scrollerDoc; - Gtk::TreeView _editDoc; - Gtk::HBox _buttonsRowDoc; - Gtk::VBox _editDocV; - - Gtk::Notebook _notebook; - - SwatchWatcher* rootWatcher; - std::vector rootWatchers; - - std::vector docWatchers; - SwatchWatcher* docWatcher; + static void _trackDocument( SwatchesPanel *panel, SPDocument *document ); + static void handleDefsModified(SPDocument *document); + + PreviewHolder* _holder; + ColorItem* _clear; + ColorItem* _remove; + int _currentIndex; SPDesktop* _currentDesktop; SPDocument* _currentDocument; - - bool _dnd_into; - SPObject* _dnd_source; - SPObject* _dnd_target; sigc::connection _documentConnection; sigc::connection _selChanged; + + friend class DocTrack; }; } //namespace Dialogs -- cgit v1.2.3 From 232d5c9f3cda7f24f4c3019c3c312f81f8797011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Fri, 14 Mar 2014 01:20:33 -0300 Subject: Small code simplification (bzr r11950.7.1) --- src/ui/tool/path-manipulator.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1cc075603..f8cc58e3b 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1206,11 +1206,7 @@ bool PathManipulator::isBSpline(bool recalculate){ if(recalculate){ BSplineSteps = this->BSplineGetSteps(); } - bool isBSpline = false; - if(BSplineSteps>0){ - isBSpline = true; - } - return isBSpline; + return BSplineSteps > 0; } // returns the corresponding strength to the position of a handler -- cgit v1.2.3 From ed6364b83dafb3d1b9cbedfa6675817833e9fdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Fri, 14 Mar 2014 01:21:08 -0300 Subject: Adding default argument to PathManipulator::isBSpline. Default argument is used when function is called with missing arguments. The default was chosen to 'true', because it is the safest value in this context. From now on, the function can be called like "_pm.isBSpline()", which is more intuitive. Still, I haven't studied the code enough to determine if this cache behaviour (force the user to think if cache is correct) is appropriate. (bzr r11950.7.2) --- src/ui/tool/path-manipulator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 5186bfc95..594f56ff9 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(bool recalculate); + bool isBSpline(bool recalculate = true); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From f9d1d1a8a33eee7fd7977361d2d559697f0fb56d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Mar 2014 18:35:31 +0100 Subject: =?UTF-8?q?disabling=20cache=20approach=20for=20isBSpline=20functi?= =?UTF-8?q?on,=20pointed=20by=20Vin=C3=ADcius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.296) --- src/ui/tool/path-manipulator.cpp | 15 ++++++++------- src/ui/tool/path-manipulator.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f8cc58e3b..adc70bc38 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -145,7 +145,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - isBSpline(true); + isBSpline(/*true*/); } PathManipulator::~PathManipulator() @@ -1201,11 +1201,12 @@ int PathManipulator::BSplineGetSteps(){ } // determines if the trace has bspline effect -bool PathManipulator::isBSpline(bool recalculate){ - static int BSplineSteps = this->BSplineGetSteps(); - if(recalculate){ - BSplineSteps = this->BSplineGetSteps(); - } +bool PathManipulator::isBSpline(/*bool recalculate*/){ + /*static*/ int BSplineSteps = this->BSplineGetSteps(); + // Taking out the static dont need this part + //if(recalculate){ + // BSplineSteps = this->BSplineGetSteps(); + //} return BSplineSteps > 0; } @@ -1282,7 +1283,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; - isBSpline(true); + isBSpline(/*true*/); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 594f56ff9..67590832d 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(bool recalculate = true); + bool isBSpline(/*bool recalculate = true*/); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From eb3102790b3c0eb1ce7131d2c4edceab5978ce88 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Mar 2014 18:38:27 +0100 Subject: simplify the code in isBSpline (bzr r11950.1.297) --- src/ui/tool/path-manipulator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index adc70bc38..3e54acddf 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1202,12 +1202,13 @@ int PathManipulator::BSplineGetSteps(){ // determines if the trace has bspline effect bool PathManipulator::isBSpline(/*bool recalculate*/){ - /*static*/ int BSplineSteps = this->BSplineGetSteps(); // Taking out the static dont need this part + // static int BSplineSteps = this->BSplineGetSteps(); //if(recalculate){ // BSplineSteps = this->BSplineGetSteps(); //} - return BSplineSteps > 0; + //return BSplineSteps > 0; + return this->BSplineGetSteps() > 0; } // returns the corresponding strength to the position of a handler -- cgit v1.2.3 From acc3de4356672491bcdd795fbac6b80ee2faf27d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 17 Mar 2014 00:57:12 +0100 Subject: Fix to solve static var in isBSpline function (bzr r11950.1.298) --- src/ui/tool/path-manipulator.cpp | 21 ++++++++++----------- src/ui/tool/path-manipulator.h | 3 ++- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 3e54acddf..841ab659a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -145,7 +145,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - isBSpline(/*true*/); + //Define if the path is BSpline on construction + isBSpline(true); } PathManipulator::~PathManipulator() @@ -664,7 +665,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite start = next; } // if we are removing, we readjust the handlers - if(isBSpline(false)){ + if(isBSpline()){ double pos = 0.0000; if(start.prev()){ pos = BSplineHandlePosition(start.prev()->back()); @@ -1201,14 +1202,11 @@ int PathManipulator::BSplineGetSteps(){ } // determines if the trace has bspline effect -bool PathManipulator::isBSpline(/*bool recalculate*/){ - // Taking out the static dont need this part - // static int BSplineSteps = this->BSplineGetSteps(); - //if(recalculate){ - // BSplineSteps = this->BSplineGetSteps(); - //} - //return BSplineSteps > 0; - return this->BSplineGetSteps() > 0; +bool PathManipulator::isBSpline(bool recalculate){ + if(recalculate){ + _is_bspline = this->BSplineGetSteps() > 0; + } + return _is_bspline; } // returns the corresponding strength to the position of a handler @@ -1284,7 +1282,8 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; - isBSpline(/*true*/); + //Refresh if is bspline some times -think on path change selection, this value get lost + isBSpline(true); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 67590832d..f15533021 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(/*bool recalculate = true*/); + bool isBSpline(bool recalculate = true); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); @@ -152,6 +152,7 @@ private: bool _show_path_direction; bool _live_outline; bool _live_objects; + bool _is_bspline; Glib::ustring _lpe_key; friend class PathManipulatorObserver; -- cgit v1.2.3 From 95b10e0707ee0e16055d5e514e1d05c929d49b5a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 18 Mar 2014 17:34:31 -0600 Subject: Added in new toy effect "Taper Strokes," readded a missing header file, bugfixes (bzr r13090.1.25) --- src/ui/clipboard.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/ui') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 8e2502545..2dabf1884 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -601,6 +601,12 @@ Glib::ustring ClipboardManagerImpl::getPathParameter(SPDesktop* desktop) */ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) { + //https://bugs.launchpad.net/inkscape/+bug/1293979 + //basically, when we do a depth-first search, we're stopping + //at the first object to be or . + //but that could then return the id of the object's + //clip path or mask, not the original path! + SPDocument *tempdoc = _retrieveClipboard(); // any target will do here if ( tempdoc == NULL ) { _userWarn(desktop, _("Nothing on the clipboard.")); @@ -608,6 +614,9 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) } Inkscape::XML::Node *root = tempdoc->getReprRoot(); + //1293979: strip out the defs of the document + root->removeChild(tempdoc->getDefs()->getRepr()); + Inkscape::XML::Node *repr = sp_repr_lookup_name(root, "svg:path", -1); // unlimited search depth if ( repr == NULL ) { repr = sp_repr_lookup_name(root, "svg:text", -1); -- cgit v1.2.3 From c1c76126846e36fab78a51e5acec475b4de5ea44 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 19 Mar 2014 21:54:30 +0100 Subject: This think fix su_v related bug on continuous paths in BSpline or Spiro mode (bzr r11950.1.301) --- src/ui/tools/freehand-base.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 3f74a5147..67b603ab0 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -495,7 +495,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Blue2 dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - + /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because we modify it when continuing through an anchor. */ @@ -614,6 +614,18 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) bool has_lpe = false; Inkscape::XML::Node *repr; + + /* if we are in bspline or spirolive the anchors curves, if exist, needs to be selected again because + we modify it when continuing through an anchor. */ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if ( ((dc->sa && !dc->sa->curve->is_empty()) || + (dc->ea && !dc->ea->curve->is_empty())) && + (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) + ) { + spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); + } + if (dc->white_item) { repr = dc->white_item->getRepr(); has_lpe = SP_LPE_ITEM(dc->white_item)->hasPathEffectRecursive(); -- cgit v1.2.3 From c6e50a519c55220ccd4efdd6a7a7dbe51cf9fa04 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Mar 2014 22:49:07 +0100 Subject: Fixing suv mac bug continuing existing bsplines/spiro paths (bzr r11950.1.303) --- src/ui/tools/freehand-base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 67b603ab0..d34ca2142 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -566,7 +566,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) s = reverse_then_unref(s); } s->append_continuous(c, 0.0625); - c->unref(); + c->reset(); c = s; } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; -- cgit v1.2.3 From 988c4a1639ca097634e336d49ad92eb1eb576f31 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 19 Mar 2014 23:05:50 +0100 Subject: Fix a bug when starting path with change from bspline to spiro and inverse (bzr r11950.1.304) --- src/ui/tools/pen-tool.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d79803644..75dd6a32b 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1445,6 +1445,10 @@ void PenTool::_bspline_spiro_off() void PenTool::_bspline_spiro_start_anchor(bool shift) { + if(this->sa->curve->is_empty()){ + return; + } + LivePathEffect::LPEBSpline *lpe_bsp = NULL; if (SP_IS_LPE_ITEM(this->white_item) && SP_LPE_ITEM(this->white_item)->hasPathEffect()){ @@ -1474,9 +1478,6 @@ void PenTool::_bspline_spiro_start_anchor(bool shift) if(!this->spiro && !this->bspline) return; - if(this->sa->curve->is_empty()) - return; - if(shift) this->_bspline_spiro_start_anchor_off(); else -- cgit v1.2.3 From 67a180fdd31fd8dd06be4df75356509001295458 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 01:48:37 +0100 Subject: Refactor of anchors (bzr r11950.1.306) --- src/ui/tools/freehand-base.cpp | 97 +++++++++++++++++------------------------- src/ui/tools/freehand-base.h | 2 + src/ui/tools/pen-tool.cpp | 18 ++++---- 3 files changed, 50 insertions(+), 67 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index d34ca2142..5897ce0ee 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -492,17 +492,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); - // Blue2 - dc->blue2_curve->reset(); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - - /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. - if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because - we modify it when continuing through an anchor. */ if (c->is_empty()) { - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); - } c->unref(); return; } @@ -526,50 +516,43 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - - /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. - this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and - close incorrectly one of the parts */ + if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { + c = reverse_then_unref(c); + } if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - dc->sa->curve = reverse_then_unref(dc->sa->curve); - } - dc->sa->curve->append_continuous(c, 0.0625); + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + dc->sc->append_continuous(c, 0.0625); c->unref(); - if(Geom::are_near(dc->sa->curve->first_path()->initialPoint(), dc->ea->dp)){ - dc->sa->curve->closepath_current(); - } - - // if the curve has an bspline or spiro LPE, we execute - // spdc_flush_white, passing the necessary starting curve. - dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - spdc_flush_white(dc, dc->sa->curve); + dc->sc->closepath_current(); }else{ - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - c = reverse_then_unref(c); - } dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - spdc_flush_white(dc, NULL); } - + spdc_flush_white(dc, NULL); return; } // Step C - test start if (dc->sa) { SPCurve *s = dc->sa->curve; + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + s = dc->sc; + } dc->white_curves = g_slist_remove(dc->white_curves, s); if (dc->sa->start) { s = reverse_then_unref(s); } s->append_continuous(c, 0.0625); - c->reset(); + c->unref(); c = s; } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + e = dc->ec; + } dc->white_curves = g_slist_remove(dc->white_curves, e); if (!dc->ea->start) { e = reverse_then_unref(e); @@ -577,16 +560,30 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->append_continuous(e, 0.0625); e->unref(); } + + spdc_flush_white(dc, c); + c->unref(); } static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) { SPCurve *c; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (dc->white_curves) { g_assert(dc->white_item); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + if(dc->sa){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + dc->white_curves = g_slist_append(dc->white_curves, dc->sc); + } + if(dc->ea){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->ea->curve); + dc->white_curves = g_slist_append(dc->white_curves, dc->ec); + } + } c = SPCurve::concat(dc->white_curves); g_slist_free(dc->white_curves); dc->white_curves = NULL; @@ -615,17 +612,6 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) bool has_lpe = false; Inkscape::XML::Node *repr; - /* if we are in bspline or spirolive the anchors curves, if exist, needs to be selected again because - we modify it when continuing through an anchor. */ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if ( ((dc->sa && !dc->sa->curve->is_empty()) || - (dc->ea && !dc->ea->curve->is_empty())) && - (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) - ) { - spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); - } - if (dc->white_item) { repr = dc->white_item->getRepr(); has_lpe = SP_LPE_ITEM(dc->white_item)->hasPathEffectRecursive(); @@ -689,19 +675,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) active = na; } } - - /* modify the anchoring curve so it is equal to the starting curve. - this curve is modified when it's modified and we need them to be equal to the closing curve */ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && - dc->sa && !dc->red_curve->is_empty() && !dc->green_anchor){ - if(active){ - active->curve = dc->sa->curve; - active->curve->ref(); - } - } - return active; } @@ -750,6 +723,14 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue2_curve = dc->blue2_curve->unref(); } + if (dc->sc) { + dc->sc = dc->sc->unref(); + } + + if (dc->ec) { + dc->ec = dc->ec->unref(); + } + // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index d5c2fc9ba..266e22783 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -74,9 +74,11 @@ public: // Start anchor SPDrawAnchor *sa; + SPCurve * sc; // End anchor SPDrawAnchor *ea; + SPCurve * ec; /* type of the LPE that is to be applied automatically to a finished path (if any) */ Inkscape::LivePathEffect::EffectType waiting_LPE_type; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 75dd6a32b..1701cf5d9 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1516,8 +1516,8 @@ void PenTool::_bspline_spiro_start_anchor_on() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } void PenTool::_bspline_spiro_start_anchor_off() @@ -1542,8 +1542,8 @@ void PenTool::_bspline_spiro_start_anchor_off() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } } @@ -1677,8 +1677,8 @@ void PenTool::_bspline_spiro_end_anchor_on() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } } @@ -1726,8 +1726,8 @@ void PenTool::_bspline_spiro_end_anchor_off() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } } } @@ -1742,7 +1742,7 @@ void PenTool::_bspline_spiro_build() SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start if(this->sa && !this->sa->curve->is_empty()){ - curve = this->sa->curve->copy(); + curve = this->sc->copy(); if (this->sa->start) { curve = curve->create_reverse(); } -- cgit v1.2.3 From 9c0d852d84da8af9cbb07ee2ed0488390225f126 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 03:27:13 +0100 Subject: Full refactor of path continuations in bspline-spirolive mode, I think no more suv mac crashes, but need to be full tested again because a lot of things changed. (bzr r11950.1.308) --- src/ui/tools/freehand-base.cpp | 37 +++++++++++++++---------------------- src/ui/tools/freehand-base.h | 4 ++-- src/ui/tools/pen-tool.cpp | 5 ++--- src/ui/tools/pencil-tool.cpp | 3 +++ 4 files changed, 22 insertions(+), 27 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5897ce0ee..cecf0c0ca 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -92,7 +92,9 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , white_curves(NULL) , white_anchors(NULL) , sa(NULL) + , sc(NULL) , ea(NULL) + , ec(NULL) , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE) , red_curve_is_valid(false) , anchor_statusbar(false) @@ -153,6 +155,12 @@ void FreehandBase::setup() { this->green_anchor = NULL; this->green_closed = FALSE; + // Create start anchor alternative curve + this->sc = new SPCurve(); + + // Create end anchor alternative curve + this->ec = new SPCurve(); + this->attach = TRUE; spdc_attach_selection(this, this->selection); } @@ -524,6 +532,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sc->append_continuous(c, 0.0625); c->unref(); dc->sc->closepath_current(); + if(dc->sa){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + dc->white_curves = g_slist_append(dc->white_curves, dc->sc); + } }else{ dc->sa->curve->append_continuous(c, 0.0625); c->unref(); @@ -536,11 +548,11 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Step C - test start if (dc->sa) { SPCurve *s = dc->sa->curve; + dc->white_curves = g_slist_remove(dc->white_curves, s); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ s = dc->sc; } - dc->white_curves = g_slist_remove(dc->white_curves, s); if (dc->sa->start) { s = reverse_then_unref(s); } @@ -549,11 +561,11 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c = s; } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; + dc->white_curves = g_slist_remove(dc->white_curves, e); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ e = dc->ec; } - dc->white_curves = g_slist_remove(dc->white_curves, e); if (!dc->ea->start) { e = reverse_then_unref(e); } @@ -570,20 +582,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) { SPCurve *c; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (dc->white_curves) { g_assert(dc->white_item); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - if(dc->sa){ - dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - dc->white_curves = g_slist_append(dc->white_curves, dc->sc); - } - if(dc->ea){ - dc->white_curves = g_slist_remove(dc->white_curves, dc->ea->curve); - dc->white_curves = g_slist_append(dc->white_curves, dc->ec); - } - } c = SPCurve::concat(dc->white_curves); g_slist_free(dc->white_curves); dc->white_curves = NULL; @@ -723,14 +724,6 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue2_curve = dc->blue2_curve->unref(); } - if (dc->sc) { - dc->sc = dc->sc->unref(); - } - - if (dc->ec) { - dc->ec = dc->ec->unref(); - } - // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 266e22783..c134c5352 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -74,11 +74,11 @@ public: // Start anchor SPDrawAnchor *sa; - SPCurve * sc; + SPCurve *sc; // End anchor SPDrawAnchor *ea; - SPCurve * ec; + SPCurve *ec; /* type of the LPE that is to be applied automatically to a finished path (if any) */ Inkscape::LivePathEffect::EffectType waiting_LPE_type; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 1701cf5d9..3ef9b96af 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1516,7 +1516,6 @@ void PenTool::_bspline_spiro_start_anchor_on() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); this->sc = tmpCurve; } @@ -1542,7 +1541,6 @@ void PenTool::_bspline_spiro_start_anchor_off() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); this->sc = tmpCurve; } @@ -1677,7 +1675,6 @@ void PenTool::_bspline_spiro_end_anchor_on() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); this->sc = tmpCurve; } } @@ -2176,6 +2173,8 @@ void PenTool::_finish(gboolean const closed) { // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); + this->sc = NULL; + this->ec = NULL; this->sa = NULL; this->ea = NULL; diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 1ccdee637..8fe01a852 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -203,6 +203,7 @@ gint PencilTool::_handleButtonPress(GdkEventButton const &bevent) { } if (anchor) { p = anchor->dp; + this->sc = anchor->curve; desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); } else { m.setup(desktop); @@ -380,6 +381,7 @@ gint PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /* Finish segment now */ if (anchor) { p = anchor->dp; + this->ec = anchor->curve; } else { this->_endpointSnap(p, revent.state); } @@ -406,6 +408,7 @@ gint PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /// \todo fixme: Clean up what follows (Lauris) if (anchor) { p = anchor->dp; + this->ec = anchor->curve; } else { Geom::Point p_end = p; this->_endpointSnap(p_end, revent.state); -- cgit v1.2.3 From 8dee559ebb54fa7e1ef995b71713c0685b333d60 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 03:35:35 +0100 Subject: Removed persistent blue line (bzr r11950.1.309) --- src/ui/tools/freehand-base.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index cecf0c0ca..ac98be2cf 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -493,6 +493,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue_bpath), NULL); + // Blue2 + dc->blue2_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); + // Red if (dc->red_curve_is_valid) { c->append_continuous(dc->red_curve, 0.0625); -- cgit v1.2.3 From 1ee8c21b5cfe9efa827eed7ab5e31fe28a9b4ae1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 03:39:27 +0100 Subject: Fixed bug continuing cusp nodes (bzr r11950.1.310) --- src/ui/tools/pen-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 3ef9b96af..cea8e67e6 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1563,7 +1563,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ - tmpCurve = this->sa->curve->copy(); + tmpCurve = this->sc->copy(); if(this->sa->start) tmpCurve = tmpCurve->create_reverse(); } -- cgit v1.2.3 From 9a04c985ec628dc749a8a82d94bcf47d482a4f63 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 20 Mar 2014 17:09:57 -0400 Subject: Fix a linker error ("static") (hopefully) Resolve compiler errors with GTK3+ (bzr r13090.1.28) --- src/ui/dialog/objects.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 338233042..85583a0e7 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1887,8 +1887,9 @@ ObjectsPanel::ObjectsPanel() : btn = Gtk::manage( new Gtk::Button() ); btn->set_tooltip_text(_("Collapse All")); #if GTK_CHECK_VERSION(3,10,0) - btn->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else + image_remove = Gtk::manage(new Gtk::Image()); image_remove->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); btn->set_image(*image_remove); #endif -- cgit v1.2.3 From e65f0ccd07f3b1278ba389025af29df498a3b3ab Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 31 Mar 2014 16:38:26 +0200 Subject: =?UTF-8?q?clarify=20the=20'sc'=20and=20'ec'=20SPCurve,=20by=20poi?= =?UTF-8?q?nt=20of=20Vin=C3=ADcius,=20whith=20the=20result=20of=20one=20cu?= =?UTF-8?q?rve=20less=20in=20the=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.320) --- src/ui/tools/freehand-base.cpp | 20 ++++++-------------- src/ui/tools/freehand-base.h | 7 +++++-- src/ui/tools/pen-tool.cpp | 18 ++++++++---------- src/ui/tools/pencil-tool.cpp | 4 +--- 4 files changed, 20 insertions(+), 29 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index ac98be2cf..04796c2a6 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -91,10 +91,9 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , white_item(NULL) , white_curves(NULL) , white_anchors(NULL) + , overwriteCurve(NULL) , sa(NULL) - , sc(NULL) , ea(NULL) - , ec(NULL) , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE) , red_curve_is_valid(false) , anchor_statusbar(false) @@ -156,10 +155,7 @@ void FreehandBase::setup() { this->green_closed = FALSE; // Create start anchor alternative curve - this->sc = new SPCurve(); - - // Create end anchor alternative curve - this->ec = new SPCurve(); + this->overwriteCurve = new SPCurve(); this->attach = TRUE; spdc_attach_selection(this, this->selection); @@ -533,12 +529,12 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) } if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - dc->sc->append_continuous(c, 0.0625); + dc->overwriteCurve->append_continuous(c, 0.0625); c->unref(); - dc->sc->closepath_current(); + dc->overwriteCurve->closepath_current(); if(dc->sa){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - dc->white_curves = g_slist_append(dc->white_curves, dc->sc); + dc->white_curves = g_slist_append(dc->white_curves, dc->overwriteCurve); } }else{ dc->sa->curve->append_continuous(c, 0.0625); @@ -555,7 +551,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->white_curves = g_slist_remove(dc->white_curves, s); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - s = dc->sc; + s = dc->overwriteCurve; } if (dc->sa->start) { s = reverse_then_unref(s); @@ -566,10 +562,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; dc->white_curves = g_slist_remove(dc->white_curves, e); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - e = dc->ec; - } if (!dc->ea->start) { e = reverse_then_unref(e); } diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 2422c3563..6e04e03b7 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -79,13 +79,16 @@ public: GSList *white_curves; GSList *white_anchors; + //ALternative curve to use on continuing exisiting curve in case of bspline or spirolive + //because usigh anchor curves give memory and random bugs, - and obscure code- in some plataform reported by su_v in mac + SPCurve *overwriteCurve; + // Start anchor SPDrawAnchor *sa; - SPCurve *sc; // End anchor SPDrawAnchor *ea; - SPCurve *ec; + /* type of the LPE that is to be applied automatically to a finished path (if any) */ Inkscape::LivePathEffect::EffectType waiting_LPE_type; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 053f1ac3d..1c0394e15 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -378,7 +378,6 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { Geom::Point event_dt(desktop->w2d(event_w)); //Test whether we hit any anchor. SPDrawAnchor * const anchor = spdc_test_inside(this, event_w); - ToolBase *event_context = SP_EVENT_CONTEXT(this); //with this we avoid creating a new point over the existing one if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ @@ -1535,7 +1534,7 @@ void PenTool::_bspline_spiro_start_anchor_on() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc = tmpCurve; + this->overwriteCurve = tmpCurve; } void PenTool::_bspline_spiro_start_anchor_off() @@ -1560,7 +1559,7 @@ void PenTool::_bspline_spiro_start_anchor_off() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc = tmpCurve; + this->overwriteCurve = tmpCurve; } } @@ -1582,7 +1581,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ - tmpCurve = this->sc->copy(); + tmpCurve = this->overwriteCurve->copy(); if(this->sa->start) tmpCurve = tmpCurve->create_reverse(); } @@ -1694,7 +1693,7 @@ void PenTool::_bspline_spiro_end_anchor_on() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc = tmpCurve; + this->overwriteCurve = tmpCurve; } } @@ -1742,8 +1741,8 @@ void PenTool::_bspline_spiro_end_anchor_off() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); - this->sc = tmpCurve; + this->overwriteCurve->reset(); + this->overwriteCurve = tmpCurve; } } } @@ -1758,7 +1757,7 @@ void PenTool::_bspline_spiro_build() SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start if(this->sa && !this->sa->curve->is_empty()){ - curve = this->sc->copy(); + curve = this->overwriteCurve->copy(); if (this->sa->start) { curve = curve->create_reverse(); } @@ -2191,8 +2190,7 @@ void PenTool::_finish(gboolean const closed) { // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); - this->sc = NULL; - this->ec = NULL; + this->overwriteCurve = NULL; this->sa = NULL; this->ea = NULL; diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 6f55d361f..0e8660248 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -200,7 +200,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) { } if (anchor) { p = anchor->dp; - this->sc = anchor->curve; + this->overwriteCurve = anchor->curve; desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); } else { m.setup(desktop); @@ -372,7 +372,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /* Finish segment now */ if (anchor) { p = anchor->dp; - this->ec = anchor->curve; } else { this->_endpointSnap(p, revent.state); } @@ -398,7 +397,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /// \todo fixme: Clean up what follows (Lauris) if (anchor) { p = anchor->dp; - this->ec = anchor->curve; } else { Geom::Point p_end = p; this->_endpointSnap(p_end, revent.state); -- cgit v1.2.3 From ac61d9ff74ea5ee53ad39e95c22348da35ef5cf0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 31 Mar 2014 16:41:27 +0200 Subject: =?UTF-8?q?use=20=20instead=20=20by=20point=20of=20?= =?UTF-8?q?Vin=C3=ADcius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.321) --- src/ui/tool/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 4824e13fb..3be3a89a7 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,7 +28,7 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include -#include +#include namespace { -- cgit v1.2.3 From 2b19c5f6508b7a59766d89f315f9f4fbc364f288 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Apr 2014 00:48:28 +0200 Subject: Some node.cpp/h work moved to path_manipulator. Header variable bsplineWeight removed from all. Simplification of code with less functions in path_manipulator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To fix: tips stop working because is handled by two static functions and couldent call to path_manipulator from here. Vinícius, any work arround? lines 480,481,1426,1427,1462 of node.cpp. gez: ¿Puedes probar si notas algun bug o problema? principalmente con la herramienta nodo, gracias. (bzr r11950.1.322) --- src/ui/tool/curve-drag-point.cpp | 4 +- src/ui/tool/node.cpp | 166 ++++++++++++++++++++++----------------- src/ui/tool/node.h | 2 - src/ui/tool/path-manipulator.cpp | 46 ++++------- src/ui/tool/path-manipulator.h | 10 +-- 5 files changed, 118 insertions(+), 110 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index ad03cf75d..013553410 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -94,8 +94,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8 && !second->isEndNode() && held_shift(*event))second->back()->move(new_pos); - else if(weight<=0.2 && !first->isEndNode() && held_shift(*event))first->front()->move(new_pos); + }else if(weight>=0.8 && held_shift(*event))second->back()->move(new_pos); + else if(weight<=0.2 && held_shift(*event))first->front()->move(new_pos); _pm.update(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 3be3a89a7..1eaf0afa7 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -30,6 +30,7 @@ #include #include + namespace { Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) @@ -168,9 +169,9 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //move the handler and its oposite the same proportion - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); } return; } @@ -185,9 +186,9 @@ void Handle::move(Geom::Point const &new_pos) setRelativePos(new_delta); //move the handler and its oposite the same proportion - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); } return; @@ -211,9 +212,9 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); // moves the handler and its oposite the same proportion - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); } } @@ -305,9 +306,9 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven //this function moves the handler and its oposite to the default proportion of 0.3334 void Handle::handle_2button_press(){ - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),0.3334)); _pm().update(); } } @@ -361,17 +362,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) new_pos = result; // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" // by default in live BSpline - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); - _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; - new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); + new_pos=_pm().BSplineHandleReposition(this,ceilf(_pm().BSplineHandlePosition(this)*steps)/steps); } } std::vector unselected; //if the snap adjustment is activated and it is not bspline - if (snap && !_pm().isBSpline(false)) { + if (snap && !_pm().isBSpline()) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -412,7 +412,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } } //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position - if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ + if(_pm().isBSpline() && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } move(new_pos); // needed for correct update, even though it's redundant @@ -431,10 +431,6 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //sets the bspline strength to 0.0000 - if(_pm().isBSpline(false)){ - _parent->bsplineWeight = 0.0000; - } } } @@ -481,8 +477,8 @@ Glib::ustring Handle::_getTip(unsigned state) const // to show the appropiate messages. We cannot do it in any different way becasue the function is constant bool isBSpline = false; - if( _parent->bsplineWeight != 0.0000) - isBSpline = true; + //if( _parent->bsplineWeight != 0.0000) + // isBSpline = true; bool can_shift_rotate = _parent->type() == NODE_CUSP && !other()->isDegenerate(); if (can_shift_rotate && !isBSpline) { more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); @@ -622,11 +618,21 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - // save the previous node strength to apply it again once the node is moved - double oldPos = 0.0000; + // save the previous nodes strength to apply it again once the node is moved + double nodeWeight = 0.0000; + double nextNodeWeight = 0.0000; + double prevNodeWeight = 0.0000; Node *n = this; - if(_pm().isBSpline(false)){ - oldPos = n->bsplineWeight; + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + if(_pm().isBSpline()){ + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(nextNode){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + } + if(prevNode){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } } setPosition(new_pos); @@ -639,21 +645,49 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); // move the affected handlers. First the node ones, later the adjoining ones. - if(_pm().isBSpline(false)){ - _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); - _pm().BSplineNodeHandlesReposition(this); + if(_pm().isBSpline()){ + _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); + if(prevNode){ + if(prevNode->front()->isDegenerate()){ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); + }else{ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + } + } + if(nextNode){ + if(nextNode->back()->isDegenerate()){ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); + }else{ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + } + } } } void Node::transform(Geom::Affine const &m) { - // save the previous node strength to apply it again later when the node is moved - double oldPos = 0.0000; - if(_pm().isBSpline(false)){ - oldPos = this->bsplineWeight; - } + Geom::Point old_pos = position(); + + // save the previous nodes strength to apply it again once the node is moved + double nodeWeight = 0.0000; + double nextNodeWeight = 0.0000; + double prevNodeWeight = 0.0000; + + Node *n = this; + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + if(_pm().isBSpline()){ + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(nextNode){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + } + if(prevNode){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } + } + setPosition(position() * m); _front.setPosition(_front.position() * m); _back.setPosition(_back.position() * m); @@ -663,10 +697,23 @@ void Node::transform(Geom::Affine const &m) _fixNeighbors(old_pos, position()); // move the involved handlers, first the node ones, later the adjoining ones - if(_pm().isBSpline(false)){ - _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); - _pm().BSplineNodeHandlesReposition(this); + if(_pm().isBSpline()){ + _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); + if(prevNode){ + if(prevNode->front()->isDegenerate()){ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); + }else{ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + } + } + if(nextNode){ + if(nextNode->back()->isDegenerate()){ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); + }else{ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + } + } } } @@ -754,19 +801,6 @@ void Node::showHandles(bool v) _back.setVisible(v); } - // define the node strength, depending on being or not bspline traced. - // every time we operate over these handlers in a trace bspline - // that strength needs to be updated. - - this->bsplineWeight = 0.0000; - if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ - if (!_front.isDegenerate()) { - _pm().BSplineHandlePosition(&_front); - } - if (!_back.isDegenerate()) { - _pm().BSplineHandlePosition(&_back); - } - } } void Node::updateHandles() @@ -870,10 +904,13 @@ void Node::setType(NodeType type, bool update_handles) } /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, or we give them the default power in curve mode */ - if(_pm().isBSpline(false)){ - if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; - _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + if(_pm().isBSpline()){ + double weight = 0.0000; + if(_pm().BSplineHandlePosition(this->front()) != 0.0000){ + weight = 0.3334; + } + _front.setPosition(_pm().BSplineHandleReposition(this->front(),weight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),weight)); } } _type = type; @@ -1123,20 +1160,9 @@ void Node::_setState(State state) mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); //this shows the handlers when selecting the nodes - if(_pm().isBSpline(false)){ - if(!this->back()->isDegenerate()){ - _pm().BSplineHandlePosition(this->back()); - }else if (!this->front()->isDegenerate()){ - _pm().BSplineHandlePosition(this->front()); - }else{ - this->bsplineWeight = 0.0000; - } - if(!this->front()->isDegenerate()){ - this->front()->setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); - } - if(!this->back()->isDegenerate()){ - this->back()->setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); - } + if(_pm().isBSpline()){ + this->front()->setPosition(_pm().BSplineHandleReposition(this->front())); + this->back()->setPosition(_pm().BSplineHandleReposition(this->back())); } break; } @@ -1397,8 +1423,8 @@ Glib::ustring Node::_getTip(unsigned state) const to show the appropiate messages. We cannot do it in any other way, because the function is constant */ bool isBSpline = false; - if( this->bsplineWeight != 0.0000) - isBSpline = true; + //if( this->bsplineWeight != 0.0000) + // isBSpline = true; if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { @@ -1433,7 +1459,7 @@ Glib::ustring Node::_getTip(unsigned state) const "%s: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype); }else if(_selection.size() == 1){ return format_tip(C_("Path node tip", - "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),this->bsplineWeight); + "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),0.0000/*this->bsplineWeight*/); } return format_tip(C_("Path node tip", "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype); diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index fc36502a5..202dbb3cd 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -191,8 +191,6 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //strength value for each node - double bsplineWeight; /** * Gets the handle that faces the given adjacent node. diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 841ab659a..905df61f4 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -666,14 +666,11 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite } // if we are removing, we readjust the handlers if(isBSpline()){ - double pos = 0.0000; if(start.prev()){ - pos = BSplineHandlePosition(start.prev()->back()); - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),pos)); + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),true)); } if(end){ - pos = BSplineHandlePosition(end->front()); - end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); + end->back()->setPosition(BSplineHandleReposition(end->back(),true)); } } @@ -1209,31 +1206,36 @@ bool PathManipulator::isBSpline(bool recalculate){ return _is_bspline; } -// returns the corresponding strength to the position of a handler -double PathManipulator::BSplineHandlePosition(Handle *h){ +// returns the corresponding strength to the position of the handlers +double PathManipulator::BSplineHandlePosition(Handle *h, bool other){ using Geom::X; using Geom::Y; double pos = 0.0000; Node *n = h->parent(); Node * nextNode = NULL; + if(other){ + h = h->other(); + } nextNode = n->nodeToward(h); - if(nextNode && n->position() != h->position()){ + if(nextNode && !Geom::are_near(n->position(), h->position())){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } - n->bsplineWeight = pos; + if ((pos == 0.0000 || pos == 1.0000) && other == false){ + return BSplineHandlePosition(h, true); + } return pos; } -// moves the handler to the corresponding position -Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ - double pos = this->BSplineHandlePosition(h); +// give the location for the handler in the corresponding position +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, bool other){ + double pos = this->BSplineHandlePosition(h, other); return BSplineHandleReposition(h,pos); } -// moves the handler to the specified position +// give the location for the handler to the specified position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1247,34 +1249,16 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - n->bsplineWeight = pos; ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + 0.005,ret[Y] + 0.005); }else{ if(pos == 0.0000){ - n->bsplineWeight = 0.0000; ret = n->position(); } } return ret; } -//moves the node handlers and its oposite handlers to the strength of its nodes -void PathManipulator::BSplineNodeHandlesReposition(Node *n){ - Node * nextNode = n->nodeToward(n->front()); - Node * prevNode = n->nodeToward(n->back()); - if(prevNode){ - if(!prevNode->isEndNode()) - prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); - prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); - } - if(nextNode){ - if(!nextNode->isEndNode()) - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); - nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); - } -} - /** Construct the geometric representation of nodes and handles, update the outline * and display * \param alert_LPE if true, first the LPE is warned what the new path is going to be before updating it diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index f15533021..cba029b68 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,11 +106,11 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(bool recalculate = true); - double BSplineHandlePosition(Handle *h); - Geom::Point BSplineHandleReposition(Handle *h); - Geom::Point BSplineHandleReposition(Handle *h,double pos); - void BSplineNodeHandlesReposition(Node *n); + + bool isBSpline(bool recalculate = false); + double BSplineHandlePosition(Handle *h, bool other = false); + Geom::Point BSplineHandleReposition(Handle *h, bool other = false); + Geom::Point BSplineHandleReposition(Handle *h, double pos); void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From 0f78c1425e814758c0a0d7f0c2578eae88fe3ab6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Apr 2014 14:02:22 +0200 Subject: =?UTF-8?q?A=20refactor=20for=20fixing=20some=20issues.=20Pending?= =?UTF-8?q?=20how=20to=20handle=20static=20functions=20Vin=C3=ADcius=20for?= =?UTF-8?q?=20handle=20tips=20in=20his=20static=20functions=20i=20know=20t?= =?UTF-8?q?wo=20ways:=20A:=20A=20bool=20property=20in=20node=20class=20of?= =?UTF-8?q?=20node.h=20to=20handle=20if=20curve=20is=20bspline=20B:=20Call?= =?UTF-8?q?=20another=20non=20static=20function=20from=20the=20static=20ti?= =?UTF-8?q?ps=20one=20-not=20tested-?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.323) --- src/ui/tool/node.cpp | 61 +++++++++++++++++++++------------------- src/ui/tool/path-manipulator.cpp | 22 +++++++-------- src/ui/tool/path-manipulator.h | 4 +-- 3 files changed, 45 insertions(+), 42 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1eaf0afa7..7ba69b039 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -170,8 +170,8 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); + setPosition(_pm().BSplineHandleReposition(this,this)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this)); } return; } @@ -187,8 +187,8 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); + setPosition(_pm().BSplineHandleReposition(this,this)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this)); } return; @@ -213,8 +213,8 @@ void Handle::move(Geom::Point const &new_pos) // moves the handler and its oposite the same proportion if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); + setPosition(_pm().BSplineHandleReposition(this,this)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this)); } } @@ -365,7 +365,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(_pm().isBSpline()){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); - new_pos=_pm().BSplineHandleReposition(this,ceilf(_pm().BSplineHandlePosition(this)*steps)/steps); + new_pos=_pm().BSplineHandleReposition(this,ceilf(_pm().BSplineHandlePosition(this,this)*steps)/steps); } } @@ -625,13 +625,15 @@ void Node::move(Geom::Point const &new_pos) Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - if(_pm().isBSpline()){ - nodeWeight = _pm().BSplineHandlePosition(n->front()); - if(nextNode){ - nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(prevNode){ + if(prevNode->isEndNode()){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front(),prevNode->front()); } - if(prevNode){ - prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } + if(nextNode){ + if(nextNode->isEndNode()){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->back(),nextNode->back()); } } @@ -649,17 +651,17 @@ void Node::move(Geom::Point const &new_pos) _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); if(prevNode){ - if(prevNode->front()->isDegenerate()){ + if(prevNode->isEndNode()){ prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); }else{ - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNode->back())); } } if(nextNode){ - if(nextNode->back()->isDegenerate()){ + if(nextNode->isEndNode()){ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->back())); } } } @@ -674,17 +676,18 @@ void Node::transform(Geom::Affine const &m) double nodeWeight = 0.0000; double nextNodeWeight = 0.0000; double prevNodeWeight = 0.0000; - Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - if(_pm().isBSpline()){ - nodeWeight = _pm().BSplineHandlePosition(n->front()); - if(nextNode){ - nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(prevNode){ + if(prevNode->isEndNode()){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front(),prevNode->front()); } - if(prevNode){ - prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } + if(nextNode){ + if(nextNode->isEndNode()){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->back(),nextNode->back()); } } @@ -701,17 +704,17 @@ void Node::transform(Geom::Affine const &m) _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); if(prevNode){ - if(prevNode->front()->isDegenerate()){ + if(prevNode->isEndNode()){ prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); }else{ - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNode->back())); } } if(nextNode){ - if(nextNode->back()->isDegenerate()){ + if(nextNode->isEndNode()){ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->front())); } } } @@ -906,7 +909,7 @@ void Node::setType(NodeType type, bool update_handles) or we give them the default power in curve mode */ if(_pm().isBSpline()){ double weight = 0.0000; - if(_pm().BSplineHandlePosition(this->front()) != 0.0000){ + if(_pm().BSplineHandlePosition(this->front()) != 0.0000 ){ weight = 0.3334; } _front.setPosition(_pm().BSplineHandleReposition(this->front(),weight)); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 905df61f4..487c31b10 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -667,10 +667,10 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite // if we are removing, we readjust the handlers if(isBSpline()){ if(start.prev()){ - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),true)); + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),start.prev()->back())); } if(end){ - end->back()->setPosition(BSplineHandleReposition(end->back(),true)); + end->back()->setPosition(BSplineHandleReposition(end->back(),end->front())); } } @@ -1207,31 +1207,31 @@ bool PathManipulator::isBSpline(bool recalculate){ } // returns the corresponding strength to the position of the handlers -double PathManipulator::BSplineHandlePosition(Handle *h, bool other){ +double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ using Geom::X; using Geom::Y; + if(h2){ + h = h2; + } double pos = 0.0000; Node *n = h->parent(); Node * nextNode = NULL; - if(other){ - h = h->other(); - } nextNode = n->nodeToward(h); - if(nextNode && !Geom::are_near(n->position(), h->position())){ + if(nextNode){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } - if ((pos == 0.0000 || pos == 1.0000) && other == false){ - return BSplineHandlePosition(h, true); + if (pos == 0.0000 && !h2){ + return BSplineHandlePosition(h, h->other()); } return pos; } // give the location for the handler in the corresponding position -Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, bool other){ - double pos = this->BSplineHandlePosition(h, other); +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){ + double pos = this->BSplineHandlePosition(h, h2); return BSplineHandleReposition(h,pos); } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index cba029b68..a85664ddf 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -108,8 +108,8 @@ private: void _createControlPointsFromGeometry(); bool isBSpline(bool recalculate = false); - double BSplineHandlePosition(Handle *h, bool other = false); - Geom::Point BSplineHandleReposition(Handle *h, bool other = false); + double BSplineHandlePosition(Handle *h, Handle *h2 = NULL); + Geom::Point BSplineHandleReposition(Handle *h, Handle *h2 = NULL); Geom::Point BSplineHandleReposition(Handle *h, double pos); void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); -- cgit v1.2.3 From 064e0f756b7525d4af0b8a34b3ef6fe89c007064 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Apr 2014 01:56:31 +0200 Subject: Refactor of end anchors. (bzr r11950.1.325) --- src/ui/tools/freehand-base.cpp | 19 +++++ src/ui/tools/pen-tool.cpp | 169 ++++++++++++++++++++--------------------- 2 files changed, 101 insertions(+), 87 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 04796c2a6..1c5b7b8e3 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -565,6 +565,25 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if (!dc->ea->start) { e = reverse_then_unref(e); } + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + e = reverse_then_unref(e); + Geom::CubicBezier const * cubic = dynamic_cast(&*e->last_segment()); + SPCurve *lastSeg = new SPCurve(); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + if( e->get_segment_count() == 1){ + e = lastSeg; + }else{ + //we eliminate the last segment + e->backspace(); + //and we add it again with the recreation + e->append_continuous(lastSeg, 0.0625); + } + } + e = reverse_then_unref(e); + } c->append_continuous(e, 0.0625); e->unref(); } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 1c0394e15..9e4df5031 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1637,62 +1637,53 @@ void PenTool::_bspline_spiro_end_anchor_on() SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); - if(!this->sa || this->sa->curve->is_empty()){ + bool reverse = false; + if( this->green_anchor && this->green_anchor->active ){ tmpCurve = this->green_curve->create_reverse(); - if(this->green_curve->get_segment_count()==0)return; - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(this->bspline){ - C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); - }else{ - C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); - } - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); - }else{ - lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); - lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + if(this->green_curve->get_segment_count()==0){ + return; } - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); + reverse = true; + } else if(this->sa){ + tmpCurve = this->overwriteCurve; + if(!this->sa->start){ + tmpCurve = tmpCurve->create_reverse(); + reverse = true; } + }else{ + return; + } + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(this->bspline){ + C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); + }else{ + C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); + } + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); + }else{ + lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); + lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + } + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (reverse) { tmpCurve = tmpCurve->create_reverse(); + } + if( this->green_anchor && this->green_anchor->active ) + { this->green_curve->reset(); this->green_curve = tmpCurve; - }else { - tmpCurve = this->sa->curve->copy(); - if(!this->sa->start) tmpCurve = tmpCurve->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(this->bspline){ - C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); - }else{ - C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); - } - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); - }else{ - lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); - lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); - } - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } - if (!this->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } + }else{ + this->overwriteCurve->reset(); this->overwriteCurve = tmpCurve; } } @@ -1702,45 +1693,43 @@ void PenTool::_bspline_spiro_end_anchor_off() SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); + bool reverse = false; this->p[2] = this->p[3]; - if(!this->sa || this->sa->curve->is_empty()){ - + if( this->green_anchor && this->green_anchor->active ){ tmpCurve = this->green_curve->create_reverse(); - if(this->green_curve->get_segment_count()==0)return; - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } + if(this->green_curve->get_segment_count()==0){ + return; + } + reverse = true; + } else if(this->sa){ + tmpCurve = this->overwriteCurve; + if(!this->sa->start){ + tmpCurve = tmpCurve->create_reverse(); + reverse = true; + } + }else{ + return; + } + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (reverse) { tmpCurve = tmpCurve->create_reverse(); + } + if( this->green_anchor && this->green_anchor->active ) + { this->green_curve->reset(); this->green_curve = tmpCurve; - } - }else { - tmpCurve = this->sa->curve->copy(); - if(!this->sa->start) tmpCurve = tmpCurve->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } - if (!this->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } + }else{ this->overwriteCurve->reset(); this->overwriteCurve = tmpCurve; } @@ -1750,8 +1739,9 @@ void PenTool::_bspline_spiro_end_anchor_off() //prepares the curves for its transformation into BSpline curve. void PenTool::_bspline_spiro_build() { - if(!this->spiro && !this->bspline) + if(!this->spiro && !this->bspline){ return; + } //We create the base curve SPCurve *curve = new SPCurve(); @@ -1763,14 +1753,19 @@ void PenTool::_bspline_spiro_build() } } - if (!this->green_curve->is_empty()) + if (!this->green_curve->is_empty()){ curve->append_continuous(this->green_curve, 0.0625); + } //and the red one if (!this->red_curve->is_empty()){ this->red_curve->reset(); this->red_curve->moveto(this->p[0]); - this->red_curve->curveto(this->p[1],this->p[2],this->p[3]); + if(this->anchor_statusbar && !this->sa && !(this->green_anchor && this->green_anchor->active)){ + this->red_curve->curveto(this->p[1],this->p[3],this->p[3]); + }else{ + this->red_curve->curveto(this->p[1],this->p[2],this->p[3]); + } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); curve->append_continuous(this->red_curve, 0.0625); } -- cgit v1.2.3 From 1185cce53f3e490c6bb7939b1d9f42272a2e2f4f Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 3 Apr 2014 14:49:00 +0200 Subject: Try and explain what selection means when aligning. Changed Selection to Selection Area (bzr r13257) --- src/ui/dialog/align-and-distribute.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 6b4aeebb9..e02ccd3f1 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -1002,7 +1002,7 @@ AlignAndDistribute::AlignAndDistribute() _combo.append(_("Smallest object")); _combo.append(_("Page")); _combo.append(_("Drawing")); - _combo.append(_("Selection")); + _combo.append(_("Selection Area")); _combo.set_active(prefs->getInt("/dialogs/align/align-to", 6)); _combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change)); -- cgit v1.2.3 From 94226a90e4ba925c940f69059249836edfcd54e8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 4 Apr 2014 15:16:22 +0200 Subject: XMLTree and InkscapePreferences are not dockable windows, don't treat them like one. (bzr r13262) --- src/ui/dialog/dialog-manager.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 47e1fdd30..4be796e67 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -96,6 +96,9 @@ DialogManager::DialogManager() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); + registerFactory("InkscapePreferences", &create); + registerFactory("XmlTree", &create); + if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); registerFactory("DocumentMetadata", &create); @@ -106,7 +109,6 @@ DialogManager::DialogManager() { registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); @@ -126,7 +128,6 @@ DialogManager::DialogManager() { registerFactory("TextFont", &create); registerFactory("SpellCheck", &create); registerFactory("Export", &create); - registerFactory("XmlTree", &create); registerFactory("CloneTiler", &create); } else { @@ -140,7 +141,6 @@ DialogManager::DialogManager() { registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); @@ -160,7 +160,6 @@ DialogManager::DialogManager() { registerFactory("TextFont", &create); registerFactory("SpellCheck", &create); registerFactory("Export", &create); - registerFactory("XmlTree", &create); registerFactory("CloneTiler", &create); } -- cgit v1.2.3 From f337f7705f290ecef1790c75f8f94c85e13777b2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 4 Apr 2014 20:12:04 +0200 Subject: fix crash. Iterating through a list to find an object is not necessary, SPDoc provides method for obtaining SPObj from idstring. The crash probably happened because deleting the object invalidated the list iterated (partly). Fixed bugs: - https://launchpad.net/bugs/1302079 (bzr r13265) --- src/ui/dialog/document-properties.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 67e788e21..2674efc1e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1236,23 +1236,16 @@ void DocumentProperties::removeEmbeddedScript(){ } } - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - while ( current ) { - if (current->data && SP_IS_OBJECT(current->data)) { - SPObject* obj = SP_OBJECT(current->data); - if (id == obj->getId()){ - - //XML Tree being used directly here while it shouldn't be. - Inkscape::XML::Node *repr = obj->getRepr(); - if (repr){ - sp_repr_unparent(repr); - - // inform the document, so we can undo - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); - } - } + SPObject* obj = SP_ACTIVE_DOCUMENT->getObjectById(id); + if (obj) { + //XML Tree being used directly here while it shouldn't be. + Inkscape::XML::Node *repr = obj->getRepr(); + if (repr){ + sp_repr_unparent(repr); + + // inform the document, so we can undo + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); } - current = g_slist_next(current); } populate_script_lists(); -- cgit v1.2.3 From 749e8b0ee6b95f7c704fd326ebe948f9f4a076d2 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 5 Apr 2014 09:22:29 +0200 Subject: Revert the xml editor to it's dockable behaviour and add a comment for the preferences. (bzr r13269) --- src/ui/dialog/dialog-manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 4be796e67..d427e3590 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -96,8 +96,8 @@ DialogManager::DialogManager() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); + // The preferences dialog is broken, the DockBehavior code resizes it's floating window to the smallest size registerFactory("InkscapePreferences", &create); - registerFactory("XmlTree", &create); if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); @@ -129,6 +129,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("CloneTiler", &create); + registerFactory("XmlTree", &create); } else { @@ -161,6 +162,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("CloneTiler", &create); + registerFactory("XmlTree", &create); } } -- cgit v1.2.3 From 7744bd7a4bdfedd8d0d04b647fd6c0e80a603cb7 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 18 Apr 2014 19:08:21 -0400 Subject: Add image rendering option for outlines. Setup desktop preferences observer. (bzr r13291.1.1) --- src/ui/dialog/inkscape-preferences.cpp | 5 +++++ src/ui/dialog/inkscape-preferences.h | 1 + 2 files changed, 6 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index d826ece09..940f105d0 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1463,6 +1463,11 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_line( false, "", _importexport_import_res_override, "", _("Use default bitmap resolution in favor of information from file")); + _page_bitmaps.add_group_header( _("Render")); + // rendering outlines for pixmap image tags + _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", true); + _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); + this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index da85b805d..1c2151605 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -292,6 +292,7 @@ protected: UI::Widget::PrefCheckButton _show_filters_info_box; UI::Widget::PrefCombo _dockbar_style; UI::Widget::PrefCombo _switcher_style; + UI::Widget::PrefCheckButton _rendering_image_outline; UI::Widget::PrefSpinButton _rendering_cache_size; UI::Widget::PrefSpinButton _filter_multi_threaded; -- cgit v1.2.3 From 47abc2d2947692786bb402cedc107e40b9cd21e5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 19 Apr 2014 00:52:30 -0400 Subject: Fix remaining issue with prefs updating (bzr r13291.1.2) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 940f105d0..559398a84 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1465,7 +1465,7 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_group_header( _("Render")); // rendering outlines for pixmap image tags - _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", true); + _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false); _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); -- cgit v1.2.3 From 67c3fc5586ae05506f75bb30fe46a071e20613d2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Apr 2014 14:04:31 +0200 Subject: Clean up of style code, removal of SPFontStyle. Step 2. (bzr r13300) --- src/ui/dialog/font-substitution.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index bf9133086..6e9ecc3c8 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -200,16 +200,16 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring * } } - if (style && style->text) { + if (style) { gchar const *style_font = NULL; - if (style->text->font_family.set) - style_font = style->text->font_family.value; - else if (style->text->font_specification.set) - style_font = style->text->font_specification.value; - else if (style->text->font_family.value) - style_font = style->text->font_family.value; - else if (style->text->font_specification.value) - style_font = style->text->font_specification.value; + if (style->font_family.set) + style_font = style->font_family.value; + else if (style->font_specification.set) + style_font = style->font_specification.value; + else if (style->font_family.value) + style_font = style->font_family.value; + else if (style->font_specification.value) + style_font = style->font_specification.value; if (style_font) { if (has_visible_text(item)) { -- cgit v1.2.3 From b9f02c6200865e24150ce14a1e480c4283b0472a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 25 Apr 2014 12:49:54 -0700 Subject: Improve keyboard navigation in LPE dialog. Fixed bugs: - https://launchpad.net/bugs/1310688 (bzr r13305) --- src/ui/dialog/livepatheffect-add.cpp | 14 ++++++++++++++ src/ui/dialog/livepatheffect-add.h | 4 ++++ 2 files changed, 18 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp index b5f51d81d..c558eddaf 100644 --- a/src/ui/dialog/livepatheffect-add.cpp +++ b/src/ui/dialog/livepatheffect-add.cpp @@ -38,6 +38,7 @@ LivePathEffectAdd::LivePathEffectAdd() : scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); scrolled_window.set_shadow_type(Gtk::SHADOW_IN); scrolled_window.set_size_request(250, 200); + scrolled_window.set_can_focus(); /** * Effect Store and Tree @@ -83,10 +84,12 @@ LivePathEffectAdd::LivePathEffectAdd() : add_action_widget(close_button, Gtk::RESPONSE_CLOSE); add_action_widget(add_button, Gtk::RESPONSE_APPLY); + /** * Signal handlers */ effectlist_treeview.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LivePathEffectAdd::onButtonEvent) ); + effectlist_treeview.signal_key_press_event().connect_notify(sigc::mem_fun(*this, &LivePathEffectAdd::onKeyEvent)); close_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)); add_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onAdd)); signal_delete_event().connect( sigc::bind_return(sigc::hide(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)), true ) ); @@ -107,6 +110,16 @@ void LivePathEffectAdd::onClose() hide(); } +void LivePathEffectAdd::onKeyEvent(GdkEventKey* evt) +{ + if (evt->keyval == GDK_KEY_Return) { + onAdd(); + } + if (evt->keyval == GDK_KEY_Escape) { + onClose(); + } +} + void LivePathEffectAdd::onButtonEvent(GdkEventButton* evt) { // Double click on tree is same as clicking the add button @@ -135,6 +148,7 @@ void LivePathEffectAdd::show(SPDesktop *desktop) dial.set_modal(true); desktop->setWindowTransient (dial.gobj()); dial.property_destroy_with_parent() = true; + dial.effectlist_treeview.grab_focus(); dial.run(); } diff --git a/src/ui/dialog/livepatheffect-add.h b/src/ui/dialog/livepatheffect-add.h index 7fa766272..99ead878c 100644 --- a/src/ui/dialog/livepatheffect-add.h +++ b/src/ui/dialog/livepatheffect-add.h @@ -74,6 +74,10 @@ protected: */ void onButtonEvent(GdkEventButton* evt); + /** + * Key event + */ + void onKeyEvent(GdkEventKey* evt); private: Gtk::TreeView effectlist_treeview; -- cgit v1.2.3 From b9f4d7dfe7411f551192a98a3d8151e14149c5ae Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 26 Apr 2014 10:17:28 +0200 Subject: Clean up of style code: Patch from suv: SPStyle: struct -> class (bzr r13309) --- src/ui/widget/style-subject.h | 2 +- src/ui/widget/style-swatch.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h index c2941d995..47da91732 100644 --- a/src/ui/widget/style-subject.h +++ b/src/ui/widget/style-subject.h @@ -20,7 +20,7 @@ class SPDesktop; class SPObject; class SPCSSAttr; -struct SPStyle; +class SPStyle; namespace Inkscape { class Selection; diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index 23ecbdfda..557ca82e2 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -29,7 +29,7 @@ #include "desktop.h" #include "preferences.h" -struct SPStyle; +class SPStyle; class SPCSSAttr; namespace Gtk { -- cgit v1.2.3 From 5a8b00f027b9eb3d4abb290d2ddf26d36d71cf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Mon, 5 May 2014 04:13:35 -0300 Subject: Enabling path manipulator to comunicate if paths are bspline when accessing const objects. This change was required to correctly show on the GUI whether or not a node was a bspline. (bzr r11950.8.1) --- src/ui/tool/node.cpp | 8 +------- src/ui/tool/node.h | 6 ++++++ src/ui/tool/path-manipulator.cpp | 12 ++++++++---- src/ui/tool/path-manipulator.h | 3 ++- 4 files changed, 17 insertions(+), 12 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7ba69b039..6cb254b7f 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1421,13 +1421,7 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - - /* if the node doesnt have strength, it marks it as bspline, we'll use it later - to show the appropiate messages. We cannot do it in any other way, because the - function is constant */ - bool isBSpline = false; - //if( this->bsplineWeight != 0.0000) - // isBSpline = true; + bool isBSpline = _pm().isBSpline(); if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 202dbb3cd..415563a7d 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -217,6 +217,7 @@ public: Node *nodeAwayFrom(Handle *h); NodeList &nodeList() { return *(static_cast(this)->ln_list); } + NodeList &nodeList() const { return *(static_cast(this)->ln_list); } /** * Move the node to the bottom of its canvas group. @@ -263,6 +264,7 @@ private: Inkscape::SnapSourceType _snapSourceType() const; Inkscape::SnapTargetType _snapTargetType() const; inline PathManipulator &_pm(); + inline PathManipulator &_pm() const; /** Determine whether two nodes are joined by a linear segment. */ static bool _is_line_segment(Node *first, Node *second); @@ -494,6 +496,10 @@ inline PathManipulator &Node::_pm() { return nodeList().subpathList().pm(); } +inline PathManipulator &Node::_pm() const { + return nodeList().subpathList().pm(); +} + // definitions for node iterator template NodeIterator::operator bool() const { diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 487c31b10..3beeed049 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1181,14 +1181,14 @@ void PathManipulator::_createControlPointsFromGeometry() } //determines if the trace has a bspline effect and the number of steps that it takes -int PathManipulator::BSplineGetSteps(){ +int PathManipulator::BSplineGetSteps() const { - LivePathEffect::LPEBSpline *lpe_bsp = NULL; + LivePathEffect::LPEBSpline const *lpe_bsp = NULL; if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + Inkscape::LivePathEffect::Effect const *thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ - lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } int steps = 0; @@ -1206,6 +1206,10 @@ bool PathManipulator::isBSpline(bool recalculate){ return _is_bspline; } +bool PathManipulator::isBSpline() const { + return BSplineGetSteps() > 0; +} + // returns the corresponding strength to the position of the handlers double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ using Geom::X; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index a85664ddf..151805c83 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -96,7 +96,7 @@ public: NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - int BSplineGetSteps(); + int BSplineGetSteps() const; // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -108,6 +108,7 @@ private: void _createControlPointsFromGeometry(); bool isBSpline(bool recalculate = false); + bool isBSpline() const; double BSplineHandlePosition(Handle *h, Handle *h2 = NULL); Geom::Point BSplineHandleReposition(Handle *h, Handle *h2 = NULL); Geom::Point BSplineHandleReposition(Handle *h, double pos); -- cgit v1.2.3 From 77ec197912229a64495bda39ac0b0943580baaaf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 5 May 2014 11:50:39 +0200 Subject: adding const _pathmanipulatos staff to handles (handles also have tips) (bzr r11950.1.341) --- src/ui/tool/node.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 415563a7d..5971956e1 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -131,6 +131,7 @@ protected: private: inline PathManipulator &_pm(); + inline PathManipulator &_pm() const; Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; @@ -492,6 +493,9 @@ inline double Handle::length() const { inline PathManipulator &Handle::_pm() { return _parent->_pm(); } +inline PathManipulator &Handle::_pm() const { + return _parent->_pm(); +} inline PathManipulator &Node::_pm() { return nodeList().subpathList().pm(); } -- cgit v1.2.3 From 1fd4e3f17b3d591c56d0a50b877909791cd6c05e Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 11:22:35 -0700 Subject: Add one more ifdef for LPETool prefs. Thanks suv! (bzr r13337) --- src/ui/dialog/inkscape-preferences.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 559398a84..e757bf702 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -500,10 +500,12 @@ void InkscapePreferences::initPageTools() _page_connector.add_line(false, "", _connector_ignore_text, "", _("If on, connector attachment points will not be shown for text objects")); +#ifdef WITH_LPETOOL //LPETool - // commented out, because the LPETool is not finished yet. + //disabled, because the LPETool is not finished yet. //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); +#endif // WITH_LPETOOL } void InkscapePreferences::initPageUI() -- cgit v1.2.3 From 65c7b8f3c893e681b5d395cbef9a8b37d17e07a8 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 11:29:46 -0700 Subject: Apparently I didn't look twice before committing. Thanks suv! (bzr r13338) --- src/ui/dialog/inkscape-preferences.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index e757bf702..b6095fa8b 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -503,8 +503,8 @@ void InkscapePreferences::initPageTools() #ifdef WITH_LPETOOL //LPETool //disabled, because the LPETool is not finished yet. - //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); - //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); + this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); + this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); #endif // WITH_LPETOOL } -- cgit v1.2.3 From 4038de8b4763974c97aa8fcb9d87b83c1a5daac7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 10 May 2014 15:16:24 -0400 Subject: Add selection sets (bzr r13090.1.75) --- src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/dialog-manager.cpp | 6 +- src/ui/dialog/tags.cpp | 1155 ++++++++++++++++++++++++++++++++++++++ src/ui/dialog/tags.h | 181 ++++++ 4 files changed, 1341 insertions(+), 3 deletions(-) create mode 100644 src/ui/dialog/tags.cpp create mode 100644 src/ui/dialog/tags.h (limited to 'src/ui') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 8a7a4a5dd..1aa73dc5b 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -100,6 +100,8 @@ ink_common_sources += \ ui/dialog/template-load-tab.h \ ui/dialog/template-widget.cpp \ ui/dialog/template-widget.h \ + ui/dialog/tags.cpp \ + ui/dialpg/tags.h \ ui/dialog/text-edit.cpp \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 22c41d75e..bd2f1eb12 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -55,7 +55,7 @@ #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/objects.h" -//#include "ui/dialog/tags.h" +#include "ui/dialog/tags.h" namespace Inkscape { namespace UI { @@ -113,7 +113,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); -// registerFactory("TagsPanel", &create); + registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -148,7 +148,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); -// registerFactory("TagsPanel", &create); + registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp new file mode 100644 index 000000000..7fdd2e906 --- /dev/null +++ b/src/ui/dialog/tags.cpp @@ -0,0 +1,1155 @@ +/* + * A simple panel for tags + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tags.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "layer-fns.h" +#include "layer-manager.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/addtoicon.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +#include "ui/tools/tool-base.h" //"event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-tag.h" +#include "sp-defs.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +TagsPanel& TagsPanel::getInstance() +{ + return *new TagsPanel(); +} + +enum { + COL_ADD = 1 +}; + +enum { + BUTTON_NEW = 0, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DELETE, + DRAGNDROP +}; + +class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : + _pnl(pnl), + _obj(obj), + _repr(repr), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + ObjectWatcher(TagsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _labelAttr ) { + _pnl->_updateObject( _obj); + } + } + } + + TagsPanel* _pnl; + SPObject* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; +}; + +class TagsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +{ + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } + } + } + + btn.set_tooltip_text (tooltip); +} + + +Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +void TagsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +void TagsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); + } +} + +bool TagsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + bool empty = _desktop->selection->isEmpty(); + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_TAG_NEW ); + } + break; + case BUTTON_TOP: + { + _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT); + } + break; + case BUTTON_BOTTOM: + { + _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); + } + break; + case BUTTON_UP: + { + _fireAction( empty ? SP_VERB_LAYER_RAISE : SP_VERB_SELECTION_RAISE ); + } + break; + case BUTTON_DOWN: + { + _fireAction( empty ? SP_VERB_LAYER_LOWER : SP_VERB_SELECTION_LOWER ); + } + break; + case BUTTON_DELETE: + { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + + +class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colParentObject); + add(_colObject); + add(_colLabel); + add(_colAddRemove); + add(_colAllowAddRemove); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colParentObject; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colAddRemove; + Gtk::TreeModelColumn _colAllowAddRemove; +}; + +void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) +{ + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && obj->parent) { + todelete->push_back(obj); + } +} + +void TagsPanel::_updateObject( SPObject *obj ) { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); +} + +bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + /* + * We get notified of layer update here (from layer->setLabel()) before layer->label() is set + * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which + * has the correct value (bug #168351) + */ + //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); + gchar const *label; + SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; + if (use && use->ref->isAttached()) { + label = use->ref->getObject()->getAttribute("inkscape:label"); + } else { + label = obj->getAttribute("inkscape:label"); + } + row[_model->_colLabel] = label ? label : obj->getId(); + row[_model->_colAddRemove] = SP_IS_TAG(obj); + } + + return false; +} + +void TagsPanel::_objectsSelected( Selection *sel ) { + + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) + { + SPObject *obj = reinterpret_cast(iter->data); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + SPObject * it = row[_model->_colObject]; + if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) + { + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + } + return false; +} + +void TagsPanel::_objectsChanged(SPObject* root) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + SPDocument* document = _desktop->doc(); + SPDefs* root = document->getDefs(); + if ( root ) { + _selectedConnection.block(); + _store->clear(); + _addObject( document, root, 0 ); + _selectedConnection.unblock(); + _objectsSelected(_desktop->selection); + _checkTreeSelection(); + } + } +} + +void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG(child)) + { + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colAddRemove] = true; + row[_model->_colAllowAddRemove] = true; + + _tree.expand_to_path( _store->get_path(iter) ); + + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + _addObject( doc, child, &row ); + } + } + if (SP_IS_TAG(obj) && obj->children) + { + Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row rowitems = *iteritems; + rowitems[_model->_colObject] = NULL; + rowitems[_model->_colParentObject] = obj; + rowitems[_model->_colLabel] = _("Items"); + rowitems[_model->_colAddRemove] = false; + rowitems[_model->_colAllowAddRemove] = false; + + _tree.expand_to_path( _store->get_path(iteritems) ); + + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child)) + { + SPItem *item = SP_TAG_USE(child)->ref->getObject(); + Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colAddRemove] = false; + row[_model->_colAllowAddRemove] = true; + + if (SP_TAG(obj)->expanded()) { + _tree.expand_to_path( _store->get_path(iter) ); + } + + if (item) { + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + item->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + } + } + } + } + } +} + +void TagsPanel::_select_tag( SPTag * tag ) +{ + for (SPObject * child = tag->children; child != NULL; child = child->next) + { + if (SP_IS_TAG(child)) { + _select_tag(SP_TAG(child)); + } else if (SP_IS_TAG_USE(child)) { + SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + if (obj) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); + _desktop->selection->add(obj); + } + } + } +} + +void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _select_tag(SP_TAG(obj)); + } else if (SP_IS_TAG_USE(obj)) { + SPObject * item = SP_TAG_USE(obj)->ref->getObject(); + if (item) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + } + } + } +} + +void TagsPanel::_pushTreeSelectionToCurrent() +{ + _selectionChangedConnection.block(); + // TODO hunt down the possible API abuse in getting NULL + if ( _desktop && _desktop->currentRoot() ) { + _desktop->selection->clear(); + _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); + } + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); +} + +void TagsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; +// if ( _tree.get_selection()->count_selected_rows() > 0 ) { +// sensitive = true; +// +// SPObject* inTree = _selectedLayer(); +// if ( inTree ) { +// +// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); +// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); +// +// } +// } + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +bool TagsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && SP_IS_TAG(obj)) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + } + case GDK_KEY_Delete: { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + return true; + } + break; + } + return false; +} + +bool TagsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + // Alt left click on the visible/lock columns - eat this event to keep row selection + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_ADD-1)) { + down_at_add = true; + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); + _defer_target = path; + } else { + down_at_add = false; + } + } else { + down_at_add = false; + } + } + + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); + } + + // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + + if (obj) { + if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { + if (SP_IS_TAG(obj)) { + bool wasadded = false; + for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) + { + SPObject *newobj = reinterpret_cast(iter->data); + bool addchild = true; + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + addchild = false; + } + } + if (addchild) { + Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); + obj->appendChild(clone); + wasadded = true; + } + } + if (wasadded) { + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to set")); + } + } else { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * tobj = *iter; + if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { + tobj->parent->getRepr()->removeChild(tobj->getRepr()); + } + } + } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + } + } + } + } + } + + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + } + + return false; +} + +void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + _dnd_into = true; + _dnd_target = _document->getDefs(); + _dnd_source.clear(); + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); + + if (_dnd_source.empty()) { + return true; + } + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y > (int)(cell_height * 2/3)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = _document->getDefs(); + _dnd_into = true; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + SPObject *pobj = row[_model->_colParentObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _dnd_target = SP_TAG(obj); + } else if (SP_IS_TAG(obj->parent)) { + _dnd_target = SP_TAG(obj->parent); + _dnd_into = true; + } + } else if (pobj && SP_IS_TAG(pobj)) { + _dnd_target = SP_TAG(pobj); + _dnd_into = true; + } else { + return true; + } + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/* + * Move a layer in response to a drag & drop action + */ +void TagsPanel::_doTreeMove( ) +{ + if (_dnd_target) { + for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) + { + SPTag *src = *iter; + if (src != _dnd_target) { + src->moveTo(_dnd_target, _dnd_into); + } + } + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPTag *src = _dnd_source.back(); + _select_tag(src); + _dnd_source.pop_back(); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, + _("Moved sets")); + } +} + + +void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +void TagsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + if (SP_IS_TAG(obj)) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } + } +} + +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + return false; +} + +bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colParentObject]; + if (obj && SP_IS_TAG(obj)) + { + SP_TAG(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Constructor + */ +TagsPanel::TagsPanel() : + UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), + _rootWatcher(0), + deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + desktopChangeConn() +{ + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); + int addColNum = _tree.append_column("type", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _tree.get_column(addColNum); + if ( col ) { + col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); + col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); + } + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); + + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); + _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); + _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); + + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); + + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new selection set") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button("Dup") ); +// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); +// _buttonsRow.add( *btn ); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Set") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + setDesktop( targetDesktop ); + + show_all_children(); + + // restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); +} + +TagsPanel::~TagsPanel() +{ + + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + deskTrack.disconnect(); +} + +void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getDefs() && document->getDefs()->getRepr()) + { + _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); + document->getDefs()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getDefs()); + } +} + +void TagsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //setLabel( _desktop->doc()->name ); + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } + } +/* + GSList const *layers = _desktop->doc()->getResourceList( "layer" ); + g_message( "layers list starts at %p", layers ); + for ( GSList const *iter=layers ; iter ; iter = iter->next ) { + SPObject *layer=static_cast(iter->data); + g_message(" {%s} [%s]", layer->id, layer->label() ); + } +*/ + deskTrack.setBase(desktop); +} + + + + + +} //namespace Dialogs +} //namespace UI +} //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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h new file mode 100644 index 000000000..d35dfba01 --- /dev/null +++ b/src/ui/dialog/tags.h @@ -0,0 +1,181 @@ +/* + * A simple dialog for tags UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TAGS_PANEL_H +#define SEEN_TAGS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPTag; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays layers. + */ +class TagsPanel : public UI::Widget::Panel +{ +public: + TagsPanel(); + virtual ~TagsPanel(); + + //virtual void setOrientation( Gtk::AnchorType how ); + + static TagsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +protected: + //virtual void _handleAction( int setId, int itemId ); + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); +private: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + TagsPanel(TagsPanel const &); // no copy + TagsPanel &operator=(TagsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); + void _select_tag( SPTag * tag ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _updateObject(SPObject *obj); + bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); + + void _objectsChanged(SPObject *root); + void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); + +// std::vector groupConnections; + TagsPanel::ObjectWatcher* _rootWatcher; + std::vector _objectWatchers; + + // Hooked to the layer manager: + sigc::connection _documentChangedConnection; + sigc::connection _selectionChangedConnection; + + sigc::connection _changedConnection; + sigc::connection _addedConnection; + sigc::connection _removedConnection; + + // Internal + sigc::connection _selectedConnection; + sigc::connection _expandedConnection; + sigc::connection _collapsedConnection; + + DesktopTracker deskTrack; + SPDesktop* _desktop; + SPDocument* _document; + ModelColumns* _model; + InternalUIBounce* _pending; + gboolean _dnd_into; + std::vector _dnd_source; + SPObject* _dnd_target; + + GdkEvent* _toggleEvent; + bool down_at_add; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _layersPage; + + sigc::connection desktopChangeConn; + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + 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 From f9b46a56e41c1fb0d743ae381394b2245f264fc8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 11 May 2014 13:57:14 +0200 Subject: i18n. Fix for bug #1318289 (preferences > bitmap > rendering shows po file headers). Fixed bugs: - https://launchpad.net/bugs/1318289 (bzr r13350) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b6095fa8b..f1a29e971 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1468,7 +1468,7 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_group_header( _("Render")); // rendering outlines for pixmap image tags _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false); - _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); + _page_bitmaps.add_line(false, "", _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } -- cgit v1.2.3 From 1fb28d6c7a8d030542ab5bcdf6ed6228356e213d Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 11 May 2014 16:04:42 +0200 Subject: i18n. Fix for bug #1318345 (untranslatable strings in trunk-r13348). Fixed bugs: - https://launchpad.net/bugs/1318345 (bzr r13352) --- src/ui/dialog/grid-arrange-tab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 8c0a4dc66..72217c729 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -708,7 +708,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); // Anchor selection widget - AlignLabel.set_label("Alignment:"); + AlignLabel.set_label(_("Alignment:")); AlignLabel.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); AlignmentSelector.setAlignment(HorizAlign, VertAlign); AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed)); -- cgit v1.2.3 From 1f1932ae4592c8f316e3a68ac86874bf87f321c4 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 11 May 2014 14:23:10 -0400 Subject: Stabilize the selection set system a bit (bzr r13090.1.76) --- src/ui/dialog/tags.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 7fdd2e906..14ad5b8cc 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -280,7 +280,8 @@ bool TagsPanel::_executeAction() for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * obj = *iter; if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); + //obj->parent->getRepr()->removeChild(obj->getRepr()); + obj->deleteObject(true, true); } } DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); @@ -576,7 +577,8 @@ bool TagsPanel::_handleKeyEvent(GdkEventKey *event) for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * obj = *iter; if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); + //obj->parent->getRepr()->removeChild(obj->getRepr()); + obj->deleteObject(true, true); } } DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); @@ -680,12 +682,14 @@ bool TagsPanel::_handleButtonEvent(GdkEventButton* event) } } else { std::vector todelete; + // FIXME unnecessary use of XML tree _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); if (!todelete.empty()) { for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * tobj = *iter; if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { - tobj->parent->getRepr()->removeChild(tobj->getRepr()); + //tobj->parent->getRepr()->removeChild(tobj->getRepr()); + tobj->deleteObject(true, true); } } } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { -- cgit v1.2.3 From 0dc8b506fe92a6f4a57d6412db69c3fea420d67a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 11 May 2014 15:08:59 -0400 Subject: Rename "Tags" to "Selection sets" to avoid confusion with a global tagging system (bzr r13090.1.77) --- src/ui/dialog/tags.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 14ad5b8cc..1b5dd9400 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -1025,7 +1025,7 @@ TagsPanel::TagsPanel() : // ------------------------------------------------------- { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "Add a new selection set", (int)BUTTON_NEW ) ); _popupMenu.show_all_children(); } -- cgit v1.2.3 From 3ef365a9d42823ded18fb31aa2c36c39005cb0ee Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 11 May 2014 23:38:10 +0200 Subject: fix build for some (windows 64 bit devlibs attempt) specifically, fixes this build error: .../include/glibmm-2.4/glibmm/threads.h:201:11: error: field 'gobject_' has incomplete type 'GThread {aka _GThread}' (bzr r13357) --- src/ui/dialog/filedialogimpl-win32.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 29bcb9a45..a71ee1ad0 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -13,6 +13,8 @@ # include "config.h" #endif +#include + #ifdef WIN32 #if WITH_GLIBMM_2_32 #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -- cgit v1.2.3 From c1b60947d10a0455b023ae8bbe7b2b4414114ac5 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 12 May 2014 15:12:41 -0700 Subject: Patch from Jabierxto to fix a bug I reported off-tracker. (bzr r13341.3.1) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1434a5c5b..f077bcffc 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -623,7 +623,7 @@ void Node::move(Geom::Point const &new_pos) Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - nodeWeight = _pm().BSplineHandlePosition(n->front()); + nodeWeight = fmax(_pm().BSplineHandlePosition(n->front()),_pm().BSplineHandlePosition(n->back())); if(prevNode){ if(prevNode->isEndNode()){ prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front(),prevNode->front()); @@ -659,7 +659,7 @@ void Node::move(Geom::Point const &new_pos) if(nextNode->isEndNode()){ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->back())); + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->front())); } } } -- cgit v1.2.3 From 8dbf7bd73db6bb549b3e0be3fba91cddfcb589b8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 May 2014 07:35:50 +0200 Subject: Fixed a bug in bspline with snaps and 1 sice segments. Pointed by LiamW (bzr r13341.1.12) --- src/ui/tool/node.cpp | 2 +- src/ui/tools/pen-tool.cpp | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index f077bcffc..ed0843b65 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -371,7 +371,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) std::vector unselected; //if the snap adjustment is activated and it is not bspline - if (snap && !_pm().isBSpline()) { + if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9e4df5031..386dc43e9 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1811,9 +1811,9 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { // commenting the function doEffect in src/live_effects/lpe-bspline.cpp - if(curve->get_segment_count() < 2) - return; Geom::PathVector const original_pathv = curve->get_pathvector(); + if (curve->get_segment_count() < 1) + return; curve->reset(); for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -1890,9 +1890,25 @@ void PenTool::_bspline_doEffect(SPCurve * curve) ++curve_it1; ++curve_it2; } + SPCurve *out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2], *out->first_segment())); + nextPointAt3 = out->first_segment()->finalPoint(); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + } + out->reset(); + delete out; SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(node); - Geom::Point startNode(0,0); + Geom::Point startNode = path_it->begin()->initialPoint(); if (path_it->closed()) { SPCurve * start = new SPCurve(); start->moveto(path_it->begin()->initialPoint()); -- cgit v1.2.3 From 9cd50c94d560a2372a755bdf58ccf7feb7afe083 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 May 2014 08:50:42 +0200 Subject: Add Simplify LPE (bzr r13341.1.13) --- src/ui/tools/node-tool.cpp | 48 ++++++++++++++++++++++++++++++--- src/ui/tools/node-tool.h | 2 ++ src/ui/widget/registered-widget.cpp | 53 +++++++++++++++++++++++++++++++++++++ src/ui/widget/registered-widget.h | 25 +++++++++++++++++ 4 files changed, 125 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..ce487831d 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -23,6 +23,8 @@ #include "message-context.h" #include "selection.h" #include "shape-editor.h" // temporary! +#include "live_effects/effect.h" +#include "display/curve.h" #include "sp-clippath.h" #include "sp-item-group.h" #include "sp-mask.h" @@ -167,6 +169,10 @@ NodeTool::~NodeTool() { this->desktop->remove_temporary_canvasitem(this->flash_tempitem); } + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + } + this->_selection_changed_connection.disconnect(); //this->_selection_modified_connection.disconnect(); this->_mouseover_changed_connection.disconnect(); @@ -252,6 +258,7 @@ void NodeTool::setup() { this->flash_tempitem = NULL; this->flashed_item = NULL; this->_last_over = NULL; + this->helperpath_tmpitem = NULL; // read prefs before adding items to selection to prevent momentarily showing the outline sp_event_context_read(this, "show_handles"); @@ -278,6 +285,41 @@ void NodeTool::setup() { } this->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive + this->update_helperpath(); +} + +void NodeTool::update_helperpath(){ + Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + this->helperpath_tmpitem = NULL; + } + if (SP_IS_LPE_ITEM(selection->singleItem())) { + Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); + if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + if (lpe) { + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + c->transform(selection->singleItem()->i2dt_affine()); + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), + 0x0000ff9A, 1.0, + SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); + } + c->unref(); + cc->unref(); + } + } + } } void NodeTool::set(const Inkscape::Preferences::Entry& value) { @@ -392,7 +434,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { for (std::set::iterator i = shapes.begin(); i != shapes.end(); ++i) { ShapeRecord const &r = *i; - if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) && + if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item) || SP_IS_GROUP(r.item) || SP_IS_OBJECTGROUP(r.item)) && this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); @@ -416,7 +458,7 @@ bool NodeTool::root_handler(GdkEvent* event) { Inkscape::Selection *selection = desktop->selection; static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - + if (this->_multipath->event(this, event)) { return true; } @@ -433,6 +475,7 @@ bool NodeTool::root_handler(GdkEvent* event) { { case GDK_MOTION_NOTIFY: { combine_motion_events(desktop->canvas, event->motion, 0); + this->update_helperpath(); SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button), FALSE, TRUE); @@ -441,7 +484,6 @@ bool NodeTool::root_handler(GdkEvent* event) { //ink_node_tool_update_tip(nt, event); this->update_tip(event); } - // create pathflash outline if (prefs->getBool("/tools/nodes/pathflash_enabled")) { if (over_item == this->flashed_item) { diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 42f89cd1c..9f0c40aa8 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -54,6 +54,7 @@ public: static const std::string prefsPath; virtual void setup(); + virtual void update_helperpath(); virtual void set(const Inkscape::Preferences::Entry& val); virtual bool root_handler(GdkEvent* event); @@ -66,6 +67,7 @@ private: SPItem *flashed_item; Inkscape::Display::TemporaryItem *flash_tempitem; + Inkscape::Display::TemporaryItem *helperpath_tmpitem; Inkscape::UI::Selector* _selector; Inkscape::UI::PathSharedData* _path_data; SPCanvasGroup *_transform_handle_group; diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 92cb3f03d..83da1a6d6 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -99,6 +99,59 @@ RegisteredCheckButton::on_toggled() _wr->setUpdating (false); } +/*######################################### + * Registered TOGGLEBUTTON + */ + +RegisteredToggleButton::~RegisteredToggleButton() +{ + _toggled_connection.disconnect(); +} + +RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) + : RegisteredWidget(label) + , _active_str(active_str) + , _inactive_str(inactive_str) +{ + init_parent(key, wr, repr_in, doc_in); + setProgrammatically = false; + set_tooltip_text (tip); + set_alignment (right? 1.0 : 0.0, 0.5); + _toggled_connection = signal_toggled().connect (sigc::mem_fun (*this, &RegisteredToggleButton::on_toggled)); +} + +void +RegisteredToggleButton::setActive (bool b) +{ + setProgrammatically = true; + set_active (b); + //The slave button is greyed out if the master button is untoggled + for (std::list::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { + (*i)->set_sensitive(b); + } + setProgrammatically = false; +} + +void +RegisteredToggleButton::on_toggled() +{ + if (setProgrammatically) { + setProgrammatically = false; + return; + } + + if (_wr->isUpdating()) + return; + _wr->setUpdating (true); + + write_to_xml(get_active() ? _active_str : _inactive_str); + //The slave button is greyed out if the master button is untoggled + for (std::list::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { + (*i)->set_sensitive(get_active()); + } + + _wr->setUpdating (false); +} /*######################################### * Registered UNITMENU diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index d64c09c16..d8c0e6602 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -163,6 +163,31 @@ protected: void on_toggled(); }; +class RegisteredToggleButton : public RegisteredWidget { +public: + virtual ~RegisteredToggleButton(); + RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL, char const *active_str = "true", char const *inactive_str = "false"); + + void setActive (bool); + + std::list _slavewidgets; + + // a slave button is only sensitive when the master button is active + // i.e. a slave button is greyed-out when the master button is not checked + + void setSlaveWidgets(std::list btns) { + _slavewidgets = btns; + } + + bool setProgrammatically; // true if the value was set by setActive, not changed by the user; + // if a callback checks it, it must reset it back to false + +protected: + char const *_active_str, *_inactive_str; + sigc::connection _toggled_connection; + void on_toggled(); +}; + class RegisteredUnitMenu : public RegisteredWidget { public: ~RegisteredUnitMenu(); -- cgit v1.2.3 From 41ab3bd526807e0a092466e7d4e979f12bab81ff Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 13 May 2014 21:17:06 +0200 Subject: fix windows 64bit build. (changes already committed to trunk) (bzr r13341.1.19) --- src/ui/dialog/filedialogimpl-win32.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 29bcb9a45..a71ee1ad0 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -13,6 +13,8 @@ # include "config.h" #endif +#include + #ifdef WIN32 #if WITH_GLIBMM_2_32 #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -- cgit v1.2.3 From 779a151867babce787dbd06ff1e40d54d3b9443d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 16:13:07 +0200 Subject: Fix Pango markup used in Text and Font dialog. (bzr r13378) --- src/ui/dialog/text-edit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 17c29c69f..c1ebb32e0 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -404,12 +404,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); // Pango font size is in 1024ths of a point - // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) ); std::ostringstream size_st; - size_st << pt_size * PANGO_SCALE; + size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers - Glib::ustring markup = "" + phrase_escaped + ""; + Glib::ustring markup = "" + phrase_escaped + ""; preview_label.set_markup(markup.c_str()); } -- cgit v1.2.3 From 16262c5a24e91309c4c762ffbb0e82b05026c9b6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 16:14:19 +0200 Subject: Fix Pango markup in Text and Font dialog. (bzr r13341.1.25) --- src/ui/dialog/text-edit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 17c29c69f..c1ebb32e0 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -404,12 +404,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); // Pango font size is in 1024ths of a point - // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) ); std::ostringstream size_st; - size_st << pt_size * PANGO_SCALE; + size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers - Glib::ustring markup = "" + phrase_escaped + ""; + Glib::ustring markup = "" + phrase_escaped + ""; preview_label.set_markup(markup.c_str()); } -- cgit v1.2.3 From 11bb6f3d4fedd1d22637f00a480dea54d505c23c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:07:31 +0200 Subject: make windows filedialog's code more portable for different mingw versions (failed on 64bit) (bzr r13380) --- src/ui/dialog/filedialogimpl-win32.cpp | 11 ++--------- src/ui/dialog/filedialogimpl-win32.h | 6 +++++- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9d91f5d56..1eeee0592 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB #define IDC_SHOW_PREVIEW 1000 -// Windows 2000 version of OPENFILENAMEW -struct OPENFILENAMEEXW : public OPENFILENAMEW { - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -}; - struct Filter { gunichar2* name; @@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu() void FileOpenDialogImplWin32::GetOpenFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_mutex != NULL); @@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt void FileSaveDialogImplWin32::GetSaveFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_main_loop != NULL); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a71ee1ad0..c523f041d 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -20,9 +20,13 @@ #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H # include #endif - #endif + #include "gc-core.h" + // define WINVER high enough so we get the correct OPENFILENAMEW size +#ifndef WINVER +#define WINVER 0x0500 +#endif #include #include "filedialogimpl-gtkmm.h" -- cgit v1.2.3 From 639540b57f19cce10e6b37df3475c252455a1b28 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:08:12 +0200 Subject: make windows filedialog's code more portable for different mingw versions (failed on 64bit) (bzr r13341.1.26) --- src/ui/dialog/filedialogimpl-win32.cpp | 12 ++---------- src/ui/dialog/filedialogimpl-win32.h | 6 +++++- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9d91f5d56..06153a2d8 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB #define IDC_SHOW_PREVIEW 1000 -// Windows 2000 version of OPENFILENAMEW -struct OPENFILENAMEEXW : public OPENFILENAMEW { - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -}; - struct Filter { gunichar2* name; @@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu() void FileOpenDialogImplWin32::GetOpenFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_mutex != NULL); @@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt void FileSaveDialogImplWin32::GetSaveFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_main_loop != NULL); @@ -1860,7 +1853,6 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread() ofn.nFilterIndex = _filter_index; ofn.lpfnHook = GetSaveFileName_hookproc; ofn.lCustData = (LPARAM)this; - _result = GetSaveFileNameW(&ofn) != 0; g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a71ee1ad0..c523f041d 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -20,9 +20,13 @@ #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H # include #endif - #endif + #include "gc-core.h" + // define WINVER high enough so we get the correct OPENFILENAMEW size +#ifndef WINVER +#define WINVER 0x0500 +#endif #include #include "filedialogimpl-gtkmm.h" -- cgit v1.2.3 From 76e9bb52fbd6a39e68cd8e34559762e2b2d1806b Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 16 May 2014 00:17:53 +0200 Subject: fix C++11 compilation (bzr r13341.1.30) --- src/ui/tool/node.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 5971956e1..101af4817 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -41,6 +41,7 @@ template class NodeIterator; } } +/* #if HAVE_TR1_UNORDERED_SET namespace std { namespace tr1 { @@ -48,6 +49,8 @@ template struct hash< Inkscape::UI::NodeIterator >; } } #endif +#endif +*/ namespace Inkscape { namespace UI { -- cgit v1.2.3 From 67e3a25d12d9a273afb1b8f9f3258b232989c660 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Fri, 23 May 2014 22:52:32 +0200 Subject: Fix flakiness of measurement tool (due to issues with parallel lines, duplicate intersections, and faulty sorting of intersections) Fixed bugs: - https://launchpad.net/bugs/1022733 (bzr r13397) --- src/ui/tools/measure-tool.cpp | 59 ++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 2c85874bc..feeb68288 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -277,21 +277,13 @@ void MeasureTool::finish() { // return ret; //} -static bool GeomPointSortPredicate(const Geom::Point& p1, const Geom::Point& p2) +static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom::PathVector const &lineseg, SPCurve *curve, std::vector &intersections) { - if (p1[Geom::Y] == p2[Geom::Y]) { - return p1[Geom::X] < p2[Geom::X]; - } else { - return p1[Geom::Y] < p2[Geom::Y]; - } -} -static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom::PathVector const &lineseg, SPCurve *curve, std::vector &intersections) -{ curve->transform(item->i2doc_affine()); - // Find all intersections of the control-line with this shape Geom::CrossingSet cs = Geom::crossings(lineseg, curve->get_pathvector()); + Geom::delete_duplicates(cs[0]); // Reconstruct and store the points of intersection for (Geom::Crossings::const_iterator m = cs[0].begin(); m != cs[0].end(); ++m) { @@ -304,10 +296,11 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) || ((*m).ta + eps < 1 && item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) { - intersections.push_back(intersection); + intersections.push_back((*m).ta); } #else - intersections.push_back(lineseg[0].pointAt((*m).ta)); + intersections.push_back((*m).ta); + #endif } } @@ -441,28 +434,20 @@ bool MeasureTool::root_handler(GdkEvent* event) { points.push_back(desktop->d2w(start_point + (i / NPOINTS) * (end_point - start_point))); } -// TODO: Felipe, why don't you simply iterate over all items, and test whether their bounding boxes intersect -// with the measurement line, instead of interpolating? E.g. bbox_of_measurement_line.intersects(*bbox_of_item). -// That's also how the object-snapper works, see _findCandidates() in object-snapper.cpp. + // TODO: Felipe, why don't you simply iterate over all items, and test whether their bounding boxes intersect + // with the measurement line, instead of interpolating over 800 points? E.g. bbox_of_measurement_line.intersects(*bbox_of_item). + // That's also how the object-snapper works, see _findCandidates() in object-snapper.cpp. + + // TODO switch to a different variable name. The single letter 'l' is easy to misread. //select elements crossed by line segment: GSList *items = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, points); - std::vector intersections; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool ignore_1st_and_last = prefs->getBool("/tools/measure/ignore_1st_and_last", true); - - if (!ignore_1st_and_last) { - intersections.push_back(desktop->dt2doc(start_point)); - } - - std::vector placements; - - // TODO switch to a different variable name. The single letter 'l' is easy to misread. + std::vector intersection_times; for (GSList *l = items; l != NULL; l = l->next) { SPItem *item = static_cast(l->data); if (SP_IS_SHAPE(item)) { - calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersections); + calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times); } else { if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); @@ -486,7 +471,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { curve->transform(item->i2doc_affine()); - calculate_intersections(desktop, item, lineseg, curve, intersections); + calculate_intersections(desktop, item, lineseg, curve, intersection_times); if (iter == te_get_layout(item)->end()) { break; @@ -496,13 +481,10 @@ bool MeasureTool::root_handler(GdkEvent* event) { } } - if (!ignore_1st_and_last) { - intersections.push_back(desktop->dt2doc(end_point)); - } - - //sort intersections - if (intersections.size() > 2) { - std::sort(intersections.begin(), intersections.end(), GeomPointSortPredicate); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { + intersection_times.push_back(0); + intersection_times.push_back(1); } Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); @@ -516,6 +498,13 @@ bool MeasureTool::root_handler(GdkEvent* event) { Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_point - start_point))); Geom::Point normal = desktop->w2d(windowNormal); + std::vector intersections; + std::sort(intersection_times.begin(), intersection_times.end()); + for (std::vector::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) { + intersections.push_back(lineseg[0].pointAt(*iter_t)); + } + + std::vector placements; for (size_t idx = 1; idx < intersections.size(); ++idx) { LabelPlacement placement; placement.lengthVal = (intersections[idx] - intersections[idx - 1]).length(); -- cgit v1.2.3 From 2ddabce031c6c408688477544f9b16a28b7b9cb1 Mon Sep 17 00:00:00 2001 From: Fridrich Strba Date: Tue, 27 May 2014 12:35:54 +0200 Subject: Port inkscape to librevenge framework for WPG, CDR and VSD imports (bzr r13398.1.1) --- src/ui/dialog/symbols.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0b048ed82 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -63,7 +63,7 @@ #ifdef WITH_LIBVISIO #include -#include +#include #endif #include "verbs.h" @@ -449,14 +449,16 @@ void SymbolsDialog::iconChanged() { // Read Visio stencil files SPDocument* read_vss( gchar* fullname, gchar* filename ) { - WPXFileStream input(fullname); + librevenge::RVNGFileStream input(fullname); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - libvisio::VSDStringVector output; - if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) { + librevenge::RVNGStringVector output; + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libvisio::VisioDocument::parseStencils(&input, &generator)) { return NULL; } -- cgit v1.2.3 From 95033e5a510be941172977dc948f9c914180e359 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 1 Jun 2014 15:05:24 +0200 Subject: spellcheck.cpp: correct indenting. disable debug output. (bzr r13341.1.44) --- src/ui/dialog/spellcheck.cpp | 74 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 8a4ddc57e..a887a7355 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -347,7 +347,7 @@ SpellCheck::init(SPDesktop *d) char *slashPos = strrchr(exeName, '\\'); if (slashPos) *slashPos = '\0'; - g_print ("%s\n", exeName); + //g_print ("Aspell prefix path: %s\n", exeName); #endif _stops = 0; @@ -356,54 +356,54 @@ SpellCheck::init(SPDesktop *d) #ifdef HAVE_ASPELL { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller = to_aspell_speller(ret); } if (_lang2 != "") { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang2.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller2 = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang2.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller2 = to_aspell_speller(ret); } if (_lang3 != "") { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang3.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller3 = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang3.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller3 = to_aspell_speller(ret); } #endif /* HAVE_ASPELL */ -- cgit v1.2.3 From fd9fa656fa1037c58963e4277c8d907a61940bd3 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 1 Jun 2014 15:40:07 +0200 Subject: remove fwd decl (a left-over, not intended for something useful) that breaks build (win64) (bzr r13404) --- src/ui/tool/node.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 4582d998a..b2f338e2c 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -41,14 +41,6 @@ template class NodeIterator; } } -#if HAVE_TR1_UNORDERED_SET -namespace std { -namespace tr1 { -template struct hash< Inkscape::UI::NodeIterator >; -} -} -#endif - namespace Inkscape { namespace UI { -- cgit v1.2.3 From 1fd57a41383419cbeddbaef27e52d55c0d02400f Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 6 Jun 2014 17:01:38 -0400 Subject: Clean up some unnecessary pointer usage in livarot (bzr r13341.1.50) --- src/ui/tools/flood-tool.cpp | 2 +- src/ui/tools/pencil-tool.cpp | 5 ++--- src/ui/tools/tweak-tool.cpp | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index d74848dc6..15bc7164c 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -408,7 +408,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto Shape *path_shape = new Shape(); path->ConvertWithBackData(0.03); - path->Fill(path_shape, 0); + path->Fill(*path_shape, 0); delete path; Shape *expanded_path_shape = new Shape(); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 0e8660248..48f8c3a28 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -760,9 +760,8 @@ void PencilTool::_sketchInterpolate() { path.LoadPathVector(Geom::path_from_piecewise(this->sketch_interpolation, 0.01)); path.Simplify(0.5); - Geom::PathVector *pathv = path.MakePathVector(); - this->sketch_interpolation = (*pathv)[0].toPwSb(); - delete pathv; + Geom::PathVector pathv = path.MakePathVector(); + this->sketch_interpolation = pathv[0].toPwSb(); } else { this->sketch_interpolation = fit_pwd2; } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 75650d3af..bc1519773 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -551,7 +551,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P Geom::Affine i2doc(item->i2doc_affine()); orig->ConvertWithBackData((0.08 - (0.07 * fidelity)) / i2doc.descrim()); // default 0.059 - orig->Fill(theShape, 0); + orig->Fill(*theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); -- cgit v1.2.3 From cb625f9576e23e2232aafc93e5b1582336624425 Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Sat, 7 Jun 2014 00:08:03 +0200 Subject: revise email theadib (bzr r13410) --- src/ui/dialog/aboutbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 121773b6d..a66855b2a 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -442,7 +442,7 @@ void AboutBox::initStrings() { */ gchar const *allTranslators = "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" -"Adib Taraben , 2004.\n" +"Adib Taraben , 2004.\n" "Alan Monfort , 2009-2010.\n" "Alastair McKinstry , 2000.\n" "Aleksandar Urošević , 2004-2006.\n" -- cgit v1.2.3 From 48ddc5ea8c9ee44c7ae388d43f9be9552acf64ae Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 6 Jun 2014 21:19:18 -0400 Subject: Undo changes in r13391 (bzr r13341.1.51) --- src/ui/tools/flood-tool.cpp | 2 +- src/ui/tools/pencil-tool.cpp | 5 +++-- src/ui/tools/tweak-tool.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 15bc7164c..d74848dc6 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -408,7 +408,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto Shape *path_shape = new Shape(); path->ConvertWithBackData(0.03); - path->Fill(*path_shape, 0); + path->Fill(path_shape, 0); delete path; Shape *expanded_path_shape = new Shape(); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 48f8c3a28..0e8660248 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -760,8 +760,9 @@ void PencilTool::_sketchInterpolate() { path.LoadPathVector(Geom::path_from_piecewise(this->sketch_interpolation, 0.01)); path.Simplify(0.5); - Geom::PathVector pathv = path.MakePathVector(); - this->sketch_interpolation = pathv[0].toPwSb(); + Geom::PathVector *pathv = path.MakePathVector(); + this->sketch_interpolation = (*pathv)[0].toPwSb(); + delete pathv; } else { this->sketch_interpolation = fit_pwd2; } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index bc1519773..75650d3af 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -551,7 +551,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P Geom::Affine i2doc(item->i2doc_affine()); orig->ConvertWithBackData((0.08 - (0.07 * fidelity)) / i2doc.descrim()); // default 0.059 - orig->Fill(*theShape, 0); + orig->Fill(theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); -- cgit v1.2.3 From 1fbcbe105b22951f565dd6ddecce3ceeb9e55a36 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 10 Jun 2014 00:12:02 +0200 Subject: fix a bug on spirolive close path (bzr r13341.1.55) --- src/ui/tools/pen-tool.cpp | 56 ++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 386dc43e9..f8243fb7f 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1556,12 +1556,11 @@ void PenTool::_bspline_spiro_start_anchor_off() //and we add it again with the recreation tmpCurve->append_continuous(lastSeg, 0.0625); } - if (this->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } - this->overwriteCurve = tmpCurve; } - + if (this->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + this->overwriteCurve = tmpCurve; } void PenTool::_bspline_spiro_motion(bool shift){ @@ -1645,7 +1644,7 @@ void PenTool::_bspline_spiro_end_anchor_on() } reverse = true; } else if(this->sa){ - tmpCurve = this->overwriteCurve; + tmpCurve = this->overwriteCurve->copy(); if(!this->sa->start){ tmpCurve = tmpCurve->create_reverse(); reverse = true; @@ -1665,7 +1664,7 @@ void PenTool::_bspline_spiro_end_anchor_on() lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); }else{ lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); - lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + lastSeg->lineto(tmpCurve->last_segment()->finalPoint()); } if( tmpCurve->get_segment_count() == 1){ tmpCurve = lastSeg; @@ -1702,7 +1701,7 @@ void PenTool::_bspline_spiro_end_anchor_off() } reverse = true; } else if(this->sa){ - tmpCurve = this->overwriteCurve; + tmpCurve = this->overwriteCurve->copy(); if(!this->sa->start){ tmpCurve = tmpCurve->create_reverse(); reverse = true; @@ -1714,25 +1713,28 @@ void PenTool::_bspline_spiro_end_anchor_off() if(cubic){ lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } - if (reverse) { - tmpCurve = tmpCurve->create_reverse(); - } - if( this->green_anchor && this->green_anchor->active ) - { - this->green_curve->reset(); - this->green_curve = tmpCurve; - }else{ - this->overwriteCurve->reset(); - this->overwriteCurve = tmpCurve; - } + }else{ + lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); + lastSeg->lineto(tmpCurve->last_segment()->finalPoint()); + } + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (reverse) { + tmpCurve = tmpCurve->create_reverse(); + } + if( this->green_anchor && this->green_anchor->active ) + { + this->green_curve->reset(); + this->green_curve = tmpCurve; + }else{ + this->overwriteCurve->reset(); + this->overwriteCurve = tmpCurve; } } -- cgit v1.2.3 From b2ae5212d7df04a0b973571748d402d5663312d6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 11 Jun 2014 23:53:17 +0200 Subject: pen tool: fix crash when finishing path with right-click or enter while dragging from path's startnode (otherwise closing the path) Fixed bugs: - https://launchpad.net/bugs/1326652 (bzr r13422) --- src/ui/tools/pen-tool.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 09c0a2a4f..b089065e8 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -481,6 +481,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { ret = true; } else if (bevent.button == 3 && this->npoints != 0) { // right click - finish path + this->ea = NULL; // unset end anchor if set (otherwise crashes) this->_finish(false); ret = true; } @@ -1018,6 +1019,7 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: if (this->npoints != 0) { + this->ea = NULL; // unset end anchor if set (otherwise crashes) this->_finish(false); ret = true; } -- cgit v1.2.3 From 61a6f2cc2082528d4df3147c39d3e16d41388db4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 09:30:53 +0200 Subject: Display symbols in document order. Fix typo in FlowSymbols.svg (bzr r13424) --- src/ui/dialog/symbols.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0dfd915fe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -613,6 +613,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList *l = NULL; l = symbols_in_doc_recursive (symbolDocument->getRoot(), l ); + l = g_slist_reverse( l ); return l; } -- cgit v1.2.3 From 5e1c70580e6d156716aba9e5dcc62a15a215da06 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 09:34:58 +0200 Subject: Display symbols in document order. (bzr r13341.1.58) --- src/ui/dialog/symbols.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0dfd915fe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -613,6 +613,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList *l = NULL; l = symbols_in_doc_recursive (symbolDocument->getRoot(), l ); + l = g_slist_reverse( l ); return l; } -- cgit v1.2.3 From ba2d7d753aec7f4c356d3fec1f07f79db5e56eec Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 18:06:01 +0200 Subject: Allow symbol zooming independent of icon screen size. (bzr r13425) --- src/ui/dialog/symbols.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.h | 9 +++++- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 0dfd915fe..c58df864c 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -219,25 +219,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : Gtk::Label* spacer = Gtk::manage(new Gtk::Label("")); tools->pack_start(* Gtk::manage(spacer)); - in_sizes = 2; // Default 32px + // Pack size (controls display area) + pack_size = 2; // Default 32px button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); - button->set_tooltip_text(_("Make Icons bigger by zooming in.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) ); + button->set_tooltip_text(_("Display more icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore)); tools->pack_start(* button, Gtk::PACK_SHRINK); button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); - button->set_tooltip_text(_("Make Icons smaller by zooming out.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) ); + button->set_tooltip_text(_("Display fewer icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless)); tools->pack_start(* button, Gtk::PACK_SHRINK); + // Toggle scale to fit on/off fitSymbol = Gtk::manage(new Gtk::ToggleButton()); fitSymbol->add(*Gtk::manage(Glib::wrap( sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) ); @@ -248,6 +250,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild)); tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK); + // Render size (scales symbols within display area) + scale_factor = 0; // Default 1:1 * pack_size/pack_size default + zoomOut = Gtk::manage(new Gtk::Button()); + zoomOut->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); + zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out.")); + zoomOut->set_relief( Gtk::RELIEF_NONE ); + zoomOut->set_focus_on_click( false ); + zoomOut->set_sensitive( false ); + zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + tools->pack_start(* zoomOut, Gtk::PACK_SHRINK); + + zoomIn = Gtk::manage(new Gtk::Button()); + zoomIn->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); + zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in.")); + zoomIn->set_relief( Gtk::RELIEF_NONE ); + zoomIn->set_focus_on_click( false ); + zoomIn->set_sensitive( false ); + zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + tools->pack_start(* zoomIn, Gtk::PACK_SHRINK); + ++row; /**********************************************************/ @@ -298,22 +322,44 @@ SymbolsDialog& SymbolsDialog::getInstance() return *new SymbolsDialog(); } +void SymbolsDialog::packless() { + if(pack_size < 4) { + pack_size++; + rebuild(); + } +} + +void SymbolsDialog::packmore() { + if(pack_size > 0) { + pack_size--; + rebuild(); + } +} + void SymbolsDialog::zoomin() { - if(in_sizes < 4) { - in_sizes++; + if(scale_factor < 4) { + scale_factor++; rebuild(); } } void SymbolsDialog::zoomout() { - if(in_sizes > 0) { - in_sizes--; + if(scale_factor > -8) { + scale_factor--; rebuild(); } } void SymbolsDialog::rebuild() { + if( fitSymbol->get_active() ) { + zoomIn->set_sensitive( false ); + zoomOut->set_sensitive( false ); + } else { + zoomIn->set_sensitive( true); + zoomOut->set_sensitive( true ); + } + store->clear(); Glib::ustring symbolSetString = symbolSet->get_active_text(); @@ -757,7 +803,7 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->ensureUpToDate(); SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; + unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); // We could use cache here, but it doesn't really work with the structure @@ -779,6 +825,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) if( fitSymbol->get_active() ) scale = psize / std::max(width, height); + else + scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0; pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); } diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 8021fb0c1..5dc1e3cad 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -65,6 +65,8 @@ private: static SymbolColumns *getColumns(); + void packless(); + void packmore(); void zoomin(); void zoomout(); void rebuild(); @@ -95,13 +97,18 @@ private: std::map symbolSets; // Index into sizes which is selected - int in_sizes; + int pack_size; + + // Scale factor + int scale_factor; Glib::RefPtr store; Gtk::ComboBoxText* symbolSet; Gtk::IconView* iconView; Gtk::Button* addSymbol; Gtk::Button* removeSymbol; + Gtk::Button* zoomIn; + Gtk::Button* zoomOut; Gtk::ToggleButton* fitSymbol; void setTargetDesktop(SPDesktop *desktop); -- cgit v1.2.3 From 5390e245e922648d989bfa10e0613e2f588a9cc7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 18:11:54 +0200 Subject: Allow symbol zooming independent of icon screen size. (bzr r13341.1.60) --- src/ui/dialog/symbols.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.h | 9 +++++- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 0dfd915fe..c58df864c 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -219,25 +219,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : Gtk::Label* spacer = Gtk::manage(new Gtk::Label("")); tools->pack_start(* Gtk::manage(spacer)); - in_sizes = 2; // Default 32px + // Pack size (controls display area) + pack_size = 2; // Default 32px button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); - button->set_tooltip_text(_("Make Icons bigger by zooming in.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) ); + button->set_tooltip_text(_("Display more icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore)); tools->pack_start(* button, Gtk::PACK_SHRINK); button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); - button->set_tooltip_text(_("Make Icons smaller by zooming out.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) ); + button->set_tooltip_text(_("Display fewer icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless)); tools->pack_start(* button, Gtk::PACK_SHRINK); + // Toggle scale to fit on/off fitSymbol = Gtk::manage(new Gtk::ToggleButton()); fitSymbol->add(*Gtk::manage(Glib::wrap( sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) ); @@ -248,6 +250,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild)); tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK); + // Render size (scales symbols within display area) + scale_factor = 0; // Default 1:1 * pack_size/pack_size default + zoomOut = Gtk::manage(new Gtk::Button()); + zoomOut->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); + zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out.")); + zoomOut->set_relief( Gtk::RELIEF_NONE ); + zoomOut->set_focus_on_click( false ); + zoomOut->set_sensitive( false ); + zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + tools->pack_start(* zoomOut, Gtk::PACK_SHRINK); + + zoomIn = Gtk::manage(new Gtk::Button()); + zoomIn->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); + zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in.")); + zoomIn->set_relief( Gtk::RELIEF_NONE ); + zoomIn->set_focus_on_click( false ); + zoomIn->set_sensitive( false ); + zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + tools->pack_start(* zoomIn, Gtk::PACK_SHRINK); + ++row; /**********************************************************/ @@ -298,22 +322,44 @@ SymbolsDialog& SymbolsDialog::getInstance() return *new SymbolsDialog(); } +void SymbolsDialog::packless() { + if(pack_size < 4) { + pack_size++; + rebuild(); + } +} + +void SymbolsDialog::packmore() { + if(pack_size > 0) { + pack_size--; + rebuild(); + } +} + void SymbolsDialog::zoomin() { - if(in_sizes < 4) { - in_sizes++; + if(scale_factor < 4) { + scale_factor++; rebuild(); } } void SymbolsDialog::zoomout() { - if(in_sizes > 0) { - in_sizes--; + if(scale_factor > -8) { + scale_factor--; rebuild(); } } void SymbolsDialog::rebuild() { + if( fitSymbol->get_active() ) { + zoomIn->set_sensitive( false ); + zoomOut->set_sensitive( false ); + } else { + zoomIn->set_sensitive( true); + zoomOut->set_sensitive( true ); + } + store->clear(); Glib::ustring symbolSetString = symbolSet->get_active_text(); @@ -757,7 +803,7 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->ensureUpToDate(); SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; + unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); // We could use cache here, but it doesn't really work with the structure @@ -779,6 +825,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) if( fitSymbol->get_active() ) scale = psize / std::max(width, height); + else + scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0; pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); } diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 8021fb0c1..5dc1e3cad 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -65,6 +65,8 @@ private: static SymbolColumns *getColumns(); + void packless(); + void packmore(); void zoomin(); void zoomout(); void rebuild(); @@ -95,13 +97,18 @@ private: std::map symbolSets; // Index into sizes which is selected - int in_sizes; + int pack_size; + + // Scale factor + int scale_factor; Glib::RefPtr store; Gtk::ComboBoxText* symbolSet; Gtk::IconView* iconView; Gtk::Button* addSymbol; Gtk::Button* removeSymbol; + Gtk::Button* zoomIn; + Gtk::Button* zoomOut; Gtk::ToggleButton* fitSymbol; void setTargetDesktop(SPDesktop *desktop); -- cgit v1.2.3 From eb4d7e1225a2e1e5a5d1da8d0ab784632bc77291 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 14 Jun 2014 14:51:11 -0400 Subject: Add clip group option from Ponyscape (bzr r13090.1.83) --- src/ui/dialog/objects.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 85583a0e7..2d558daae 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -106,7 +106,7 @@ enum { BUTTON_LOCK_ALL, BUTTON_UNLOCK_ALL, BUTTON_SETCLIP, -// BUTTON_CLIPGROUP, + BUTTON_CLIPGROUP, // BUTTON_SETINVCLIP, BUTTON_UNSETCLIP, BUTTON_SETMASK, @@ -269,7 +269,7 @@ Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int cod } if ( action ) { - label = action->name; + // label = action->name; } } } @@ -1257,6 +1257,10 @@ bool ObjectsPanel::_executeAction() _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); } break; + case BUTTON_CLIPGROUP: + { + _fireAction ( SP_VERB_OBJECT_CREATE_CLIP_GROUP ); + } case BUTTON_SETCLIP: { _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); @@ -1935,8 +1939,8 @@ ObjectsPanel::ObjectsPanel() : _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); - //not implemented - //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); //will never be implemented //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) ); -- cgit v1.2.3 From f1305982b84adfe04cdeb2686c3b1d7ed3a37bc7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 25 Jun 2014 23:05:33 +0200 Subject: fix windows build (gtk3) partly. broken because of windows.h poluting namespace with "interface" struct name. (bzr r13341.1.68) --- src/ui/dialog/filedialogimpl-win32.h | 3 ++- src/ui/dialog/print.cpp | 9 +++++---- src/ui/widget/preferences-widget.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index c523f041d..f77249abd 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -22,13 +22,14 @@ #endif #endif +#include "filedialogimpl-gtkmm.h" + #include "gc-core.h" // define WINVER high enough so we get the correct OPENFILENAMEW size #ifndef WINVER #define WINVER 0x0500 #endif #include -#include "filedialogimpl-gtkmm.h" namespace Inkscape diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..459e64041 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,10 +13,6 @@ #ifdef HAVE_CONFIG_H # include #endif -#ifdef WIN32 -#include -#include -#endif #include "print.h" #include @@ -33,6 +29,11 @@ #include +#ifdef WIN32 +#include +#include +#endif + static void draw_page( #ifdef WIN32 diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 3ba00c083..7f3e6cd47 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -14,10 +14,6 @@ # include #endif -#ifdef WIN32 -#include -#endif - #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif @@ -49,6 +45,10 @@ #include #include +#ifdef WIN32 +#include +#endif + using namespace Inkscape::UI::Widget; namespace Inkscape { -- cgit v1.2.3 From 96fec2043bbac0293fb30486d6c6a8650190abff Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 29 Jun 2014 09:21:44 +0200 Subject: Layers. Fix for Bug #1326131 (Can't delete layer from context menu). Fixed bugs: - https://launchpad.net/bugs/1326131 (bzr r13442) --- src/ui/dialog/layers.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index b5dac0595..65351cb68 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -926,9 +926,8 @@ LayersPanel::LayersPanel() : // ------------------------------------------------------- { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); @@ -944,9 +943,14 @@ LayersPanel::LayersPanel() : _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); - _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), "Up", (int)BUTTON_UP ) ); - _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), "Down", (int)BUTTON_DOWN ) ); + _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("layer-raise"), "Up", (int)BUTTON_UP ) ); + _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("layer-lower"), "Down", (int)BUTTON_DOWN ) ); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DELETE, 0, "Delete", (int)BUTTON_DELETE ) ); + _popupMenu.show_all_children(); } // ------------------------------------------------------- -- cgit v1.2.3 From 74ac381c0cfbee634a7677aba3db6b2a0fd5f13f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 29 Jun 2014 17:10:43 +0200 Subject: Enable rendering of new filter blend modes (but don't add them to GUI). (bzr r13341.1.70) --- src/ui/widget/filter-effect-chooser.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 65706a9dc..78988a041 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -56,15 +56,12 @@ const Glib::ustring SimpleFilterModifier::get_blend_mode() if (!(_flags & BLEND)) { return "normal"; } - if (_blend.get_active_row_number() == 5) { + + const Util::EnumData *d = _blend.get_active_data(); + if (d) { + return _blend.get_active_data()->key; + } else return "normal"; - } else { - const Util::EnumData *d = _blend.get_active_data(); - if (d) { - return _blend.get_active_data()->key; - } else - return "normal"; - } } void SimpleFilterModifier::set_blend_mode(const int val) -- cgit v1.2.3 From 5382e1fb57cb06f5d4a21e3e553ccdd9395014f5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 29 Jun 2014 17:12:27 +0200 Subject: Enable rendering of new filter blend modes (but don't add them to GUI). (bzr r13443) --- src/ui/widget/filter-effect-chooser.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 65706a9dc..78988a041 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -56,15 +56,12 @@ const Glib::ustring SimpleFilterModifier::get_blend_mode() if (!(_flags & BLEND)) { return "normal"; } - if (_blend.get_active_row_number() == 5) { + + const Util::EnumData *d = _blend.get_active_data(); + if (d) { + return _blend.get_active_data()->key; + } else return "normal"; - } else { - const Util::EnumData *d = _blend.get_active_data(); - if (d) { - return _blend.get_active_data()->key; - } else - return "normal"; - } } void SimpleFilterModifier::set_blend_mode(const int val) -- cgit v1.2.3 From 6351d4ea2ea398e0096c14b3ba57ca28dfd2f8a3 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 1 Jul 2014 23:58:08 +0200 Subject: Fix pentool backspace bug. Thanks Jabier Fixed bugs: - https://launchpad.net/bugs/1336561 (bzr r13445) --- src/ui/tools/pen-tool.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index b089065e8..70cbcaf0d 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -55,15 +55,15 @@ static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical namespace { - ToolBase* createPenContext() { - return new PenTool(); - } + ToolBase* createPenContext() { + return new PenTool(); + } - bool penContextRegistered = ToolFactory::instance().registerObject("/tools/freehand/pen", createPenContext); + bool penContextRegistered = ToolFactory::instance().registerObject("/tools/freehand/pen", createPenContext); } const std::string& PenTool::getPrefsPath() { - return PenTool::prefsPath; + return PenTool::prefsPath; } const std::string PenTool::prefsPath = "/tools/freehand/pen"; @@ -277,7 +277,7 @@ bool PenTool::item_handler(SPItem* item, GdkEvent* event) { } if (!ret) { - ret = FreehandBase::item_handler(item, event); + ret = FreehandBase::item_handler(item, event); } return ret; @@ -315,7 +315,7 @@ bool PenTool::root_handler(GdkEvent* event) { } if (!ret) { - ret = FreehandBase::root_handler(event); + ret = FreehandBase::root_handler(event); } return ret; @@ -1061,8 +1061,9 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { this->red_curve->reset(); // Destroy topmost green bpath if (this->green_bpaths) { - if (this->green_bpaths->data) + if (this->green_bpaths->data) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // Get last segment @@ -1078,11 +1079,21 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { } else { this->p[1] = this->p[0]; } - Geom::Point const pt(( this->npoints < 4 - ? (Geom::Point)(crv->finalPoint()) - : this->p[3] )); + Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); this->npoints = 2; - this->green_curve->backspace(); + // delete the last segment of the green curve + if (this->green_curve->get_segment_count() == 1) { + this->npoints = 5; + if (this->green_bpaths) { + if (this->green_bpaths->data) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } + this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); + } + this->green_curve->reset(); + } else { + this->green_curve->backspace(); + } sp_canvas_item_hide(this->c0); sp_canvas_item_hide(this->c1); sp_canvas_item_hide(this->cl0); -- cgit v1.2.3 From 77934815e32b73477fc5e7b19e61de702a303fd5 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 2 Jul 2014 00:13:46 +0200 Subject: pen tool: add back removal of curvature handle when backspace-deleting a node while drawing many code improvements: unnecessary casts, whitespace, { }, reduce variable scope. should all be noops. (bzr r13341.1.73) --- src/ui/tools/pen-tool.cpp | 61 +++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 0d8a2668b..aead3ebc0 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -958,40 +958,42 @@ void PenTool::_lastpointToCurve() { // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. if (this->npoints != 5 && !this->spiro && !this->bspline) return; - Geom::CubicBezier const * cubic; - this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); + + this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3.)*(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); //modificate the last segment of the green curve so it creates the type of node we need - if(this->spiro||this->bspline){ - if(!this->green_curve->is_empty()){ + if (this->spiro||this->bspline) { + if (!this->green_curve->is_empty()) { Geom::Point A(0,0); Geom::Point B(0,0); Geom::Point C(0,0); Geom::Point D(0,0); - SPCurve * previous = new SPCurve(); - cubic = dynamic_cast( this->green_curve->last_segment() ); + Geom::CubicBezier const *cubic = dynamic_cast( this->green_curve->last_segment() ); //We obtain the last segment 4 points in the previous curve if ( cubic ){ A = (*cubic)[0]; B = (*cubic)[1]; - if(this->spiro){ - C = this->p[0] + (Geom::Point)(this->p[0] - this->p[1]); - }else - C = this->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + if (this->spiro) { + C = this->p[0] + (this->p[0] - this->p[1]); + } else { + C = this->green_curve->last_segment()->finalPoint() + (1./3.)*(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + } D = (*cubic)[3]; - }else{ + } else { A = this->green_curve->last_segment()->initialPoint(); B = this->green_curve->last_segment()->initialPoint(); - if(this->spiro) - C = this->p[0] + (Geom::Point)(this->p[0] - this->p[1]); - else - C = this->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + if (this->spiro) { + C = this->p[0] + (this->p[0] - this->p[1]); + } else { + C = this->green_curve->last_segment()->finalPoint() + (1./3.)*(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + } D = this->green_curve->last_segment()->finalPoint(); } + SPCurve *previous = new SPCurve(); previous->moveto(A); previous->curveto(B, C, D); - if( this->green_curve->get_segment_count() == 1){ + if ( this->green_curve->get_segment_count() == 1) { this->green_curve = previous; - }else{ + } else { //we eliminate the last segment this->green_curve->backspace(); //and we add it again with the recreation @@ -999,7 +1001,7 @@ void PenTool::_lastpointToCurve() { } } //if the last node is an union with another curve - if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ + if (this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()) { this->_bspline_spiro_start_anchor(false); } } @@ -1242,12 +1244,12 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { } } else { // Reset red curve - Geom::CubicBezier const * cubic = NULL; this->red_curve->reset(); // Destroy topmost green bpath if (this->green_bpaths) { - if (this->green_bpaths->data) + if (this->green_bpaths->data) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // Get last segment @@ -1270,17 +1272,16 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } - Geom::Point const pt((this->npoints < 4 - ? (Geom::Point)(crv->finalPoint()) - : this->p[3])); + Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); this->npoints = 2; // delete the last segment of the green curve if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { - if (this->green_bpaths->data) + if (this->green_bpaths->data) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } this->green_curve->reset(); @@ -1289,14 +1290,16 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { } // assign the value of this->p[1] to the oposite of the green line last segment if(this->spiro){ - cubic = dynamic_cast(this->green_curve->last_segment()); + Geom::CubicBezier const *cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { - this->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2]); + this->p[1] = (*cubic)[3] + (*cubic)[3] - (*cubic)[2]; SP_CTRL(this->c1)->moveto(this->p[0]); } else { this->p[1] = this->p[0]; } } + sp_canvas_item_hide(this->c0); + sp_canvas_item_hide(this->c1); sp_canvas_item_hide(this->cl0); sp_canvas_item_hide(this->cl1); this->state = PenTool::POINT; @@ -1607,7 +1610,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ if(shift) this->p[2] = this->p[3]; }else{ - this->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); + this->p[1] = (*cubic)[3] + ((*cubic)[3] - (*cubic)[2] ); this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); } }else{ @@ -1659,7 +1662,7 @@ void PenTool::_bspline_spiro_end_anchor_on() C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); }else{ - C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); + C = this->p[3] + this->p[3] - this->p[2]; } if(cubic){ lastSeg->moveto((*cubic)[0]); @@ -2164,7 +2167,7 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { pen_last_paraxial_dir = this->nextParaxialDirection(p, this->p[0], state); } - ++this->num_clicks; + ++num_clicks; if (!this->red_curve->is_empty()) { -- cgit v1.2.3 From 371f45365a6b6ea42d17c8ea33cc0072f318967e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Jul 2014 13:14:35 +0200 Subject: Add LPE fillet-chamfer (bzr r13341.1.74) --- src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 257 ++++++++++++++++++++++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 112 +++++++++++ src/ui/tool/multi-path-manipulator.h | 3 +- src/ui/tool/path-manipulator.cpp | 20 +- 5 files changed, 388 insertions(+), 6 deletions(-) create mode 100644 src/ui/dialog/lpe-fillet-chamfer-properties.cpp create mode 100644 src/ui/dialog/lpe-fillet-chamfer-properties.h (limited to 'src/ui') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index daa8aea22..1bd939707 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -114,4 +114,6 @@ ink_common_sources += \ ui/dialog/undo-history.h \ ui/dialog/xml-tree.cpp \ ui/dialog/xml-tree.h \ + ui/dialog/lpe-fillet-chamfer-properties.cpp \ + ui/dialog/lpe-fillet-chamfer-properties.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp new file mode 100644 index 000000000..a68c7ee08 --- /dev/null +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -0,0 +1,257 @@ +/** + * From the code of Liam P.White from his Power Stroke Knot dialog + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if GLIBMM_DISABLE_DEPRECATED &&HAVE_GLIBMM_THREADS_H +#include +#endif + +#include "lpe-fillet-chamfer-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include +#include +#include "util/units.h" + +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() + : _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + mainVBox->set_homogeneous(false); + _layout_table.set_spacings(4); + _layout_table.resize(2, 2); + + // Layer name widgets + _fillet_chamfer_position_entry.set_activates_default(true); + _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); + _fillet_chamfer_position_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, + Gtk::FILL); + _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, + Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _fillet_chamfer_type_fillet.set_label(_("Fillet")); + _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); + _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); + _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_double_chamfer.set_label(_("Double chamfer")); + _fillet_chamfer_type_double_chamfer.set_group(_fillet_chamfer_type_group); + + mainVBox->pack_start(_layout_table, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_double_chamfer, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_apply)); + + signal_delete_event().connect(sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)), + true)); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_fillet_chamfer_position_entry); +} + +FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() +{ + + _setDesktop(NULL); +} + +void FilletChamferPropertiesDialog::showDialog( + SPDesktop *desktop, Geom::Point knotpoint, + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt, + const gchar *unit) +{ + FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); + + dialog->_setDesktop(desktop); + dialog->_setUnit(unit); + dialog->_setKnotPoint(knotpoint); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Fillet-Chamfer")); + dialog->_apply_button.set_label(_("_Modify")); + + dialog->set_modal(true); + desktop->setWindowTransient(dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void FilletChamferPropertiesDialog::_apply() +{ + std::istringstream i_pos(_fillet_chamfer_position_entry.get_text()); + double d_pos, d_width; + if (i_pos >> d_pos) { + if (_fillet_chamfer_type_fillet.get_active() == true) { + d_width = 1; + } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { + d_width = 2; + } else if (_fillet_chamfer_type_chamfer.get_active() == true) { + d_width = 3; + } else { + d_width = 4; + } + if (_flexible) { + if (d_pos > 99.99999 || d_pos < 0) { + d_pos = 0; + } + d_pos = _index + (d_pos / 100); + } else { + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, "px"); + d_pos = d_pos * -1; + } + _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); + } + _close(); +} + +void FilletChamferPropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + return false; +} + +void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) +{ + if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { + _apply(); + } +} + +void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +{ + double position; + if (knotpoint.x() > 0) { + double intpart; + position = modf(knotpoint[Geom::X], &intpart) * 100; + _flexible = true; + _index = intpart; + _fillet_chamfer_position_label.set_label(_("Position (%):")); + } else { + _flexible = false; + std::string posConcat = + std::string(_("Position (")) + std::string(unit) + std::string(")"); + _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); + position = knotpoint[Geom::X] * -1; + position = Inkscape::Util::Quantity::convert(position, "px", unit); + } + std::ostringstream s; + s.imbue(std::locale::classic()); + s << position; + _fillet_chamfer_position_entry.set_text(s.str()); + if (knotpoint.y() == 1) { + _fillet_chamfer_type_fillet.set_active(true); + } else if (knotpoint.y() == 2) { + _fillet_chamfer_type_inverse_fillet.set_active(true); + } else if (knotpoint.y() == 3) { + _fillet_chamfer_type_chamfer.set_active(true); + } else if (knotpoint.y() == 1) { + _fillet_chamfer_type_double_chamfer.set_active(true); + } +} + +void FilletChamferPropertiesDialog::_setPt( + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt) +{ + _knotpoint = const_cast< + Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity *>( + pt); +} + +void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) +{ + unit = abbr; +} + +void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) +{ + if (desktop) { + Inkscape::GC::anchor(desktop); + } + if (_desktop) { + Inkscape::GC::release(_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + +/* + 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 +// : diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h new file mode 100644 index 000000000..a07b5ab66 --- /dev/null +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -0,0 +1,112 @@ +/** + * + * From the code of Liam P.White from his Power Stroke Knot dialog + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H +#define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H + +#include <2geom/point.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "live_effects/parameter/filletchamferpointarray.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class FilletChamferPropertiesDialog : public Gtk::Dialog { +public: + FilletChamferPropertiesDialog(); + virtual ~FilletChamferPropertiesDialog(); + + Glib::ustring getName() const { + return "LayerPropertiesDialog"; + } + + static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt, + const gchar *unit); + +protected: + + SPDesktop *_desktop; + Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity * + _knotpoint; + + Gtk::Label _fillet_chamfer_position_label; + Gtk::Entry _fillet_chamfer_position_entry; + Gtk::RadioButton::Group _fillet_chamfer_type_group; + Gtk::RadioButton _fillet_chamfer_type_fillet; + Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; + Gtk::RadioButton _fillet_chamfer_type_chamfer; + Gtk::RadioButton _fillet_chamfer_type_double_chamfer; + + Gtk::Table _layout_table; + bool _position_visible; + double _index; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static FilletChamferPropertiesDialog &_instance() { + static FilletChamferPropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt); + void _setUnit(const gchar *abbr); + void _apply(); + void _close(); + bool _flexible; + const gchar *unit; + void _setKnotPoint(Geom::Point knotpoint); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton *event); + + friend class Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity; + +private: + FilletChamferPropertiesDialog( + FilletChamferPropertiesDialog const &); // no copy + FilletChamferPropertiesDialog &operator=( + FilletChamferPropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +/* + 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 +// : diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index 1328372c6..569a8e154 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -53,6 +53,7 @@ public: void insertNodesAtExtrema(ExtremumType extremum); void insertNodes(); + void alertLPE(); void duplicateNodes(); void joinNodes(); void breakNodes(); @@ -104,7 +105,7 @@ private: } void _commit(CommitEvent cps); - void _done(gchar const *reason, bool alert_LPE = false); + void _done(gchar const *reason, bool alert_LPE = true); void _doneWithCleanup(gchar const *reason, bool alert_LPE = false); guint32 _getOutlineColor(ShapeRole role); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 3beeed049..01cff5ad7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -11,6 +11,7 @@ */ #include "live_effects/lpe-powerstroke.h" +#include "live_effects/lpe-fillet-chamfer.h" #include #include #include @@ -1300,11 +1301,20 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) _spcurve->set_pathvector(pathv); if (alert_LPE) { /// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming? - if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()) { - PathEffectList effect_list = _path->getEffectList(); - LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast( effect_list.front()->lpeobject->get_lpe() ); - if (lpe_pwr) { - lpe_pwr->adjustForNewPath(pathv); + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE); + if(thisEffect){ + LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe_pwr) { + lpe_pwr->adjustForNewPath(pathv); + } + } + thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::FILLET_CHAMFER); + if(thisEffect){ + LivePathEffect::LPEFilletChamfer *lpe_fll = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe_fll) { + lpe_fll->adjustForNewPath(pathv); + } } } } -- cgit v1.2.3 From 22e482dd499a412dba05b570fec09cf08bc668f2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Jul 2014 13:29:03 +0200 Subject: Fixed CMakeLists.txt pointed by Liam (bzr r13341.1.75) --- src/ui/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 7d80f1e36..125755c48 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -78,6 +78,7 @@ set(ui_SRC dialog/layers.cpp dialog/livepatheffect-add.cpp dialog/livepatheffect-editor.cpp + dialog/lpe-fillet-chamfer-properties.cpp dialog/memory.cpp dialog/messages.cpp dialog/new-from-template.cpp @@ -198,6 +199,7 @@ set(ui_SRC dialog/layers.h dialog/livepatheffect-add.h dialog/livepatheffect-editor.h + dialog/lpe-fillet-chamfer-properties.h dialog/memory.h dialog/messages.h dialog/new-from-template.h -- cgit v1.2.3 From 962ef8a02c2dbaf2049c1951ec8953ba885f9e19 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 5 Jul 2014 12:01:13 -0400 Subject: Fix FTBFS gtk3 & make check (bzr r13341.1.78) --- src/ui/dialog/lpe-fillet-chamfer-properties.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index a07b5ab66..d3e859bff 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -9,15 +9,7 @@ #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #include <2geom/point.h> -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include "live_effects/parameter/filletchamferpointarray.h" class SPDesktop; -- cgit v1.2.3 From 3c71759c0b922e85dbbbffe92ca31cc000d4eced Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Fri, 11 Jul 2014 18:26:18 -0400 Subject: scale tiled clones to document units (Bug 1288860) Fixed bugs: - https://launchpad.net/bugs/1288860 (bzr r13451) --- src/ui/dialog/clonetiler.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index fb131d8da..e5f18216c 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2242,6 +2242,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_remove (NULL, dlg, false); + double scale_units = Inkscape::Util::Quantity::convert(1, "px", sp_desktop_document(desktop)->getDefaultUnit()); + double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); double shiftx_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_j", 0, -10000, 10000); @@ -2311,8 +2313,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) int jmax = prefs->getInt(prefs_path + "jmax", 2); bool fillrect = prefs->getBool(prefs_path + "fillrect"); - double fillwidth = prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); - double fillheight = prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); + double fillwidth = scale_units*prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); + double fillheight = scale_units*prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); bool dotrace = prefs->getBool(prefs_path + "dotrace"); int pick = prefs->getInt(prefs_path + "pick"); @@ -2358,11 +2360,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX ); Geom::OptRect r = item->documentBounds(bbox_type); if (r) { - w = r->dimensions()[Geom::X]; - h = r->dimensions()[Geom::Y]; - x0 = r->min()[Geom::X]; - y0 = r->min()[Geom::Y]; - center = desktop->dt2doc(item->getCenter()); + w = scale_units*r->dimensions()[Geom::X]; + h = scale_units*r->dimensions()[Geom::Y]; + x0 = scale_units*r->min()[Geom::X]; + y0 = scale_units*r->min()[Geom::Y]; + center = scale_units*desktop->dt2doc(item->getCenter()); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", center[Geom::Y]); @@ -2578,7 +2580,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) Geom::Point new_center; bool center_set = false; if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) { - new_center = desktop->dt2doc(item->getCenter()) * t; + new_center = scale_units*desktop->dt2doc(item->getCenter()) * t; center_set = true; } -- cgit v1.2.3 From 6d5bd2bf07165531a10d9925e8800fe5c9cd9be3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 14 Jul 2014 00:59:33 +0200 Subject: Update togglebutton parameter to handle if you want: Active text, Active icon, Inactive text, Inactive Icon (bzr r13341.1.88) --- src/ui/widget/registered-widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 83da1a6d6..8a81b1c02 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -109,7 +109,7 @@ RegisteredToggleButton::~RegisteredToggleButton() } RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) - : RegisteredWidget(label) + : RegisteredWidget() , _active_str(active_str) , _inactive_str(inactive_str) { -- cgit v1.2.3 From 7e68da8d1bc6a91031fa4a05cc5f8ca032bd960d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 19 Jul 2014 18:06:37 -0400 Subject: Workarounds for crash bugs 1309050, 601336; will fix properly in experimental Fixed bugs: - https://launchpad.net/bugs/601336 - https://launchpad.net/bugs/1309050 (bzr r13455) --- src/ui/tools/tool-base.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 4195c9eb2..f1d90f6c6 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -1289,8 +1289,7 @@ void sp_event_context_snap_delay_handler(ToolBase *ec, // now, just in case there's no future motion event that drops under the speed limit (when // stopping abruptly) delete ec->_delayed_snap_event; - ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, - event, origin); // watchdog is reset, i.e. pushed forward in time + ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, event, origin); // watchdog is reset, i.e. pushed forward in time // If the watchdog expires before a new motion event is received, we will snap (as explained // above). This means however that when the timer is too short, we will always snap and that the // speed threshold is ineffective. In the extreme case the delay is set to zero, and snapping will @@ -1301,15 +1300,13 @@ void sp_event_context_snap_delay_handler(ToolBase *ec, // snap, and set a new watchdog again. if (ec->_delayed_snap_event == NULL) { // no watchdog has been set // it might have already expired, so we'll set a new one; the snapping frequency will be limited this way - ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, - dse_item2, event, origin); + ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, event, origin); } // else: watchdog has been set before and we'll wait for it to expire } } else { // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog g_assert(ec->_delayed_snap_event == NULL); - ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, - event, origin); + ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, event, origin); } prev_pos = event_pos; -- cgit v1.2.3 From 9b1d9867e9cfbf56b44e8a996a4ccf2e7f288b87 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 22 Jul 2014 02:29:52 +0200 Subject: fix bug pointed by LiamW in Spirolive (bzr r13341.1.94) --- src/ui/tools/pen-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index aead3ebc0..56bcbef0d 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1611,7 +1611,6 @@ void PenTool::_bspline_spiro_motion(bool shift){ this->p[2] = this->p[3]; }else{ this->p[1] = (*cubic)[3] + ((*cubic)[3] - (*cubic)[2] ); - this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); } }else{ this->p[1] = this->p[0]; -- cgit v1.2.3 From 38acb1deed8b48ab28cc28ba0dfc577a5e205da9 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:15:15 +0200 Subject: Fixed some unused variables warnings. (bzr r13458) --- src/ui/tools/spray-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 08d3119a1..29f1b9a73 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -677,7 +677,7 @@ bool SprayTool::root_handler(GdkEvent* event) { desktop->setToolboxAdjustmentValue("population", this->population * 100); Geom::Point const scroll_w(event->button.x, event->button.y); Geom::Point const scroll_dt = desktop->point();; - Geom::Point motion_doc(desktop->dt2doc(scroll_dt)); + switch (event->scroll.direction) { case GDK_SCROLL_DOWN: case GDK_SCROLL_UP: { -- cgit v1.2.3 From b178124078314b78baca08fb65e12cc894242d3a Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:16:13 +0200 Subject: Replaced some abs/fabs with std::abs. (bzr r13459) --- src/ui/tools/pen-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 70cbcaf0d..649c64034 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1185,7 +1185,7 @@ void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint sta // we are drawing horizontal/vertical lines and hit an anchor; Geom::Point const origin = this->p[0]; // if the previous point and the anchor are not aligned either horizontally or vertically... - if ((abs(p[Geom::X] - origin[Geom::X]) > 1e-9) && (abs(p[Geom::Y] - origin[Geom::Y]) > 1e-9)) { + if ((std::abs(p[Geom::X] - origin[Geom::X]) > 1e-9) && (std::abs(p[Geom::Y] - origin[Geom::Y]) > 1e-9)) { // ...then we should draw an L-shaped path, consisting of two paraxial segments Geom::Point intermed = p; this->_setToNearestHorizVert(intermed, status, false); -- cgit v1.2.3 From d7c36cd293ee35f53a5b47f2795b061888d4f79b Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:16:52 +0200 Subject: Fixed some logic errors; clang warnings. (bzr r13460) --- src/ui/dialog/template-widget.cpp | 2 +- src/ui/widget/style-swatch.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index ef91962d4..9758b35ac 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -120,7 +120,7 @@ void TemplateWidget::_displayTemplateDetails() if (_current_template.long_description != "") message += _("Description: ") + _current_template.long_description + "\n\n"; - if (~_current_template.keywords.empty()){ + if (!_current_template.keywords.empty()){ message += _("Keywords: "); for (std::set::iterator it = _current_template.keywords.begin(); it != _current_template.keywords.end(); ++it) message += *it + " "; diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index a33c1d09f..98f4e47cd 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -261,7 +261,7 @@ void StyleSwatch::setStyle(SPCSSAttr *css) Glib::ustring css_string; sp_repr_css_write_string (_css, css_string); SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT); - if (~css_string.empty()) { + if (!css_string.empty()) { sp_style_merge_from_style_string (temp_spstyle, css_string.c_str()); } -- cgit v1.2.3 From 964d747265af3f80ed83a54b444ed5ae200a441d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 11:50:39 -0400 Subject: Fix for crash regression 1348927 -- dialogs that are shown but have not been presented are buggy Fixed bugs: - https://launchpad.net/bugs/1348927 (bzr r13471) --- src/ui/dialog/dialog-manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index d427e3590..7e69e439a 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -251,7 +251,7 @@ void DialogManager::showDialog(gchar const *name, bool grabfocus) { /** * Shows the named dialog, creating it if necessary. */ -void DialogManager::showDialog(GQuark name, bool grabfocus) { +void DialogManager::showDialog(GQuark name, bool /*grabfocus*/) { bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false); GTimer *timer = (wantTiming) ? g_timer_new() : 0; // if needed, must be created/started before getDialog() Dialog *dialog = getDialog(name); @@ -262,8 +262,8 @@ void DialogManager::showDialog(GQuark name, bool grabfocus) { tracker->setAutodelete(true); timer = 0; } - if (grabfocus) - dialog->present(); + // should check for grabfocus, but lp:1348927 prevents it + dialog->present(); } if ( timer ) { -- cgit v1.2.3 From cc73219a498e87298578996011b80680214f7a96 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 13:11:51 -0400 Subject: Clean up some ShapeHolder related things (bzr r13341.1.100) --- src/ui/tools/arc-tool.cpp | 6 +++--- src/ui/tools/box3d-tool.cpp | 6 +++--- src/ui/tools/flood-tool.cpp | 6 +++--- src/ui/tools/lpe-tool.cpp | 7 +++---- src/ui/tools/node-tool.cpp | 2 +- src/ui/tools/rect-tool.cpp | 6 +++--- src/ui/tools/spiral-tool.cpp | 6 +++--- src/ui/tools/star-tool.cpp | 6 +++--- src/ui/tools/text-tool.cpp | 6 +++--- 9 files changed, 25 insertions(+), 26 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 43f8eb9e1..9fd68f1b9 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -102,8 +102,8 @@ ArcTool::~ArcTool() { * destroys old and creates new knotholder. */ void ArcTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void ArcTool::setup() { @@ -115,7 +115,7 @@ void ArcTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index e00894d55..b998267c2 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -112,8 +112,8 @@ Box3dTool::~Box3dTool() { * destroys old and creates new knotholder. */ void Box3dTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); if (selection->perspList().size() == 1) { // selecting a single box changes the current perspective @@ -147,7 +147,7 @@ void Box3dTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index d74848dc6..3fb56b2ad 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -119,8 +119,8 @@ FloodTool::~FloodTool() { * destroys old and creates new knotholder. */ void FloodTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void FloodTool::setup() { @@ -130,7 +130,7 @@ void FloodTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index 9ab6d7814..e9b9421f1 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -129,8 +129,7 @@ void LpeTool::setup() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (item) { - this->shape_editor->set_item(item, SH_NODEPATH); - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } if (prefs->getBool("/tools/lpetool/selcue")) { @@ -146,9 +145,9 @@ void sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpoint { LpeTool *lc = SP_LPETOOL_CONTEXT(data); - lc->shape_editor->unset_item(SH_KNOTHOLDER); + lc->shape_editor->unset_item(); SPItem *item = selection->singleItem(); - lc->shape_editor->set_item(item, SH_KNOTHOLDER); + lc->shape_editor->set_item(item); } void LpeTool::set(const Inkscape::Preferences::Entry& val) { diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index ce487831d..36f33e478 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -438,7 +438,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); - si->set_item(r.item, SH_KNOTHOLDER); + si->set_item(r.item); this->_shape_editors.insert(const_cast(r.item), si); } } diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 39f422c1a..819671dd6 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -102,8 +102,8 @@ RectTool::~RectTool() { * destroys old and creates new knotholder. */ void RectTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void RectTool::setup() { @@ -113,7 +113,7 @@ void RectTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 5ae229df8..83712457a 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -104,8 +104,8 @@ SpiralTool::~SpiralTool() { * destroys old and creates new knotholder. */ void SpiralTool::selection_changed(Inkscape::Selection *selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void SpiralTool::setup() { @@ -119,7 +119,7 @@ void SpiralTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } Inkscape::Selection *selection = sp_desktop_selection(this->desktop); diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index 68f998920..ed28c0a8d 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -112,8 +112,8 @@ StarTool::~StarTool() { void StarTool::selection_changed(Inkscape::Selection* selection) { g_assert (selection != NULL); - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void StarTool::setup() { @@ -129,7 +129,7 @@ void StarTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } Inkscape::Selection *selection = sp_desktop_selection(this->desktop); diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index ac830fe6b..b60a39e5d 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -177,7 +177,7 @@ void TextTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item && SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection = sp_desktop_selection(desktop)->connectChangedFirst( @@ -1411,10 +1411,10 @@ void TextTool::_selectionChanged(Inkscape::Selection *selection) ToolBase *ec = SP_EVENT_CONTEXT(this); - ec->shape_editor->unset_item(SH_KNOTHOLDER); + ec->shape_editor->unset_item(); SPItem *item = selection->singleItem(); if (item && SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { - ec->shape_editor->set_item(item, SH_KNOTHOLDER); + ec->shape_editor->set_item(item); } if (this->text && (item != this->text)) { -- cgit v1.2.3 From c263637743407a181ac2f12226727553bda6cb37 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 28 Jul 2014 17:25:41 -0400 Subject: Fix for copy&paste clone original with clip-path/mask Fixed bugs: - https://launchpad.net/bugs/1293979 (bzr r13478) --- src/ui/clipboard.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/ui') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 8e2502545..1209b19cd 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -601,6 +601,12 @@ Glib::ustring ClipboardManagerImpl::getPathParameter(SPDesktop* desktop) */ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) { + // https://bugs.launchpad.net/inkscape/+bug/1293979 + // basically, when we do a depth-first search, we're stopping + // at the first object to be or . + // but that could then return the id of the object's + // clip path or mask, not the original path! + SPDocument *tempdoc = _retrieveClipboard(); // any target will do here if ( tempdoc == NULL ) { _userWarn(desktop, _("Nothing on the clipboard.")); @@ -608,6 +614,9 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) } Inkscape::XML::Node *root = tempdoc->getReprRoot(); + // 1293979: strip out the defs of the document + root->removeChild(tempdoc->getDefs()->getRepr()); + Inkscape::XML::Node *repr = sp_repr_lookup_name(root, "svg:path", -1); // unlimited search depth if ( repr == NULL ) { repr = sp_repr_lookup_name(root, "svg:text", -1); -- cgit v1.2.3 From 553293740817862cb756c770f6bee01dd00089bf Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 23:48:41 +0200 Subject: fix crash bug (reported by su_v on IRC) related to removing color profiles (bzr r13481) --- src/ui/dialog/document-properties.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2674efc1e..9141b2268 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -596,6 +596,7 @@ void DocumentProperties::removeSelectedProfile(){ //XML Tree being used directly here while it shouldn't be. sp_repr_unparent(obj->getRepr()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_COLOR_PROFILE, _("Remove linked color profile")); + break; // removing the color profile likely invalidates part of the traversed list, stop traversing here. } current = g_slist_next(current); } -- cgit v1.2.3 From 6934b8ce1b39c6d3533fa3da86aa32cac5282056 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 28 Jul 2014 21:47:11 -0400 Subject: Fix for 1346972 (freehand shape mode should pick stroke width from tool's active style) Fixed bugs: - https://launchpad.net/bugs/1346972 (bzr r13482) --- src/ui/tools/freehand-base.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 288a200f4..a90a23a3e 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -225,6 +225,31 @@ static void spdc_apply_powerstroke_shape(const std::vector & points Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); static_cast(lpe)->offset_points.param_set_and_write_new_value(points); + // find out stroke width (TODO: is there an easier way??) + SPDesktop *desktop = dc->desktop; + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); + Inkscape::GC::release(repr); + + char const* tool = SP_IS_PEN_CONTEXT(dc) ? "/tools/freehand/pen" : "/tools/freehand/pencil"; + + // apply the tool's current style + sp_desktop_apply_style_tool(desktop, repr, tool, false); + + double stroke_width = 1.0; + char const *style_str = NULL; + style_str = repr->attribute("style"); + if (style_str) { + SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); + sp_style_merge_from_style_string(style, style_str); + stroke_width = style->stroke_width.computed; + style->stroke_width.computed = 0; + sp_style_unref(style); + } + + char * width_str = new char[50]; + sprintf(width_str, "0,%f", stroke_width / 2.); + // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); lpe->getRepr()->setAttribute("end_linecap_type", "zerowidth"); @@ -232,6 +257,9 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("sort_points", "true"); lpe->getRepr()->setAttribute("interpolator_type", "CubicBezierJohan"); lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); + lpe->getRepr()->setAttribute("offset_points", width_str); + + delete [] width_str; } static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) -- cgit v1.2.3 From 702d7523e258cb18802dfedeef642589e99e89f0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 30 Jul 2014 02:26:30 +0200 Subject: add last applied branch - mode to strokes on pen/pencil (bzr r13341.1.108) --- src/ui/tools/freehand-base.cpp | 45 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 1c5b7b8e3..86b78c953 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -44,6 +44,8 @@ #include "live_effects/lpe-powerstroke.h" #include "style.h" #include "ui/control-manager.h" +// clipboard support +#include "ui/clipboard.h" #include "ui/tools/freehand-base.h" #include @@ -261,7 +263,13 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } - int shape = prefs->getInt(tool_name(dc) + "/shape", 0); + //Store the clipboard path to apply in the future without the use of clipboard + static Geom::PathVector previous_shape_pathv; + enum shapeType { NONE, TRIANGLE_IN, TRIANGLE_OUT, ELLIPSE, CLIPBOARD, LAST_APPLIED }; + static shapeType previous_shape_type = NONE; + + + shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); @@ -269,11 +277,18 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 + if(shape == LAST_APPLIED){ + shape = previous_shape_type; + if(shape == CLIPBOARD){ + shape = LAST_APPLIED; + } + } + switch (shape) { - case 0: + case NONE: // don't apply any shape break; - case 1: + case TRIANGLE_IN: { // "triangle in" std::vector points(1); @@ -283,7 +298,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape_applied = true; break; } - case 2: + case TRIANGLE_OUT: { // "triangle out" guint curve_length = curve->get_segment_count(); @@ -294,7 +309,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape_applied = true; break; } - case 3: + case ELLIPSE: { // "ellipse" SPCurve *c = new SPCurve(); @@ -307,22 +322,40 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->closepath(); spdc_paste_curve_as_freehand_shape(c, dc, item); c->unref(); + shape_applied = true; break; } - case 4: + case CLIPBOARD: { // take shape from clipboard; TODO: catch the case where clipboard is empty Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); static_cast(lpe)->pattern.on_paste_button_click(); + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); + previous_shape_pathv = sp_svg_read_pathv(svgd.data()); shape_applied = true; break; } + case LAST_APPLIED: + { + if(previous_shape_pathv.size() != 0){ + SPCurve * c = new SPCurve(); + c->set_pathvector(previous_shape_pathv); + spdc_paste_curve_as_freehand_shape(c, dc, item); + c->unref(); + + shape_applied = true; + } + break; + } default: break; } + previous_shape_type = shape; + if (shape_applied) { // apply original stroke color as fill and unset stroke; then return SPCSSAttr *css = sp_repr_css_attr_new(); -- cgit v1.2.3 From a0acffb60236ee6d8c6f8ccc2f29d36b5aa02dda Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 1 Aug 2014 10:28:31 -0400 Subject: Fix for #906794, #1246550 (live effects not showing helper paths) Fixed bugs: - https://launchpad.net/bugs/1246550 - https://launchpad.net/bugs/906794 (bzr r13487) --- src/ui/tools/node-tool.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/ui/tools/node-tool.h | 2 ++ 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..0778e3f3f 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -19,6 +19,7 @@ #include "display/curve.h" #include "display/sp-canvas.h" #include "document.h" +#include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "message-context.h" #include "selection.h" @@ -166,6 +167,9 @@ NodeTool::~NodeTool() { if (this->flash_tempitem) { this->desktop->remove_temporary_canvasitem(this->flash_tempitem); } + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + } this->_selection_changed_connection.disconnect(); //this->_selection_modified_connection.disconnect(); @@ -246,6 +250,7 @@ void NodeTool::setup() { ))) ); + this->helperpath_tmpitem = NULL; this->cursor_drag = false; this->show_transform_handles = true; this->single_node_transform_handles = false; @@ -278,6 +283,44 @@ void NodeTool::setup() { } this->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive + this->update_helperpath(); +} + +// show helper paths of the applied LPE, if any +void NodeTool::update_helperpath () { + Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + this->helperpath_tmpitem = NULL; + } + + if (SP_IS_LPE_ITEM(selection->singleItem())) { + Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); + if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + if (lpe) { + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + c->transform(selection->singleItem()->i2dt_affine()); + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), + 0x0000ff9A, 1.0, + SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); + } + c->unref(); + cc->unref(); + } + } + } } void NodeTool::set(const Inkscape::Preferences::Entry& value) { @@ -392,7 +435,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { for (std::set::iterator i = shapes.begin(); i != shapes.end(); ++i) { ShapeRecord const &r = *i; - if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) && + if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item) || SP_IS_GROUP(r.item) || SP_IS_OBJECTGROUP(r.item)) && this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); @@ -432,6 +475,7 @@ bool NodeTool::root_handler(GdkEvent* event) { switch (event->type) { case GDK_MOTION_NOTIFY: { + this->update_helperpath(); combine_motion_events(desktop->canvas, event->motion, 0); SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button), FALSE, TRUE); diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 4d15ab70e..459ecd0a7 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -51,6 +51,7 @@ public: static const std::string prefsPath; virtual void setup(); + virtual void update_helperpath(); virtual void set(const Inkscape::Preferences::Entry& val); virtual bool root_handler(GdkEvent* event); @@ -62,6 +63,7 @@ private: sigc::connection _sizeUpdatedConn; SPItem *flashed_item; + Inkscape::Display::TemporaryItem *helperpath_tmpitem; Inkscape::Display::TemporaryItem *flash_tempitem; Inkscape::UI::Selector* _selector; Inkscape::UI::PathSharedData* _path_data; -- cgit v1.2.3 From b2842360758b2333a651ef9932c1e438e90628e3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 4 Aug 2014 11:21:54 +0200 Subject: Fixed some redraw problems moving nodes in bspline mode (bzr r13341.1.115) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- src/ui/tools/pen-tool.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 01cff5ad7..9839be437 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1219,6 +1219,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ h = h2; } double pos = 0.0000; + const double handleCubicGap = 0.01; Node *n = h->parent(); Node * nextNode = NULL; nextNode = n->nodeToward(h); @@ -1226,7 +1227,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(Geom::Point(h->position()[X] - handleCubicGap,h->position()[Y] - handleCubicGap),*lineInsideNodes->first_segment()); } if (pos == 0.0000 && !h2){ return BSplineHandlePosition(h, h->other()); @@ -1244,6 +1245,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; + const double handleCubicGap = 0.01; Geom::Point ret = h->position(); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; @@ -1255,7 +1257,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); ret = SBasisInsideNodes.valueAt(pos); - ret = Geom::Point(ret[X] + 0.005,ret[Y] + 0.005); + ret = Geom::Point(ret[X] + handleCubicGap,ret[Y] + handleCubicGap); }else{ if(pos == 0.0000){ ret = n->position(); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d826eaf48..9a73d497f 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -84,7 +84,7 @@ namespace Tools { static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical - +const double handleCubicGap = 0.01; namespace { ToolBase* createPenContext() { return new PenTool(); @@ -1454,7 +1454,7 @@ void PenTool::_bspline_spiro_on() this->p[0] = this->red_curve->first_segment()->initialPoint(); this->p[3] = this->red_curve->first_segment()->finalPoint(); this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]); - this->p[2] = Geom::Point(this->p[2][X] + 0.005,this->p[2][Y] + 0.005); + this->p[2] = Geom::Point(this->p[2][X] + handleCubicGap,this->p[2][Y] + handleCubicGap); } } @@ -1522,7 +1522,7 @@ void PenTool::_bspline_spiro_start_anchor_on() Geom::Point A = tmpCurve->last_segment()->initialPoint(); Geom::Point D = tmpCurve->last_segment()->finalPoint(); Geom::Point C = D + (1./3)*(A - D); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); + C = Geom::Point(C[X] + handleCubicGap,C[Y] + handleCubicGap); if(cubic){ lastSeg->moveto(A); lastSeg->curveto((*cubic)[1],C,D); @@ -1580,10 +1580,10 @@ void PenTool::_bspline_spiro_motion(bool shift){ this->npoints = 5; SPCurve *tmpCurve = new SPCurve(); this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]); - this->p[2] = Geom::Point(this->p[2][X] + 0.005,this->p[2][Y] + 0.005); + this->p[2] = Geom::Point(this->p[2][X] + handleCubicGap,this->p[2][Y] + handleCubicGap); if(this->green_curve->is_empty() && !this->sa){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); - this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); + this->p[1] = Geom::Point(this->p[1][X] + handleCubicGap,this->p[1][Y] + handleCubicGap); }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ @@ -1608,7 +1608,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ WPower->reset(); this->p[1] = SBasisWPower.valueAt(WP); if(!Geom::are_near(this->p[1],this->p[0])) - this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); + this->p[1] = Geom::Point(this->p[1][X] + handleCubicGap,this->p[1][Y] + handleCubicGap); if(shift) this->p[2] = this->p[3]; }else{ @@ -1638,7 +1638,7 @@ void PenTool::_bspline_spiro_end_anchor_on() using Geom::X; using Geom::Y; this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]); - this->p[2] = Geom::Point(this->p[2][X] + 0.005,this->p[2][Y] + 0.005); + this->p[2] = Geom::Point(this->p[2][X] + handleCubicGap,this->p[2][Y] + handleCubicGap); SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); @@ -1661,7 +1661,7 @@ void PenTool::_bspline_spiro_end_anchor_on() Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(this->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); + C = Geom::Point(C[X] + handleCubicGap,C[Y] + handleCubicGap); }else{ C = this->p[3] + this->p[3] - this->p[2]; } -- cgit v1.2.3 From 2029349f5291ae10048202732a89f34c0a179130 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 20:40:19 -0400 Subject: Add in some debugging code that will complain when deleted knots are accessed by snap handler (bzr r13341.1.120) --- src/ui/tools/tool-base.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index f1d90f6c6..c23da87c0 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -58,6 +58,7 @@ #include "sp-guide.h" #include "color.h" #include "knot.h" +#include "knot-ptr.h" // globals for temporary switching to selector by space static bool selector_toggled = FALSE; @@ -1359,6 +1360,7 @@ gboolean sp_event_context_snap_watchdog_callback(gpointer data) { break; case DelayedSnapEvent::KNOT_HANDLER: { gpointer knot = dse->getItem2(); + check_if_knot_deleted(knot); if (knot && SP_IS_KNOT(knot)) { sp_knot_handler_request_position(dse->getEvent(), SP_KNOT(knot)); } -- cgit v1.2.3 From 5a4eae28b6bd036a3ba87fdf90f8560cc1ca5c41 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Thu, 7 Aug 2014 13:43:16 -0400 Subject: refresh clip path when editing in XML editor (Bug 1349018) Fixed bugs: - https://launchpad.net/bugs/1349018 (bzr r13502) --- src/ui/dialog/xml-tree.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 55d0aff09..c87e42633 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -1033,6 +1033,7 @@ void XmlTree::cmd_set_attr() updated->updateRepr(); } + reinterpret_cast(current_desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); DocumentUndo::done(current_document, SP_VERB_DIALOG_XML_EDITOR, _("Change attribute")); -- cgit v1.2.3 From d59ab0cc036239f5e2f6040b2f439ba7b55af4c3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 8 Aug 2014 09:47:46 -0400 Subject: Ponyscape feature: finish pen drawing on context switch (bzr r13090.1.101) --- src/ui/tools/pen-tool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9a73d497f..318591df5 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -239,7 +239,9 @@ void PenTool::finish() { sp_event_context_discard_delayed_snap_event(this); if (this->npoints != 0) { - this->_cancel(); + // switching context - finish path + this->ea = NULL; // unset end anchor if set (otherwise crashes) + this->_finish(false); } FreehandBase::finish(); -- cgit v1.2.3 From e9f9ba07739cdb52c649e8e10dca9de76c71114d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 8 Aug 2014 16:20:44 -0400 Subject: Massive performance improvment for basic node operations with thousands of nodes (bzr r13341.1.124) --- src/ui/tool/control-point-selection.cpp | 49 +++++++++++++++++++++++++++------ src/ui/tool/control-point-selection.h | 13 +++++---- src/ui/tool/multi-path-manipulator.cpp | 2 +- src/ui/tool/node.cpp | 32 ++++++++++++++++++++- src/ui/tool/path-manipulator.cpp | 10 +++++-- src/ui/tool/path-manipulator.h | 3 +- src/ui/tool/selectable-control-point.h | 1 + src/ui/tools/node-tool.cpp | 2 +- 8 files changed, 93 insertions(+), 19 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index d10ed0f0d..998f74ee0 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -74,7 +74,7 @@ ControlPointSelection::~ControlPointSelection() } /** Add a control point to the selection. */ -std::pair ControlPointSelection::insert(const value_type &x) +std::pair ControlPointSelection::insert(const value_type &x, bool notify) { iterator found = _points.find(x); if (found != _points.end()) { @@ -86,6 +86,10 @@ std::pair ControlPointSelection::insert(c x->updateState(); _pointChanged(x, true); + if (notify) { + signal_selection_changed.emit(std::vector(1, x), true); + } + return std::pair(found, true); } @@ -97,47 +101,75 @@ void ControlPointSelection::erase(iterator pos) erased->updateState(); _pointChanged(erased, false); } -ControlPointSelection::size_type ControlPointSelection::erase(const key_type &k) +ControlPointSelection::size_type ControlPointSelection::erase(const key_type &k, bool notify) { iterator pos = _points.find(k); if (pos == _points.end()) return 0; erase(pos); + + if (notify) { + signal_selection_changed.emit(std::vector(1, k), false); + } return 1; } void ControlPointSelection::erase(iterator first, iterator last) { + std::vector out(first, last); while (first != last) erase(first++); + signal_selection_changed.emit(out, false); } /** Remove all points from the selection, making it empty. */ void ControlPointSelection::clear() { + std::vector out(begin(), end()); for (iterator i = begin(); i != end(); ) erase(i++); + if (!out.empty()) + signal_selection_changed.emit(out, false); } /** Select all points that this selection can contain. */ void ControlPointSelection::selectAll() { for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) { - insert(*i); + insert(*i, false); } + std::vector out(_all_points.begin(), _all_points.end()); + if (!out.empty()) + signal_selection_changed.emit(out, true); } /** Select all points inside the given rectangle (in desktop coordinates). */ void ControlPointSelection::selectArea(Geom::Rect const &r) { + std::vector out; for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) { - if (r.contains(**i)) - insert(*i); + if (r.contains(**i)) { + insert(*i, false); + out.push_back(*i); + } } + if (!out.empty()) + signal_selection_changed.emit(out, true); } /** Unselect all selected points and select all unselected points. */ void ControlPointSelection::invertSelection() { + std::vector in, out; for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) { - if ((*i)->selected()) erase(*i); - else insert(*i); + if ((*i)->selected()) { + in.push_back(*i); + erase(*i); + } + else { + out.push_back(*i); + insert(*i, false); + } } + if (!in.empty()) + signal_selection_changed.emit(in, false); + if (!out.empty()) + signal_selection_changed.emit(out, true); } void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir) { @@ -166,6 +198,7 @@ void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir) if (match) { if (grow) insert(match); else erase(match); + signal_selection_changed.emit(std::vector(1, match), grow); } } @@ -389,7 +422,7 @@ void ControlPointSelection::_pointChanged(SelectableControlPoint *p, bool select _handles->rotationCenter().move(_bounds->midpoint()); } - signal_point_changed.emit(p, selected); + //signal_point_changed.emit(p, selected); } void ControlPointSelection::_mouseoverChanged() diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index a087e0455..2d812c0a3 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -62,18 +62,19 @@ public: const_iterator end() const { return _points.end(); } // insert - std::pair insert(const value_type& x); + std::pair insert(const value_type& x, bool notify = true); template void insert(InputIterator first, InputIterator last) { for (; first != last; ++first) { - insert(*first); + insert(*first, false); } + signal_selection_changed.emit(std::vector(first, last), true); } // erase void clear(); void erase(iterator pos); - size_type erase(const key_type& k); + size_type erase(const key_type& k, bool notify = true); void erase(iterator first, iterator last); // find @@ -108,7 +109,9 @@ public: void toggleTransformHandlesMode(); sigc::signal signal_update; - sigc::signal signal_point_changed; + // It turns out that emitting a signal after every point is selected or deselected is not too efficient, + // so this can be done in a massive group once the selection is finally changed. + sigc::signal, bool> signal_selection_changed; sigc::signal signal_commit; void getOriginalPoints(std::vector &pts); @@ -166,4 +169,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 68aaa77a5..b32bafdbf 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -122,7 +122,7 @@ MultiPathManipulator::MultiPathManipulator(PathSharedData &data, sigc::connectio { _selection.signal_commit.connect( sigc::mem_fun(*this, &MultiPathManipulator::_commit)); - _selection.signal_point_changed.connect( + _selection.signal_selection_changed.connect( sigc::hide( sigc::hide( signal_coords_changed.make_slot()))); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index ed0843b65..e38f82673 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1623,7 +1623,37 @@ void NodeList::reverse() void NodeList::clear() { - for (iterator i = begin(); i != end();) erase (i++); + // ugly but more efficient clearing mechanism + std::vector to_clear; + std::vector > nodes; + long in = -1; + for (iterator i = begin(); i != end(); ++i) { + SelectableControlPoint *rm = static_cast(i._node); + if (std::find(to_clear.begin(), to_clear.end(), &rm->_selection) == to_clear.end()) { + to_clear.push_back(&rm->_selection); + ++in; + } + nodes.push_back(std::make_pair(rm, in)); + } + for (size_t i = 0, e = nodes.size(); i != e; ++i) { + to_clear[nodes[i].second]->erase(nodes[i].first, false); + } + std::vector > emission; + for (long i = 0, e = to_clear.size(); i != e; ++i) { + emission.push_back(std::vector()); + for (size_t j = 0, f = nodes.size(); j != f; ++j) { + if (nodes[j].second != i) + break; + emission[i].push_back(nodes[j].first); + } + } + + for (size_t i = 0, e = emission.size(); i != e; ++i) { + to_clear[i]->signal_selection_changed.emit(emission[i], false); + } + + for (iterator i = begin(); i != end();) + erase (i++); } NodeList::iterator NodeList::erase(iterator i) diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9839be437..5f20aece7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -140,8 +140,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _selection.signal_update.connect( sigc::bind(sigc::mem_fun(*this, &PathManipulator::update), false)); - _selection.signal_point_changed.connect( - sigc::mem_fun(*this, &PathManipulator::_selectionChanged)); + _selection.signal_selection_changed.connect( + sigc::mem_fun(*this, &PathManipulator::_selectionChangedM)); _desktop->signal_zoom_changed.connect( sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); @@ -1524,6 +1524,12 @@ bool PathManipulator::_handleClicked(Handle *h, GdkEventButton *event) return false; } +void PathManipulator::_selectionChangedM(std::vector pvec, bool selected) { + for (size_t n = 0, e = pvec.size(); n < e; ++n) { + _selectionChanged(pvec[n], selected); + } +} + void PathManipulator::_selectionChanged(SelectableControlPoint *p, bool selected) { if (selected) ++_num_selected; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 151805c83..4d2bf4300 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -122,7 +122,8 @@ private: Glib::ustring _nodetypesKey(); Inkscape::XML::Node *_getXMLNode(); - void _selectionChanged(SelectableControlPoint *p, bool selected); + void _selectionChangedM(std::vector pvec, bool selected); + void _selectionChanged(SelectableControlPoint * p, bool selected); bool _nodeClicked(Node *, GdkEventButton *); void _handleGrabbed(); bool _handleClicked(Handle *, GdkEventButton *); diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index 8acfc1168..362d4addc 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -28,6 +28,7 @@ public: virtual Geom::Rect bounds() const { return Geom::Rect(position(), position()); } + friend class NodeList; protected: diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index d2584ee74..d4d7b2c35 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -245,7 +245,7 @@ void NodeTool::setup() { ) ); - this->_selected_nodes->signal_point_changed.connect( + this->_selected_nodes->signal_selection_changed.connect( // Hide both signal parameters and bind the function parameter to 0 // sigc::signal // <=> -- cgit v1.2.3 From 764f8e7612bbf000a5fab4eeed165432f4ff779b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 22:47:25 -0400 Subject: Further fixes related to bug #1327267, toolbars don't need to update when their context is not in use (bzr r13341.1.126) --- src/ui/tools/arc-tool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/arc-tool.h b/src/ui/tools/arc-tool.h index c4c67660d..55cbaf78c 100644 --- a/src/ui/tools/arc-tool.h +++ b/src/ui/tools/arc-tool.h @@ -30,7 +30,7 @@ namespace Inkscape { } #define SP_ARC_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) -#define SP_IS_ARC_CONTEXT(obj) (dynamic_cast(const Inkscape::UI::Tools::ToolBase*(obj)) != NULL) +#define SP_IS_ARC_CONTEXT(obj) (dynamic_cast(obj) != NULL) namespace Inkscape { namespace UI { -- cgit v1.2.3 From f83624750df7b8d4bd1652d25553436b739ad618 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 23:58:09 -0400 Subject: Add meshes to selected style widget (bzr r13341.1.129) --- src/ui/widget/selected-style.cpp | 21 +++++++++++++++++++++ src/ui/widget/selected-style.h | 11 +++++++++++ 2 files changed, 32 insertions(+) (limited to 'src/ui') diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 042a6614e..85538c8c7 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -25,6 +25,7 @@ #include "desktop-style.h" #include "sp-namedview.h" #include "sp-linear-gradient.h" +#include "sp-mesh-gradient.h" #include "sp-radial-gradient.h" #include "sp-pattern.h" #include "ui/dialog/dialog-manager.h" @@ -209,6 +210,18 @@ SelectedStyle::SelectedStyle(bool /*layout*/) _gradient_box_r[i].pack_start(*(Glib::wrap(_gradient_preview_r[i]))); _gradient_box_r[i].show_all(); +#ifdef WITH_MESH + _mgradient[i].set_markup (_("M")); + sp_set_font_size_smaller (GTK_WIDGET(_mgradient[i].gobj())); + _mgradient[i].show_all(); + __mgradient[i] = (i == SS_FILL)? (_("Mesh gradient fill")) : (_("Mesh gradient stroke")); + + _gradient_preview_m[i] = GTK_WIDGET(sp_gradient_image_new (NULL)); + _gradient_box_m[i].pack_start(_mgradient[i]); + _gradient_box_m[i].pack_start(*(Glib::wrap(_gradient_preview_m[i]))); + _gradient_box_m[i].show_all(); +#endif + _many[i].set_markup (_("Different")); sp_set_font_size_smaller (GTK_WIDGET(_many[i].gobj())); _many[i].show_all(); @@ -1028,6 +1041,14 @@ SelectedStyle::update() place->add(_gradient_box_r[i]); place->set_tooltip_text(__rgradient[i]); _mode[i] = SS_RGRADIENT; +#ifdef WITH_MESH + } else if (SP_IS_MESHGRADIENT(server)) { + SPGradient *vector = SP_GRADIENT(server)->getVector(); + sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_m[i]), vector); + place->add(_gradient_box_m[i]); + place->set_tooltip_text(__mgradient[i]); + _mode[i] = SS_MGRADIENT; +#endif } else if (SP_IS_PATTERN (server)) { place->add(_pattern[i]); place->set_tooltip_text(__pattern[i]); diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 9557a8d74..df0f41507 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -60,6 +60,9 @@ enum { SS_PATTERN, SS_LGRADIENT, SS_RGRADIENT, +#ifdef WITH_MESH + SS_MGRADIENT, +#endif SS_MANY, SS_COLOR }; @@ -186,6 +189,14 @@ protected: GtkWidget *_gradient_preview_r[2]; Gtk::HBox _gradient_box_r[2]; +#ifdef WITH_MESH + Gtk::Label _mgradient[2]; + Glib::ustring __mgradient[2]; + + GtkWidget *_gradient_preview_m[2]; + Gtk::HBox _gradient_box_m[2]; +#endif + Gtk::Label _many[2]; Glib::ustring __many[2]; -- cgit v1.2.3 From 3511d63cc7b04e5fc5ae0ff8de616f0594c5dbcb Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 10 Aug 2014 00:07:19 -0400 Subject: Get gradient tool to shut up about invalid casts with meshes (bzr r13341.1.131) --- src/ui/tools/gradient-tool.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index a0bbfbaf1..4f9a7b59b 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -213,17 +213,20 @@ sp_gradient_context_is_over_line (GradientTool *rc, SPItem *item, Geom::Point ev //Translate mouse point into proper coord system rc->mousepoint_doc = desktop->w2d(event_p); - SPCtrlLine* line = SP_CTRLLINE(item); + if (SP_IS_CTRLLINE(item)) { + SPCtrlLine* line = SP_CTRLLINE(item); - Geom::LineSegment ls(line->s, line->e); - Geom::Point nearest = ls.pointAt(ls.nearestPoint(rc->mousepoint_doc)); - double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom(); + Geom::LineSegment ls(line->s, line->e); + Geom::Point nearest = ls.pointAt(ls.nearestPoint(rc->mousepoint_doc)); + double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom(); - double tolerance = (double) SP_EVENT_CONTEXT(rc)->tolerance; + double tolerance = (double) SP_EVENT_CONTEXT(rc)->tolerance; - bool close = (dist_screen < tolerance); + bool close = (dist_screen < tolerance); - return close; + return close; + } + return false; } static std::vector -- cgit v1.2.3 From c73ebf3c732e19f665de2d490a915eabf425905e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 13 Aug 2014 08:24:04 +0200 Subject: Printing. Fix for Bug #264831 (Print settings not persistent). Printing. Fix for Bug #508529 (Printing rastered image offsets the page). Fixed bugs: - https://launchpad.net/bugs/264831 - https://launchpad.net/bugs/508529 (bzr r13509) --- src/ui/dialog/print.cpp | 8 +++++++- src/ui/widget/rendering-options.cpp | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..4d8d512df 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -18,6 +18,7 @@ #include #endif +#include "preferences.h" #include "print.h" #include @@ -44,14 +45,18 @@ static void draw_page( gint /*page_nr*/, gpointer user_data) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data; //printf("%s %d\n",__FUNCTION__, page_nr); if (junk->_tab->as_bitmap()) { // Render as exported PNG + prefs->setBool("/dialogs/printing/asbitmap", true); gdouble width = (junk->_doc)->getWidth().value("px"); gdouble height = (junk->_doc)->getHeight().value("px"); gdouble dpi = junk->_tab->bitmap_dpi(); + prefs->setDouble("/dialogs/printing/dpi", dpi); + std::string tmp_png; std::string tmp_base = "inkscape-print-png-XXXXXX"; @@ -92,7 +97,7 @@ static void draw_page( cairo_get_matrix(cr, &m); cairo_scale(cr, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi); // FIXME: why is the origin offset?? - cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0); + cairo_set_source_surface(cr, png->cobj(), 0, 0); cairo_paint(cr); cairo_set_matrix(cr, &m); } @@ -106,6 +111,7 @@ static void draw_page( } else { // Render as vectors + prefs->setBool("/dialogs/printing/asbitmap", false); Inkscape::Extension::Internal::CairoRenderer renderer; Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext(); diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp index d6248df69..511b0375c 100644 --- a/src/ui/widget/rendering-options.cpp +++ b/src/ui/widget/rendering-options.cpp @@ -12,6 +12,7 @@ # include #endif +#include "preferences.h" #include "rendering-options.h" #include "util/units.h" #include @@ -38,6 +39,7 @@ RenderingOptions::RenderingOptions () : Glib::ustring(""), Glib::ustring(""), false) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // set up tooltips _radio_vector.set_tooltip_text( _("Render using Cairo vector operations. " @@ -52,15 +54,21 @@ RenderingOptions::RenderingOptions () : set_border_width(2); - // default to vector operations - _radio_vector.set_active (true); Gtk::RadioButtonGroup group = _radio_vector.get_group (); _radio_bitmap.set_group (group); _radio_bitmap.signal_toggled().connect(sigc::mem_fun(*this, &RenderingOptions::_toggled)); - + + // default to vector operations + if (prefs->getBool("/dialogs/printing/asbitmap", false)) { + _radio_bitmap.set_active(); + } else { + _radio_vector.set_active(); + } + // configure default DPI _dpi.setRange(Inkscape::Util::Quantity::convert(1, "in", "pt"),2400.0); - _dpi.setValue(Inkscape::Util::Quantity::convert(1, "in", "pt")); + _dpi.setValue(prefs->getDouble("/dialogs/printing/dpi", + Inkscape::Util::Quantity::convert(1, "in", "pt"))); _dpi.setIncrements(1.0,10.0); _dpi.setDigits(0); _dpi.update(); -- cgit v1.2.3 From 9d5529ca1b43a144f825fc58d6aa37911a4ac7f6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 13 Aug 2014 09:12:45 -0400 Subject: Fix build (bzr r13510) --- src/ui/dialog/print.cpp | 4 +++- src/ui/widget/rendering-options.cpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 4d8d512df..ed39ebb32 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,14 +13,16 @@ #ifdef HAVE_CONFIG_H # include #endif + #ifdef WIN32 #include #include #endif +#include + #include "preferences.h" #include "print.h" -#include #include "extension/internal/cairo-render-context.h" #include "extension/internal/cairo-renderer.h" diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp index 511b0375c..837387f7b 100644 --- a/src/ui/widget/rendering-options.cpp +++ b/src/ui/widget/rendering-options.cpp @@ -12,6 +12,8 @@ # include #endif +#include + #include "preferences.h" #include "rendering-options.h" #include "util/units.h" -- cgit v1.2.3 From 9fdd8f25ee0f04d337864c7ec5e3216dae727e3c Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 14 Aug 2014 22:09:10 +0200 Subject: Fix some transformation center regressions, related to the viewbox/units changes (bzr r13512) --- src/ui/dialog/document-properties.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 9141b2268..4e4616724 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -45,6 +45,7 @@ #include "widgets/icon.h" #include "xml/node-event-vector.h" #include "xml/repr.h" +#include // std::min #include "rdf.h" #include "ui/widget/entity-entry.h" @@ -1735,9 +1736,9 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale) - viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); + gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 940176d1a9959328f186cb21c22bf43d4cfed4fc Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 15 Aug 2014 08:43:45 +0200 Subject: Preferences. Fix for Bug #184499 (Inkscape Preferences dialog does not remember tabs/pages). Fixed bugs: - https://launchpad.net/bugs/184499 (bzr r13517) --- src/ui/dialog/inkscape-preferences.cpp | 8 ++++++-- src/ui/dialog/inkscape-preferences.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index f1a29e971..5d065dc60 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -76,7 +76,8 @@ InkscapePreferences::InkscapePreferences() : UI::Widget::Panel ("", "/dialogs/preferences", SP_VERB_DIALOG_DISPLAY), _max_dialog_width(0), _max_dialog_height(0), - _current_page(0) + _current_page(0), + _init(true) { //get the width of a spinbutton Inkscape::UI::Widget::SpinButton* sb = new Inkscape::UI::Widget::SpinButton; @@ -2000,6 +2001,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter) Gtk::TreeModel::Row row = *iter; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int desired_page = prefs->getInt("/dialogs/preferences/page", 0); + _init = false; if (desired_page == row[_page_list_columns._col_id]) { if (desired_page >= PREFS_PAGE_TOOLS && desired_page <= PREFS_PAGE_TOOLS_CONNECTOR) @@ -2049,7 +2051,9 @@ void InkscapePreferences::on_pagelist_selection_changed() Gtk::TreeModel::Row row = *iter; _current_page = row[_page_list_columns._col_page]; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + if (!_init) { + prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + } _page_title.set_markup("" + row[_page_list_columns._col_name] + ""); _page_frame.add(*_current_page); _current_page->show(); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 1c2151605..9f37626ed 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -532,6 +532,7 @@ private: InkscapePreferences(); InkscapePreferences(InkscapePreferences const &d); InkscapePreferences operator=(InkscapePreferences const &d); + bool _init; }; } // namespace Dialog -- cgit v1.2.3 From 2a2db8af11c2e518bd7bfe520e2f88a7e439d939 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Aug 2014 22:47:53 -0400 Subject: Merge in font-speedup branch to improve launch times (bzr r13341.1.140) --- src/ui/dialog/text-edit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index c1ebb32e0..e44809c65 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -344,9 +344,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - // This is done for us by text-toolbar. No need to do it twice. - // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); - // fontlister->selection_update(); + // This is normally done for us by text-toolbar but only when we are in text editing context + fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); -- cgit v1.2.3 From 282a7ce3f988e792545c19854b5f55cff1291cbe Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 13:44:01 -0400 Subject: Fix gtk3 crash when using "close" button Fixed bugs: - https://launchpad.net/bugs/1090936 (bzr r13341.1.143) --- src/ui/dialog/dialog.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 645294bb5..22ba0b6fb 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -317,20 +317,7 @@ void Dialog::_apply() void Dialog::_close() { - GtkWidget *dlg = GTK_WIDGET(_behavior->gobj()); - - GdkEventAny event; - event.type = GDK_DELETE; - event.window = gtk_widget_get_window(dlg); - event.send_event = TRUE; - - if (event.window) - g_object_ref(G_OBJECT(event.window)); - - gtk_main_do_event ((GdkEvent*)&event); - - if (event.window) - g_object_unref(G_OBJECT(event.window)); + _behavior->hide(); } void Dialog::_defocus() -- cgit v1.2.3 From 2a04905eb339f85263babd7d668dd43f072f75b3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 14:13:20 -0400 Subject: Fix accidental regression in previous commit (bzr r13341.1.144) --- src/ui/dialog/dialog.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 22ba0b6fb..f2c63ed8d 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -318,6 +318,7 @@ void Dialog::_apply() void Dialog::_close() { _behavior->hide(); + _onDeleteEvent(NULL); } void Dialog::_defocus() -- cgit v1.2.3 From 62339f48161baf01b49d331b7c31ab9d8fb64ec6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 14:54:39 +0200 Subject: fix Windows 64-bit build (bzr r13341.1.154) --- src/ui/dialog/print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index ed39ebb32..a015d28f9 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -14,13 +14,13 @@ # include #endif +#include + #ifdef WIN32 #include #include #endif -#include - #include "preferences.h" #include "print.h" -- cgit v1.2.3 From e469f1f4eb04e7cc1401c6679a41c217287ae888 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 15:17:43 +0200 Subject: fix Windows 64-bit build (bzr r13531) --- src/ui/dialog/print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index ed39ebb32..a015d28f9 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -14,13 +14,13 @@ # include #endif +#include + #ifdef WIN32 #include #include #endif -#include - #include "preferences.h" #include "print.h" -- cgit v1.2.3 From fd314c7cbec965ec702c3ea80e1e48d41302d687 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 21:30:32 +0100 Subject: Fix deprecated VBox use (bzr r13341.1.165) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- src/ui/dialog/new-from-template.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index a68c7ee08..c1e16495b 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -44,7 +44,7 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { - Gtk::Box *mainVBox = get_vbox(); + Gtk::Box *mainVBox = get_content_area(); mainVBox->set_homogeneous(false); _layout_table.set_spacings(4); _layout_table.resize(2, 2); diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index f326bb3ee..5ce96d10f 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -26,11 +26,11 @@ NewFromTemplate::NewFromTemplate() set_title(_("New From Template")); resize(400, 400); - get_vbox()->pack_start(_main_widget); + get_content_area()->pack_start(_main_widget); Gtk::Alignment *align; align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); - get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); + get_content_area()->pack_end(*align, Gtk::PACK_SHRINK); align->set_padding(0, 0, 0, 15); align->add(_create_template_button); -- cgit v1.2.3 From 6388fa1d00b2731feb0b9eedd03c2751d2efee84 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:35:35 +0100 Subject: Migrate more widgets to Gtk::Grid (bzr r13341.1.169) --- src/ui/dialog/grid-arrange-tab.h | 8 +++++--- src/ui/dialog/polar-arrange-tab.cpp | 32 ++++++++++++++++++++++++++++++++ src/ui/dialog/polar-arrange-tab.h | 19 ++++++++++++++++++- src/ui/widget/anchor-selector.cpp | 16 +++++++++++++++- src/ui/widget/anchor-selector.h | 20 ++++++++++++++++++-- 5 files changed, 88 insertions(+), 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/grid-arrange-tab.h b/src/ui/dialog/grid-arrange-tab.h index 9d6700b39..a137d1694 100644 --- a/src/ui/dialog/grid-arrange-tab.h +++ b/src/ui/dialog/grid-arrange-tab.h @@ -17,14 +17,16 @@ #ifndef INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H #define INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H -#include - +#include "ui/widget/scalar-unit.h" #include "ui/dialog/arrange-tab.h" #include "ui/widget/anchor-selector.h" -#include "ui/widget/scalar-unit.h" #include "ui/widget/spinbutton.h" +#include +#include +#include + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index a00b8fc02..80579c9d3 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -25,6 +25,7 @@ #include "desktop.h" #include "sp-ellipse.h" #include "sp-item-transform.h" +#include namespace Inkscape { namespace UI { @@ -32,7 +33,11 @@ namespace Dialog { PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) : parent(parent_), +#if WITH_GTKMM_3_0 + parametersTable(), +#else parametersTable(3, 3, false), +#endif centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), centerX("", "X coordinate of the center", centerY), radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), @@ -76,7 +81,11 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) pack_start(arrangeOnParametersRadio, false, false); centerLabel.set_text(_("Center X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(centerLabel, 0, 0, 1, 1); +#else parametersTable.attach(centerLabel, 0, 1, 0, 1, Gtk::FILL); +#endif centerX.setDigits(2); centerX.setIncrements(0.2, 0); centerX.setRange(-10000, 10000); @@ -85,11 +94,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) centerY.setIncrements(0.2, 0); centerY.setRange(-10000, 10000); centerY.setValue(0, "px"); +#if WITH_GTKMM_3_0 + parametersTable.attach(centerX, 1, 0, 1, 1); + parametersTable.attach(centerY, 2, 0, 1, 1); +#else parametersTable.attach(centerX, 1, 2, 0, 1, Gtk::FILL); parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); +#endif radiusLabel.set_text(_("Radius X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(radiusLabel, 0, 1, 1, 1); +#else parametersTable.attach(radiusLabel, 0, 1, 1, 2, Gtk::FILL); +#endif radiusX.setDigits(2); radiusX.setIncrements(0.2, 0); radiusX.setRange(0.001, 10000); @@ -98,11 +116,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) radiusY.setIncrements(0.2, 0); radiusY.setRange(0.001, 10000); radiusY.setValue(100, "px"); +#if WITH_GTKMM_3_0 + parametersTable.attach(radiusX, 1, 1, 1, 1); + parametersTable.attach(radiusY, 2, 1, 1, 1); +#else parametersTable.attach(radiusX, 1, 2, 1, 2, Gtk::FILL); parametersTable.attach(radiusY, 2, 3, 1, 2, Gtk::FILL); +#endif angleLabel.set_text(_("Angle X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(angleLabel, 0, 2, 1, 1); +#else parametersTable.attach(angleLabel, 0, 1, 2, 3, Gtk::FILL); +#endif angleX.setDigits(2); angleX.setIncrements(0.2, 0); angleX.setRange(-10000, 10000); @@ -111,8 +138,13 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) angleY.setIncrements(0.2, 0); angleY.setRange(-10000, 10000); angleY.setValue(180, "°"); +#if WITH_GTKMM_3_0 + parametersTable.attach(angleX, 1, 2, 1, 1); + parametersTable.attach(angleY, 2, 2, 1, 1); +#else parametersTable.attach(angleX, 1, 2, 2, 3, Gtk::FILL); parametersTable.attach(angleY, 2, 3, 2, 3, Gtk::FILL); +#endif pack_start(parametersTable, false, false); rotateObjectsCheckBox.set_label(_("Rotate objects")); diff --git a/src/ui/dialog/polar-arrange-tab.h b/src/ui/dialog/polar-arrange-tab.h index f6c3b2906..f7d7bf11f 100644 --- a/src/ui/dialog/polar-arrange-tab.h +++ b/src/ui/dialog/polar-arrange-tab.h @@ -10,9 +10,22 @@ #ifndef INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H #define INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include "ui/widget/scalar-unit.h" #include "ui/widget/anchor-selector.h" #include "ui/dialog/arrange-tab.h" -#include "ui/widget/scalar-unit.h" + +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif namespace Inkscape { namespace UI { @@ -62,7 +75,11 @@ private: Gtk::RadioButton arrangeOnLastCircleRadio; Gtk::RadioButton arrangeOnParametersRadio; +#if WITH_GTKMM_3_0 + Gtk::Grid parametersTable; +#else Gtk::Table parametersTable; +#endif Gtk::Label centerLabel; Inkscape::UI::Widget::ScalarUnit centerY; diff --git a/src/ui/widget/anchor-selector.cpp b/src/ui/widget/anchor-selector.cpp index 82e27ee89..df00b786a 100644 --- a/src/ui/widget/anchor-selector.cpp +++ b/src/ui/widget/anchor-selector.cpp @@ -28,7 +28,11 @@ void AnchorSelector::setupButton(const Glib::ustring& icon, Gtk::ToggleButton& b AnchorSelector::AnchorSelector() : Gtk::Alignment(0.5, 0, 0, 0), +#if WITH_GTKMM_3_0 + _container() +#else _container(3, 3, true) +#endif { setupButton(INKSCAPE_ICON("boundingbox_top_left"), _buttons[0]); setupButton(INKSCAPE_ICON("boundingbox_top"), _buttons[1]); @@ -40,10 +44,20 @@ AnchorSelector::AnchorSelector() setupButton(INKSCAPE_ICON("boundingbox_bottom"), _buttons[7]); setupButton(INKSCAPE_ICON("boundingbox_bottom_right"), _buttons[8]); +#if WITH_GTKMM_3_0 + _container.set_row_homogeneous(); + _container.set_column_homogeneous(true); +#endif + for(int i = 0; i < 9; ++i) { _buttons[i].signal_clicked().connect( sigc::bind(sigc::mem_fun(*this, &AnchorSelector::btn_activated), i)); + +#if WITH_GTKMM_3_0 + _container.attach(_buttons[i], i % 3, i / 3, 1, 1); +#else _container.attach(_buttons[i], i % 3, i % 3+1, i / 3, i / 3+1, Gtk::FILL, Gtk::FILL); +#endif } _selection = 4; _buttons[4].set_active(); @@ -94,4 +108,4 @@ void AnchorSelector::setAlignment(int horizontal, int vertical) fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/anchor-selector.h b/src/ui/widget/anchor-selector.h index 2263438e3..0a702d296 100644 --- a/src/ui/widget/anchor-selector.h +++ b/src/ui/widget/anchor-selector.h @@ -10,7 +10,18 @@ #ifndef ANCHOR_SELECTOR_H_ #define ANCHOR_SELECTOR_H_ -#include +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif namespace Inkscape { namespace UI { @@ -21,7 +32,12 @@ class AnchorSelector : public Gtk::Alignment private: Gtk::ToggleButton _buttons[9]; int _selection; + +#if WITH_GTKMM_3_0 + Gtk::Grid _container; +#else Gtk::Table _container; +#endif sigc::signal _selectionChanged; @@ -56,4 +72,4 @@ public: fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3 From 81ae160f5d204d3841505a6c364c064f77f17f88 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:52:01 +0100 Subject: Finish Gtk::Grid migration (bzr r13341.1.170) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 13 +++++++++++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index c1e16495b..f5a554b36 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -46,18 +46,31 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() { Gtk::Box *mainVBox = get_content_area(); mainVBox->set_homogeneous(false); + +#if WITH_GTKMM_3_0 + _layout_table.set_row_spacing(4); + _layout_table.set_column_spacing(4); +#else _layout_table.set_spacings(4); _layout_table.resize(2, 2); +#endif // Layer name widgets _fillet_chamfer_position_entry.set_activates_default(true); _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); _fillet_chamfer_position_label.set_alignment(1.0, 0.5); +#if WITH_GTKMM_3_0 + _layout_table.attach(_fillet_chamfer_position_label, 0, 0, 1, 1); + _layout_table.attach(_fillet_chamfer_position_entry, 1, 0, 1, 1); + _fillet_chamfer_position_entry.set_hexpand(); +#else _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); +#endif + _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index d3e859bff..6667e5785 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -8,10 +8,24 @@ #ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + #include <2geom/point.h> -#include #include "live_effects/parameter/filletchamferpointarray.h" +#include +#include +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif + class SPDesktop; namespace Inkscape { @@ -46,7 +60,12 @@ protected: Gtk::RadioButton _fillet_chamfer_type_chamfer; Gtk::RadioButton _fillet_chamfer_type_double_chamfer; +#if WITH_GTKMM_3_0 + Gtk::Grid _layout_table; +#else Gtk::Table _layout_table; +#endif + bool _position_visible; double _index; -- cgit v1.2.3 From a3e1d94ae50f769d2b1539307cf182ce5801e647 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 11:37:18 +0100 Subject: Fix Gtk+ 2 build (bzr r13341.1.171) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 5 +++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 2 +- src/ui/dialog/new-from-template.cpp | 15 ++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index f5a554b36..eef32d10d 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -44,7 +44,12 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { +#if WITH_GTKMM_3_0 Gtk::Box *mainVBox = get_content_area(); +#else + Gtk::Box *mainVBox = get_vbox(); +#endif + mainVBox->set_homogeneous(false); #if WITH_GTKMM_3_0 diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 6667e5785..9beca02e1 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -12,10 +12,10 @@ #include "config.h" #endif +#include #include <2geom/point.h> #include "live_effects/parameter/filletchamferpointarray.h" -#include #include #include #include diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index 5ce96d10f..e30b148bb 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -8,6 +8,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#if HAVE_CONFIG_H + #include "config.h" +#endif #include "new-from-template.h" #include "file.h" @@ -25,12 +28,22 @@ NewFromTemplate::NewFromTemplate() { set_title(_("New From Template")); resize(400, 400); - + +#if WITH_GTKMM_3_0 get_content_area()->pack_start(_main_widget); +#else + get_vbox()->pack_start(_main_widget); +#endif Gtk::Alignment *align; align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + +#if WITH_GTKMM_3_0 get_content_area()->pack_end(*align, Gtk::PACK_SHRINK); +#else + get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); +#endif + align->set_padding(0, 0, 0, 15); align->add(_create_template_button); -- cgit v1.2.3 From 8920e3ea655df6447e2ed6f8b0b5621442d20cb5 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 12:31:46 +0100 Subject: Fix strict build with Gtk+ 2 (bzr r13341.1.172) --- src/ui/tools/tool-base.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index c23da87c0..c28b86416 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -18,6 +18,8 @@ # include "config.h" #endif +#include "widgets/desktop-widget.h" + #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif @@ -40,7 +42,6 @@ #include "desktop-handles.h" #include "desktop-events.h" #include "desktop-style.h" -#include "widgets/desktop-widget.h" #include "sp-namedview.h" #include "selection.h" #include "interface.h" -- cgit v1.2.3 From c2a65687bd392c251a320030b0a6a813e093dc9f Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 16:20:54 +0100 Subject: More GObject boilerplate reduction (bzr r13341.1.175) --- src/ui/view/view-widget.cpp | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) (limited to 'src/ui') diff --git a/src/ui/view/view-widget.cpp b/src/ui/view/view-widget.cpp index 5cb0df215..671a4afe6 100644 --- a/src/ui/view/view-widget.cpp +++ b/src/ui/view/view-widget.cpp @@ -15,32 +15,9 @@ //using namespace Inkscape::UI::View; // SPViewWidget - -static void sp_view_widget_class_init(SPViewWidgetClass *vwc); -static void sp_view_widget_init(SPViewWidget *widget); static void sp_view_widget_dispose(GObject *object); -static GtkEventBoxClass *widget_parent_class; - -GType sp_view_widget_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPViewWidgetClass), - NULL, NULL, - (GClassInitFunc) sp_view_widget_class_init, - NULL, NULL, - sizeof(SPViewWidget), - 0, - (GInstanceInitFunc) sp_view_widget_init, - NULL - }; - type = g_type_register_static (GTK_TYPE_EVENT_BOX, "SPViewWidget", &info, (GTypeFlags)0); - } - - return type; -} +G_DEFINE_TYPE(SPViewWidget, sp_view_widget, GTK_TYPE_EVENT_BOX); /** * Callback to initialize the SPViewWidget vtable. @@ -48,8 +25,6 @@ GType sp_view_widget_get_type(void) static void sp_view_widget_class_init(SPViewWidgetClass *vwc) { GObjectClass *object_class = G_OBJECT_CLASS(vwc); - - widget_parent_class = (GtkEventBoxClass*) g_type_class_peek_parent(vwc); object_class->dispose = sp_view_widget_dispose; } @@ -77,8 +52,8 @@ static void sp_view_widget_dispose(GObject *object) vw->view = NULL; } - if (((GObjectClass *) (widget_parent_class))->dispose) { - (* ((GObjectClass *) (widget_parent_class))->dispose)(object); + if (G_OBJECT_CLASS(sp_view_widget_parent_class)->dispose) { + G_OBJECT_CLASS(sp_view_widget_parent_class)->dispose(object); } Inkscape::GC::request_early_collection(); -- cgit v1.2.3 From be6f51a507f0fddb403255adb8b25002ae10f154 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 25 Aug 2014 17:34:11 +0200 Subject: fix bug coninuing existing paths whith no LPE in bspline/spiro modes (bzr r13341.1.176) --- src/ui/tools/freehand-base.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index aad924844..72250a550 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -610,13 +610,13 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if (dc->sa) { SPCurve *s = dc->sa->curve; dc->white_curves = g_slist_remove(dc->white_curves, s); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - s = dc->overwriteCurve; - } if (dc->sa->start) { s = reverse_then_unref(s); } + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + dc->overwriteCurve = s; + } s->append_continuous(c, 0.0625); c->unref(); c = s; -- cgit v1.2.3 From 4a6dfa29131adb8c7470ab66a839d144b02542e5 Mon Sep 17 00:00:00 2001 From: su_v Date: Tue, 26 Aug 2014 10:41:57 +0200 Subject: librevenge: update to latest patch from bug #1323592 (support old and new versions of libwpg, libcdr and libvisio ) (bzr r13398.1.7) --- src/ui/dialog/symbols.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 27e40f552..a9cf8d068 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -62,8 +62,20 @@ #include "widgets/icon.h" #ifdef WITH_LIBVISIO -#include -#include + #include + + // TODO: Drop this check when librevenge is widespread. + #if WITH_LIBVISIO01 + #include + + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; + #else + #include + + typedef WPXFileStream RVNGFileStream; + typedef libvisio::VSDStringVector RVNGStringVector; + #endif #endif #include "verbs.h" @@ -495,16 +507,20 @@ void SymbolsDialog::iconChanged() { // Read Visio stencil files SPDocument* read_vss( gchar* fullname, gchar* filename ) { - librevenge::RVNGFileStream input(fullname); + RVNGFileStream input(fullname); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - librevenge::RVNGStringVector output; + RVNGStringVector output; +#if WITH_LIBVISIO01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libvisio::VisioDocument::parseStencils(&input, &generator)) { +#else + if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) { +#endif return NULL; } -- cgit v1.2.3 From 2d1275f0337e3fe49ea493f58135c81d0e3af36d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 11:55:28 +0100 Subject: Standardise InkscapeApplication GObject implementation (namespace not supported properly) (bzr r13341.1.179) --- src/ui/dialog/align-and-distribute.cpp | 4 ++-- src/ui/dialog/clonetiler.cpp | 4 ++-- src/ui/dialog/clonetiler.h | 4 ++-- src/ui/dialog/desktop-tracker.cpp | 2 +- src/ui/dialog/desktop-tracker.h | 5 ++--- src/ui/dialog/dialog-manager.cpp | 4 ++-- src/ui/dialog/dialog.cpp | 2 +- src/ui/dialog/dialog.h | 4 ++-- src/ui/dialog/document-metadata.cpp | 4 ++-- src/ui/dialog/document-metadata.h | 4 ++-- src/ui/dialog/document-properties.cpp | 4 ++-- src/ui/dialog/document-properties.h | 4 ++-- src/ui/dialog/fill-and-stroke.h | 2 +- src/ui/dialog/grid-arrange-tab.cpp | 2 +- src/ui/dialog/panel-dialog.h | 12 ++++++------ src/ui/dialog/transformation.cpp | 4 ++-- src/ui/widget/object-composite-settings.cpp | 4 ++-- src/ui/widget/object-composite-settings.h | 6 +++--- src/ui/widget/panel.cpp | 4 ++-- src/ui/widget/panel.h | 12 ++++++------ 20 files changed, 45 insertions(+), 46 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index e02ccd3f1..8352de1e3 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -829,14 +829,14 @@ private : -static void on_tool_changed(Inkscape::Application */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) +static void on_tool_changed(InkscapeApplication */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop && desktop->getEventContext()) daad->setMode(tools_active(desktop) == TOOLS_NODES); } -static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) +static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) { daad->randomize_bbox = Geom::OptRect(); } diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index e5f18216c..d9e2c03ba 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1349,7 +1349,7 @@ void CloneTiler::on_picker_color_changed(guint rgba) is_updating = false; } -void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) { GtkWidget *buttons = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles")); GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status")); @@ -1378,7 +1378,7 @@ void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape* } } -void CloneTiler::clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg) +void CloneTiler::clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg) { clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); } diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index e2a0240ee..9bacc701d 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -58,8 +58,8 @@ protected: static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/); static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg); static void clonetiler_unclump(GtkWidget */*widget*/, void *); - static void clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); - static void clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg); + static void clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); + static void clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg); static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source); static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg); static guint clonetiler_number_of_clones(SPObject *obj); diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp index 8a359dd2d..3ed998252 100644 --- a/src/ui/dialog/desktop-tracker.cpp +++ b/src/ui/dialog/desktop-tracker.cpp @@ -94,7 +94,7 @@ sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slottrackActive) { self->setDesktop(desktop); diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index 7da55cf2f..7b944ddfa 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -12,11 +12,10 @@ typedef struct _GtkWidget GtkWidget; class SPDesktop; +struct InkscapeApplication; namespace Inkscape { -struct Application; - namespace UI { namespace Dialog { @@ -37,7 +36,7 @@ public: sigc::connection connectDesktopChanged( const sigc::slot & slot ); private: - static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, DesktopTracker *self ); + static gboolean activateDesktopCB(InkscapeApplication *inkscape, SPDesktop *desktop, DesktopTracker *self ); static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self); void handleHierarchyChange(); diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 7e69e439a..0da638546 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -70,13 +70,13 @@ inline Dialog *create() { return PanelDialog::template create(); } /** * This class is provided as a container for Inkscape's various - * dialogs. This allows Inkscape::Application to treat the various + * dialogs. This allows InkscapeApplication to treat the various * dialogs it invokes, as abstractions. * * DialogManager is essentially a cache of dialogs. It lets us * initialize dialogs lazily - instead of constructing them during * application startup, they're constructed the first time they're - * actually invoked by Inkscape::Application. The constructed + * actually invoked by InkscapeApplication. The constructed * dialog is held here after that, so future invokations of the * dialog don't need to get re-constructed each time. The memory for * the dialogs are then reclaimed when the DialogManager is destroyed. diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index f2c63ed8d..4f0d9fbe1 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -41,7 +41,7 @@ namespace Inkscape { namespace UI { namespace Dialog { -void sp_retransientize(Inkscape::Application */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) +void sp_retransientize(InkscapeApplication */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) { Dialog *dlg = static_cast(dlgPtr); dlg->onDesktopActivated (desktop); diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h index ec5d203bc..ccff43a56 100644 --- a/src/ui/dialog/dialog.h +++ b/src/ui/dialog/dialog.h @@ -18,10 +18,10 @@ #include "floating-behavior.h" class SPDesktop; +struct InkscapeApplication; namespace Inkscape { class Selection; -struct Application; } namespace Inkscape { @@ -30,7 +30,7 @@ namespace Dialog { enum BehaviorType { FLOATING, DOCK }; -void sp_retransientize(Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr); +void sp_retransientize(InkscapeApplication *inkscape, SPDesktop *desktop, gpointer dlgPtr); gboolean sp_retransientize_again(gpointer dlgPtr); void sp_dialog_shutdown(GObject *object, gpointer dlgPtr); diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index 09c505860..77ea175d9 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -223,7 +223,7 @@ DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) } void -DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) +DocumentMetadata::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); @@ -231,7 +231,7 @@ DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *des } void -DocumentMetadata::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) +DocumentMetadata::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index 3b7ed1ec8..77084bc3d 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -56,8 +56,8 @@ protected: void init(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); - void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop); + void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); Gtk::Notebook _notebook; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 4e4616724..5ad82644e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1594,7 +1594,7 @@ void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument update(); } -void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) +void DocumentProperties::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); @@ -1603,7 +1603,7 @@ void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDeskt update(); } -void DocumentProperties::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) +void DocumentProperties::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index 495f3177d..ee7e88b18 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -94,8 +94,8 @@ protected: void save_default_metadata(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); - void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop); + void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer; Gtk::Notebook _notebook; diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 340cb860f..35c98ef9c 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -41,7 +41,7 @@ public: virtual void setDesktop(SPDesktop *desktop); - void selectionChanged(Inkscape::Application *inkscape, + void selectionChanged(InkscapeApplication *inkscape, Inkscape::Selection *selection); void showPageFill(); diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 72217c729..1417b39fa 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -572,7 +572,7 @@ void GridArrangeTab::updateSelection() ## Experimental ##########################*/ -static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) +static void updateSelectionCallback(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) { dlg->updateSelection(); } diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h index 1fefd811e..b4a355083 100644 --- a/src/ui/dialog/panel-dialog.h +++ b/src/ui/dialog/panel-dialog.h @@ -49,19 +49,19 @@ public: virtual UI::Widget::Panel &getPanel() { return _panel; } protected: - static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { + static void handle_deactivate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { g_return_if_fail(data != NULL); static_cast(data)->_propagateDesktopDeactivated(application, desktop); } - static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { + static void _handle_activate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { g_return_if_fail(data != NULL); static_cast(data)->_propagateDesktopActivated(application, desktop); } inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); - inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *); - inline virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *); + inline virtual void _propagateDesktopActivated(InkscapeApplication *, SPDesktop *); + inline virtual void _propagateDesktopDeactivated(InkscapeApplication *, SPDesktop *); UI::Widget::Panel &_panel; sigc::connection _document_replaced_connection; @@ -134,14 +134,14 @@ void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument _panel.signalDocumentReplaced().emit(desktop, document); } -void PanelDialogBase::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopActivated(InkscapeApplication *application, SPDesktop *desktop) { _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced)); _panel.signalActivateDesktop().emit(application, desktop); } -void PanelDialogBase::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopDeactivated(InkscapeApplication *application, SPDesktop *desktop) { _document_replaced_connection.disconnect(); _panel.signalDeactiveDesktop().emit(application, desktop); diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index a7f0b068e..3e135b9b2 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -47,13 +47,13 @@ namespace Inkscape { namespace UI { namespace Dialog { -static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) +static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); } -static void on_selection_modified( Inkscape::Application */*inkscape*/, +static void on_selection_modified( InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, guint /*flags*/, Transformation *daad ) diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index 537db0fdd..e4cd76345 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -40,7 +40,7 @@ namespace UI { namespace Widget { /*void ObjectCompositeSettings::_on_desktop_activate( - Inkscape::Application *application, + InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w ) { @@ -50,7 +50,7 @@ namespace Widget { } void ObjectCompositeSettings::_on_desktop_deactivate( - Inkscape::Application *application, + InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w ) { diff --git a/src/ui/widget/object-composite-settings.h b/src/ui/widget/object-composite-settings.h index 19a6cb2a5..e375bf24a 100644 --- a/src/ui/widget/object-composite-settings.h +++ b/src/ui/widget/object-composite-settings.h @@ -30,9 +30,9 @@ #include "ui/widget/spinbutton.h" class SPDesktop; +struct InkscapeApplication; namespace Inkscape { -struct Application; namespace UI { namespace Widget { @@ -66,8 +66,8 @@ private: gulong _desktop_activated; sigc::connection _subject_changed; - static void _on_desktop_activate(Inkscape::Application *application, SPDesktop *desktop, ObjectCompositeSettings *w); - static void _on_desktop_deactivate(Inkscape::Application *application, SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_activate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_deactivate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); void _subjectChanged(); void _blendBlurValueChanged(); void _opacityValueChanged(); diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp index b37137228..0abd81b16 100644 --- a/src/ui/widget/panel.cpp +++ b/src/ui/widget/panel.cpp @@ -643,13 +643,13 @@ Panel::signalDocumentReplaced() return _signal_document_replaced; } -sigc::signal & +sigc::signal & Panel::signalActivateDesktop() { return _signal_activate_desktop; } -sigc::signal & +sigc::signal & Panel::signalDeactiveDesktop() { return _signal_deactive_desktop; diff --git a/src/ui/widget/panel.h b/src/ui/widget/panel.h index 0c3d822b8..177314797 100644 --- a/src/ui/widget/panel.h +++ b/src/ui/widget/panel.h @@ -45,9 +45,9 @@ namespace Gtk { class MenuItem; } -namespace Inkscape { +struct InkscapeApplication; -struct Application; +namespace Inkscape { class Selection; namespace UI { @@ -116,8 +116,8 @@ public: void setResponseSensitive(int response_id, bool setting); virtual sigc::signal &signalDocumentReplaced(); - virtual sigc::signal &signalActivateDesktop(); - virtual sigc::signal &signalDeactiveDesktop(); + virtual sigc::signal &signalActivateDesktop(); + virtual sigc::signal &signalDeactiveDesktop(); protected: /** @@ -147,8 +147,8 @@ protected: sigc::signal _signal_response; sigc::signal _signal_present; sigc::signal _signal_document_replaced; - sigc::signal _signal_activate_desktop; - sigc::signal _signal_deactive_desktop; + sigc::signal _signal_activate_desktop; + sigc::signal _signal_deactive_desktop; private: void _init(); -- cgit v1.2.3 From 7fd8ede6c698136bfa675dd4f1d5da6f5803154f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Tue, 26 Aug 2014 22:38:14 +0200 Subject: Fix rotation center regression caused by my own commit 13512 Fixed bugs: - https://launchpad.net/bugs/1360953 - https://launchpad.net/bugs/1360946 (bzr r13534) --- src/ui/dialog/document-properties.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 4e4616724..2757a0ec9 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1736,9 +1736,13 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = doc->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = doc->getWidth().value("px") / vb.width(); + gdouble viewscale_h = doc->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 65e028240540fafc4269bd43e66cdeaf41408b12 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sat, 30 Aug 2014 08:24:40 +0200 Subject: Translators list update (bzr r13536) --- src/ui/dialog/aboutbox.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index a66855b2a..7cd069132 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -482,6 +482,7 @@ void AboutBox::initStrings() { "Elias Norberg , 2009.\n" "Equipe de Tradução Inkscape Brasil , 2007.\n" "Fatih Demir , 2000.\n" +"Firas Hanife , 2014.\n" "Foppe Benedictus , 2007-2009.\n" "Francesc Dorca , 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador , 2003.\n" @@ -493,8 +494,9 @@ void AboutBox::initStrings() { "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" "Ivan Masár , 2006-2010. \n" +"Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" -"Jānis Eisaks , 2012, 2013.\n" +"Jānis Eisaks , 2012-2014.\n" "Jeffrey Steve Borbón Sanabria , 2005.\n" "Jesper Öqvist , 2010, 2011.\n" "Joaquim Perez i Noguer , 2008-2009.\n" @@ -516,7 +518,7 @@ void AboutBox::initStrings() { "Kingsley Turner , 2006.\n" "Kitae , 2006.\n" "Kjartan Maraas , 2000-2002.\n" -"Kris De Gussem , 2008-2013.\n" +"Kris De Gussem , 2008-2014.\n" "Lauris Kaplinski , 2000.\n" "Leandro Regueiro , 2006-2008, 2010.\n" "Liu Xiaoqin , 2008.\n" @@ -536,7 +538,7 @@ void AboutBox::initStrings() { "Muhammad Bashir Al-Noimi , 2008.\n" "Myckel Habets , 2008.\n" "Nguyen Dinh Trung , 2007, 2008.\n" -"Nicolas Dufour , 2008-2013.\n" +"Nicolas Dufour , 2008-2014.\n" "Pawan Chitrakar , 2006.\n" "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" -- cgit v1.2.3 From 9066e62e9f0cb4972f3b7988004393e96e55e09d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 30 Aug 2014 12:00:43 +0100 Subject: Fix modelines (bzr r13341.1.183) --- src/ui/dialog/aboutbox.cpp | 6 +++--- src/ui/dialog/aboutbox.h | 6 +++--- src/ui/dialog/inkscape-preferences.h | 4 ++-- src/ui/widget/button.cpp | 6 +++--- src/ui/widget/button.h | 6 +++--- src/ui/widget/entity-entry.cpp | 4 ++-- src/ui/widget/entity-entry.h | 4 ++-- src/ui/widget/licensor.cpp | 4 ++-- src/ui/widget/licensor.h | 4 ++-- src/ui/widget/notebook-page.cpp | 6 +++--- src/ui/widget/notebook-page.h | 6 +++--- src/ui/widget/page-sizer.cpp | 4 ++-- src/ui/widget/page-sizer.h | 4 ++-- src/ui/widget/preferences-widget.h | 4 ++-- src/ui/widget/registered-widget.cpp | 4 ++-- src/ui/widget/registered-widget.h | 4 ++-- src/ui/widget/registry.cpp | 4 ++-- src/ui/widget/registry.h | 4 ++-- src/ui/widget/rotateable.cpp | 6 +++--- src/ui/widget/rotateable.h | 4 ++-- src/ui/widget/selected-style.cpp | 4 ++-- src/ui/widget/selected-style.h | 6 +++--- src/ui/widget/spin-scale.cpp | 6 +++--- src/ui/widget/spin-scale.h | 6 +++--- src/ui/widget/spin-slider.cpp | 6 +++--- src/ui/widget/spin-slider.h | 6 +++--- src/ui/widget/spinbutton.cpp | 6 +++--- src/ui/widget/spinbutton.h | 6 +++--- src/ui/widget/style-swatch.cpp | 4 ++-- src/ui/widget/style-swatch.h | 6 +++--- src/ui/widget/tolerance-slider.cpp | 4 ++-- src/ui/widget/tolerance-slider.h | 4 ++-- src/ui/widget/unit-menu.cpp | 6 +++--- src/ui/widget/unit-menu.h | 4 ++-- 34 files changed, 84 insertions(+), 84 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index a66855b2a..44ed3b58f 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -941,13 +941,13 @@ void AboutBox::initStrings() { } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/aboutbox.h b/src/ui/dialog/aboutbox.h index 7b3308672..015e344a1 100644 --- a/src/ui/dialog/aboutbox.h +++ b/src/ui/dialog/aboutbox.h @@ -55,13 +55,13 @@ private: #endif // INKSCAPE_UI_DIALOG_ABOUTBOX_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 9f37626ed..dcea91741 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -545,9 +545,9 @@ private: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/button.cpp b/src/ui/widget/button.cpp index bac866920..6c2d419cf 100644 --- a/src/ui/widget/button.cpp +++ b/src/ui/widget/button.cpp @@ -51,13 +51,13 @@ RadioButton::RadioButton(Glib::ustring const &label, Glib::ustring const &toolti } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/button.h b/src/ui/widget/button.h index a214dd881..471b7d8a2 100644 --- a/src/ui/widget/button.h +++ b/src/ui/widget/button.h @@ -67,13 +67,13 @@ public: #endif // INKSCAPE_UI_WIDGET_BUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/entity-entry.cpp b/src/ui/widget/entity-entry.cpp index 0f526f77a..c7d5efe29 100644 --- a/src/ui/widget/entity-entry.cpp +++ b/src/ui/widget/entity-entry.cpp @@ -206,9 +206,9 @@ EntityMultiLineEntry::on_changed() Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/entity-entry.h b/src/ui/widget/entity-entry.h index 09289496d..35f6ecfb4 100644 --- a/src/ui/widget/entity-entry.h +++ b/src/ui/widget/entity-entry.h @@ -76,9 +76,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/licensor.cpp b/src/ui/widget/licensor.cpp index 42f352e3c..7429bb07e 100644 --- a/src/ui/widget/licensor.cpp +++ b/src/ui/widget/licensor.cpp @@ -160,9 +160,9 @@ void Licensor::update (SPDocument *doc) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/licensor.h b/src/ui/widget/licensor.h index 0ac3e5ab8..c75c5fe9e 100644 --- a/src/ui/widget/licensor.h +++ b/src/ui/widget/licensor.h @@ -56,9 +56,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/notebook-page.cpp b/src/ui/widget/notebook-page.cpp index 6653499b8..2f03ed23b 100644 --- a/src/ui/widget/notebook-page.cpp +++ b/src/ui/widget/notebook-page.cpp @@ -44,13 +44,13 @@ NotebookPage::NotebookPage(int n_rows, int n_columns, bool expand, bool fill, gu } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/notebook-page.h b/src/ui/widget/notebook-page.h index 38ae9e054..4f7915423 100644 --- a/src/ui/widget/notebook-page.h +++ b/src/ui/widget/notebook-page.h @@ -67,13 +67,13 @@ protected: #endif // INKSCAPE_UI_WIDGET_NOTEBOOK_PAGE_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index eae0d4a95..89b0b8f7e 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -728,9 +728,9 @@ PageSizer::on_units_changed() Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h index dc8e34d82..f4bcae4b6 100644 --- a/src/ui/widget/page-sizer.h +++ b/src/ui/widget/page-sizer.h @@ -277,9 +277,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index cb4ce17d1..5d9816e74 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -306,9 +306,9 @@ public: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 8a81b1c02..44d8dcbf3 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -788,9 +788,9 @@ RegisteredRandom::on_value_changed() Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index d8c0e6602..1f505a3cd 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -419,9 +419,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registry.cpp b/src/ui/widget/registry.cpp index 725e52791..ea8198422 100644 --- a/src/ui/widget/registry.cpp +++ b/src/ui/widget/registry.cpp @@ -48,9 +48,9 @@ Registry::setUpdating (bool upd) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registry.h b/src/ui/widget/registry.h index 2da29735c..a236b96ad 100644 --- a/src/ui/widget/registry.h +++ b/src/ui/widget/registry.h @@ -39,9 +39,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp index 72ec69362..2d7597d7c 100644 --- a/src/ui/widget/rotateable.cpp +++ b/src/ui/widget/rotateable.cpp @@ -173,13 +173,13 @@ Rotateable::~Rotateable() { } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/rotateable.h b/src/ui/widget/rotateable.h index 52fb5306c..6404c3550 100644 --- a/src/ui/widget/rotateable.h +++ b/src/ui/widget/rotateable.h @@ -62,9 +62,9 @@ private: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 85538c8c7..a0a163286 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -1571,9 +1571,9 @@ Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index df0f41507..0b6a14762 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -301,13 +301,13 @@ protected: #endif // INKSCAPE_UI_WIDGET_BUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-scale.cpp b/src/ui/widget/spin-scale.cpp index ade3d1e60..bb08d67df 100644 --- a/src/ui/widget/spin-scale.cpp +++ b/src/ui/widget/spin-scale.cpp @@ -235,13 +235,13 @@ void DualSpinScale::update_linked() } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-scale.h b/src/ui/widget/spin-scale.h index 5fec8b1d8..d0447e4a6 100644 --- a/src/ui/widget/spin-scale.h +++ b/src/ui/widget/spin-scale.h @@ -113,13 +113,13 @@ private: #endif // INKSCAPE_UI_WIDGET_SPIN_SCALE_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp index 1cb59a7b3..9b361ae78 100644 --- a/src/ui/widget/spin-slider.cpp +++ b/src/ui/widget/spin-slider.cpp @@ -262,13 +262,13 @@ void DualSpinSlider::update_linked() } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-slider.h b/src/ui/widget/spin-slider.h index 5f86fd15a..74982ea58 100644 --- a/src/ui/widget/spin-slider.h +++ b/src/ui/widget/spin-slider.h @@ -111,13 +111,13 @@ private: #endif // INKSCAPE_UI_WIDGET_SPIN_SLIDER_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp index 7709a837b..d7669d4e5 100644 --- a/src/ui/widget/spinbutton.cpp +++ b/src/ui/widget/spinbutton.cpp @@ -100,13 +100,13 @@ void SpinButton::undo() } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spinbutton.h b/src/ui/widget/spinbutton.h index 812b5f515..cbe33e8ea 100644 --- a/src/ui/widget/spinbutton.h +++ b/src/ui/widget/spinbutton.h @@ -111,13 +111,13 @@ private: #endif // INKSCAPE_UI_WIDGET_SPINBUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 98f4e47cd..157fd2ad9 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -386,9 +386,9 @@ void StyleSwatch::setStyle(SPStyle *query) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index 557ca82e2..582d2ebb3 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -108,13 +108,13 @@ friend class ToolObserver; #endif // INKSCAPE_UI_WIDGET_BUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index 5fc588fdc..aac7451f4 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -216,9 +216,9 @@ void ToleranceSlider::update (double val) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/tolerance-slider.h b/src/ui/widget/tolerance-slider.h index 2184cd52b..7ae8e4712 100644 --- a/src/ui/widget/tolerance-slider.h +++ b/src/ui/widget/tolerance-slider.h @@ -88,9 +88,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/unit-menu.cpp b/src/ui/widget/unit-menu.cpp index 7416a2f02..423313a1f 100644 --- a/src/ui/widget/unit-menu.cpp +++ b/src/ui/widget/unit-menu.cpp @@ -140,13 +140,13 @@ bool UnitMenu::isRadial() const } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/unit-menu.h b/src/ui/widget/unit-menu.h index 114c536c9..2fd25a6a9 100644 --- a/src/ui/widget/unit-menu.h +++ b/src/ui/widget/unit-menu.h @@ -141,9 +141,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 977857ef75a45ed1ec79cfdcf0f25dd66d4a7e86 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 30 Aug 2014 14:00:28 +0100 Subject: Reduce header bloat (bzr r13341.1.184) --- src/ui/dialog/clonetiler.h | 1 - src/ui/dialog/export.h | 9 --------- src/ui/dialog/filedialogimpl-gtkmm.cpp | 1 + src/ui/tools/flood-tool.h | 4 +--- src/ui/tools/select-tool.h | 1 - src/ui/tools/spiral-tool.h | 8 +++----- src/ui/tools/text-tool.h | 7 +++---- src/ui/widget/unit-tracker.h | 7 +++++-- 8 files changed, 13 insertions(+), 25 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index 9bacc701d..70da86338 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -11,7 +11,6 @@ #define __SP_CLONE_TILER_H__ #include "ui/widget/panel.h" -#include #include "ui/dialog/desktop-tracker.h" #include "ui/widget/color-picker.h" diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 6f3c0dfac..23af0109b 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -12,20 +12,11 @@ #ifndef SP_EXPORT_H #define SP_EXPORT_H -#include -#include - -#include -#include -#include #include -#include -#include "desktop.h" #include "ui/dialog/desktop-tracker.h" #include "ui/widget/panel.h" #include "ui/widget/button.h" -#include "ui/widget/entry.h" namespace Gtk { class Dialog; diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 8ba3ad684..575519848 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -40,6 +40,7 @@ #include #include +#include "document.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" diff --git a/src/ui/tools/flood-tool.h b/src/ui/tools/flood-tool.h index 3ed670e8b..5104a42e9 100644 --- a/src/ui/tools/flood-tool.h +++ b/src/ui/tools/flood-tool.h @@ -11,9 +11,7 @@ * Released under GNU GPL */ -#include -#include -#include +#include #include "ui/tools/tool-base.h" #define SP_FLOOD_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) diff --git a/src/ui/tools/select-tool.h b/src/ui/tools/select-tool.h index edc4069a2..5af99a56a 100644 --- a/src/ui/tools/select-tool.h +++ b/src/ui/tools/select-tool.h @@ -13,7 +13,6 @@ */ #include "ui/tools/tool-base.h" -#include #define SP_SELECT_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_SELECT_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) diff --git a/src/ui/tools/spiral-tool.h b/src/ui/tools/spiral-tool.h index 416aeb7e4..add92342d 100644 --- a/src/ui/tools/spiral-tool.h +++ b/src/ui/tools/spiral-tool.h @@ -15,17 +15,15 @@ * Released under GNU GPL */ -#include -#include -#include +#include #include <2geom/point.h> #include "ui/tools/tool-base.h" -#include "sp-spiral.h" - #define SP_SPIRAL_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_SPIRAL_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) +class SPSpiral; + namespace Inkscape { namespace UI { namespace Tools { diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h index ca2b3d19a..289ee180d 100644 --- a/src/ui/tools/text-tool.h +++ b/src/ui/tools/text-tool.h @@ -14,10 +14,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -/* #include */ -#include -#include -#include +#include #include "ui/tools/tool-base.h" #include <2geom/point.h> @@ -26,6 +23,8 @@ #define SP_TEXT_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_TEXT_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) +typedef struct _GtkIMContext GtkIMContext; + struct SPCtrlLine; namespace Inkscape { diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h index 61bb556ef..06245930e 100644 --- a/src/ui/widget/unit-tracker.h +++ b/src/ui/widget/unit-tracker.h @@ -16,13 +16,16 @@ #define INKSCAPE_UI_WIDGET_UNIT_TRACKER_H #include -#include - #include "util/units.h" using Inkscape::Util::Unit; using Inkscape::Util::UnitType; +typedef struct _GObject GObject; +typedef struct _GtkAction GtkAction; +typedef struct _GtkAdjustment GtkAdjustment; +typedef struct _GtkListStore GtkListStore; + namespace Inkscape { namespace UI { namespace Widget { -- cgit v1.2.3 From 8dfc079b2537894d03f3b43a2e1d05b0d576dd7b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 31 Aug 2014 17:19:39 -0400 Subject: Fix for bug #1363497 (strange crash with knot path effect) Fixed bugs: - https://launchpad.net/bugs/1363497 (bzr r13537) --- src/ui/tools/node-tool.cpp | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 0778e3f3f..4be547506 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -298,27 +298,23 @@ void NodeTool::update_helperpath () { if (SP_IS_LPE_ITEM(selection->singleItem())) { Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { - if (lpe) { - SPCurve *c = new SPCurve(); - SPCurve *cc = new SPCurve(); - std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); - for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { - cc->set_pathvector(*p); - c->append(cc, false); - cc->reset(); - } - if (!c->is_empty()) { - c->transform(selection->singleItem()->i2dt_affine()); - SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), - 0x0000ff9A, 1.0, - SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); - this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); - } - c->unref(); - cc->unref(); - } + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), 0x0000ff9A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + sp_canvas_item_affine_absolute(helperpath, selection->singleItem()->i2dt_affine()); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath, 0); + } + c->unref(); + cc->unref(); } } } -- cgit v1.2.3 From 3380db70b04c1a5df6c0ad2ffef56d3c469f8614 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Mon, 1 Sep 2014 21:36:17 -0400 Subject: Updated about box authors list from AUTHORS file. (bzr r13539) --- src/ui/dialog/aboutbox.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 7cd069132..f3cffa244 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -254,6 +254,7 @@ void AboutBox::initStrings() { "Nicholas Bishop\n" "Joshua L. Blocher\n" "Hanno Böck\n" +"Tomasz Boczkowski\n" "Henrik Bohre\n" "Boldewyn\n" "Daniel Borgmann\n" @@ -270,6 +271,7 @@ void AboutBox::initStrings() { "Gail Carmichael\n" "Ed Catmur\n" "Chema Celorio\n" +"Jabiertxo Arraiza Cenoz\n" "Johan Ceuppens\n" "Zbigniew Chyla\n" "Alexander Clausen\n" @@ -311,6 +313,7 @@ void AboutBox::initStrings() { "Hannes Hochreiner\n" "Thomas Holder\n" "Joel Holdsworth\n" +"Christoffer Holmstedt\n" "Alan Horkan\n" "Karl Ove Hufthammer\n" "Richard Hughes\n" @@ -319,6 +322,7 @@ void AboutBox::initStrings() { "Thomas Ingham\n" "Jean-Olivier Irisson\n" "Bob Jamison\n" +"Ted Janeczko\n" "jEsuSdA\n" "Fernando Lucchesi Bastos Jurema\n" "Lauris Kaplinski\n" @@ -342,7 +346,9 @@ void AboutBox::initStrings() { "Aurel-Aimé Marmion\n" "Colin Marquardt\n" "Craig Marshall\n" +"Ivan Masár\n" "Dmitry G. Mastrukov\n" +"David Mathog\n" "Matiphas\n" "Michael Meeks\n" "Federico Mena\n" @@ -360,8 +366,10 @@ void AboutBox::initStrings() { "Nick\n" "Andreas Nilsson\n" "Mitsuru Oka\n" +"Vinícius dos Santos Oliveira\n" "Martin Owens\n" "Alvin Penner\n" +"Matthew Petroff\n" "Jon Phillips\n" "Zdenko Podobny\n" "Alexandre Prokoudine\n" @@ -398,6 +406,8 @@ void AboutBox::initStrings() { "Joakim Verona\n" "Lucas Vieites\n" "Daniel Wagenaar\n" +"Liam P. White\n" +"Sebastian Wüst\n" "Michael Wybrow\n" "Gellule Xg\n" "Daniel Yacob\n" -- cgit v1.2.3 From f92e6ec4025b82d140a65a949741e10d2380c5d6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 2 Sep 2014 16:37:58 -0400 Subject: Fix locale issue in powerstroke width selection (bzr r13542) --- src/ui/tools/freehand-base.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index a90a23a3e..37a170bc9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -247,8 +247,9 @@ static void spdc_apply_powerstroke_shape(const std::vector & points sp_style_unref(style); } - char * width_str = new char[50]; - sprintf(width_str, "0,%f", stroke_width / 2.); + std::ostringstream s; + s.imbue(std::locale::classic()); + s << "0," << stroke_width / 2.; // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); @@ -257,9 +258,7 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("sort_points", "true"); lpe->getRepr()->setAttribute("interpolator_type", "CubicBezierJohan"); lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); - lpe->getRepr()->setAttribute("offset_points", width_str); - - delete [] width_str; + lpe->getRepr()->setAttribute("offset_points", s.str().c_str()); } static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) -- cgit v1.2.3 From 395b34493e806b4aa2333c694d7d6e4e4d4700a4 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 2 Sep 2014 17:14:55 -0400 Subject: Remove misleading dialogs directory (bzr r13341.1.192) --- src/ui/CMakeLists.txt | 2 + src/ui/Makefile_insert | 2 + src/ui/dialog-events.cpp | 255 +++++++++++++++++++++++++++++++++ src/ui/dialog-events.h | 76 ++++++++++ src/ui/dialog/dock-behavior.cpp | 2 +- src/ui/dialog/export.cpp | 2 +- src/ui/dialog/filedialog.cpp | 2 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/filedialogimpl-win32.cpp | 2 +- src/ui/dialog/find.cpp | 2 +- src/ui/dialog/floating-behavior.cpp | 2 +- src/ui/dialog/font-substitution.cpp | 2 +- src/ui/dialog/guides.cpp | 2 +- src/ui/dialog/ocaldialogs.cpp | 2 +- src/ui/dialog/ocaldialogs.h | 3 +- src/ui/dialog/xml-tree.cpp | 2 +- src/ui/widget/color-picker.cpp | 2 +- 17 files changed, 348 insertions(+), 14 deletions(-) create mode 100644 src/ui/dialog-events.cpp create mode 100644 src/ui/dialog-events.h (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 125755c48..56908f58e 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -2,6 +2,7 @@ set(ui_SRC clipboard.cpp control-manager.cpp + dialog-events.cpp previewholder.cpp uxmanager.cpp @@ -156,6 +157,7 @@ set(ui_SRC clipboard.h control-manager.h control-types.h + dialog-events.h icon-names.h previewable.h previewfillable.h diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index 4081f86f8..94064d0cf 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -6,6 +6,8 @@ ink_common_sources += \ ui/control-manager.cpp \ ui/control-manager.h \ ui/control-types.h \ + ui/dialog-events.cpp \ + ui/dialog-events.h \ ui/icon-names.h \ ui/previewable.h \ ui/previewfillable.h \ diff --git a/src/ui/dialog-events.cpp b/src/ui/dialog-events.cpp new file mode 100644 index 000000000..6bd93bbc3 --- /dev/null +++ b/src/ui/dialog-events.cpp @@ -0,0 +1,255 @@ +/** + * @file + * Event handler for dialog windows. + */ +/* Authors: + * bulia byak + * Johan Engelen + * + * Copyright (C) 2003-2007 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + +#include +#include +#include +#include "macros.h" +#include +#include "desktop.h" +#include "inkscape-private.h" +#include "preferences.h" +#include "ui/tools/tool-base.h" + +#include "ui/dialog-events.h" + + +/** + * Remove focus from window to whoever it is transient for. + */ +void sp_dialog_defocus_cpp(Gtk::Window *win) +{ + //find out the document window we're transient for + Gtk::Window *w = win->get_transient_for(); + + //switch to it + if (w) { + w->present(); + } +} + +void +sp_dialog_defocus (GtkWindow *win) +{ + GtkWindow *w; + //find out the document window we're transient for + w = gtk_window_get_transient_for(GTK_WINDOW(win)); + //switch to it + + if (w) { + gtk_window_present (w); + } +} + + +/** + * Callback to defocus a widget's parent dialog. + */ +void sp_dialog_defocus_callback_cpp(Gtk::Entry *e) +{ + sp_dialog_defocus_cpp(dynamic_cast(e->get_toplevel())); +} + +void +sp_dialog_defocus_callback (GtkWindow * /*win*/, gpointer data) +{ + sp_dialog_defocus( GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(data))) ); +} + + + +void +sp_dialog_defocus_on_enter_cpp (Gtk::Entry *e) +{ + e->signal_activate().connect(sigc::bind(sigc::ptr_fun(&sp_dialog_defocus_callback_cpp), e)); +} + +void +sp_dialog_defocus_on_enter (GtkWidget *w) +{ + g_signal_connect ( G_OBJECT (w), "activate", + G_CALLBACK (sp_dialog_defocus_callback), w ); +} + + + +gboolean +sp_dialog_event_handler (GtkWindow *win, GdkEvent *event, gpointer data) +{ + +// if the focus is inside the Text and Font textview, do nothing + GObject *dlg = G_OBJECT(data); + if (g_object_get_data (dlg, "eatkeys")) { + return FALSE; + } + + gboolean ret = FALSE; + + switch (event->type) { + + case GDK_KEY_PRESS: + + switch (Inkscape::UI::Tools::get_group0_keyval (&event->key)) { + case GDK_KEY_Escape: + sp_dialog_defocus (win); + ret = TRUE; + break; + case GDK_KEY_F4: + case GDK_KEY_w: + case GDK_KEY_W: + // close dialog + if (MOD__CTRL_ONLY(event)) { + + /* this code sends a delete_event to the dialog, + * instead of just destroying it, so that the + * dialog can do some housekeeping, such as remember + * its position. + */ + GdkEventAny event; + GtkWidget *widget = GTK_WIDGET(win); + event.type = GDK_DELETE; + event.window = gtk_widget_get_window (widget); + event.send_event = TRUE; + g_object_ref (G_OBJECT (event.window)); + gtk_main_do_event(reinterpret_cast(&event)); + g_object_unref (G_OBJECT (event.window)); + + ret = TRUE; + } + break; + default: // pass keypress to the canvas + break; + } + default: + ; + } + + return ret; + +} + + + +/** + * Make the argument dialog transient to the currently active document + * window. + */ +void sp_transientize(GtkWidget *dialog) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); +#ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs + // _set_skip_taskbar_hint makes transient dialogs NON-transient! When dialogs + // are made transient (_set_transient_for), they are already removed from + // the taskbar in Win32. + if (prefs->getBool( "/options/dialogsskiptaskbar/value")) { + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); + } +#endif + + gint transient_policy = prefs->getIntLimited("/options/transientpolicy/value", 1, 0, 2); + +#ifdef WIN32 // Win32 special code to enable transient dialogs + transient_policy = 2; +#endif + + if (transient_policy) { + + // if there's an active document window, attach dialog to it as a transient: + + if ( SP_ACTIVE_DESKTOP ) + { + SP_ACTIVE_DESKTOP->setWindowTransient (dialog, transient_policy); + } + } +} // end of sp_transientize() + +void on_transientize (SPDesktop *desktop, win_data *wd ) +{ + sp_transientize_callback (0, desktop, wd); +} + +void +sp_transientize_callback ( InkscapeApplication * /*inkscape*/, + SPDesktop *desktop, win_data *wd ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint transient_policy = prefs->getIntLimited( "/options/transientpolicy/value", 1, 0, 2); + +#ifdef WIN32 // Win32 special code to enable transient dialogs + transient_policy = 1; +#endif + + if (!transient_policy) + return; + + if (wd->win) + { + desktop->setWindowTransient (wd->win, transient_policy); + } +} + +void on_dialog_hide (GtkWidget *w) +{ + if (w) + gtk_widget_hide (w); +} + +void on_dialog_unhide (GtkWidget *w) +{ + if (w) + gtk_widget_show (w); +} + +gboolean +sp_dialog_hide(GObject * /*object*/, gpointer data) +{ + GtkWidget *dlg = GTK_WIDGET(data); + + if (dlg) + gtk_widget_hide (dlg); + + return TRUE; +} + + + +gboolean +sp_dialog_unhide(GObject * /*object*/, gpointer data) +{ + GtkWidget *dlg = GTK_WIDGET(data); + + if (dlg) + gtk_widget_show (dlg); + + return TRUE; +} + + +/* + 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 : diff --git a/src/ui/dialog-events.h b/src/ui/dialog-events.h new file mode 100644 index 000000000..b33eb3f38 --- /dev/null +++ b/src/ui/dialog-events.h @@ -0,0 +1,76 @@ +/** @file + * @brief Event handler for dialog windows + */ +/* Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_DIALOG_EVENTS_H +#define SEEN_DIALOG_EVENTS_H + + +/* + * event callback can only accept one argument, but we need two, + * hence this struct. + * each dialog has a local static copy: + * win is the dialog window + * stop is the transientize semaphore: when 0, retransientizing this dialog + * is allowed + */ + +namespace Gtk { +class Window; +class Entry; +} + +class SPDesktop; + +struct InkscapeApplication; + +typedef struct { + GtkWidget *win; + guint stop; +} win_data; + + +gboolean sp_dialog_event_handler ( GtkWindow *win, + GdkEvent *event, + gpointer data ); + +void sp_dialog_defocus_cpp (Gtk::Window *win); +void sp_dialog_defocus_callback_cpp(Gtk::Entry *e); +void sp_dialog_defocus_on_enter_cpp(Gtk::Entry *e); + +void sp_dialog_defocus ( GtkWindow *win ); +void sp_dialog_defocus_callback ( GtkWindow *win, gpointer data ); +void sp_dialog_defocus_on_enter ( GtkWidget *w ); +void sp_transientize ( GtkWidget *win ); + +void on_transientize ( SPDesktop *desktop, + win_data *wd ); + +void sp_transientize_callback ( InkscapeApplication *inkscape, + SPDesktop *desktop, + win_data *wd ); + +void on_dialog_hide (GtkWidget *w); +void on_dialog_unhide (GtkWidget *w); +gboolean sp_dialog_hide (GObject *object, gpointer data); +gboolean sp_dialog_unhide (GObject *object, gpointer data); + +#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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp index 9b216e841..f65b298c9 100644 --- a/src/ui/dialog/dock-behavior.cpp +++ b/src/ui/dialog/dock-behavior.cpp @@ -24,7 +24,7 @@ #include "verbs.h" #include "dialog.h" #include "preferences.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include #include diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 913713e5c..cd8fdbd92 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -62,7 +62,7 @@ #include "sp-namedview.h" #include "selection-chemistry.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "preferences.h" #include "verbs.h" #include "interface.h" diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index e71605739..00ed09551 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -20,7 +20,7 @@ #include "filedialog.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "extension/output.h" #include "preferences.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 575519848..5778b44db 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -22,7 +22,7 @@ #endif #include "filedialogimpl-gtkmm.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "io/sys.h" #include "path-prefix.h" diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 06153a2d8..ee6a0ef3a 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -31,7 +31,7 @@ //Inkscape includes #include "inkscape.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 37f2761df..9b814bb9f 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -31,7 +31,7 @@ #include "selection.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "verbs.h" #include "interface.h" #include "preferences.h" diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index dd07f009a..f286588b2 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -28,7 +28,7 @@ #include "inkscape.h" #include "desktop.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "preferences.h" #include "verbs.h" diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index 6e9ecc3c8..db7bdf222 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -27,7 +27,7 @@ #include "document.h" #include "selection.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "desktop-handles.h" #include "selection-chemistry.h" #include "preferences.h" diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 80740113c..76c26a3cb 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -28,7 +28,7 @@ #include "ui/tools/tool-base.h" #include "widgets/desktop-widget.h" #include -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "message-context.h" #include "xml/repr.h" #include "verbs.h" diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index f676e75fd..607087f6d 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -27,7 +27,7 @@ #include "filedialogimpl-gtkmm.h" #include "interface.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "io/sys.h" #include "preferences.h" diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h index e21030bcd..bd028c145 100644 --- a/src/ui/dialog/ocaldialogs.h +++ b/src/ui/dialog/ocaldialogs.h @@ -38,8 +38,7 @@ //Inkscape includes #include "ui/dialog/filedialog.h" - -#include +#include "ui/dialog-events.h" struct _xmlNode; typedef _xmlNode xmlNode; diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index c87e42633..9a8c188b2 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -24,7 +24,7 @@ #include "desktop.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" #include "ui/tools/tool-base.h" diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index 5585f2db4..6b5a351f6 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -15,7 +15,7 @@ #include "desktop-handles.h" #include "document.h" #include "document-undo.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "widgets/sp-color-notebook.h" #include "verbs.h" -- cgit v1.2.3 From 2b4e6c9e057eaa7268b8ba76e76ff3e38c2ed28e Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Tue, 2 Sep 2014 16:51:04 -0700 Subject: Remove more whiteboard related leftovers. (bzr r13543) --- src/ui/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 7d80f1e36..2b9dd6e45 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -89,7 +89,6 @@ set(ui_SRC dialog/print.cpp dialog/symbols.cpp dialog/xml-tree.cpp - # dialog/session-player.cpp dialog/spellcheck.cpp dialog/svg-fonts-dialog.cpp dialog/swatches.cpp @@ -101,9 +100,6 @@ set(ui_SRC dialog/pixelartdialog.cpp dialog/transformation.cpp dialog/undo-history.cpp - # dialog/whiteboard-connect.cpp - # dialog/whiteboard-sharewithchat.cpp - # dialog/whiteboard-sharewithuser.cpp widget/anchor-selector.cpp widget/button.cpp -- cgit v1.2.3 From 0d0958e3b2aff0ed5f3ad7a98b4035213475c7f1 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 7 Sep 2014 13:02:01 -0400 Subject: Update to experimental r13543 (bzr r13090.1.108) --- src/ui/CMakeLists.txt | 2 + src/ui/Makefile_insert | 2 + src/ui/dialog-events.cpp | 255 +++++++++++++++++++++++++++++++++ src/ui/dialog-events.h | 76 ++++++++++ src/ui/dialog/aboutbox.cpp | 18 ++- src/ui/dialog/dock-behavior.cpp | 2 +- src/ui/dialog/document-properties.cpp | 10 +- src/ui/dialog/export.cpp | 2 +- src/ui/dialog/filedialog.cpp | 2 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/filedialogimpl-win32.cpp | 2 +- src/ui/dialog/find.cpp | 2 +- src/ui/dialog/floating-behavior.cpp | 2 +- src/ui/dialog/font-substitution.cpp | 2 +- src/ui/dialog/guides.cpp | 2 +- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/ocaldialogs.cpp | 2 +- src/ui/dialog/ocaldialogs.h | 3 +- src/ui/dialog/tags.cpp | 2 +- src/ui/dialog/xml-tree.cpp | 2 +- src/ui/tools/freehand-base.cpp | 9 +- src/ui/tools/node-tool.cpp | 38 +++-- src/ui/widget/color-picker.cpp | 2 +- 23 files changed, 393 insertions(+), 48 deletions(-) create mode 100644 src/ui/dialog-events.cpp create mode 100644 src/ui/dialog-events.h (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 125755c48..56908f58e 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -2,6 +2,7 @@ set(ui_SRC clipboard.cpp control-manager.cpp + dialog-events.cpp previewholder.cpp uxmanager.cpp @@ -156,6 +157,7 @@ set(ui_SRC clipboard.h control-manager.h control-types.h + dialog-events.h icon-names.h previewable.h previewfillable.h diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index 4081f86f8..94064d0cf 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -6,6 +6,8 @@ ink_common_sources += \ ui/control-manager.cpp \ ui/control-manager.h \ ui/control-types.h \ + ui/dialog-events.cpp \ + ui/dialog-events.h \ ui/icon-names.h \ ui/previewable.h \ ui/previewfillable.h \ diff --git a/src/ui/dialog-events.cpp b/src/ui/dialog-events.cpp new file mode 100644 index 000000000..6bd93bbc3 --- /dev/null +++ b/src/ui/dialog-events.cpp @@ -0,0 +1,255 @@ +/** + * @file + * Event handler for dialog windows. + */ +/* Authors: + * bulia byak + * Johan Engelen + * + * Copyright (C) 2003-2007 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + +#include +#include +#include +#include "macros.h" +#include +#include "desktop.h" +#include "inkscape-private.h" +#include "preferences.h" +#include "ui/tools/tool-base.h" + +#include "ui/dialog-events.h" + + +/** + * Remove focus from window to whoever it is transient for. + */ +void sp_dialog_defocus_cpp(Gtk::Window *win) +{ + //find out the document window we're transient for + Gtk::Window *w = win->get_transient_for(); + + //switch to it + if (w) { + w->present(); + } +} + +void +sp_dialog_defocus (GtkWindow *win) +{ + GtkWindow *w; + //find out the document window we're transient for + w = gtk_window_get_transient_for(GTK_WINDOW(win)); + //switch to it + + if (w) { + gtk_window_present (w); + } +} + + +/** + * Callback to defocus a widget's parent dialog. + */ +void sp_dialog_defocus_callback_cpp(Gtk::Entry *e) +{ + sp_dialog_defocus_cpp(dynamic_cast(e->get_toplevel())); +} + +void +sp_dialog_defocus_callback (GtkWindow * /*win*/, gpointer data) +{ + sp_dialog_defocus( GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(data))) ); +} + + + +void +sp_dialog_defocus_on_enter_cpp (Gtk::Entry *e) +{ + e->signal_activate().connect(sigc::bind(sigc::ptr_fun(&sp_dialog_defocus_callback_cpp), e)); +} + +void +sp_dialog_defocus_on_enter (GtkWidget *w) +{ + g_signal_connect ( G_OBJECT (w), "activate", + G_CALLBACK (sp_dialog_defocus_callback), w ); +} + + + +gboolean +sp_dialog_event_handler (GtkWindow *win, GdkEvent *event, gpointer data) +{ + +// if the focus is inside the Text and Font textview, do nothing + GObject *dlg = G_OBJECT(data); + if (g_object_get_data (dlg, "eatkeys")) { + return FALSE; + } + + gboolean ret = FALSE; + + switch (event->type) { + + case GDK_KEY_PRESS: + + switch (Inkscape::UI::Tools::get_group0_keyval (&event->key)) { + case GDK_KEY_Escape: + sp_dialog_defocus (win); + ret = TRUE; + break; + case GDK_KEY_F4: + case GDK_KEY_w: + case GDK_KEY_W: + // close dialog + if (MOD__CTRL_ONLY(event)) { + + /* this code sends a delete_event to the dialog, + * instead of just destroying it, so that the + * dialog can do some housekeeping, such as remember + * its position. + */ + GdkEventAny event; + GtkWidget *widget = GTK_WIDGET(win); + event.type = GDK_DELETE; + event.window = gtk_widget_get_window (widget); + event.send_event = TRUE; + g_object_ref (G_OBJECT (event.window)); + gtk_main_do_event(reinterpret_cast(&event)); + g_object_unref (G_OBJECT (event.window)); + + ret = TRUE; + } + break; + default: // pass keypress to the canvas + break; + } + default: + ; + } + + return ret; + +} + + + +/** + * Make the argument dialog transient to the currently active document + * window. + */ +void sp_transientize(GtkWidget *dialog) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); +#ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs + // _set_skip_taskbar_hint makes transient dialogs NON-transient! When dialogs + // are made transient (_set_transient_for), they are already removed from + // the taskbar in Win32. + if (prefs->getBool( "/options/dialogsskiptaskbar/value")) { + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); + } +#endif + + gint transient_policy = prefs->getIntLimited("/options/transientpolicy/value", 1, 0, 2); + +#ifdef WIN32 // Win32 special code to enable transient dialogs + transient_policy = 2; +#endif + + if (transient_policy) { + + // if there's an active document window, attach dialog to it as a transient: + + if ( SP_ACTIVE_DESKTOP ) + { + SP_ACTIVE_DESKTOP->setWindowTransient (dialog, transient_policy); + } + } +} // end of sp_transientize() + +void on_transientize (SPDesktop *desktop, win_data *wd ) +{ + sp_transientize_callback (0, desktop, wd); +} + +void +sp_transientize_callback ( InkscapeApplication * /*inkscape*/, + SPDesktop *desktop, win_data *wd ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint transient_policy = prefs->getIntLimited( "/options/transientpolicy/value", 1, 0, 2); + +#ifdef WIN32 // Win32 special code to enable transient dialogs + transient_policy = 1; +#endif + + if (!transient_policy) + return; + + if (wd->win) + { + desktop->setWindowTransient (wd->win, transient_policy); + } +} + +void on_dialog_hide (GtkWidget *w) +{ + if (w) + gtk_widget_hide (w); +} + +void on_dialog_unhide (GtkWidget *w) +{ + if (w) + gtk_widget_show (w); +} + +gboolean +sp_dialog_hide(GObject * /*object*/, gpointer data) +{ + GtkWidget *dlg = GTK_WIDGET(data); + + if (dlg) + gtk_widget_hide (dlg); + + return TRUE; +} + + + +gboolean +sp_dialog_unhide(GObject * /*object*/, gpointer data) +{ + GtkWidget *dlg = GTK_WIDGET(data); + + if (dlg) + gtk_widget_show (dlg); + + return TRUE; +} + + +/* + 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 : diff --git a/src/ui/dialog-events.h b/src/ui/dialog-events.h new file mode 100644 index 000000000..b33eb3f38 --- /dev/null +++ b/src/ui/dialog-events.h @@ -0,0 +1,76 @@ +/** @file + * @brief Event handler for dialog windows + */ +/* Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_DIALOG_EVENTS_H +#define SEEN_DIALOG_EVENTS_H + + +/* + * event callback can only accept one argument, but we need two, + * hence this struct. + * each dialog has a local static copy: + * win is the dialog window + * stop is the transientize semaphore: when 0, retransientizing this dialog + * is allowed + */ + +namespace Gtk { +class Window; +class Entry; +} + +class SPDesktop; + +struct InkscapeApplication; + +typedef struct { + GtkWidget *win; + guint stop; +} win_data; + + +gboolean sp_dialog_event_handler ( GtkWindow *win, + GdkEvent *event, + gpointer data ); + +void sp_dialog_defocus_cpp (Gtk::Window *win); +void sp_dialog_defocus_callback_cpp(Gtk::Entry *e); +void sp_dialog_defocus_on_enter_cpp(Gtk::Entry *e); + +void sp_dialog_defocus ( GtkWindow *win ); +void sp_dialog_defocus_callback ( GtkWindow *win, gpointer data ); +void sp_dialog_defocus_on_enter ( GtkWidget *w ); +void sp_transientize ( GtkWidget *win ); + +void on_transientize ( SPDesktop *desktop, + win_data *wd ); + +void sp_transientize_callback ( InkscapeApplication *inkscape, + SPDesktop *desktop, + win_data *wd ); + +void on_dialog_hide (GtkWidget *w); +void on_dialog_unhide (GtkWidget *w); +gboolean sp_dialog_hide (GObject *object, gpointer data); +gboolean sp_dialog_unhide (GObject *object, gpointer data); + +#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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 44ed3b58f..7212fa372 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -254,6 +254,7 @@ void AboutBox::initStrings() { "Nicholas Bishop\n" "Joshua L. Blocher\n" "Hanno Böck\n" +"Tomasz Boczkowski\n" "Henrik Bohre\n" "Boldewyn\n" "Daniel Borgmann\n" @@ -270,6 +271,7 @@ void AboutBox::initStrings() { "Gail Carmichael\n" "Ed Catmur\n" "Chema Celorio\n" +"Jabiertxo Arraiza Cenoz\n" "Johan Ceuppens\n" "Zbigniew Chyla\n" "Alexander Clausen\n" @@ -311,6 +313,7 @@ void AboutBox::initStrings() { "Hannes Hochreiner\n" "Thomas Holder\n" "Joel Holdsworth\n" +"Christoffer Holmstedt\n" "Alan Horkan\n" "Karl Ove Hufthammer\n" "Richard Hughes\n" @@ -319,6 +322,7 @@ void AboutBox::initStrings() { "Thomas Ingham\n" "Jean-Olivier Irisson\n" "Bob Jamison\n" +"Ted Janeczko\n" "jEsuSdA\n" "Fernando Lucchesi Bastos Jurema\n" "Lauris Kaplinski\n" @@ -342,7 +346,9 @@ void AboutBox::initStrings() { "Aurel-Aimé Marmion\n" "Colin Marquardt\n" "Craig Marshall\n" +"Ivan Masár\n" "Dmitry G. Mastrukov\n" +"David Mathog\n" "Matiphas\n" "Michael Meeks\n" "Federico Mena\n" @@ -360,8 +366,10 @@ void AboutBox::initStrings() { "Nick\n" "Andreas Nilsson\n" "Mitsuru Oka\n" +"Vinícius dos Santos Oliveira\n" "Martin Owens\n" "Alvin Penner\n" +"Matthew Petroff\n" "Jon Phillips\n" "Zdenko Podobny\n" "Alexandre Prokoudine\n" @@ -398,6 +406,8 @@ void AboutBox::initStrings() { "Joakim Verona\n" "Lucas Vieites\n" "Daniel Wagenaar\n" +"Liam P. White\n" +"Sebastian Wüst\n" "Michael Wybrow\n" "Gellule Xg\n" "Daniel Yacob\n" @@ -482,6 +492,7 @@ void AboutBox::initStrings() { "Elias Norberg , 2009.\n" "Equipe de Tradução Inkscape Brasil , 2007.\n" "Fatih Demir , 2000.\n" +"Firas Hanife , 2014.\n" "Foppe Benedictus , 2007-2009.\n" "Francesc Dorca , 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador , 2003.\n" @@ -493,8 +504,9 @@ void AboutBox::initStrings() { "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" "Ivan Masár , 2006-2010. \n" +"Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" -"Jānis Eisaks , 2012, 2013.\n" +"Jānis Eisaks , 2012-2014.\n" "Jeffrey Steve Borbón Sanabria , 2005.\n" "Jesper Öqvist , 2010, 2011.\n" "Joaquim Perez i Noguer , 2008-2009.\n" @@ -516,7 +528,7 @@ void AboutBox::initStrings() { "Kingsley Turner , 2006.\n" "Kitae , 2006.\n" "Kjartan Maraas , 2000-2002.\n" -"Kris De Gussem , 2008-2013.\n" +"Kris De Gussem , 2008-2014.\n" "Lauris Kaplinski , 2000.\n" "Leandro Regueiro , 2006-2008, 2010.\n" "Liu Xiaoqin , 2008.\n" @@ -536,7 +548,7 @@ void AboutBox::initStrings() { "Muhammad Bashir Al-Noimi , 2008.\n" "Myckel Habets , 2008.\n" "Nguyen Dinh Trung , 2007, 2008.\n" -"Nicolas Dufour , 2008-2013.\n" +"Nicolas Dufour , 2008-2014.\n" "Pawan Chitrakar , 2006.\n" "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp index 9b216e841..f65b298c9 100644 --- a/src/ui/dialog/dock-behavior.cpp +++ b/src/ui/dialog/dock-behavior.cpp @@ -24,7 +24,7 @@ #include "verbs.h" #include "dialog.h" #include "preferences.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include #include diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 5ad82644e..2a3a1dd86 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1736,9 +1736,13 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = doc->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = doc->getWidth().value("px") / vb.width(); + gdouble viewscale_h = doc->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 913713e5c..cd8fdbd92 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -62,7 +62,7 @@ #include "sp-namedview.h" #include "selection-chemistry.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "preferences.h" #include "verbs.h" #include "interface.h" diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp index e71605739..00ed09551 100644 --- a/src/ui/dialog/filedialog.cpp +++ b/src/ui/dialog/filedialog.cpp @@ -20,7 +20,7 @@ #include "filedialog.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "extension/output.h" #include "preferences.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 575519848..5778b44db 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -22,7 +22,7 @@ #endif #include "filedialogimpl-gtkmm.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "io/sys.h" #include "path-prefix.h" diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 06153a2d8..ee6a0ef3a 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -31,7 +31,7 @@ //Inkscape includes #include "inkscape.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 37f2761df..9b814bb9f 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -31,7 +31,7 @@ #include "selection.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "verbs.h" #include "interface.h" #include "preferences.h" diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index dd07f009a..f286588b2 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -28,7 +28,7 @@ #include "inkscape.h" #include "desktop.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "interface.h" #include "preferences.h" #include "verbs.h" diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index 6e9ecc3c8..db7bdf222 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -27,7 +27,7 @@ #include "document.h" #include "selection.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "desktop-handles.h" #include "selection-chemistry.h" #include "preferences.h" diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 80740113c..76c26a3cb 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -28,7 +28,7 @@ #include "ui/tools/tool-base.h" #include "widgets/desktop-widget.h" #include -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "message-context.h" #include "xml/repr.h" #include "verbs.h" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 2d558daae..ecd4ff42f 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -25,7 +25,7 @@ #include "desktop.h" #include "desktop-style.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" #include "filter-chemistry.h" diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index f676e75fd..607087f6d 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -27,7 +27,7 @@ #include "filedialogimpl-gtkmm.h" #include "interface.h" #include "gc-core.h" -#include +#include "ui/dialog-events.h" #include "io/sys.h" #include "preferences.h" diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h index e21030bcd..bd028c145 100644 --- a/src/ui/dialog/ocaldialogs.h +++ b/src/ui/dialog/ocaldialogs.h @@ -38,8 +38,7 @@ //Inkscape includes #include "ui/dialog/filedialog.h" - -#include +#include "ui/dialog-events.h" struct _xmlNode; typedef _xmlNode xmlNode; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index b2ca1b6da..127e4d95e 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -50,7 +50,7 @@ #include "sp-root.h" #include "ui/tools/tool-base.h" //"event-context.h" #include "selection.h" -#include "dialogs/dialog-events.h" +//#include "dialogs/dialog-events.h" #include "widgets/sp-color-notebook.h" #include "style.h" #include "filter-chemistry.h" diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index c87e42633..9a8c188b2 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -24,7 +24,7 @@ #include "desktop.h" #include "desktop-handles.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "document.h" #include "document-undo.h" #include "ui/tools/tool-base.h" diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 72250a550..bab6bc7e3 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -262,8 +262,9 @@ static void spdc_apply_powerstroke_shape(const std::vector & points sp_style_unref(style); } - char * width_str = new char[50]; - sprintf(width_str, "0,%f", stroke_width / 2.); + std::ostringstream s; + s.imbue(std::locale::classic()); + s << "0," << stroke_width / 2.; // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); @@ -272,9 +273,7 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("sort_points", "true"); lpe->getRepr()->setAttribute("interpolator_type", "CubicBezierJohan"); lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); - lpe->getRepr()->setAttribute("offset_points", width_str); - - delete [] width_str; + lpe->getRepr()->setAttribute("offset_points", s.str().c_str()); } static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 975894586..0b98bacc1 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -305,27 +305,23 @@ void NodeTool::update_helperpath () { if (SP_IS_LPE_ITEM(selection->singleItem())) { Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { - if (lpe) { - SPCurve *c = new SPCurve(); - SPCurve *cc = new SPCurve(); - std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); - for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { - cc->set_pathvector(*p); - c->append(cc, false); - cc->reset(); - } - if (!c->is_empty()) { - c->transform(selection->singleItem()->i2dt_affine()); - SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), - 0x0000ff9A, 1.0, - SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); - this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); - } - c->unref(); - cc->unref(); - } + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), 0x0000ff9A, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + sp_canvas_item_affine_absolute(helperpath, selection->singleItem()->i2dt_affine()); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath, 0); + } + c->unref(); + cc->unref(); } } } diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index 5585f2db4..6b5a351f6 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -15,7 +15,7 @@ #include "desktop-handles.h" #include "document.h" #include "document-undo.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include "widgets/sp-color-notebook.h" #include "verbs.h" -- cgit v1.2.3 From 71c3b0398381d4bace1427bbda11f486fcbcc307 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Mon, 8 Sep 2014 10:13:03 -0700 Subject: partial rollback of r13544, allow old recursive behavior for some locations, but not EMF import (bzr r13549) --- src/ui/dialog/document-properties.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2757a0ec9..1f220b246 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1747,7 +1747,8 @@ void DocumentProperties::onDocUnitChange() doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, viewscale*doc->getRoot()->viewBox.min()[Geom::Y] + - (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2)); + (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2), + false); ShapeEditor::blockSetItem(false); } prefs->setBool("/options/transform/stroke", transform_stroke); -- cgit v1.2.3 From 39d4d238a04162c559f83011999cc16feb6da88f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 11 Sep 2014 05:30:09 +0200 Subject: add radius support to fillet-chamfer, bugfixes (bzr r13341.1.203) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 71 +++++++++++++------------ src/ui/dialog/lpe-fillet-chamfer-properties.h | 31 ++++------- 2 files changed, 46 insertions(+), 56 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index eef32d10d..ad8b66b8c 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -12,9 +12,9 @@ #include #endif +#include #include "lpe-fillet-chamfer-properties.h" #include -#include #include #include #include "inkscape.h" @@ -31,9 +31,8 @@ #include "selection-chemistry.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" -#include -#include #include "util/units.h" +#include //#include "event-context.h" @@ -44,38 +43,24 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { -#if WITH_GTKMM_3_0 - Gtk::Box *mainVBox = get_content_area(); -#else Gtk::Box *mainVBox = get_vbox(); -#endif - mainVBox->set_homogeneous(false); - -#if WITH_GTKMM_3_0 - _layout_table.set_row_spacing(4); - _layout_table.set_column_spacing(4); -#else _layout_table.set_spacings(4); _layout_table.resize(2, 2); -#endif // Layer name widgets - _fillet_chamfer_position_entry.set_activates_default(true); + _fillet_chamfer_position_numeric.set_digits(4); + _fillet_chamfer_position_numeric.set_increments(1,1); + //todo: get tha max aloable infinity freeze the widget + _fillet_chamfer_position_numeric.set_range(0., 999999999999999999.); + _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); _fillet_chamfer_position_label.set_alignment(1.0, 0.5); -#if WITH_GTKMM_3_0 - _layout_table.attach(_fillet_chamfer_position_label, 0, 0, 1, 1); - _layout_table.attach(_fillet_chamfer_position_entry, 1, 0, 1, 1); - _fillet_chamfer_position_entry.set_hexpand(); -#else _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); - _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, + _layout_table.attach(_fillet_chamfer_position_numeric, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); -#endif - _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); @@ -115,7 +100,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() show_all_children(); - set_focus(_fillet_chamfer_position_entry); + set_focus(_fillet_chamfer_position_numeric); } FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() @@ -128,12 +113,16 @@ void FilletChamferPropertiesDialog::showDialog( SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt, - const gchar *unit) + const gchar *unit, + bool use_distance, + bool aprox_radius) { FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); dialog->_setDesktop(desktop); dialog->_setUnit(unit); + dialog->_set_use_distance(use_distance); + dialog->_set_aprox(aprox_radius); dialog->_setKnotPoint(knotpoint); dialog->_setPt(pt); @@ -150,9 +139,9 @@ void FilletChamferPropertiesDialog::showDialog( void FilletChamferPropertiesDialog::_apply() { - std::istringstream i_pos(_fillet_chamfer_position_entry.get_text()); - double d_pos, d_width; - if (i_pos >> d_pos) { + double d_width; + double d_pos = _fillet_chamfer_position_numeric.get_value(); + if (d_pos) { if (_fillet_chamfer_type_fillet.get_active() == true) { d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { @@ -203,6 +192,13 @@ void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) { double position; + std::string distance_or_radius = std::string(_("Radius ")); + if(aprox){ + distance_or_radius = std::string(_("Radius aproximated ")); + } + if(use_distance){ + distance_or_radius = std::string(_("Knot distance ")); + } if (knotpoint.x() > 0) { double intpart; position = modf(knotpoint[Geom::X], &intpart) * 100; @@ -211,16 +207,13 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) _fillet_chamfer_position_label.set_label(_("Position (%):")); } else { _flexible = false; - std::string posConcat = - std::string(_("Position (")) + std::string(unit) + std::string(")"); + std::string posConcat = distance_or_radius + + std::string(_("(")) + std::string(unit) + std::string(")"); _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); position = knotpoint[Geom::X] * -1; position = Inkscape::Util::Quantity::convert(position, "px", unit); } - std::ostringstream s; - s.imbue(std::locale::classic()); - s << position; - _fillet_chamfer_position_entry.set_text(s.str()); + _fillet_chamfer_position_numeric.set_value(position); if (knotpoint.y() == 1) { _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { @@ -246,6 +239,16 @@ void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) unit = abbr; } +void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance) +{ + use_distance = use_knot_distance; +} + +void FilletChamferPropertiesDialog::_set_aprox(bool aprox_radius) +{ + aprox = aprox_radius; +} + void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) { if (desktop) { diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 9beca02e1..47ff97b00 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -8,24 +8,10 @@ #ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include #include <2geom/point.h> +#include #include "live_effects/parameter/filletchamferpointarray.h" -#include -#include -#include - -#if WITH_GTKMM_3_0 - #include -#else - #include -#endif - class SPDesktop; namespace Inkscape { @@ -44,7 +30,9 @@ public: static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt, - const gchar *unit); + const gchar *unit, + bool use_distance, + bool aprox_radius); protected: @@ -53,19 +41,14 @@ protected: _knotpoint; Gtk::Label _fillet_chamfer_position_label; - Gtk::Entry _fillet_chamfer_position_entry; + Gtk::SpinButton _fillet_chamfer_position_numeric; Gtk::RadioButton::Group _fillet_chamfer_type_group; Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; Gtk::RadioButton _fillet_chamfer_type_double_chamfer; -#if WITH_GTKMM_3_0 - Gtk::Grid _layout_table; -#else Gtk::Table _layout_table; -#endif - bool _position_visible; double _index; @@ -83,10 +66,14 @@ protected: void _setPt(const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt); void _setUnit(const gchar *abbr); + void _set_use_distance(bool use_knot_distance); + void _set_aprox(bool aprox_radius); void _apply(); void _close(); bool _flexible; const gchar *unit; + bool use_distance; + bool aprox; void _setKnotPoint(Geom::Point knotpoint); void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); -- cgit v1.2.3 From 1e435432e61ca5794f784e3758d1034aa93cc171 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 12 Sep 2014 07:59:27 +0200 Subject: i18n. Fix for Bug #1368375 (Page titles in preferences don't escape text for markup) by houz. Fixed bugs: - https://launchpad.net/bugs/1368375 (bzr r13552) --- src/ui/dialog/inkscape-preferences.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 5d065dc60..e04748759 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -2054,7 +2054,8 @@ void InkscapePreferences::on_pagelist_selection_changed() if (!_init) { prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); } - _page_title.set_markup("" + row[_page_list_columns._col_name] + ""); + Glib::ustring col_name_escaped = Glib::Markup::escape_text( row[_page_list_columns._col_name] ); + _page_title.set_markup("" + col_name_escaped + ""); _page_frame.add(*_current_page); _current_page->show(); while (Gtk::Main::events_pending()) -- cgit v1.2.3 From e81250edbb1751c3626b01645872f74948081a19 Mon Sep 17 00:00:00 2001 From: su_v Date: Sat, 13 Sep 2014 19:48:17 +0200 Subject: Fix GTK3 build (bzr r13555) --- src/ui/dialog/inkscape-preferences.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index e04748759..7d43adc0f 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -19,6 +19,7 @@ #include "inkscape-preferences.h" #include +#include #include #include #include -- cgit v1.2.3 From 0403ae2f0f76e56b31e369160648968671324d13 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 16 Sep 2014 01:07:32 +0200 Subject: fixing cusp node bug on bspline -problems moving nodes because tiny handles (bzr r13341.1.209) --- src/ui/tool/path-manipulator.cpp | 4 +++- src/ui/tools/pen-tool.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 5f20aece7..f30ecb1d1 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1227,7 +1227,9 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(Geom::Point(h->position()[X] - handleCubicGap,h->position()[Y] - handleCubicGap),*lineInsideNodes->first_segment()); + if(!are_near(h->position(), n->position())){ + pos = Geom::nearest_point(Geom::Point(h->position()[X] ,h->position()[Y] - handleCubicGap),*lineInsideNodes->first_segment()); + } } if (pos == 0.0000 && !h2){ return BSplineHandlePosition(h, h->other()); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 318591df5..b68231e10 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1586,6 +1586,9 @@ void PenTool::_bspline_spiro_motion(bool shift){ if(this->green_curve->is_empty() && !this->sa){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); this->p[1] = Geom::Point(this->p[1][X] + handleCubicGap,this->p[1][Y] + handleCubicGap); + if(shift){ + this->p[2] = this->p[3]; + } }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ @@ -1609,8 +1612,11 @@ void PenTool::_bspline_spiro_motion(bool shift){ SBasisWPower = WPower->first_segment()->toSBasis(); WPower->reset(); this->p[1] = SBasisWPower.valueAt(WP); - if(!Geom::are_near(this->p[1],this->p[0])) + if(!Geom::are_near(this->p[1],this->p[0])){ this->p[1] = Geom::Point(this->p[1][X] + handleCubicGap,this->p[1][Y] + handleCubicGap); + } else { + this->p[1] = this->p[0]; + } if(shift) this->p[2] = this->p[3]; }else{ -- cgit v1.2.3 From 7ec3afaf68ebfedabd4c4addd74812ff8f055955 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 16 Sep 2014 17:09:19 +0200 Subject: Fix bug moving nodes in bspline mode (bzr r13341.1.210) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f30ecb1d1..edb74cb40 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1228,7 +1228,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); if(!are_near(h->position(), n->position())){ - pos = Geom::nearest_point(Geom::Point(h->position()[X] ,h->position()[Y] - handleCubicGap),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(Geom::Point(h->position()[X] - handleCubicGap, h->position()[Y] - handleCubicGap), *lineInsideNodes->first_segment()); } } if (pos == 0.0000 && !h2){ -- cgit v1.2.3 From fb4d4b30b50b7b4505d63772c0aeca4c05c2c5c6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 22 Sep 2014 21:15:47 +0200 Subject: Fix for strange gap at shift to cusp in bspline Now curves with cusp noden in bspline mode looks better, more smooth. Remove some duplicate code from outside for loops Fix a bug continuing shapes in bspline-spiro mode. Style code formating (bzr r13341.1.215) --- src/ui/tools/freehand-base.cpp | 8 +- src/ui/tools/pen-tool.cpp | 232 ++++++++++++++++++++--------------------- 2 files changed, 115 insertions(+), 125 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bab6bc7e3..17f173e47 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -609,12 +609,12 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if (dc->sa) { SPCurve *s = dc->sa->curve; dc->white_curves = g_slist_remove(dc->white_curves, s); - if (dc->sa->start) { - s = reverse_then_unref(s); - } if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - dc->overwriteCurve = s; + s = dc->overwriteCurve; + } + if (dc->sa->start) { + s = reverse_then_unref(s); } s->append_continuous(c, 0.0625); c->unref(); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index b68231e10..a72934ae3 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1827,155 +1827,145 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { // commenting the function doEffect in src/live_effects/lpe-bspline.cpp - Geom::PathVector const original_pathv = curve->get_pathvector(); - if (curve->get_segment_count() < 1) + if (curve->get_segment_count() < 1){ return; + } + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el + //penúltimo + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); + path_it != original_pathv.end(); ++path_it) { + //Si está vacío... if (path_it->empty()) continue; + //Itreadores - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); - Geom::Point previousNode(0,0); - Geom::Point node(0,0); - Geom::Point pointAt1(0,0); - Geom::Point pointAt2(0,0); - Geom::Point nextPointAt1(0,0); - Geom::Point nextPointAt2(0,0); - Geom::Point nextPointAt3(0,0); - Geom::D2< Geom::SBasis > SBasisIn; - Geom::D2< Geom::SBasis > SBasisOut; - Geom::D2< Geom::SBasis > SBasisHelper; + Geom::Point previousNode(0, 0); + Geom::Point node(0, 0); + Geom::Point pointAt1(0, 0); + Geom::Point pointAt2(0, 0); + Geom::Point nextPointAt1(0, 0); + Geom::D2 SBasisIn; + Geom::D2 SBasisOut; + Geom::D2 SBasisHelper; Geom::CubicBezier const *cubic = NULL; if (path_it->closed()) { - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type if (are_near(closingline.initialPoint(), closingline.finalPoint())) { curve_endit = path_it->end_open(); } } - while ( curve_it2 != curve_endit ) - { - SPCurve * in = new SPCurve(); + nCurve->moveto(curve_it1->initialPoint()); + while (curve_it1 != curve_endit) { + SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if(cubic){ + cubic = dynamic_cast(&*curve_it1); + if (cubic) { SBasisIn = in->first_segment()->toSBasis(); - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); - pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); - }else{ + if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { + pointAt1 = SBasisIn.valueAt(0.3334); + } else { + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1], *in->first_segment())); + } + if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) { + pointAt2 = SBasisIn.valueAt(0.6667); + } else { + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2], *in->first_segment())); + } + } else { pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); } in->reset(); delete in; - SPCurve * out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast(&*curve_it2); - if(cubic){ - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; - nextPointAt3 = (*cubic)[3]; - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); + if ( curve_it2 != curve_endit ) { + SPCurve *out = new SPCurve(); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + cubic = dynamic_cast(&*curve_it2); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { + nextPointAt1 = SBasisIn.valueAt(0.3334); + } else { + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + } + out->reset(); + delete out; + } + Geom::Point startNode = path_it->begin()->initialPoint(); + if (path_it->closed() && curve_it2 == curve_endit) { + SPCurve *start = new SPCurve(); + start->moveto(path_it->begin()->initialPoint()); + start->lineto(path_it->begin()->finalPoint()); + Geom::D2 SBasisStart = start->first_segment()->toSBasis(); + SPCurve *lineHelper = new SPCurve(); + cubic = dynamic_cast(&*path_it->begin()); + if (cubic) { + lineHelper->moveto(SBasisStart.valueAt( + Geom::nearest_point((*cubic)[1], *start->first_segment()))); + } else { + lineHelper->moveto(start->first_segment()->initialPoint()); + } + start->reset(); + delete start; + + SPCurve *end = new SPCurve(); + end->moveto(curve_it1->initialPoint()); + end->lineto(curve_it1->finalPoint()); + Geom::D2 SBasisEnd = end->first_segment()->toSBasis(); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + lineHelper->lineto(SBasisEnd.valueAt( + Geom::nearest_point((*cubic)[2], *end->first_segment()))); + } else { + lineHelper->lineto(end->first_segment()->finalPoint()); + } + end->reset(); + delete end; + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + delete lineHelper; + startNode = SBasisHelper.valueAt(0.5); + nCurve->curveto(pointAt1, pointAt2, startNode); + nCurve->move_endpoints(startNode, startNode); + } else if ( curve_it2 == curve_endit) { + nCurve->curveto(pointAt1, pointAt2, curve_it1->finalPoint()); + nCurve->move_endpoints(path_it->begin()->initialPoint(), curve_it1->finalPoint()); + } else { + SPCurve *lineHelper = new SPCurve(); + lineHelper->moveto(pointAt2); + lineHelper->lineto(nextPointAt1); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + delete lineHelper; + previousNode = node; + node = SBasisHelper.valueAt(0.5); + Geom::CubicBezier const *cubic2 = dynamic_cast(&*curve_it1); + if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) { + node = curve_it1->finalPoint(); + } + nCurve->curveto(pointAt1, pointAt2, node); } - out->reset(); - delete out; - SPCurve *lineHelper = new SPCurve(); - lineHelper->moveto(pointAt2); - lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - delete lineHelper; - previousNode = node; - node = SBasisHelper.valueAt(0.5); - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(previousNode); - curveHelper->curveto(pointAt1, pointAt2, node); - nCurve->append_continuous(curveHelper, 0.0625); - curveHelper->reset(); - delete curveHelper; ++curve_it1; ++curve_it2; } - SPCurve *out = new SPCurve(); - out->moveto(curve_it1->initialPoint()); - out->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2], *out->first_segment())); - nextPointAt3 = out->first_segment()->finalPoint(); - } else { - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - } - out->reset(); - delete out; - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(node); - Geom::Point startNode = path_it->begin()->initialPoint(); - if (path_it->closed()) { - SPCurve * start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - Geom::D2< Geom::SBasis > SBasisStart = start->first_segment()->toSBasis(); - SPCurve *lineHelper = new SPCurve(); - cubic = dynamic_cast(&*path_it->begin()); - if(cubic){ - lineHelper->moveto(SBasisStart.valueAt(Geom::nearest_point((*cubic)[1],*start->first_segment()))); - }else{ - lineHelper->moveto(start->first_segment()->initialPoint()); - } - start->reset(); - delete start; - - SPCurve * end = new SPCurve(); - end->moveto(curve_it1->initialPoint()); - end->lineto(curve_it1->finalPoint()); - Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis(); - cubic = dynamic_cast(&*curve_it1); - if(cubic){ - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()))); - }else{ - lineHelper->lineto(end->first_segment()->finalPoint()); - } - end->reset(); - delete end; - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - delete lineHelper; - startNode = SBasisHelper.valueAt(0.5); - curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); - nCurve->append_continuous(curveHelper, 0.0625); - nCurve->move_endpoints(startNode,startNode); - }else{ - SPCurve * start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - startNode = start->first_segment()->initialPoint(); - start->reset(); - delete start; - curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->append_continuous(curveHelper, 0.0625); - nCurve->move_endpoints(startNode,nextPointAt3); - } - curveHelper->reset(); - delete curveHelper; if (path_it->closed()) { nCurve->closepath_current(); } - curve->append(nCurve,false); + curve->append(nCurve, false); nCurve->reset(); delete nCurve; } -- cgit v1.2.3 From 127e68f823638bee0728d275dc2610ed1e062b6b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 22 Sep 2014 23:59:18 +0200 Subject: Fix a bug in BSpline, happend pressing any key hover a modified weight handle -it buggy reset to default weight-. (bzr r13341.1.216) --- src/ui/tool/node.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index e38f82673..8ef5a61dc 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -293,6 +293,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } + break; // new double click event to set the handlers of a node to the default proportion, 0.3334% case GDK_2BUTTON_PRESS: handle_2button_press(); -- cgit v1.2.3 From 4c9804125c8b62e195313ac9ec97e92bd542cbdd Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 23 Sep 2014 17:42:51 +0200 Subject: fix bug -bad power- inserting nodes near cusp nodes in bspline (bzr r13341.1.218) --- src/ui/tool/path-manipulator.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index edb74cb40..48b19ef7a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -991,9 +991,37 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d // set new handle positions Node *n = new Node(_multi_path_manipulator._path_data.node_data, seg2[0]); - n->back()->setPosition(seg1[2]); - n->front()->setPosition(seg2[1]); - n->setType(NODE_SMOOTH, false); + if(!isBSpline()){ + n->back()->setPosition(seg1[2]); + n->front()->setPosition(seg2[1]); + n->setType(NODE_SMOOTH, false); + } else { + const double handleCubicGap = 0.01; + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + if(second->back()->isDegenerate()){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(second->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + Geom::Point next = SBasisInsideNodes.valueAt(0.3334); + next = Geom::Point(next[Geom::X] + handleCubicGap,next[Geom::Y] + handleCubicGap); + lineInsideNodes->reset(); + n->front()->setPosition(next); + }else{ + n->front()->setPosition(seg2[1]); + } + if(first->front()->isDegenerate()){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(first->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + Geom::Point previous = SBasisInsideNodes.valueAt(0.3334); + previous = Geom::Point(previous[Geom::X] + handleCubicGap,previous[Geom::Y] + handleCubicGap); + n->back()->setPosition(previous); + }else{ + n->back()->setPosition(seg1[2]); + } + n->setType(NODE_CUSP, false); + } inserted = list.insert(insert_at, n); first->front()->move(seg1[1]); -- cgit v1.2.3 From 86cf2d0a97e0412629102ae51df0a4797f9179db Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 23 Sep 2014 23:43:31 +0200 Subject: remove magic numbers from bspline (bzr r13341.1.219) --- src/ui/tool/node.cpp | 35 ++++++++++++++++++++--------------- src/ui/tool/path-manipulator.cpp | 16 ++++++++++------ 2 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 8ef5a61dc..c52bd4c07 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -59,6 +59,11 @@ Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) namespace Inkscape { namespace UI { +const double handleCubicGap = 0.01; +const double noPower = 0.0; +const double defaultStartPower = 0.3334; +const double defaultEndPower = 0.6667; + ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke {0xff000000, 0x000000ff}, // mouseover fill, stroke @@ -294,7 +299,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven default: break; } break; - // new double click event to set the handlers of a node to the default proportion, 0.3334% + // new double click event to set the handlers of a node to the default proportion, defaultStartPower% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -305,11 +310,11 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//this function moves the handler and its oposite to the default proportion of 0.3334 +//this function moves the handler and its oposite to the default proportion of defaultStartPower void Handle::handle_2button_press(){ if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this,0.3334)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),0.3334)); + setPosition(_pm().BSplineHandleReposition(this,defaultStartPower)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),defaultStartPower)); _pm().update(); } } @@ -618,9 +623,9 @@ void Node::move(Geom::Point const &new_pos) Geom::Point delta = new_pos - position(); // save the previous nodes strength to apply it again once the node is moved - double nodeWeight = 0.0000; - double nextNodeWeight = 0.0000; - double prevNodeWeight = 0.0000; + double nodeWeight = noPower; + double nextNodeWeight = noPower; + double prevNodeWeight = noPower; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); @@ -672,9 +677,9 @@ void Node::transform(Geom::Affine const &m) Geom::Point old_pos = position(); // save the previous nodes strength to apply it again once the node is moved - double nodeWeight = 0.0000; - double nextNodeWeight = 0.0000; - double prevNodeWeight = 0.0000; + double nodeWeight = noPower; + double nextNodeWeight = noPower; + double prevNodeWeight = noPower; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); @@ -904,12 +909,12 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, + /* in node type changes, about bspline traces, we can mantain them with noPower power in border mode, or we give them the default power in curve mode */ if(_pm().isBSpline()){ - double weight = 0.0000; - if(_pm().BSplineHandlePosition(this->front()) != 0.0000 ){ - weight = 0.3334; + double weight = noPower; + if(_pm().BSplineHandlePosition(this->front()) != noPower ){ + weight = defaultStartPower; } _front.setPosition(_pm().BSplineHandleReposition(this->front(),weight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),weight)); @@ -1455,7 +1460,7 @@ Glib::ustring Node::_getTip(unsigned state) const "%s: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype); }else if(_selection.size() == 1){ return format_tip(C_("Path node tip", - "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),0.0000/*this->bsplineWeight*/); + "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),noPower/*this->bsplineWeight*/); } return format_tip(C_("Path node tip", "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 48b19ef7a..52ff5d42c 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -56,6 +56,10 @@ enum PathChange { }; } // anonymous namespace +const double handleCubicGap = 0.01; +const double noPower = 0.0; +const double defaultStartPower = 0.3334; +const double defaultEndPower = 0.6667; /** * Notifies the path manipulator when something changes the path being edited @@ -1003,7 +1007,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(second->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - Geom::Point next = SBasisInsideNodes.valueAt(0.3334); + Geom::Point next = SBasisInsideNodes.valueAt(defaultStartPower); next = Geom::Point(next[Geom::X] + handleCubicGap,next[Geom::Y] + handleCubicGap); lineInsideNodes->reset(); n->front()->setPosition(next); @@ -1014,7 +1018,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(first->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - Geom::Point previous = SBasisInsideNodes.valueAt(0.3334); + Geom::Point previous = SBasisInsideNodes.valueAt(defaultStartPower); previous = Geom::Point(previous[Geom::X] + handleCubicGap,previous[Geom::Y] + handleCubicGap); n->back()->setPosition(previous); }else{ @@ -1246,7 +1250,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ if(h2){ h = h2; } - double pos = 0.0000; + double pos = noPower; const double handleCubicGap = 0.01; Node *n = h->parent(); Node * nextNode = NULL; @@ -1259,7 +1263,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ pos = Geom::nearest_point(Geom::Point(h->position()[X] - handleCubicGap, h->position()[Y] - handleCubicGap), *lineInsideNodes->first_segment()); } } - if (pos == 0.0000 && !h2){ + if (pos == noPower && !h2){ return BSplineHandlePosition(h, h->other()); } return pos; @@ -1282,14 +1286,14 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; nextNode = n->nodeToward(h); - if(nextNode && pos != 0.0000){ + if(nextNode && pos != noPower){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + handleCubicGap,ret[Y] + handleCubicGap); }else{ - if(pos == 0.0000){ + if(pos == noPower){ ret = n->position(); } } -- cgit v1.2.3 From f692482d773d75799712e8bd3c48d1da3d752a03 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 24 Sep 2014 03:27:47 +0200 Subject: Show the helper curves in pen tool with the color of the current layer defined in objects dialog (bzr r13341.1.220) --- src/ui/tools/freehand-base.cpp | 1 + src/ui/tools/freehand-base.h | 1 + src/ui/tools/pen-tool.cpp | 46 ++++++++++++++++-------------------------- 3 files changed, 19 insertions(+), 29 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 17f173e47..bc979821a 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -80,6 +80,7 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , red_color(0xff00007f) , blue_color(0x0000ff7f) , green_color(0x00ff007f) + , highlight_color(0x0000007f) , red_bpath(NULL) , red_curve(NULL) , blue_bpath(NULL) diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 6e04e03b7..fb2db86f6 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -55,6 +55,7 @@ public: guint32 red_color; guint32 blue_color; guint32 green_color; + guint32 highlight_color; // Red SPCanvasItem *red_bpath; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index a72934ae3..9a86dfe2c 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -188,7 +188,6 @@ void PenTool::_pen_context_set_mode(guint mode) { */ void PenTool::setup() { FreehandBase::setup(); - ControlManager &mgr = ControlManager::getManager(); // Pen indicators @@ -435,7 +434,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { // This is allowed, if we just canceled curve case PenTool::POINT: if (this->npoints == 0) { - + this->_bspline_spiro_color(); Geom::Point p; if ((bevent.state & GDK_CONTROL_MASK) && (this->polylines_only || this->polylines_paraxial)) { p = event_dt; @@ -702,11 +701,9 @@ bool PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { } // calls the function "bspline_spiro_motion" when the mouse starts or stops moving if(this->bspline){ - this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); }else{ if ( Geom::LInfty( event_w - pen_drag_origin_w ) > (tolerance/2) || mevent.time == 0) { - this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); pen_drag_origin_w = event_w; } @@ -746,6 +743,7 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::POINT: if ( this->npoints == 0 ) { // Start new thread only with button release + this->_bspline_spiro_color(); if (anchor) { p = anchor->dp; } @@ -1387,42 +1385,32 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t // this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. void PenTool::_bspline_spiro_color() { - bool remake_green_bpaths = false; + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(this->spiro){ - //If the colour is not defined as trasparent, por example when changing - //from drawing to spiro mode or when selecting the pen tool - if(this->green_color != 0x00ff000){ - //We change the green and red colours to transparent, so this lines are not necessary - //to the drawing with spiro - this->red_color = 0xff00000; - this->green_color = 0x00ff000; - remake_green_bpaths = true; - } + this->red_color = 0xff00000; + this->green_color = 0x00ff000; }else if(this->bspline){ - //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent - if(this->green_color != 0xff00007f){ - //since we are not im spiro mode, we assign the original colours - //to the red and the green curve, removing their transparency - this->red_color = 0xff00007f; - //Damos color rojo a la linea verde + this->highlight_color = SP_ITEM(this->desktop->currentLayer())->highlight_color(); + if((unsigned int)prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) == this->highlight_color){ this->green_color = 0xff00007f; - remake_green_bpaths = true; + this->red_color = 0xff00007f; + } else { + this->green_color = this->highlight_color; + this->red_color = this->highlight_color; } }else{ - //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent - if(this->green_color != 0x00ff007f){ - //since we are not im spiro mode, we assign the original colours - //to the red and the green curve, removing their transparency - this->red_color = 0xff00007f; + this->highlight_color = SP_ITEM(this->desktop->currentLayer())->highlight_color(); + this->red_color = 0xff00007f; + if((unsigned int)prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) == this->highlight_color){ this->green_color = 0x00ff007f; - remake_green_bpaths = true; + } else { + this->green_color = this->highlight_color; } - //we hide the spiro/bspline rests sp_canvas_item_hide(this->blue2_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified - if (this->green_bpaths && remake_green_bpaths) { + if (this->green_bpaths) { // remove old piecewise green canvasitems while (this->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); -- cgit v1.2.3 From 8a766e96c9317858d547ccf571bbca206c8f8e1b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 24 Sep 2014 03:43:01 +0200 Subject: Now add the helper colors also to pencil helper (bzr r13341.1.221) --- src/ui/tools/pencil-tool.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 0e8660248..ca6dffc12 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -803,6 +803,7 @@ void PencilTool::_fitAndSplit() { g_assert(is_zero(this->req_tangent) || is_unit_vector(this->req_tangent)); Geom::Point const tHatEnd(0, 0); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int const n_segs = Geom::bezier_fit_cubic_full(b, NULL, this->p, this->npoints, this->req_tangent, tHatEnd, tolerance_sq, 1); @@ -816,7 +817,6 @@ void PencilTool::_fitAndSplit() { using Geom::X; using Geom::Y; // if we are in BSpline we modify the trace to create adhoc nodes - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ Geom::Point B = b[0] + (1./3)*(b[3] - b[0]); @@ -855,6 +855,13 @@ void PencilTool::_fitAndSplit() { /// \todo fixme: SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), curve); curve->unref(); + + this->highlight_color = SP_ITEM(this->desktop->currentLayer())->highlight_color(); + if((unsigned int)prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) == this->highlight_color){ + this->green_color = 0x00ff007f; + } else { + this->green_color = this->highlight_color; + } sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), this->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); this->green_bpaths = g_slist_prepend(this->green_bpaths, cshape); -- cgit v1.2.3 From 128c104aa13184648dbe91de0a2d1d4a71062938 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Sep 2014 04:01:09 +0200 Subject: Change colors of helper paths also in middle draw when change the mode -spiro, bspline...- (bzr r13341.1.222) --- src/ui/tools/pen-tool.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9a86dfe2c..ecd10b068 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -181,6 +181,7 @@ void PenTool::_pen_context_set_mode(guint mode) { // define the nodes this->spiro = (mode == 1); this->bspline = (mode == 2); + this->_bspline_spiro_color(); } /** -- cgit v1.2.3 From 9cf38f99fc246131a2f2d9c3c55617488003b3b4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 24 Sep 2014 04:56:55 +0200 Subject: A bit refactor, remove some old vars (bzr r13341.1.223) --- src/ui/tools/freehand-base.cpp | 22 ---------------------- src/ui/tools/freehand-base.h | 4 ---- src/ui/tools/pen-tool.cpp | 15 ++++++--------- 3 files changed, 6 insertions(+), 35 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bc979821a..46ab53eef 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -85,8 +85,6 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , red_curve(NULL) , blue_bpath(NULL) , blue_curve(NULL) - , blue2_bpath(NULL) - , blue2_curve(NULL) , green_bpaths(NULL) , green_curve(NULL) , green_anchor(NULL) @@ -143,13 +141,6 @@ void FreehandBase::setup() { // Create blue curve this->blue_curve = new SPCurve(); - // Create blue2 bpath - this->blue2_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue2_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - - // Create blue2 curve - this->blue2_curve = new SPCurve(); - // Create green curve this->green_curve = new SPCurve(); @@ -550,10 +541,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue_bpath), NULL); - // Blue2 - dc->blue2_curve->reset(); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - // Red if (dc->red_curve_is_valid) { c->append_continuous(dc->red_curve, 0.0625); @@ -791,15 +778,6 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue_curve = dc->blue_curve->unref(); } - // Blue2 - if (dc->blue2_bpath) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->blue2_bpath)); - dc->blue2_bpath = NULL; - } - if (dc->blue2_curve) { - dc->blue2_curve = dc->blue2_curve->unref(); - } - // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index fb2db86f6..6b4265215 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -65,10 +65,6 @@ public: SPCanvasItem *blue_bpath; SPCurve *blue_curve; - // Blue2 - SPCanvasItem *blue2_bpath; - SPCurve *blue2_curve; - // Green GSList *green_bpaths; SPCurve *green_curve; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index ecd10b068..2c5ffc182 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1327,9 +1327,6 @@ void PenTool::_resetColors() { // Blue this->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), NULL); - // Blue2 - this->blue2_curve->reset(); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue2_bpath), NULL); // Green while (this->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); @@ -1407,7 +1404,7 @@ void PenTool::_bspline_spiro_color() } else { this->green_color = this->highlight_color; } - sp_canvas_item_hide(this->blue2_bpath); + sp_canvas_item_hide(this->blue_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified @@ -1792,11 +1789,11 @@ void PenTool::_bspline_spiro_build() this->_spiro_doEffect(curve); } - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue2_bpath), curve); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue2_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_item_show(this->blue2_bpath); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_item_show(this->blue_bpath); curve->unref(); - this->blue2_curve->reset(); + this->blue_curve->reset(); //We hide the holders that doesn't contribute anything if(this->spiro){ sp_canvas_item_show(this->c1); @@ -1808,7 +1805,7 @@ void PenTool::_bspline_spiro_build() sp_canvas_item_hide(this->cl0); }else{ //if the curve is empty - sp_canvas_item_hide(this->blue2_bpath); + sp_canvas_item_hide(this->blue_bpath); } } -- cgit v1.2.3 From 3f649ca279f98542e8147e9bd5ab67691c6e21a0 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Sep 2014 21:22:34 +0200 Subject: Fix bug in object dialog, in highlight color couldent select opacity, now fixed (bzr r13341.1.224) --- src/ui/dialog/objects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index ecd4ff42f..07a27c96e 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1450,7 +1450,7 @@ void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) guint32 rgba = color.toRGBA32( alpha ); ObjectsPanel *ptr = reinterpret_cast(cp); - + //Set the highlight color for all items in the _highlight_target (all selected items) for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) { -- cgit v1.2.3 From 389581f8c8a49e7cd922a09e0088e1414a7db05b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 29 Sep 2014 03:50:36 +0200 Subject: This push add suport to helper paths redraw to nodes, handles and knots. This redraw at mouse movement. Whith knots also redraw at button release event (bzr r13341.1.227) --- src/ui/tool/node.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c52bd4c07..5d6e96588 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -27,10 +27,11 @@ #include "ui/tool/event-utils.h" #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" +#include "ui/tools/node-tool.h" +#include "tools-switch.h" #include #include - namespace { Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) @@ -329,6 +330,10 @@ bool Handle::grabbed(GdkEventMotion *) void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) { + if (tools_isactive(_desktop, TOOLS_NODES)) { + Inkscape::UI::Tools::NodeTool *nt = static_cast(_desktop->event_context); + nt->update_helperpath(); + } Geom::Point parent_pos = _parent->position(); Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; @@ -1222,6 +1227,10 @@ bool Node::grabbed(GdkEventMotion *event) void Node::dragged(Geom::Point &new_pos, GdkEventMotion *event) { + if (tools_isactive(_desktop, TOOLS_NODES)) { + Inkscape::UI::Tools::NodeTool *nt = static_cast(_desktop->event_context); + nt->update_helperpath(); + } // For a note on how snapping is implemented in Inkscape, see snap.h. SnapManager &sm = _desktop->namedview->snap_manager; // even if we won't really snap, we might still call the one of the -- cgit v1.2.3 From 3c73700a91c6dc1561b3b70dcdc0c051d23405d3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 Sep 2014 15:57:21 +0200 Subject: Remove NRTypePosDef class and associated cruft. More direct CSS -> Pango translation. (bzr r13569) --- src/ui/dialog/text-edit.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index c1ebb32e0..a00db1715 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -32,7 +32,6 @@ extern "C" { #include #include -#include #include #include -- cgit v1.2.3 From e186cf544131e582a43316767257f199e6af986c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 29 Sep 2014 16:21:07 +0200 Subject: Remove NRTypePosDef class and associated cruft. More direct CSS -> Pango translation. (bzr r13341.1.233) --- src/ui/dialog/text-edit.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index e44809c65..9996fc0f9 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -32,7 +32,6 @@ extern "C" { #include #include -#include #include #include -- cgit v1.2.3 From 9b31ef3b28b2ebb3ca258a6fb7de1524fcc17378 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 30 Sep 2014 20:06:07 +0200 Subject: change header include order to fix win64 build (bzr r13341.1.235) --- src/ui/widget/highlight-picker.cpp | 3 ++- src/ui/widget/insertordericon.cpp | 3 ++- src/ui/widget/insertordericon.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index 2afdc02a6..c03f526dc 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -11,13 +11,14 @@ # include "config.h" #endif +#include + #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif #include "display/cairo-utils.h" -#include #include "highlight-picker.h" #include "widgets/icon.h" diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp index 2f06225bc..17930daa2 100644 --- a/src/ui/widget/insertordericon.cpp +++ b/src/ui/widget/insertordericon.cpp @@ -7,6 +7,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "ui/widget/insertordericon.h" + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -15,7 +17,6 @@ #include #endif -#include "ui/widget/insertordericon.h" #include diff --git a/src/ui/widget/insertordericon.h b/src/ui/widget/insertordericon.h index 4b4b51de2..e6c2e1c5b 100644 --- a/src/ui/widget/insertordericon.h +++ b/src/ui/widget/insertordericon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { -- cgit v1.2.3 From 0b7731f9d93442ba18df146b85ce46bdb0c21220 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 1 Oct 2014 09:00:39 +0200 Subject: Fix for bug #690255 (Rename te_IN.po to te.po). Fixed bugs: - https://launchpad.net/bugs/690255 (bzr r13571) --- src/ui/dialog/inkscape-preferences.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 7d43adc0f..8d43358a7 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -526,11 +526,11 @@ void InkscapePreferences::initPageUI() _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian Bokmål (nb)"), _("Norwegian Nynorsk (nn)"), _("Panjabi (pa)"), _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), - _("Swedish (sv)"),_("Telugu (te_IN)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; + _("Swedish (sv)"),_("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "nl", "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", "gl", "he", "hu", "id", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa", - "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te_IN", "th", "tr", "uk", "vi" }; + "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te", "th", "tr", "uk", "vi" }; { // sorting languages according to translated name -- cgit v1.2.3 From 66fd1af880dddae1fa77e9c0cc22e475de4d54d2 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 2 Oct 2014 10:04:45 +0200 Subject: Fixing inconsistencies in the PixelArt dialog. (bzr r13575) --- src/ui/dialog/pixelartdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp index 2d25f54d7..5113f172a 100644 --- a/src/ui/dialog/pixelartdialog.cpp +++ b/src/ui/dialog/pixelartdialog.cpp @@ -385,8 +385,8 @@ void PixelArtDialogImpl::vectorize() if ( input.pixbuf->get_width() > 256 || input.pixbuf->get_height() > 256 ) { - char *msg = _("Image looks too big. Process may take a while and is" - " wise to save your document before continue." + char *msg = _("Image looks too big. Process may take a while and it is" + " wise to save your document before continuing." "\n\nContinue the procedure (without saving)?"); Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true); -- cgit v1.2.3 From 50a19700fb02a712803aa3623f0920d562116534 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 2 Oct 2014 10:32:46 +0200 Subject: i18n. Fix for Bug #380522 (strings that need to be fixed for translation). Translations. Inkscape.pot and French translation update. Fixed bugs: - https://launchpad.net/bugs/380522 (bzr r13576) --- src/ui/dialog/filter-effects-dialog.cpp | 2 +- src/ui/dialog/inkscape-preferences.cpp | 8 ++++---- src/ui/dialog/input.cpp | 2 +- src/ui/widget/selected-style.cpp | 6 +++++- 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index c2367c2a2..bd44846a3 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -546,7 +546,7 @@ public: _matrix(SP_ATTR_VALUES, _("This matrix determines a linear transform on color space. Each line affects one of the color components. Each column determines how much of each color component from the input is passed to the output. The last column does not depend on input colors, so can be used to adjust a constant component value.")), _saturation("", 0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES), _angle("", 0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES), - _label(_("None"), Gtk::ALIGN_START), + _label(C_("Label", "None"), Gtk::ALIGN_START), _use_stored(false), _saturation_store(0), _angle_store(0) diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 8d43358a7..c2da12058 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -331,7 +331,7 @@ void InkscapePreferences::initPageTools() _page_selector.add_line( true, "", _t_sel_trans_outl, "", _("Show only a box outline of the objects when moving or transforming")); _page_selector.add_group_header( _("Per-object selection cue")); - _t_sel_cue_none.init ( _("None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0); + _t_sel_cue_none.init ( C_("Selection cue", "None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0); _page_selector.add_line( true, "", _t_sel_cue_none, "", _("No per-object selection indication")); _t_sel_cue_mark.init ( _("Mark"), "/options/selcue/value", Inkscape::SelCue::MARK, true, &_t_sel_cue_none); @@ -642,7 +642,7 @@ void InkscapePreferences::initPageUI() _win_save_viewport.init ( _("Save and restore documents viewport"), "/options/savedocviewport/value", true); _win_zoom_resize.init ( _("Zoom when window is resized"), "/options/stickyzoom/value", false); _win_show_close.init ( _("Show close button on dialogs"), "/dialogs/showclose", false); - _win_ontop_none.init ( _("None"), "/options/transientpolicy/value", 0, false, 0); + _win_ontop_none.init ( C_("Dialog on top", "None"), "/options/transientpolicy/value", 0, false, 0); _win_ontop_normal.init ( _("Normal"), "/options/transientpolicy/value", 1, true, &_win_ontop_none); _win_ontop_agressive.init ( _("Aggressive"), "/options/transientpolicy/value", 2, false, &_win_ontop_none); @@ -1260,7 +1260,7 @@ void InkscapePreferences::initPageBehavior() _page_steps.add_line( false, "", _steps_compass, "", _("When on, angles are displayed with 0 at north, 0 to 360 range, positive clockwise; otherwise with 0 at east, -180 to 180 range, positive counterclockwise")); int const num_items = 17; - Glib::ustring labels[num_items] = {"90", "60", "45", "36", "30", "22.5", "18", "15", "12", "10", "7.5", "6", "3", "2", "1", "0.5", _("None")}; + Glib::ustring labels[num_items] = {"90", "60", "45", "36", "30", "22.5", "18", "15", "12", "10", "7.5", "6", "3", "2", "1", "0.5", C_("Rotation angle", "None")}; int values[num_items] = {2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 24, 30, 60, 90, 180, 360, 0}; _steps_rot_snap.set_size_request(_sb_width); _steps_rot_snap.init("/options/rotationsnapsperpi/value", labels, values, num_items, 12); @@ -1836,7 +1836,7 @@ void InkscapePreferences::initPageSpellcheck() AspellDictInfoEnumeration *dels = aspell_dict_info_list_elements(dlist); - languages.push_back(Glib::ustring(_("None"))); + languages.push_back(Glib::ustring(C_("Spellchecker language", "None"))); langValues.push_back(Glib::ustring("")); const AspellDictInfo *entry; diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 4be6716a5..8343cd6fe 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -1622,7 +1622,7 @@ void InputDialogImpl::ConfPanel::setAxis(gint count) if (barNum < count) { row[axisColumns.value] = Glib::ustring::format(barNum+1); } else { - row[axisColumns.value] = _("None"); + row[axisColumns.value] = C_("Input device axe", "None"); } } diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 042a6614e..f01366e19 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -179,7 +179,11 @@ SelectedStyle::SelectedStyle(bool /*layout*/) _na[i].show_all(); __na[i] = (_("Nothing selected")); - _none[i].set_markup (C_("Fill and stroke", "None")); + if (i == SS_FILL) { + _none[i].set_markup (C_("Fill", "None")); + } else { + _none[i].set_markup (C_("Stroke", "None")); + } sp_set_font_size_smaller (GTK_WIDGET(_none[i].gobj())); _none[i].show_all(); __none[i] = (i == SS_FILL)? (C_("Fill and stroke", "No fill")) : (C_("Fill and stroke", "No stroke")); -- cgit v1.2.3 From 380f71793aba455f86eae2c75532b24dc613e71d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 3 Oct 2014 21:32:26 -0400 Subject: Refactor SPGuide to use more C++ (bzr r13341.1.241) --- src/ui/dialog/guides.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 76c26a3cb..4519a905f 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -100,7 +100,7 @@ void GuidelinePropertiesDialog::_onOK() double rad_angle = Geom::deg_to_rad( deg_angle ); normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0)); } - sp_guide_set_normal(*_guide, normal, true); + _guide->set_normal(normal, true); double const points_x = _spin_button_x.getValue("px"); double const points_y = _spin_button_y.getValue("px"); @@ -108,11 +108,11 @@ void GuidelinePropertiesDialog::_onOK() if (!_mode) newpos += _oldpos; - sp_guide_moveto(*_guide, newpos, true); + _guide->moveto(newpos, true); const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() ); - sp_guide_set_label(*_guide, name, true); + _guide->set_label(name, true); g_free((gpointer) name); #if WITH_GTKMM_3_0 @@ -124,7 +124,7 @@ void GuidelinePropertiesDialog::_onOK() #endif //TODO: why 257? verify this! - sp_guide_set_color(*_guide, r, g, b, true); + _guide->set_color(r, g, b, true); DocumentUndo::done(_guide->document, SP_VERB_NONE, _("Set guide properties")); @@ -295,16 +295,17 @@ void GuidelinePropertiesDialog::_setup() { signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response)); // initialize dialog - _oldpos = _guide->point_on_line; + _oldpos = _guide->getPoint(); if (_guide->isVertical()) { _oldangle = 90; } else if (_guide->isHorizontal()) { _oldangle = 0; } else { - _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) ); + _oldangle = Geom::rad_to_deg( std::atan2( - _guide->getNormal()[Geom::X], _guide->getNormal()[Geom::Y] ) ); } { + // FIXME holy crap!!! Inkscape::XML::Node *repr = _guide->getRepr(); const gchar *guide_id = repr->attribute("id"); gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id); @@ -312,7 +313,7 @@ void GuidelinePropertiesDialog::_setup() { g_free(label); } { - gchar *guide_description = sp_guide_description(_guide, false); + gchar *guide_description = _guide->description(false); gchar *label = g_strdup_printf(_("Current: %s"), guide_description); g_free(guide_description); _label_descr.set_markup(label); @@ -320,15 +321,15 @@ void GuidelinePropertiesDialog::_setup() { } // init name entry - _label_entry.getEntry()->set_text(_guide->label ? _guide->label : ""); + _label_entry.getEntry()->set_text(_guide->getLabel() ? _guide->getLabel() : ""); #if WITH_GTKMM_3_0 Gdk::RGBA c; - c.set_rgba(((_guide->color>>24)&0xff) / 255.0, ((_guide->color>>16)&0xff) / 255.0, ((_guide->color>>8)&0xff) / 255.0); + 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); #else Gdk::Color c; - c.set_rgb_p(((_guide->color>>24)&0xff) / 255.0, ((_guide->color>>16)&0xff) / 255.0, ((_guide->color>>8)&0xff) / 255.0); + c.set_rgb_p(((_guide->getColor()>>24)&0xff) / 255.0, ((_guide->getColor()>>16)&0xff) / 255.0, ((_guide->getColor()>>8)&0xff) / 255.0); _color.set_color(c); #endif -- cgit v1.2.3 From efd39893a4f5e629a9df2d0674222aea1be14199 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 12:38:15 -0400 Subject: Move obvious ui component to ui/ (bzr r13341.1.247) --- src/ui/Makefile_insert | 2 + src/ui/dialog/clonetiler.cpp | 2 +- src/ui/dialog/dialog.cpp | 2 +- src/ui/dialog/dock-behavior.cpp | 2 +- src/ui/dialog/export.cpp | 2 +- src/ui/dialog/extension-editor.cpp | 2 +- src/ui/dialog/filedialogimpl-gtkmm.cpp | 2 +- src/ui/dialog/find.cpp | 2 +- src/ui/dialog/floating-behavior.cpp | 2 +- src/ui/dialog/ocaldialogs.cpp | 2 +- src/ui/dialog/spellcheck.cpp | 2 +- src/ui/dialog/template-load-tab.cpp | 2 +- src/ui/dialog/text-edit.cpp | 2 +- src/ui/dialog/xml-tree.cpp | 2 +- src/ui/interface.cpp | 2230 ++++++++++++++++++++++++++++++++ src/ui/interface.h | 277 ++++ src/ui/tools/tool-base.cpp | 2 +- 17 files changed, 2523 insertions(+), 14 deletions(-) create mode 100644 src/ui/interface.cpp create mode 100644 src/ui/interface.h (limited to 'src/ui') diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index 94064d0cf..4c6b49ed6 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -9,6 +9,8 @@ ink_common_sources += \ ui/dialog-events.cpp \ ui/dialog-events.h \ ui/icon-names.h \ + ui/interface.cpp \ + ui/interface.h \ ui/previewable.h \ ui/previewfillable.h \ ui/previewholder.cpp \ diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index d9e2c03ba..1d6d0403e 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -38,7 +38,7 @@ #include "util/units.h" #include "helper/window.h" #include "inkscape.h" -#include "interface.h" +#include "ui/interface.h" #include "macros.h" #include "message-stack.h" #include "preferences.h" diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 4f0d9fbe1..213965a18 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -28,7 +28,7 @@ #include "desktop-handles.h" #include "shortcuts.h" #include "preferences.h" -#include "interface.h" +#include "ui/interface.h" #include "verbs.h" #include "ui/tool/event-utils.h" diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp index f65b298c9..50a6db208 100644 --- a/src/ui/dialog/dock-behavior.cpp +++ b/src/ui/dialog/dock-behavior.cpp @@ -18,7 +18,7 @@ #include "dock-behavior.h" #include "inkscape.h" #include "desktop.h" -#include "interface.h" +#include "ui/interface.h" #include "widgets/icon.h" #include "ui/widget/dock.h" #include "verbs.h" diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index cd8fdbd92..a4d8801f7 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -65,7 +65,7 @@ #include "ui/dialog-events.h" #include "preferences.h" #include "verbs.h" -#include "interface.h" +#include "ui/interface.h" #include "sp-root.h" #include "extension/output.h" diff --git a/src/ui/dialog/extension-editor.cpp b/src/ui/dialog/extension-editor.cpp index cd5491c24..9bdddc0e0 100644 --- a/src/ui/dialog/extension-editor.cpp +++ b/src/ui/dialog/extension-editor.cpp @@ -25,7 +25,7 @@ #include "verbs.h" #include "preferences.h" -#include "interface.h" +#include "ui/interface.h" #include "extension/extension.h" #include "extension/db.h" diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 5778b44db..511237f4d 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -23,7 +23,7 @@ #include "filedialogimpl-gtkmm.h" #include "ui/dialog-events.h" -#include "interface.h" +#include "ui/interface.h" #include "io/sys.h" #include "path-prefix.h" #include "preferences.h" diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 9b814bb9f..1a4823e4a 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -33,7 +33,7 @@ #include "ui/dialog-events.h" #include "verbs.h" -#include "interface.h" +#include "ui/interface.h" #include "preferences.h" #include "sp-text.h" #include "sp-flowtext.h" diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index f286588b2..11db14801 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -29,7 +29,7 @@ #include "inkscape.h" #include "desktop.h" #include "ui/dialog-events.h" -#include "interface.h" +#include "ui/interface.h" #include "preferences.h" #include "verbs.h" diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index 607087f6d..c4dd9df98 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -25,7 +25,7 @@ #include "path-prefix.h" #include "filedialogimpl-gtkmm.h" -#include "interface.h" +#include "ui/interface.h" #include "gc-core.h" #include "ui/dialog-events.h" #include "io/sys.h" diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index a887a7355..b8436ebf1 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -25,7 +25,7 @@ #include "desktop-handles.h" #include "tools-switch.h" #include "ui/tools/text-tool.h" -#include "interface.h" +#include "ui/interface.h" #include "preferences.h" #include "sp-text.h" #include "sp-flowtext.h" diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index d75f81456..13cb01eef 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -24,7 +24,7 @@ #include "extension/db.h" #include "extension/effect.h" #include "inkscape.h" -#include "interface.h" +#include "ui/interface.h" #include "file.h" #include "path-prefix.h" #include "preferences.h" diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 9996fc0f9..0f4a6f7f1 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -51,7 +51,7 @@ extern "C" { #include "ui/icon-names.h" #include "preferences.h" #include "verbs.h" -#include "interface.h" +#include "ui/interface.h" #include "svg/css-ostringstream.h" #include "widgets/icon.h" #include "widgets/font-selector.h" diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 9a8c188b2..7ab6c78ba 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -30,7 +30,7 @@ #include "ui/tools/tool-base.h" #include "helper/window.h" #include "inkscape.h" -#include "interface.h" +#include "ui/interface.h" #include "macros.h" #include "message-context.h" #include "message-stack.h" diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp new file mode 100644 index 000000000..7830a8de1 --- /dev/null +++ b/src/ui/interface.cpp @@ -0,0 +1,2230 @@ +/** + * @file + * Main UI stuff. + */ +/* Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * Jon A. Cruz + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2012 Kris De Gussem + * Copyright (C) 2010 authors + * Copyright (C) 1999-2005 authors + * Copyright (C) 2004 David Turner + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ui/dialog/dialog-manager.h" +#include +#include "file.h" +#include +#include + +#include "inkscape-private.h" +#include "extension/db.h" +#include "extension/effect.h" +#include "extension/input.h" +#include "widgets/icon.h" +#include "preferences.h" +#include "path-prefix.h" +#include "shortcuts.h" +#include "document.h" +#include "desktop-handles.h" +#include "ui/interface.h" +#include "desktop.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "svg-view-widget.h" +#include "widgets/desktop-widget.h" +#include "sp-item-group.h" +#include "sp-text.h" +#include "sp-gradient.h" +#include "sp-flowtext.h" +#include "sp-namedview.h" +#include "sp-root.h" +#include "ui/view/view.h" +#include "helper/action.h" +#include "helper/action-context.h" +#include "helper/gnome-utils.h" +#include "helper/window.h" +#include "io/sys.h" +#include "ui/dialog-events.h" +#include "message-context.h" +#include "ui/uxmanager.h" +#include "ui/clipboard.h" + +#include "display/sp-canvas.h" +#include "color.h" +#include "svg/svg-color.h" +#include "desktop-style.h" +#include "style.h" +#include "ui/tools/tool-base.h" +#include "gradient-drag.h" +#include "widgets/ege-paint-def.h" +#include "document-undo.h" +#include "sp-anchor.h" +#include "sp-clippath.h" +#include "sp-image.h" +#include "sp-item.h" +#include "sp-mask.h" +#include "message-stack.h" +#include "ui/dialog/layer-properties.h" + +#include + +#include + +using Inkscape::DocumentUndo; + +/* Drag and Drop */ +typedef enum { + URI_LIST, + SVG_XML_DATA, + SVG_DATA, + PNG_DATA, + JPEG_DATA, + IMAGE_DATA, + APP_X_INKY_COLOR, + APP_X_COLOR, + APP_OSWB_COLOR, + APP_X_INK_PASTE +} ui_drop_target_info; + +static GtkTargetEntry ui_drop_target_entries [] = { + {(gchar *)"text/uri-list", 0, URI_LIST }, + {(gchar *)"image/svg+xml", 0, SVG_XML_DATA }, + {(gchar *)"image/svg", 0, SVG_DATA }, + {(gchar *)"image/png", 0, PNG_DATA }, + {(gchar *)"image/jpeg", 0, JPEG_DATA }, +#if ENABLE_MAGIC_COLORS + {(gchar *)"application/x-inkscape-color", 0, APP_X_INKY_COLOR}, +#endif // ENABLE_MAGIC_COLORS + {(gchar *)"application/x-oswb-color", 0, APP_OSWB_COLOR }, + {(gchar *)"application/x-color", 0, APP_X_COLOR }, + {(gchar *)"application/x-inkscape-paste", 0, APP_X_INK_PASTE } +}; + +static GtkTargetEntry *completeDropTargets = 0; +static int completeDropTargetsCount = 0; +static bool temporarily_block_actions = false; + +#define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0]) +static guint nui_drop_target_entries = ENTRIES_SIZE(ui_drop_target_entries); +static void sp_ui_import_files(gchar *buffer); +static void sp_ui_import_one_file(char const *filename); +static void sp_ui_import_one_file_with_check(gpointer filename, gpointer unused); +static void sp_ui_drag_data_received(GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data); +static void sp_ui_drag_motion( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data ); +static void sp_ui_drag_leave( GtkWidget *widget, + GdkDragContext *drag_context, + guint event_time, + gpointer user_data ); +static void sp_ui_menu_item_set_name(GtkWidget *data, + Glib::ustring const &name); +static void sp_recent_open(GtkRecentChooser *, gpointer); + +static void injectRenamedIcons(); + +static const int MIN_ONSCREEN_DISTANCE = 50; + +void +sp_create_window(SPViewWidget *vw, bool editable) +{ + g_return_if_fail(vw != NULL); + g_return_if_fail(SP_IS_VIEW_WIDGET(vw)); + + Gtk::Window *win = Inkscape::UI::window_new("", TRUE); + + gtk_container_add(GTK_CONTAINER(win->gobj()), GTK_WIDGET(vw)); + gtk_widget_show(GTK_WIDGET(vw)); + + if (editable) { + g_object_set_data(G_OBJECT(vw), "window", win); + + SPDesktopWidget *desktop_widget = reinterpret_cast(vw); + SPDesktop* desktop = desktop_widget->desktop; + + desktop_widget->window = win; + + win->set_data("desktop", desktop); + win->set_data("desktopwidget", desktop_widget); + + win->signal_delete_event().connect(sigc::mem_fun(*(SPDesktop*)vw->view, &SPDesktop::onDeleteUI)); + win->signal_window_state_event().connect(sigc::mem_fun(*desktop, &SPDesktop::onWindowStateEvent)); + win->signal_focus_in_event().connect(sigc::mem_fun(*desktop_widget, &SPDesktopWidget::onFocusInEvent)); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint prefs_geometry = + (2==prefs->getInt("/options/savewindowgeometry/value", 0)); + if (prefs_geometry) { + gint pw = prefs->getInt("/desktop/geometry/width", -1); + gint ph = prefs->getInt("/desktop/geometry/height", -1); + gint px = prefs->getInt("/desktop/geometry/x", -1); + gint py = prefs->getInt("/desktop/geometry/y", -1); + gint full = prefs->getBool("/desktop/geometry/fullscreen"); + gint maxed = prefs->getBool("/desktop/geometry/maximized"); + if (pw>0 && ph>0) { + gint w = MIN(gdk_screen_width(), pw); + gint h = MIN(gdk_screen_height(), ph); + gint x = MIN(gdk_screen_width() - MIN_ONSCREEN_DISTANCE, px); + gint y = MIN(gdk_screen_height() - MIN_ONSCREEN_DISTANCE, py); + if (w>0 && h>0) { + x = MIN(gdk_screen_width() - w, x); + y = MIN(gdk_screen_height() - h, y); + desktop->setWindowSize(w, h); + } + + // Only restore xy for the first window so subsequent windows don't overlap exactly + // with first. (Maybe rule should be only restore xy if it's different from xy of + // other desktops?) + + // Empirically it seems that active_desktop==this desktop only the first time a + // desktop is created. + SPDesktop *active_desktop = SP_ACTIVE_DESKTOP; + if (active_desktop == desktop || active_desktop==NULL) { + desktop->setWindowPosition(Geom::Point(x, y)); + } + } + if (maxed) { + win->maximize(); + } + if (full) { + win->fullscreen(); + } + } + + } + + if ( completeDropTargets == 0 || completeDropTargetsCount == 0 ) + { + std::vector types; + + GSList *list = gdk_pixbuf_get_formats(); + while ( list ) { + int i = 0; + GdkPixbufFormat *one = (GdkPixbufFormat*)list->data; + gchar** typesXX = gdk_pixbuf_format_get_mime_types(one); + for ( i = 0; typesXX[i]; i++ ) { + types.push_back(g_strdup(typesXX[i])); + } + g_strfreev(typesXX); + + list = g_slist_next(list); + } + completeDropTargetsCount = nui_drop_target_entries + types.size(); + completeDropTargets = new GtkTargetEntry[completeDropTargetsCount]; + for ( int i = 0; i < (int)nui_drop_target_entries; i++ ) { + completeDropTargets[i] = ui_drop_target_entries[i]; + } + int pos = nui_drop_target_entries; + + for (std::vector::iterator it = types.begin() ; it != types.end() ; it++) { + completeDropTargets[pos].target = *it; + completeDropTargets[pos].flags = 0; + completeDropTargets[pos].info = IMAGE_DATA; + pos++; + } + } + + gtk_drag_dest_set((GtkWidget*)win->gobj(), + GTK_DEST_DEFAULT_ALL, + completeDropTargets, + completeDropTargetsCount, + GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE)); + + + g_signal_connect(G_OBJECT(win->gobj()), + "drag_data_received", + G_CALLBACK(sp_ui_drag_data_received), + NULL); + g_signal_connect(G_OBJECT(win->gobj()), + "drag_motion", + G_CALLBACK(sp_ui_drag_motion), + NULL); + g_signal_connect(G_OBJECT(win->gobj()), + "drag_leave", + G_CALLBACK(sp_ui_drag_leave), + NULL); + win->show(); + + // needed because the first ACTIVATE_DESKTOP was sent when there was no window yet + if ( SP_IS_DESKTOP_WIDGET(vw) ) { + inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); + } +} + +void +sp_ui_new_view() +{ + SPDocument *document; + SPViewWidget *dtw; + + document = SP_ACTIVE_DOCUMENT; + if (!document) return; + + dtw = sp_desktop_widget_new(sp_document_namedview(document, NULL)); + g_return_if_fail(dtw != NULL); + + sp_create_window(dtw, TRUE); + sp_namedview_window_from_document(static_cast(dtw->view)); + sp_namedview_update_layers_from_document(static_cast(dtw->view)); +} + +void sp_ui_new_view_preview() +{ + SPDocument *document = SP_ACTIVE_DOCUMENT; + if ( document ) { + SPViewWidget *dtw = reinterpret_cast(sp_svg_view_widget_new(document)); + g_return_if_fail(dtw != NULL); + SP_SVG_VIEW_WIDGET(dtw)->setResize(true, 400.0, 400.0); + + sp_create_window(dtw, FALSE); + } +} + +void +sp_ui_close_view(GtkWidget */*widget*/) +{ + SPDesktop *dt = SP_ACTIVE_DESKTOP; + + if (dt == NULL) { + return; + } + + if (dt->shutdown()) { + return; // Shutdown operation has been canceled, so do nothing + } + + // If closing the last document, open a new document so Inkscape doesn't quit. + std::list desktops; + inkscape_get_all_desktops(desktops); + if (desktops.size() == 1) { + Glib::ustring templateUri = sp_file_default_template_uri(); + SPDocument *doc = SPDocument::createNewDoc( templateUri.c_str() , TRUE, true ); + // Set viewBox if it doesn't exist + if (!doc->getRoot()->viewBox_set) { + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); + } + dt->change_document(doc); + sp_namedview_window_from_document(dt); + sp_namedview_update_layers_from_document(dt); + return; + } + + // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP, + // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad) + dt->destroyWidget(); +} + + +unsigned int +sp_ui_close_all(void) +{ + /* Iterate through all the windows, destroying each in the order they + become active */ + while (SP_ACTIVE_DESKTOP) { + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (dt->shutdown()) { + /* The user canceled the operation, so end doing the close */ + return FALSE; + } + // Shutdown can proceed; use the stored reference to the desktop here instead of the current SP_ACTIVE_DESKTOP, + // because the user might have changed the focus in the meantime (see bug #381357 on Launchpad) + dt->destroyWidget(); + } + + return TRUE; +} + +/* + * Some day when the right-click menus are ready to start working + * smarter with the verbs, we'll need to change this NULL being + * sent to sp_action_perform to something useful, or set some kind + * of global "right-clicked position" variable for actions to + * investigate when they're called. + */ +static void +sp_ui_menu_activate(void */*object*/, SPAction *action) +{ + if (!temporarily_block_actions) { + sp_action_perform(action, NULL); + } +} + +static void +sp_ui_menu_select_action(void */*object*/, SPAction *action) +{ + sp_action_get_view(action)->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, action->tip); +} + +static void +sp_ui_menu_deselect_action(void */*object*/, SPAction *action) +{ + sp_action_get_view(action)->tipsMessageContext()->clear(); +} + +static void +sp_ui_menu_select(gpointer object, gpointer tip) +{ + Inkscape::UI::View::View *view = static_cast (g_object_get_data(G_OBJECT(object), "view")); + view->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, (gchar *)tip); +} + +static void +sp_ui_menu_deselect(gpointer object) +{ + Inkscape::UI::View::View *view = static_cast (g_object_get_data(G_OBJECT(object), "view")); + view->tipsMessageContext()->clear(); +} + +/** + * Creates and attaches a scaled icon to the given menu item. + */ +static void +sp_ui_menuitem_add_icon( GtkWidget *item, gchar *icon_name ) +{ + static bool iconsInjected = false; + if ( !iconsInjected ) { + iconsInjected = true; + injectRenamedIcons(); + } + GtkWidget *icon; + + icon = sp_icon_new( Inkscape::ICON_SIZE_MENU, icon_name ); + gtk_widget_show(icon); + gtk_image_menu_item_set_image((GtkImageMenuItem *) item, icon); +} // end of sp_ui_menu_add_icon + +void +sp_ui_dialog_title_string(Inkscape::Verb *verb, gchar *c) +{ + SPAction *action; + unsigned int shortcut; + gchar *s; + gchar *atitle; + + action = verb->get_action(Inkscape::ActionContext()); + if (!action) + return; + + atitle = sp_action_get_title(action); + + s = g_stpcpy(c, atitle); + + g_free(atitle); + + shortcut = sp_shortcut_get_primary(verb); + if (shortcut!=GDK_KEY_VoidSymbol) { + gchar* key = sp_shortcut_get_label(shortcut); + s = g_stpcpy(s, " ("); + s = g_stpcpy(s, key); + s = g_stpcpy(s, ")"); + g_free(key); + } +} + + +/** + * Appends a custom menu UI from a verb. + * + * @see ContextMenu::AppendItemFromVerb for a c++ified alternative. Consider dropping sp_ui_menu_append_item_from_verb when c++ifying interface.cpp. + */ +static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape::UI::View::View *view, bool radio = false, GSList *group = NULL) +{ + SPAction *action; + GtkWidget *item; + + if (verb->get_code() == SP_VERB_NONE) { + + item = gtk_separator_menu_item_new(); + + } else { + + action = verb->get_action(Inkscape::ActionContext(view)); + if (!action) return NULL; + + if (radio) { + item = gtk_radio_menu_item_new_with_mnemonic(group, action->name); + } else { + item = gtk_image_menu_item_new_with_mnemonic(action->name); + } + + gtk_label_set_markup_with_mnemonic( GTK_LABEL(gtk_bin_get_child(GTK_BIN (item))), action->name); + + GtkAccelGroup *accel_group = sp_shortcut_get_accel_group(); + gtk_menu_set_accel_group(menu, accel_group); + + sp_shortcut_add_accelerator(item, sp_shortcut_get_primary(verb)); + + action->signal_set_sensitive.connect( + sigc::bind<0>( + sigc::ptr_fun(>k_widget_set_sensitive), + item)); + action->signal_set_name.connect( + sigc::bind<0>( + sigc::ptr_fun(&sp_ui_menu_item_set_name), + item)); + + if (!action->sensitive) { + gtk_widget_set_sensitive(item, FALSE); + } + + if (action->image) { + sp_ui_menuitem_add_icon(item, action->image); + } + gtk_widget_set_events(item, GDK_KEY_PRESS_MASK); + g_object_set_data(G_OBJECT(item), "view", (gpointer) view); + g_signal_connect( G_OBJECT(item), "activate", G_CALLBACK(sp_ui_menu_activate), action ); + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select_action), action ); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect_action), action ); + } + + gtk_widget_show(item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + return item; + +} // end of sp_ui_menu_append_item_from_verb + + +Glib::ustring getLayoutPrefPath( Inkscape::UI::View::View *view ) +{ + Glib::ustring prefPath; + + if (reinterpret_cast(view)->is_focusMode()) { + prefPath = "/focus/"; + } else if (reinterpret_cast(view)->is_fullscreen()) { + prefPath = "/fullscreen/"; + } else { + prefPath = "/window/"; + } + + return prefPath; +} + +static void +checkitem_toggled(GtkCheckMenuItem *menuitem, gpointer user_data) +{ + gchar const *pref = (gchar const *) user_data; + Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); + SPAction *action = (SPAction *) g_object_get_data(G_OBJECT(menuitem), "action"); + + if (action) { + + sp_ui_menu_activate(menuitem, action); + + } else if (pref) { + // All check menu items should have actions now, but just in case + Glib::ustring pref_path = getLayoutPrefPath( view ); + pref_path += pref; + pref_path += "/state"; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean checked = gtk_check_menu_item_get_active(menuitem); + prefs->setBool(pref_path, checked); + + reinterpret_cast(view)->layoutWidget(); + } +} + +static bool getViewStateFromPref(Inkscape::UI::View::View *view, gchar const *pref) +{ + Glib::ustring pref_path = getLayoutPrefPath( view ); + pref_path += pref; + pref_path += "/state"; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + return prefs->getBool(pref_path, true); +} + +#if GTK_CHECK_VERSION(3,0,0) +static gboolean checkitem_update(GtkWidget *widget, cairo_t * /*cr*/, gpointer user_data) +#else +static gboolean checkitem_update(GtkWidget *widget, GdkEventExpose * /*event*/, gpointer user_data) +#endif +{ + GtkCheckMenuItem *menuitem=GTK_CHECK_MENU_ITEM(widget); + + gchar const *pref = (gchar const *) user_data; + Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); + SPAction *action = (SPAction *) g_object_get_data(G_OBJECT(menuitem), "action"); + SPDesktop *dt = static_cast(view); + + bool ison = false; + if (action) { + + if (!strcmp(action->id, "ToggleGrid")) { + ison = dt->gridsEnabled(); + } + else if (!strcmp(action->id, "ToggleGuides")) { + ison = dt->namedview->getGuides(); + } + else if (!strcmp(action->id, "ViewCmsToggle")) { + ison = dt->colorProfAdjustEnabled(); + } + else { + ison = getViewStateFromPref(view, pref); + } + } else if (pref) { + // The Show/Hide menu items without actions + ison = getViewStateFromPref(view, pref); + } + + g_signal_handlers_block_by_func(G_OBJECT(menuitem), (gpointer)(GCallback)checkitem_toggled, user_data); + gtk_check_menu_item_set_active(menuitem, ison); + g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), (gpointer)(GCallback)checkitem_toggled, user_data); + + return FALSE; +} + + +static void taskToggled(GtkCheckMenuItem *menuitem, gpointer userData) +{ + if ( gtk_check_menu_item_get_active(menuitem) ) { + gint taskNum = GPOINTER_TO_INT(userData); + taskNum = (taskNum < 0) ? 0 : (taskNum > 2) ? 2 : taskNum; + + Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); + + // note: this will change once more options are in the task set support: + Inkscape::UI::UXManager::getInstance()->setTask( dynamic_cast(view), taskNum ); + } +} + + +/** + * Callback function to update the status of the radio buttons in the View -> Display mode menu (Normal, No Filters, Outline) and Color display mode. + */ +#if GTK_CHECK_VERSION(3,0,0) +static gboolean update_view_menu(GtkWidget *widget, cairo_t * /*cr*/, gpointer user_data) +#else +static gboolean update_view_menu(GtkWidget *widget, GdkEventExpose * /*event*/, gpointer user_data) +#endif +{ + SPAction *action = (SPAction *) user_data; + g_assert(action->id != NULL); + + Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(widget), "view"); + SPDesktop *dt = static_cast(view); + Inkscape::RenderMode mode = dt->getMode(); + Inkscape::ColorMode colormode = dt->getColorMode(); + + bool new_state = false; + if (!strcmp(action->id, "ViewModeNormal")) { + new_state = mode == Inkscape::RENDERMODE_NORMAL; + } else if (!strcmp(action->id, "ViewModeNoFilters")) { + new_state = mode == Inkscape::RENDERMODE_NO_FILTERS; + } else if (!strcmp(action->id, "ViewModeOutline")) { + new_state = mode == Inkscape::RENDERMODE_OUTLINE; + } else if (!strcmp(action->id, "ViewColorModeNormal")) { + new_state = colormode == Inkscape::COLORMODE_NORMAL; + } else if (!strcmp(action->id, "ViewColorModeGrayscale")) { + new_state = colormode == Inkscape::COLORMODE_GRAYSCALE; + } else if (!strcmp(action->id, "ViewColorModePrintColorsPreview")) { + new_state = colormode == Inkscape::COLORMODE_PRINT_COLORS_PREVIEW; + } else { + g_warning("update_view_menu does not handle this verb"); + } + + if (new_state) { //only one of the radio buttons has to be activated; the others will automatically be deactivated + if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget))) { + // When the GtkMenuItem version of the "activate" signal has been emitted by a GtkRadioMenuItem, there is a second + // emission as the most recently active item is toggled to inactive. This is dealt with before the original signal is handled. + // This emission however should not invoke any actions, hence we block it here: + temporarily_block_actions = true; + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (widget), TRUE); + temporarily_block_actions = false; + } + } + + return FALSE; +} + +static void +sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View *view, gchar const *label, gchar const *tip, gchar const *pref, + void (*callback_toggle)(GtkCheckMenuItem *, gpointer user_data), +#if GTK_CHECK_VERSION(3,0,0) + gboolean (*callback_update)(GtkWidget *widget, cairo_t *cr, gpointer user_data), +#else + gboolean (*callback_update)(GtkWidget *widget, GdkEventExpose *event, gpointer user_data), +#endif + Inkscape::Verb *verb) +{ + unsigned int shortcut = (verb) ? sp_shortcut_get_primary(verb) : 0; + SPAction *action = (verb) ? verb->get_action(Inkscape::ActionContext(view)) : 0; + GtkWidget *item = gtk_check_menu_item_new_with_mnemonic(action ? action->name : label); + +#if 0 + if (!action->sensitive) { + gtk_widget_set_sensitive(item, FALSE); + } +#endif + + sp_shortcut_add_accelerator(item, shortcut); + + gtk_widget_show(item); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + g_object_set_data(G_OBJECT(item), "view", (gpointer) view); + g_object_set_data(G_OBJECT(item), "action", (gpointer) action); + + g_signal_connect( G_OBJECT(item), "toggled", (GCallback) callback_toggle, (void *) pref); + +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect( G_OBJECT(item), "draw", (GCallback) callback_update, (void *) pref); +#else + g_signal_connect( G_OBJECT(item), "expose_event", (GCallback) callback_update, (void *) pref); +#endif + + (*callback_update)(item, NULL, (void *)pref); + + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), (gpointer) (action ? action->tip : tip)); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), NULL); + +} + +static void +sp_recent_open(GtkRecentChooser *recent_menu, gpointer /*user_data*/) +{ + // dealing with the bizarre filename convention in Inkscape for now + gchar *uri = gtk_recent_chooser_get_current_uri(GTK_RECENT_CHOOSER(recent_menu)); + gchar *local_fn = g_filename_from_uri(uri, NULL, NULL); + gchar *utf8_fn = g_filename_to_utf8(local_fn, -1, NULL, NULL, NULL); + sp_file_open(utf8_fn, NULL); + g_free(utf8_fn); + g_free(local_fn); + g_free(uri); +} + +static void +sp_ui_checkboxes_menus(GtkMenu *m, Inkscape::UI::View::View *view) +{ + //sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", + // checkitem_toggled, checkitem_update, 0); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "commands", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_COMMANDS_TOOLBAR)); + sp_ui_menu_append_check_item_from_verb(m, view,NULL, NULL, "snaptoolbox", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_SNAP_TOOLBAR)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "toppanel", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_TOOL_TOOLBAR)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "toolbox", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_TOOLBOX)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "rulers", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_RULERS)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "scrollbars", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_SCROLLBARS)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "panels", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_PALETTE)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "statusbar", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_STATUSBAR)); +} + + +static void addTaskMenuItems(GtkMenu *menu, Inkscape::UI::View::View *view) +{ + gchar const* data[] = { + C_("Interface setup", "Default"), _("Default interface setup"), + C_("Interface setup", "Custom"), _("Setup for custom task"), + C_("Interface setup", "Wide"), _("Setup for widescreen work"), + 0, 0 + }; + + GSList *group = 0; + int count = 0; + gint active = Inkscape::UI::UXManager::getInstance()->getDefaultTask( dynamic_cast(view) ); + for (gchar const **strs = data; strs[0]; strs += 2, count++) + { + GtkWidget *item = gtk_radio_menu_item_new_with_label( group, strs[0] ); + group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) ); + if ( count == active ) + { + gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), TRUE ); + } + + g_object_set_data( G_OBJECT(item), "view", view ); + g_signal_connect( G_OBJECT(item), "toggled", reinterpret_cast(taskToggled), GINT_TO_POINTER(count) ); + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), const_cast(strs[1]) ); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), 0 ); + + gtk_widget_show( item ); + gtk_menu_shell_append( GTK_MENU_SHELL(menu), item ); + } +} + + +/** + * Observer that updates the recent list's max document count. + */ +class MaxRecentObserver : public Inkscape::Preferences::Observer { +public: + MaxRecentObserver(GtkWidget *recent_menu) : + Observer("/options/maxrecentdocuments/value"), + _rm(recent_menu) + {} + virtual void notify(Inkscape::Preferences::Entry const &e) { + gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(_rm), e.getInt()); + // hack: the recent menu doesn't repopulate after changing the limit, so we force it + g_signal_emit_by_name((gpointer) gtk_recent_manager_get_default(), "changed"); + } +private: + GtkWidget *_rm; +}; + +/** + * This function turns XML into a menu. + * + * This function is realitively simple as it just goes through the XML + * and parses the individual elements. In the case of a submenu, it + * just calls itself recursively. Because it is only reasonable to have + * a couple of submenus, it is unlikely this will go more than two or + * three times. + * + * In the case of an unrecognized verb, a menu item is made to identify + * the verb that is missing, and display that. The menu item is also made + * insensitive. + * + * @param menus This is the XML that defines the menu + * @param menu Menu to be added to + * @param view The View that this menu is being built for + */ +static void sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape::UI::View::View *view) +{ + if (menus == NULL) return; + if (menu == NULL) return; + GSList *group = NULL; + + for (Inkscape::XML::Node *menu_pntr = menus; + menu_pntr != NULL; + menu_pntr = menu_pntr->next()) { + if (!strcmp(menu_pntr->name(), "submenu")) { + GtkWidget *mitem = gtk_menu_item_new_with_mnemonic(_(menu_pntr->attribute("name"))); + GtkWidget *submenu = gtk_menu_new(); + sp_ui_build_dyn_menus(menu_pntr->firstChild(), submenu, view); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), GTK_WIDGET(submenu)); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem); + continue; + } + if (!strcmp(menu_pntr->name(), "verb")) { + gchar const *verb_name = menu_pntr->attribute("verb-id"); + Inkscape::Verb *verb = Inkscape::Verb::getbyid(verb_name); + + if (verb != NULL) { + if (menu_pntr->attribute("radio") != NULL) { + GtkWidget *item = sp_ui_menu_append_item_from_verb (GTK_MENU(menu), verb, view, true, group); + group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item)); + if (menu_pntr->attribute("default") != NULL) { + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + } + if (verb->get_code() != SP_VERB_NONE) { + SPAction *action = verb->get_action(Inkscape::ActionContext(view)); +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect( G_OBJECT(item), "draw", (GCallback) update_view_menu, (void *) action); +#else + g_signal_connect( G_OBJECT(item), "expose_event", (GCallback) update_view_menu, (void *) action); +#endif + } + } else if (menu_pntr->attribute("check") != NULL) { + SPAction *action = NULL; + if (verb->get_code() != SP_VERB_NONE) { + action = verb->get_action(Inkscape::ActionContext(view)); + } + sp_ui_menu_append_check_item_from_verb(GTK_MENU(menu), view, action->name, action->tip, NULL, + checkitem_toggled, checkitem_update, verb); + + } else { + sp_ui_menu_append_item_from_verb(GTK_MENU(menu), verb, view); + group = NULL; + } + } else { + gchar string[120]; + g_snprintf(string, 120, _("Verb \"%s\" Unknown"), verb_name); + string[119] = '\0'; /* may not be terminated */ + GtkWidget *item = gtk_menu_item_new_with_label(string); + gtk_widget_set_sensitive(item, false); + gtk_widget_show(item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } + continue; + } + if (!strcmp(menu_pntr->name(), "separator") + // This was spelt wrong in the original version + // and so this is for backward compatibility. It can + // probably be dropped after the 0.44 release. + || !strcmp(menu_pntr->name(), "seperator")) { + GtkWidget *item = gtk_separator_menu_item_new(); + gtk_widget_show(item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + continue; + } + + if (!strcmp(menu_pntr->name(), "recent-file-list")) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // create recent files menu + int max_recent = prefs->getInt("/options/maxrecentdocuments/value"); + GtkWidget *recent_menu = gtk_recent_chooser_menu_new_for_manager(gtk_recent_manager_get_default()); + gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(recent_menu), max_recent); + // sort most recently used documents first to preserve previous behavior + gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(recent_menu), GTK_RECENT_SORT_MRU); + g_signal_connect(G_OBJECT(recent_menu), "item-activated", G_CALLBACK(sp_recent_open), (gpointer) NULL); + + // add filter to only open files added by Inkscape + GtkRecentFilter *inkscape_only_filter = gtk_recent_filter_new(); + gtk_recent_filter_add_application(inkscape_only_filter, g_get_prgname()); + gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(recent_menu), inkscape_only_filter); + + gtk_recent_chooser_set_show_tips (GTK_RECENT_CHOOSER(recent_menu), TRUE); + gtk_recent_chooser_set_show_not_found (GTK_RECENT_CHOOSER(recent_menu), FALSE); + + GtkWidget *recent_item = gtk_menu_item_new_with_mnemonic(_("Open _Recent")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(recent_item), recent_menu); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(recent_item)); + // this will just sit and update the list's item count + static MaxRecentObserver *mro = new MaxRecentObserver(recent_menu); + prefs->addObserver(*mro); + continue; + } + if (!strcmp(menu_pntr->name(), "objects-checkboxes")) { + sp_ui_checkboxes_menus(GTK_MENU(menu), view); + continue; + } + if (!strcmp(menu_pntr->name(), "task-checkboxes")) { + addTaskMenuItems(GTK_MENU(menu), view); + continue; + } + } +} + +GtkWidget *sp_ui_main_menubar(Inkscape::UI::View::View *view) +{ + GtkWidget *mbar = gtk_menu_bar_new(); + sp_ui_build_dyn_menus(inkscape_get_menus(INKSCAPE), mbar, view); + return mbar; +} + + +/* Drag and Drop */ +void +sp_ui_drag_data_received(GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint /*event_time*/, + gpointer /*user_data*/) +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + switch (info) { +#if ENABLE_MAGIC_COLORS + case APP_X_INKY_COLOR: + { + int destX = 0; + int destY = 0; + gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY ); + Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) ); + + SPItem *item = desktop->getItemAtPoint( where, true ); + if ( item ) + { + bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE); + + if ( data->length >= 8 ) { + cmsHPROFILE srgbProf = cmsCreate_sRGBProfile(); + + gchar c[64] = {0}; + // Careful about endian issues. + guint16* dataVals = (guint16*)data->data; + sp_svg_write_color( c, sizeof(c), + SP_RGBA32_U_COMPOSE( + 0x0ff & (dataVals[0] >> 8), + 0x0ff & (dataVals[1] >> 8), + 0x0ff & (dataVals[2] >> 8), + 0xff // can't have transparency in the color itself + //0x0ff & (data->data[3] >> 8), + )); + SPCSSAttr *css = sp_repr_css_attr_new(); + bool updatePerformed = false; + + if ( data->length > 14 ) { + int flags = dataVals[4]; + + // piggie-backed palette entry info + int index = dataVals[5]; + Glib::ustring palName; + for ( int i = 0; i < dataVals[6]; i++ ) { + palName += (gunichar)dataVals[7+i]; + } + + // Now hook in a magic tag of some sort. + if ( !palName.empty() && (flags & 1) ) { + gchar* str = g_strdup_printf("%d|", index); + palName.insert( 0, str ); + g_free(str); + str = 0; + + item->setAttribute( + fillnotstroke ? "inkscape:x-fill-tag":"inkscape:x-stroke-tag", + palName.c_str(), + false ); + item->updateRepr(); + + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); + updatePerformed = true; + } + } + + if ( !updatePerformed ) { + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c ); + } + + sp_desktop_apply_css_recursive( item, css, true ); + item->updateRepr(); + + SPDocumentUndo::done( doc , SP_VERB_NONE, + _("Drop color")); + + if ( srgbProf ) { + cmsCloseProfile( srgbProf ); + } + } + } + } + break; +#endif // ENABLE_MAGIC_COLORS + + case APP_X_COLOR: + { + int destX = 0; + int destY = 0; + gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY ); + Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) ); + Geom::Point const button_dt(desktop->w2d(where)); + Geom::Point const button_doc(desktop->dt2doc(button_dt)); + + if ( gtk_selection_data_get_length (data) == 8 ) { + gchar colorspec[64] = {0}; + // Careful about endian issues. + guint16* dataVals = (guint16*)gtk_selection_data_get_data (data); + sp_svg_write_color( colorspec, sizeof(colorspec), + SP_RGBA32_U_COMPOSE( + 0x0ff & (dataVals[0] >> 8), + 0x0ff & (dataVals[1] >> 8), + 0x0ff & (dataVals[2] >> 8), + 0xff // can't have transparency in the color itself + //0x0ff & (data->data[3] >> 8), + )); + + SPItem *item = desktop->getItemAtPoint( where, true ); + + bool consumed = false; + if (desktop->event_context && desktop->event_context->get_drag()) { + consumed = desktop->event_context->get_drag()->dropColor(item, colorspec, button_dt); + if (consumed) { + DocumentUndo::done( doc , SP_VERB_NONE, _("Drop color on gradient") ); + desktop->event_context->get_drag()->updateDraggers(); + } + } + + //if (!consumed && tools_active(desktop, TOOLS_TEXT)) { + // consumed = sp_text_context_drop_color(c, button_doc); + // if (consumed) { + // SPDocumentUndo::done( doc , SP_VERB_NONE, _("Drop color on gradient stop")); + // } + //} + + if (!consumed && item) { + bool fillnotstroke = (gdk_drag_context_get_actions (drag_context) != GDK_ACTION_MOVE); + if (fillnotstroke && + (SP_IS_SHAPE(item) || SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))) { + Path *livarot_path = Path_for_item(item, true, true); + livarot_path->ConvertWithBackData(0.04); + + boost::optional position = get_nearest_position_on_Path(livarot_path, button_doc); + if (position) { + Geom::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t); + Geom::Point delta = nearest - button_doc; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + delta = desktop->d2w(delta); + double stroke_tolerance = + ( !item->style->stroke.isNone() ? + desktop->current_zoom() * + item->style->stroke_width.computed * + item->i2dt_affine().descrim() * 0.5 + : 0.0) + + prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); + + if (Geom::L2 (delta) < stroke_tolerance) { + fillnotstroke = false; + } + } + delete livarot_path; + } + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", colorspec ); + + sp_desktop_apply_css_recursive( item, css, true ); + item->updateRepr(); + + DocumentUndo::done( doc , SP_VERB_NONE, + _("Drop color") ); + } + } + } + break; + + case APP_OSWB_COLOR: + { + bool worked = false; + Glib::ustring colorspec; + if ( gtk_selection_data_get_format (data) == 8 ) { + ege::PaintDef color; + worked = color.fromMIMEData("application/x-oswb-color", + reinterpret_cast(gtk_selection_data_get_data (data)), + gtk_selection_data_get_length (data), + gtk_selection_data_get_format (data)); + if ( worked ) { + if ( color.getType() == ege::PaintDef::CLEAR ) { + colorspec = ""; // TODO check if this is sufficient + } else if ( color.getType() == ege::PaintDef::NONE ) { + colorspec = "none"; + } else { + unsigned int r = color.getR(); + unsigned int g = color.getG(); + unsigned int b = color.getB(); + + SPGradient* matches = 0; + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( color.descr == grad->getId() ) { + if ( grad->hasStops() ) { + matches = grad; + break; + } + } + } + if (matches) { + colorspec = "url(#"; + colorspec += matches->getId(); + colorspec += ")"; + } else { + gchar* tmp = g_strdup_printf("#%02x%02x%02x", r, g, b); + colorspec = tmp; + g_free(tmp); + } + } + } + } + if ( worked ) { + int destX = 0; + int destY = 0; + gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY ); + Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) ); + Geom::Point const button_dt(desktop->w2d(where)); + Geom::Point const button_doc(desktop->dt2doc(button_dt)); + + SPItem *item = desktop->getItemAtPoint( where, true ); + + bool consumed = false; + if (desktop->event_context && desktop->event_context->get_drag()) { + consumed = desktop->event_context->get_drag()->dropColor(item, colorspec.c_str(), button_dt); + if (consumed) { + DocumentUndo::done( doc , SP_VERB_NONE, _("Drop color on gradient") ); + desktop->event_context->get_drag()->updateDraggers(); + } + } + + if (!consumed && item) { + bool fillnotstroke = (gdk_drag_context_get_actions (drag_context) != GDK_ACTION_MOVE); + if (fillnotstroke && + (SP_IS_SHAPE(item) || SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))) { + Path *livarot_path = Path_for_item(item, true, true); + livarot_path->ConvertWithBackData(0.04); + + boost::optional position = get_nearest_position_on_Path(livarot_path, button_doc); + if (position) { + Geom::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t); + Geom::Point delta = nearest - button_doc; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + delta = desktop->d2w(delta); + double stroke_tolerance = + ( !item->style->stroke.isNone() ? + desktop->current_zoom() * + item->style->stroke_width.computed * + item->i2dt_affine().descrim() * 0.5 + : 0.0) + + prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); + + if (Geom::L2 (delta) < stroke_tolerance) { + fillnotstroke = false; + } + } + delete livarot_path; + } + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", colorspec.c_str() ); + + sp_desktop_apply_css_recursive( item, css, true ); + item->updateRepr(); + + DocumentUndo::done( doc , SP_VERB_NONE, + _("Drop color") ); + } + } + } + break; + + case SVG_DATA: + case SVG_XML_DATA: { + gchar *svgdata = (gchar *)gtk_selection_data_get_data (data); + + Inkscape::XML::Document *rnewdoc = sp_repr_read_mem(svgdata, gtk_selection_data_get_length (data), SP_SVG_NS_URI); + + if (rnewdoc == NULL) { + sp_ui_error_dialog(_("Could not parse SVG data")); + return; + } + + Inkscape::XML::Node *repr = rnewdoc->root(); + gchar const *style = repr->attribute("style"); + + Inkscape::XML::Node *newgroup = rnewdoc->createElement("svg:g"); + newgroup->setAttribute("style", style); + + Inkscape::XML::Document * xml_doc = doc->getReprDoc(); + for (Inkscape::XML::Node *child = repr->firstChild(); child != NULL; child = child->next()) { + Inkscape::XML::Node *newchild = child->duplicate(xml_doc); + newgroup->appendChild(newchild); + } + + Inkscape::GC::release(rnewdoc); + + // Add it to the current layer + + // Greg's edits to add intelligent positioning of svg drops + SPObject *new_obj = NULL; + new_obj = desktop->currentLayer()->appendChildRepr(newgroup); + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + selection->set(SP_ITEM(new_obj)); + + // move to mouse pointer + { + sp_desktop_document(desktop)->ensureUpToDate(); + Geom::OptRect sel_bbox = selection->visualBounds(); + if (sel_bbox) { + Geom::Point m( desktop->point() - sel_bbox->midpoint() ); + sp_selection_move_relative(selection, m, false); + } + } + + Inkscape::GC::release(newgroup); + DocumentUndo::done( doc, SP_VERB_NONE, + _("Drop SVG") ); + break; + } + + case URI_LIST: { + gchar *uri = (gchar *)gtk_selection_data_get_data (data); + sp_ui_import_files(uri); + break; + } + + case APP_X_INK_PASTE: { + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + cm->paste(desktop); + DocumentUndo::done( doc, SP_VERB_NONE, _("Drop Symbol") ); + break; + } + + case PNG_DATA: + case JPEG_DATA: + case IMAGE_DATA: { + const char *mime = (info == JPEG_DATA ? "image/jpeg" : "image/png"); + + Inkscape::Extension::DB::InputList o; + Inkscape::Extension::db.get_input_list(o); + Inkscape::Extension::DB::InputList::const_iterator i = o.begin(); + while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) { + ++i; + } + Inkscape::Extension::Extension *ext = *i; + bool save = (strcmp(ext->get_param_optiongroup("link"), "embed") == 0); + ext->set_param_optiongroup("link", "embed"); + ext->set_gui(false); + + gchar *filename = g_build_filename( g_get_tmp_dir(), "inkscape-dnd-import", NULL ); + g_file_set_contents(filename, + reinterpret_cast(gtk_selection_data_get_data (data)), + gtk_selection_data_get_length (data), + NULL); + file_import(doc, filename, ext); + g_free(filename); + + ext->set_param_optiongroup("link", save ? "embed" : "link"); + ext->set_gui(true); + DocumentUndo::done( doc , SP_VERB_NONE, + _("Drop bitmap image") ); + break; + } + } +} + +#include "ui/tools/gradient-tool.h" + +void sp_ui_drag_motion( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, + GtkSelectionData */*data*/, + guint /*info*/, + guint /*event_time*/, + gpointer /*user_data*/) +{ +// SPDocument *doc = SP_ACTIVE_DOCUMENT; +// SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + +// g_message("drag-n-drop motion (%4d, %4d) at %d", x, y, event_time); +} + +static void sp_ui_drag_leave( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + guint /*event_time*/, + gpointer /*user_data*/ ) +{ +// g_message("drag-n-drop leave at %d", event_time); +} + +static void +sp_ui_import_files(gchar *buffer) +{ + GList *list = gnome_uri_list_extract_filenames(buffer); + if (!list) + return; + g_list_foreach(list, sp_ui_import_one_file_with_check, NULL); + g_list_foreach(list, (GFunc) g_free, NULL); + g_list_free(list); +} + +static void +sp_ui_import_one_file_with_check(gpointer filename, gpointer /*unused*/) +{ + if (filename) { + if (strlen((char const *)filename) > 2) + sp_ui_import_one_file((char const *)filename); + } +} + +static void +sp_ui_import_one_file(char const *filename) +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if (!doc) return; + + if (filename == NULL) return; + + // Pass off to common implementation + // TODO might need to get the proper type of Inkscape::Extension::Extension + file_import( doc, filename, NULL ); +} + +void +sp_ui_error_dialog(gchar const *message) +{ + GtkWidget *dlg; + gchar *safeMsg = Inkscape::IO::sanitizeString(message); + + dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, "%s", safeMsg); + sp_transientize(dlg); + gtk_window_set_resizable(GTK_WINDOW(dlg), FALSE); + gtk_dialog_run(GTK_DIALOG(dlg)); + gtk_widget_destroy(dlg); + g_free(safeMsg); +} + +bool +sp_ui_overwrite_file(gchar const *filename) +{ + bool return_value = FALSE; + + if (Inkscape::IO::file_test(filename, G_FILE_TEST_EXISTS)) { + Gtk::Window *window = SP_ACTIVE_DESKTOP->getToplevel(); + gchar* baseName = g_path_get_basename( filename ); + gchar* dirName = g_path_get_dirname( filename ); + GtkWidget* dialog = gtk_message_dialog_new_with_markup( window->gobj(), + (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _( "A file named \"%s\" already exists. Do you want to replace it?\n\n" + "The file already exists in \"%s\". Replacing it will overwrite its contents." ), + baseName, + dirName + ); + gtk_dialog_add_buttons( GTK_DIALOG(dialog), + _("_Cancel"), GTK_RESPONSE_NO, + _("Replace"), GTK_RESPONSE_YES, + NULL ); + gtk_dialog_set_default_response( GTK_DIALOG(dialog), GTK_RESPONSE_YES ); + + if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_YES ) { + return_value = TRUE; + } else { + return_value = FALSE; + } + gtk_widget_destroy(dialog); + g_free( baseName ); + g_free( dirName ); + } else { + return_value = TRUE; + } + + return return_value; +} + +static void +sp_ui_menu_item_set_name(GtkWidget *data, Glib::ustring const &name) +{ + if (data || GTK_IS_BIN (data)) { + void *child = gtk_bin_get_child (GTK_BIN (data)); + //child is either + //- a GtkBox, whose first child is a label displaying name if the menu + //item has an accel key + //- a GtkLabel if the menu has no accel key + if (child != NULL){ + if (GTK_IS_LABEL(child)) { + gtk_label_set_markup_with_mnemonic(GTK_LABEL (child), name.c_str()); + } else if (GTK_IS_BOX(child)) { + gtk_label_set_markup_with_mnemonic( + GTK_LABEL (gtk_container_get_children(GTK_CONTAINER (child))->data), + name.c_str()); + }//else sp_ui_menu_append_item_from_verb has been modified and can set + //a menu item in yet another way... + } + } +} + +void injectRenamedIcons() +{ + Glib::RefPtr iconTheme = Gtk::IconTheme::get_default(); + + std::vector< std::pair > renamed; + renamed.push_back(std::make_pair("gtk-file", "document-x-generic")); + renamed.push_back(std::make_pair("gtk-directory", "folder")); + + for ( std::vector< std::pair >::iterator it = renamed.begin(); it < renamed.end(); ++it ) { + bool hasIcon = iconTheme->has_icon(it->first); + bool hasSecondIcon = iconTheme->has_icon(it->second); + + if ( !hasIcon && hasSecondIcon ) { + Glib::ArrayHandle sizes = iconTheme->get_icon_sizes(it->second); + for ( Glib::ArrayHandle::iterator it2 = sizes.begin(); it2 < sizes.end(); ++it2 ) { + Glib::RefPtr pb = iconTheme->load_icon( it->second, *it2 ); + if ( pb ) { + // install a private copy of the pixbuf to avoid pinning a theme + Glib::RefPtr pbCopy = pb->copy(); + Gtk::IconTheme::add_builtin_icon( it->first, *it2, pbCopy ); + } + } + } + } +} + + +ContextMenu::ContextMenu(SPDesktop *desktop, SPItem *item) : + _item(item), + MIGroup(), + MIParent(_("Go to parent")) +{ +// g_message("ContextMenu"); + _object = static_cast(item); + _desktop = desktop; + + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_UNDO)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_REDO)); + AddSeparator(); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_CUT)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_COPY)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_PASTE)); + AddSeparator(); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DUPLICATE)); + AppendItemFromVerb(Inkscape::Verb::get(SP_VERB_EDIT_DELETE)); + + positionOfLastDialog = 10; // 9 in front + 1 for the separator in the next if; used to position the dialog menu entries below each other + + /* Item menu */ + if (item!=NULL) { + AddSeparator(); + MakeObjectMenu(); + } + + /* layer menu */ + SPGroup *group=NULL; + if (item) { + if (SP_IS_GROUP(item)) { + group = SP_GROUP(item); + } else if ( item != _desktop->currentRoot() && SP_IS_GROUP(item->parent) ) { + group = SP_GROUP(item->parent); + } + } + + if (( group && group != _desktop->currentLayer() ) || + ( _desktop->currentLayer() != _desktop->currentRoot() && _desktop->currentLayer()->parent != _desktop->currentRoot() ) ) { + AddSeparator(); + } + + if ( group && group != _desktop->currentLayer() ) { + /* TRANSLATORS: #%1 is the id of the group e.g. , not a number. */ + MIGroup.set_label (Glib::ustring::compose(_("Enter group #%1"), group->getId())); + MIGroup.set_data("group", group); + MIGroup.signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ContextMenu::EnterGroup),&MIGroup)); + MIGroup.show(); + append(MIGroup); + } + + if ( _desktop->currentLayer() != _desktop->currentRoot() ) { + if ( _desktop->currentLayer()->parent != _desktop->currentRoot() ) { + MIParent.signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::LeaveGroup)); + MIParent.show(); + append(MIParent); + } + } +} + +ContextMenu::~ContextMenu(void) +{ +} + +Gtk::SeparatorMenuItem* ContextMenu::AddSeparator(void) +{ + Gtk::SeparatorMenuItem* sep = Gtk::manage(new Gtk::SeparatorMenuItem()); + sep->show(); + append(*sep); + return sep; +} + +void ContextMenu::EnterGroup(Gtk::MenuItem* mi) +{ + _desktop->setCurrentLayer(reinterpret_cast(mi->get_data("group"))); + _desktop->selection->clear(); +} + +void ContextMenu::LeaveGroup(void) +{ + _desktop->setCurrentLayer(_desktop->currentLayer()->parent); +} + +void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb)//, SPDesktop *view)//, bool radio, GSList *group) +{ + SPAction *action; + SPDesktop *view = _desktop; + + if (verb->get_code() == SP_VERB_NONE) { + Gtk::MenuItem *item = AddSeparator(); + item->show(); + append(*item); + } else { + action = verb->get_action(Inkscape::ActionContext(view)); + if (!action) { + return; + } + + Gtk::ImageMenuItem *item = Gtk::manage(new Gtk::ImageMenuItem(action->name, true)); + + sp_shortcut_add_accelerator(GTK_WIDGET(item->gobj()), sp_shortcut_get_primary(verb)); + + action->signal_set_sensitive.connect(sigc::mem_fun(*this, &ContextMenu::set_sensitive)); + action->signal_set_name.connect(sigc::mem_fun(*item, &ContextMenu::set_name)); + + if (!action->sensitive) { + item->set_sensitive(FALSE); + } + + if (action->image) { + sp_ui_menuitem_add_icon((GtkWidget*)item->gobj(), action->image); + } + item->set_events(Gdk::KEY_PRESS_MASK); + item->signal_activate().connect(sigc::bind(sigc::ptr_fun(sp_ui_menu_activate),item,action)); + item->signal_select().connect(sigc::bind(sigc::ptr_fun(sp_ui_menu_select_action),item,action)); + item->signal_deselect().connect(sigc::bind(sigc::ptr_fun(sp_ui_menu_deselect_action),item,action)); + item->show(); + append(*item); + } +} + +void ContextMenu::MakeObjectMenu(void) +{ +// GObjectClass *klass = G_OBJECT_GET_CLASS(_object); //to deduce the object's type from its class +// +// if (G_TYPE_CHECK_CLASS_TYPE(klass, SP_TYPE_ITEM)) +// { +// MakeItemMenu (); +// } +// if (G_TYPE_CHECK_CLASS_TYPE(klass, SP_TYPE_GROUP)) +// { +// MakeGroupMenu(); +// } +// if (G_TYPE_CHECK_CLASS_TYPE(klass, SP_TYPE_ANCHOR)) +// { +// MakeAnchorMenu(); +// } +// if (G_TYPE_CHECK_CLASS_TYPE(klass, SP_TYPE_IMAGE)) +// { +// MakeImageMenu(); +// } +// if (G_TYPE_CHECK_CLASS_TYPE(klass, SP_TYPE_SHAPE)) +// { +// MakeShapeMenu(); +// } +// if (G_TYPE_CHECK_CLASS_TYPE(klass, SP_TYPE_TEXT)) +// { +// MakeTextMenu(); +// } + + if (SP_IS_ITEM(_object)) { + MakeItemMenu(); + } + + if (SP_IS_GROUP(_object)) { + MakeGroupMenu(); + } + + if (SP_IS_ANCHOR(_object)) { + MakeAnchorMenu(); + } + + if (SP_IS_IMAGE(_object)) { + MakeImageMenu(); + } + + if (SP_IS_SHAPE(_object)) { + MakeShapeMenu(); + } + + if (SP_IS_TEXT(_object)) { + MakeTextMenu(); + } +} + +void ContextMenu::MakeItemMenu (void) +{ + Gtk::MenuItem* mi; + + /* Item dialog */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Object Properties..."),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemProperties)); + mi->show(); + append(*mi);//insert(*mi,positionOfLastDialog++); + + AddSeparator(); + + /* Select item */ + if (Inkscape::Verb::getbyid( "org.inkscape.followlink" )) { + mi = Gtk::manage(new Gtk::MenuItem(_("_Select This"), 1)); + if (_desktop->selection->includes(_item)) { + mi->set_sensitive(FALSE); + } else { + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemSelectThis)); + } + mi->show(); + append(*mi); + } + + + mi = Gtk::manage(new Gtk::MenuItem(_("Select Same"))); + mi->show(); + Gtk::Menu *select_same_submenu = Gtk::manage(new Gtk::Menu()); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } + mi->set_submenu(*select_same_submenu); + append(*mi); + + /* Select same fill and stroke */ + mi = Gtk::manage(new Gtk::MenuItem(_("Fill and Stroke"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillStroke)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); + + /* Select same fill color */ + mi = Gtk::manage(new Gtk::MenuItem(_("Fill Color"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillColor)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); + + /* Select same stroke color */ + mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Color"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeColor)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); + + /* Select same stroke style */ + mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Style"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeStyle)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); + + /* Select same stroke style */ + mi = Gtk::manage(new Gtk::MenuItem(_("Object type"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameObjectType)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + select_same_submenu->append(*mi); + + /* Move to layer */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Move to layer ..."), 1)); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } else { + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemMoveTo)); + } + mi->show(); + append(*mi); + + /* Create link */ + mi = Gtk::manage(new Gtk::MenuItem(_("Create _Link"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemCreateLink)); + mi->set_sensitive(!SP_IS_ANCHOR(_item)); + mi->show(); + append(*mi); + + bool ClipRefOK=false; + bool MaskRefOK=false; + if (_item){ + if (_item->clip_ref){ + if (_item->clip_ref->getObject()){ + ClipRefOK=true; + } + } + } + if (_item){ + if (_item->mask_ref){ + if (_item->mask_ref->getObject()){ + MaskRefOK=true; + } + } + } + /* Set mask */ + mi = Gtk::manage(new Gtk::MenuItem(_("Set Mask"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetMask)); + if (ClipRefOK || MaskRefOK) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); + + /* Release mask */ + mi = Gtk::manage(new Gtk::MenuItem(_("Release Mask"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseMask)); + if (MaskRefOK) { + mi->set_sensitive(TRUE); + } else { + mi->set_sensitive(FALSE); + } + mi->show(); + append(*mi); + + /*SSet Clip Group */ + mi = Gtk::manage(new Gtk::MenuItem(_("Create Clip G_roup"),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::CreateGroupClip)); + mi->set_sensitive(TRUE); + mi->show(); + append(*mi); + + /* Set Clip */ + mi = Gtk::manage(new Gtk::MenuItem(_("Set Cl_ip"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetClip)); + if (ClipRefOK || MaskRefOK) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); + + /* Release Clip */ + mi = Gtk::manage(new Gtk::MenuItem(_("Release C_lip"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseClip)); + if (ClipRefOK) { + mi->set_sensitive(TRUE); + } else { + mi->set_sensitive(FALSE); + } + mi->show(); + append(*mi); + + /* Group */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Group"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateGroup)); + if (_desktop->selection->isEmpty() || _desktop->selection->single()) { + mi->set_sensitive(FALSE); + } else { + mi->set_sensitive(TRUE); + } + mi->show(); + append(*mi); +} + +void ContextMenu::SelectSameFillStroke(void) +{ + sp_select_same_fill_stroke_style(_desktop, true, true, true); +} + +void ContextMenu::SelectSameFillColor(void) +{ + sp_select_same_fill_stroke_style(_desktop, true, false, false); +} + +void ContextMenu::SelectSameStrokeColor(void) +{ + sp_select_same_fill_stroke_style(_desktop, false, true, false); +} + +void ContextMenu::SelectSameStrokeStyle(void) +{ + sp_select_same_stroke_style(_desktop); +} + +void ContextMenu::SelectSameObjectType(void) +{ + sp_select_same_object_type(_desktop); +} + +void ContextMenu::ItemProperties(void) +{ + _desktop->selection->set(_item); + _desktop->_dlg_mgr->showDialog("ObjectProperties"); +} + +void ContextMenu::ItemSelectThis(void) +{ + _desktop->selection->set(_item); +} + +void ContextMenu::ItemMoveTo(void) +{ + Inkscape::UI::Dialogs::LayerPropertiesDialog::showMove(_desktop, _desktop->currentLayer()); +} + + + +void ContextMenu::ItemCreateLink(void) +{ + Inkscape::XML::Document *xml_doc = _desktop->doc()->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); + _item->parent->getRepr()->addChild(repr, _item->getRepr()); + SPObject *object = _item->document->getObjectByRepr(repr); + g_return_if_fail(SP_IS_ANCHOR(object)); + + const char *id = _item->getRepr()->attribute("id"); + Inkscape::XML::Node *child = _item->getRepr()->duplicate(xml_doc); + _item->deleteObject(false); + repr->addChild(child, NULL); + child->setAttribute("id", id); + + Inkscape::GC::release(repr); + Inkscape::GC::release(child); + + DocumentUndo::done(object->document, SP_VERB_NONE, _("Create link")); + + _desktop->selection->set(SP_ITEM(object)); + _desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +void ContextMenu::SetMask(void) +{ + sp_selection_set_mask(_desktop, false, false); +} + +void ContextMenu::ReleaseMask(void) +{ + sp_selection_unset_mask(_desktop, false); +} + +void ContextMenu::CreateGroupClip(void) +{ + sp_selection_set_clipgroup(_desktop); +} + +void ContextMenu::SetClip(void) +{ + sp_selection_set_mask(_desktop, true, false); +} + + +void ContextMenu::ReleaseClip(void) +{ + sp_selection_unset_mask(_desktop, true); +} + +void ContextMenu::MakeGroupMenu(void) +{ + /* Ungroup */ + Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("_Ungroup"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroup)); + mi->show(); + append(*mi); +} + +void ContextMenu::ActivateGroup(void) +{ + sp_selection_group(_desktop->selection, _desktop); +} + +void ContextMenu::ActivateUngroup(void) +{ + GSList *children = NULL; + + sp_item_group_ungroup(static_cast(_item), &children); + _desktop->selection->setList(children); + g_slist_free(children); +} + +void ContextMenu::MakeAnchorMenu(void) +{ + Gtk::MenuItem* mi; + + /* Link dialog */ + mi = Gtk::manage(new Gtk::MenuItem(_("Link _Properties..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkProperties)); + mi->show(); + insert(*mi,positionOfLastDialog++); + + /* Select item */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Follow Link"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkFollow)); + mi->show(); + append(*mi); + + /* Reset transformations */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Remove Link"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkRemove)); + mi->show(); + append(*mi); +} + +void ContextMenu::AnchorLinkProperties(void) +{ + _desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +void ContextMenu::AnchorLinkFollow(void) +{ + + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + // Opening the selected links with a python extension + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.inkscape.followlink" ); + if (verb) { + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +void ContextMenu::AnchorLinkRemove(void) +{ + GSList *children = NULL; + sp_item_group_ungroup(static_cast(_item), &children, false); + DocumentUndo::done(_desktop->doc(), SP_VERB_NONE, _("Remove link")); + g_slist_free(children); +} + +void ContextMenu::MakeImageMenu (void) +{ + Gtk::MenuItem* mi; + Inkscape::XML::Node *ir = _object->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + /* Image properties */ + mi = Gtk::manage(new Gtk::MenuItem(_("Image _Properties..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageProperties)); + mi->show(); + insert(*mi,positionOfLastDialog++); + + /* Edit externally */ + mi = Gtk::manage(new Gtk::MenuItem(_("Edit Externally..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEdit)); + mi->show(); + insert(*mi,positionOfLastDialog++); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + mi->set_sensitive( FALSE ); + } + + /* Trace Bitmap */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Trace Bitmap..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageTraceBitmap)); + mi->show(); + insert(*mi,positionOfLastDialog++); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } + + /* Trace Pixel Art */ + mi = Gtk::manage(new Gtk::MenuItem(_("Trace Pixel Art"), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageTracePixelArt)); + mi->show(); + insert(*mi,positionOfLastDialog++); + if (_desktop->selection->isEmpty()) { + mi->set_sensitive(FALSE); + } + + /* Embed image */ + if (Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" )) { + mi = Gtk::manage(new Gtk::MenuItem(C_("Context menu", "Embed Image"))); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEmbed)); + mi->show(); + insert(*mi,positionOfLastDialog++); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + mi->set_sensitive( FALSE ); + } + } + + /* Extract image */ + if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { + mi = Gtk::manage(new Gtk::MenuItem(C_("Context menu", "Extract Image..."))); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageExtract)); + mi->show(); + insert(*mi,positionOfLastDialog++); + if ( (!href) || ((strncmp(href, "data:", 5) != 0)) ) { + mi->set_sensitive( FALSE ); + } + } +} + +void ContextMenu::ImageProperties(void) +{ + _desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +Glib::ustring ContextMenu::getImageEditorName() { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring value; + Glib::ustring choices = prefs->getString("/options/bitmapeditor/value"); + if (!choices.empty()) { + value = choices; + } + else { + value = "gimp"; + } + return value; +} + +void ContextMenu::ImageEdit(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + GSList const *selected = _desktop->selection->itemList(); + + GError* errThing = 0; + Glib::ustring cmdline = getImageEditorName(); + Glib::ustring name; + Glib::ustring fullname; + +#ifdef WIN32 + // g_spawn_command_line_sync parsing is done according to Unix shell rules, + // not Windows command interpreter rules. Thus we need to enclose the + // executable path with single quotes. + int index = cmdline.find(".exe"); + if ( index < 0 ) index = cmdline.find(".bat"); + if ( index < 0 ) index = cmdline.find(".com"); + if ( index >= 0 ) { + Glib::ustring editorBin = cmdline.substr(0, index + 4).c_str(); + Glib::ustring args = cmdline.substr(index + 4, cmdline.length()).c_str(); + editorBin.insert(0, "'"); + editorBin.append("'"); + cmdline = editorBin; + cmdline.append(args); + } else { + // Enclose the whole command line if no executable path can be extracted. + cmdline.insert(0, "'"); + cmdline.append("'"); + } +#endif + + for (GSList const *iter = selected; iter != NULL; iter = iter->next) { + Inkscape::XML::Node *ir = SP_ITEM(iter->data)->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + if (strncmp (href,"file:",5) == 0) { + // URI to filename conversion + name = g_filename_from_uri(href, NULL, NULL); + } else { + name.append(href); + } + + if (Glib::path_is_absolute(name)) { + fullname = name; + } else if (SP_ACTIVE_DOCUMENT->getBase()) { + fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); + } else { + fullname = Glib::build_filename(Glib::get_current_dir(), name); + } + + cmdline.append(" '"); + cmdline.append(fullname.c_str()); + cmdline.append("'"); + } + + //g_warning("##Command line: %s\n", cmdline.c_str()); + + g_spawn_command_line_async(cmdline.c_str(), &errThing); + + if ( errThing ) { + g_warning("Problem launching editor (%d). %s", errThing->code, errThing->message); + (_desktop->messageStack())->flash(Inkscape::ERROR_MESSAGE, errThing->message); + g_error_free(errThing); + errThing = 0; + } +} + +void ContextMenu::ImageTraceBitmap(void) +{ + inkscape_dialogs_unhide(); + _desktop->_dlg_mgr->showDialog("Trace"); +} + +void ContextMenu::ImageTracePixelArt(void) +{ + inkscape_dialogs_unhide(); + _desktop->_dlg_mgr->showDialog("PixelArt"); +} + +void ContextMenu::ImageEmbed(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" ); + if (verb) { + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +void ContextMenu::ImageExtract(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" ); + if (verb) { + SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop)); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +void ContextMenu::MakeShapeMenu (void) +{ + Gtk::MenuItem* mi; + + /* Item dialog */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Fill and Stroke..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::FillSettings)); + mi->show(); + insert(*mi,positionOfLastDialog++); +} + +void ContextMenu::FillSettings(void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + _desktop->_dlg_mgr->showDialog("FillAndStroke"); +} + +void ContextMenu::MakeTextMenu (void) +{ + Gtk::MenuItem* mi; + + /* Fill and Stroke dialog */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Fill and Stroke..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::FillSettings)); + mi->show(); + insert(*mi,positionOfLastDialog++); + + /* Edit Text dialog */ + mi = Gtk::manage(new Gtk::MenuItem(_("_Text and Font..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::TextSettings)); + mi->show(); + insert(*mi,positionOfLastDialog++); + + /* Spellcheck dialog */ + mi = Gtk::manage(new Gtk::MenuItem(_("Check Spellin_g..."), 1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SpellcheckSettings)); + mi->show(); + insert(*mi,positionOfLastDialog++); +} + +void ContextMenu::TextSettings (void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + _desktop->_dlg_mgr->showDialog("TextFont"); +} + +void ContextMenu::SpellcheckSettings (void) +{ + if (_desktop->selection->isEmpty()) { + _desktop->selection->set(_item); + } + + _desktop->_dlg_mgr->showDialog("SpellCheck"); +} + +/* + 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 : diff --git a/src/ui/interface.h b/src/ui/interface.h new file mode 100644 index 000000000..6fb74046f --- /dev/null +++ b/src/ui/interface.h @@ -0,0 +1,277 @@ +#ifndef SEEN_SP_INTERFACE_H +#define SEEN_SP_INTERFACE_H + +/* + * Main UI stuff + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2012 Kris De Gussem + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +//#ifdef HAVE_CONFIG_H +//# include +//#endif + +#include + +class SPItem; +class SPObject; +class SPDesktop; +class SPViewWidget; + +namespace Gtk { +class SeparatorMenuItem; +} + +namespace Inkscape { + +class Verb; + +namespace UI { +namespace View { +class View; +} // namespace View +} // namespace UI +} // namespace Inkscape + +/** + * Create a new document window. + */ +void sp_create_window (SPViewWidget *vw, bool editable); + +/** + * \param widget unused + */ +void sp_ui_close_view (GtkWidget *widget); + +void sp_ui_new_view (void); + +/** + * @todo TODO: not yet working. To be re-enabled (by adding to menu) once it works. + */ +void sp_ui_new_view_preview (void); + +/** + * This function is called to exit the program, and iterates through all + * open document view windows, attempting to close each in turn. If the + * view has unsaved information, the user will be prompted to save, + * discard, or cancel. + * + * Returns FALSE if the user cancels the close_all operation, TRUE + * otherwise. + */ +unsigned int sp_ui_close_all (void); + +/** + * Build the main tool bar. + * + * Currently the main tool bar is built as a dynamic XML menu using + * \c sp_ui_build_dyn_menus. This function builds the bar, and then + * pass it to get items attached to it. + * + * @param view View to build the bar for + */ +GtkWidget *sp_ui_main_menubar (Inkscape::UI::View::View *view); + +void sp_menu_append_recent_documents (GtkWidget *menu); +void sp_ui_dialog_title_string (Inkscape::Verb * verb, char* c); + +Glib::ustring getLayoutPrefPath( Inkscape::UI::View::View *view ); + +/** + * + */ +void sp_ui_error_dialog (char const* message); +bool sp_ui_overwrite_file (char const* filename); + + +/** + * Implements the Inkscape context menu. + * + * For the context menu implementation, the ContextMenu class stores the object + * that was selected in a private data member. This should be farely safe to do + * and a pointer to the SPItem as well as SPObject class are kept. + * All callbacks of the context menu entries are implemented as private + * functions. + * + * @todo add callbacks to destroy the context menu when it is closed (=key or mouse button pressed out of the scope of the context menu) + */ +class ContextMenu : public Gtk::Menu +{ + public: + /** + * The ContextMenu constructor contains all code to create and show the + * menu entries (aka child widgets). + * + * @param desktop pointer to the desktop the user is currently working on. + * @param item SPItem pointer to the object selected at the time the ContextMenu is created. + */ + ContextMenu(SPDesktop *desktop, SPItem *item); + ~ContextMenu(void); + + private: + SPItem *_item; // pointer to the object selected at the time the ContextMenu is created + SPObject *_object; // pointer to the object selected at the time the ContextMenu is created + SPDesktop *_desktop; //pointer to the desktop the user was currently working on at the time the ContextMenu is created + + int positionOfLastDialog; + + Gtk::MenuItem MIGroup; //menu entry to enter a group + Gtk::MenuItem MIParent; //menu entry to leave a group + + /** + * auxiliary function that adds a separator line in the context menu + */ + Gtk::SeparatorMenuItem* AddSeparator(void); + + /** + * c++ified version of sp_ui_menu_append_item. + * + * @see sp_ui_menu_append_item_from_verb and synchronize/drop that function when c++ifying other code in interface.cpp + */ + void AppendItemFromVerb(Inkscape::Verb *verb); + + /** + * main function which is responsible for creating the context sensitive menu items, + * calls subfunctions below to create the menu entry widgets. + */ + void MakeObjectMenu (void); + /** + * creates menu entries for an SP_TYPE_ITEM object + */ + void MakeItemMenu (void); + /** + * creates menu entries for a grouped object + */ + void MakeGroupMenu (void); + /** + * creates menu entries for an anchor object + */ + void MakeAnchorMenu (void); + /** + * creates menu entries for a bitmap image object + */ + void MakeImageMenu (void); + /** + * creates menu entries for a shape object + */ + void MakeShapeMenu (void); + /** + * creates menu entries for a text object + */ + void MakeTextMenu (void); + + void EnterGroup(Gtk::MenuItem* mi); + void LeaveGroup(void); + ////////////////////////////////////////// + //callbacks for the context menu entries of an SP_TYPE_ITEM object + void ItemProperties(void); + void ItemSelectThis(void); + void ItemMoveTo(void); + void SelectSameFillStroke(void); + void SelectSameFillColor(void); + void SelectSameStrokeColor(void); + void SelectSameStrokeStyle(void); + void SelectSameObjectType(void); + void ItemCreateLink(void); + void CreateGroupClip(void); + void SetMask(void); + void ReleaseMask(void); + void SetClip(void); + void ReleaseClip(void); + ////////////////////////////////////////// + + + /** + * callback, is executed on clicking the anchor "Group" and "Ungroup" menu entry + */ + void ActivateUngroup(void); + void ActivateGroup(void); + + void AnchorLinkProperties(void); + /** + * placeholder for callback to be executed on clicking the anchor "Follow link" context menu entry + * @todo add code to follow link externally + */ + void AnchorLinkFollow(void); + + /** + * callback, is executed on clicking the anchor "Link remove" menu entry + */ + void AnchorLinkRemove(void); + + + /** + * callback, opens the image properties dialog and is executed on clicking the context menu entry with similar name + */ + void ImageProperties(void); + + /** + * callback, is executed on clicking the image "Edit Externally" menu entry + */ + void ImageEdit(void); + + /** + * auxiliary function that loads the external image editor name from the settings. + */ + Glib::ustring getImageEditorName(); + + /** + * callback, is executed on clicking the "Embed Image" menu entry + */ + void ImageEmbed(void); + + /** + * callback, is executed on clicking the "Trace Bitmap" menu entry + */ + void ImageTraceBitmap(void); + + /** + * callback, is executed on clicking the "Trace Pixel Art" menu entry + */ + void ImageTracePixelArt(void); + + /** + * callback, is executed on clicking the "Extract Image" menu entry + */ + void ImageExtract(void); + + + /** + * callback, is executed on clicking the "Fill and Stroke" menu entry + */ + void FillSettings(void); + + + /** + * callback, is executed on clicking the "Text and Font" menu entry + */ + void TextSettings(void); + + /** + * callback, is executed on clicking the "Check spelling" menu entry + */ + void SpellcheckSettings(void); +}; + +#endif // SEEN_SP_INTERFACE_H + +/* + 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 : diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index c28b86416..150e899ce 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -44,7 +44,7 @@ #include "desktop-style.h" #include "sp-namedview.h" #include "selection.h" -#include "interface.h" +#include "ui/interface.h" #include "macros.h" #include "tools-switch.h" #include "preferences.h" -- cgit v1.2.3 From 59c5c3e7575768faa00dd7d9fde9eca6d8815aab Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 14:14:01 -0400 Subject: Move GtkAction subclasses to widgets/ (bzr r13341.1.249) --- src/ui/widget/unit-tracker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp index 67eb1f48d..c6318db25 100644 --- a/src/ui/widget/unit-tracker.cpp +++ b/src/ui/widget/unit-tracker.cpp @@ -13,7 +13,7 @@ */ #include "unit-tracker.h" -#include "ege-select-one-action.h" +#include "widgets/ege-select-one-action.h" #define COLUMN_STRING 0 -- cgit v1.2.3 From 0a9152515fe0a64b0fa1f2735d30dbaf577add6d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 14:32:08 -0400 Subject: Fix CMakeLists (bzr r13341.1.250) --- src/ui/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 56908f58e..0f6e560d2 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -3,6 +3,7 @@ set(ui_SRC clipboard.cpp control-manager.cpp dialog-events.cpp + interface.cpp previewholder.cpp uxmanager.cpp @@ -159,6 +160,7 @@ set(ui_SRC control-types.h dialog-events.h icon-names.h + interface.h previewable.h previewfillable.h previewholder.h -- cgit v1.2.3 From b700110359cc8bba13357efe42f1b1bdb8069ed8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 5 Oct 2014 21:48:43 +0200 Subject: Use actual SVG width and height property values in preview image text. (bzr r13341.1.251) --- src/ui/dialog/filedialogimpl-gtkmm.cpp | 40 ++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 511237f4d..2c13d40b6 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -40,6 +40,8 @@ #include #include +#include + #include "document.h" #include "extension/input.h" #include "extension/output.h" @@ -191,6 +193,40 @@ void SVGPreview::showImage(Glib::ustring &theFileName) { Glib::ustring fileName = theFileName; + // Let's get real width and height from SVG file. These are template + // files so we assume they are well formed. + + // std::cout << "SVGPreview::showImage: " << theFileName << std::endl; + std::ifstream input(theFileName.c_str()); + + std::string width; + std::string height; + + if( !input ) { + std::cout << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; + } else { + + std::string token; + + Glib::MatchInfo match_info; + Glib::RefPtr regex1 = Glib::Regex::create("width=\"(.*)\""); + Glib::RefPtr regex2 = Glib::Regex::create("height=\"(.*)\""); + + while( !input.eof() && (height.empty() || width.empty()) ) { + + input >> token; + // std::cout << "|" << token << "|" << std::endl; + + if (regex1->match(token, match_info)) { + width = match_info.fetch(1).raw(); + } + + if (regex2->match(token, match_info)) { + height = match_info.fetch(1).raw(); + } + + } + } /*##################################### # LET'S HAVE SOME FUN WITH SVG! @@ -270,7 +306,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName) " style=\"font-size:24.000000;font-style:normal;font-weight:normal;" " fill:#000000;fill-opacity:1.0000000;stroke:none;" " font-family:Sans\"\n" - " x=\"10\" y=\"26\">%d x %d\n" //# VALUES HERE + " x=\"10\" y=\"26\">%s x %s\n" //# VALUES HERE "\n\n"; // if (!Glib::get_charset()) //If we are not utf8 @@ -280,7 +316,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName) /* FIXME: Do proper XML quoting for fileName. */ gchar *xmlBuffer = g_strdup_printf(xformat, previewWidth, previewHeight, imgX, imgY, scaledImgWidth, scaledImgHeight, - fileName.c_str(), rectX, rectY, rectWidth, rectHeight, imgWidth, imgHeight); + fileName.c_str(), rectX, rectY, rectWidth, rectHeight, width.c_str(), height.c_str() ); // g_message("%s\n", xmlBuffer); -- cgit v1.2.3 From 8a779e74c5243e3efe16431fdd215efe4380bcfc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 5 Oct 2014 22:07:53 +0200 Subject: Attempt to fix build breakage reported by su_v (but not seen locally). (bzr r13341.1.252) --- src/ui/dialog/filedialogimpl-gtkmm.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 2c13d40b6..5d330f7f0 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -21,6 +21,8 @@ #include #endif +#include + #include "filedialogimpl-gtkmm.h" #include "ui/dialog-events.h" #include "ui/interface.h" @@ -203,7 +205,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName) std::string height; if( !input ) { - std::cout << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; + std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; } else { std::string token; -- cgit v1.2.3 From 156cf3323a936c7dfccd9e09458cd8b5d174b7fe Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 19:24:27 -0400 Subject: Move more UI code into ui/ (bzr r13341.1.253) --- src/ui/CMakeLists.txt | 8 + src/ui/Makefile_insert | 9 + src/ui/clipboard.cpp | 2 +- src/ui/dialog/align-and-distribute.cpp | 2 +- src/ui/dialog/document-properties.cpp | 4 +- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/spellcheck.cpp | 2 +- src/ui/draw-anchor.cpp | 105 +++ src/ui/draw-anchor.h | 52 ++ src/ui/object-edit.cpp | 1399 ++++++++++++++++++++++++++++++++ src/ui/object-edit.h | 84 ++ src/ui/shape-editor.cpp | 177 ++++ src/ui/shape-editor.h | 71 ++ src/ui/tool-factory.h | 40 + src/ui/tool/node.cpp | 2 +- src/ui/tools-switch.cpp | 196 +++++ src/ui/tools-switch.h | 64 ++ src/ui/tools/arc-tool.cpp | 4 +- src/ui/tools/box3d-tool.cpp | 4 +- src/ui/tools/calligraphic-tool.cpp | 2 +- src/ui/tools/connector-tool.cpp | 2 +- src/ui/tools/dropper-tool.cpp | 2 +- src/ui/tools/eraser-tool.cpp | 2 +- src/ui/tools/flood-tool.cpp | 4 +- src/ui/tools/freehand-base.cpp | 2 +- src/ui/tools/gradient-tool.cpp | 2 +- src/ui/tools/lpe-tool.cpp | 4 +- src/ui/tools/measure-tool.cpp | 2 +- src/ui/tools/mesh-tool.cpp | 2 +- src/ui/tools/node-tool.cpp | 4 +- src/ui/tools/pen-tool.cpp | 6 +- src/ui/tools/pencil-tool.cpp | 4 +- src/ui/tools/rect-tool.cpp | 4 +- src/ui/tools/select-tool.cpp | 4 +- src/ui/tools/spiral-tool.cpp | 4 +- src/ui/tools/spray-tool.cpp | 2 +- src/ui/tools/star-tool.cpp | 4 +- src/ui/tools/text-tool.cpp | 4 +- src/ui/tools/tool-base.cpp | 4 +- src/ui/tools/tool-base.h | 4 +- src/ui/tools/tweak-tool.cpp | 2 +- src/ui/tools/zoom-tool.cpp | 2 +- 42 files changed, 2253 insertions(+), 46 deletions(-) create mode 100644 src/ui/draw-anchor.cpp create mode 100644 src/ui/draw-anchor.h create mode 100644 src/ui/object-edit.cpp create mode 100644 src/ui/object-edit.h create mode 100644 src/ui/shape-editor.cpp create mode 100644 src/ui/shape-editor.h create mode 100644 src/ui/tool-factory.h create mode 100644 src/ui/tools-switch.cpp create mode 100644 src/ui/tools-switch.h (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 0f6e560d2..8bae15fa5 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -3,8 +3,12 @@ set(ui_SRC clipboard.cpp control-manager.cpp dialog-events.cpp + draw-anchor.cpp interface.cpp + object-edit.cpp previewholder.cpp + shape-editor.cpp + tools-switch.cpp uxmanager.cpp cache/svg_preview_cache.cpp @@ -159,11 +163,15 @@ set(ui_SRC control-manager.h control-types.h dialog-events.h + draw-anchor.h icon-names.h interface.h + object-edit.h previewable.h previewfillable.h previewholder.h + shape-editor.h + tools-switch.h uxmanager.h cache/svg_preview_cache.h diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index 4c6b49ed6..7aeb4a83d 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -8,12 +8,21 @@ ink_common_sources += \ ui/control-types.h \ ui/dialog-events.cpp \ ui/dialog-events.h \ + ui/draw-anchor.cpp \ + ui/draw-anchor.h \ ui/icon-names.h \ ui/interface.cpp \ ui/interface.h \ + ui/object-edit.cpp \ + ui/object-edit.h \ ui/previewable.h \ ui/previewfillable.h \ ui/previewholder.cpp \ ui/previewholder.h \ + ui/shape-editor.cpp \ + ui/shape-editor.h \ + ui/tool-factory.h \ + ui/tools-switch.cpp \ + ui/tools-switch.h \ ui/uxmanager.cpp \ ui/uxmanager.h diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 1209b19cd..40500cf15 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -76,7 +76,7 @@ #include "svg/css-ostringstream.h" // used in copy #include "ui/tools/text-tool.h" #include "text-editing.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "path-chemistry.h" #include "util/units.h" #include "helper/png-write.h" diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 8352de1e3..431da7ad1 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -38,7 +38,7 @@ #include "sp-item-transform.h" #include "sp-text.h" #include "text-editing.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/tools/node-tool.h" #include "ui/tool/multi-path-manipulator.h" diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2a3a1dd86..071ac037f 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -31,13 +31,13 @@ #include "inkscape.h" #include "io/sys.h" #include "preferences.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-namedview.h" #include "sp-root.h" #include "sp-script.h" #include "style.h" #include "svg/stringstream.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/widget/color-picker.h" #include "ui/widget/scalar-unit.h" #include "ui/dialog/filedialog.h" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 07a27c96e..93d5dfbd5 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -43,7 +43,7 @@ #include "sp-root.h" #include "sp-shape.h" #include "style.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index b8436ebf1..9faa8a2cb 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -23,7 +23,7 @@ #include "selection.h" #include "desktop.h" #include "desktop-handles.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/tools/text-tool.h" #include "ui/interface.h" #include "preferences.h" diff --git a/src/ui/draw-anchor.cpp b/src/ui/draw-anchor.cpp new file mode 100644 index 000000000..84c919018 --- /dev/null +++ b/src/ui/draw-anchor.cpp @@ -0,0 +1,105 @@ +/** \file + * Anchors implementation. + */ + +/* + * Authors: + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/draw-anchor.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "ui/tools/tool-base.h" +#include "ui/tools/lpe-tool.h" +#include "display/sodipodi-ctrl.h" +#include "display/curve.h" +#include "ui/control-manager.h" + +using Inkscape::ControlManager; + +#define FILL_COLOR_NORMAL 0xffffff7f +#define FILL_COLOR_MOUSEOVER 0xff0000ff + +/** + * Creates an anchor object and initializes it. + */ +SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, Geom::Point delta) +{ + if (SP_IS_LPETOOL_CONTEXT(dc)) { + // suppress all kinds of anchors in LPEToolContext + return NULL; + } + + SPDrawAnchor *a = g_new(SPDrawAnchor, 1); + + a->dc = dc; + a->curve = curve; + curve->ref(); + a->start = start; + a->active = FALSE; + a->dp = delta; + a->ctrl = ControlManager::getManager().createControl(sp_desktop_controls(&dc->getDesktop()), Inkscape::CTRL_TYPE_ANCHOR); + + SP_CTRL(a->ctrl)->moveto(delta); + + ControlManager::getManager().track(a->ctrl); + + return a; +} + +/** + * Destroys the anchor's canvas item and frees the anchor object. + */ +SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor) +{ + if (anchor->curve) { + anchor->curve->unref(); + } + if (anchor->ctrl) { + sp_canvas_item_destroy(anchor->ctrl); + } + g_free(anchor); + return NULL; +} + +/** + * Test if point is near anchor, if so fill anchor on canvas and return + * pointer to it or NULL. + */ +SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate) +{ + SPCtrl *ctrl = SP_CTRL(anchor->ctrl); + + if ( activate && ( Geom::LInfty( w - anchor->dc->getDesktop().d2w(anchor->dp) ) <= (ctrl->box.width() / 2.0) ) ) { + if (!anchor->active) { + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_MOUSEOVER, NULL); + anchor->active = TRUE; + } + return anchor; + } + + if (anchor->active) { + g_object_set(anchor->ctrl, "fill_color", FILL_COLOR_NORMAL, NULL); + anchor->active = FALSE; + } + return NULL; +} + + +/* + 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 : diff --git a/src/ui/draw-anchor.h b/src/ui/draw-anchor.h new file mode 100644 index 000000000..1f7b55920 --- /dev/null +++ b/src/ui/draw-anchor.h @@ -0,0 +1,52 @@ +#ifndef SEEN_DRAW_ANCHOR_H +#define SEEN_DRAW_ANCHOR_H + +/** \file + * Drawing anchors. + */ + +#include <2geom/point.h> + +namespace Inkscape { +namespace UI { +namespace Tools { + +class FreehandBase; + +} +} +} + +class SPCurve; +struct SPCanvasItem; + +/// The drawing anchor. +/// \todo Make this a regular knot, this will allow to set statusbar tips. +struct SPDrawAnchor { + Inkscape::UI::Tools::FreehandBase *dc; + SPCurve *curve; + unsigned int start : 1; + unsigned int active : 1; + Geom::Point dp; + SPCanvasItem *ctrl; +}; + + +SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, + Geom::Point delta); +SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor); +SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate); + + +#endif /* !SEEN_DRAW_ANCHOR_H */ + +/* + 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 : diff --git a/src/ui/object-edit.cpp b/src/ui/object-edit.cpp new file mode 100644 index 000000000..cc96727f8 --- /dev/null +++ b/src/ui/object-edit.cpp @@ -0,0 +1,1399 @@ +/* + * Node editing extension to objects + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * Maximilian Albert + * Abhishek Sharma + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#include "sp-item.h" +#include "sp-rect.h" +#include "box3d.h" +#include "sp-ellipse.h" +#include "sp-star.h" +#include "sp-spiral.h" +#include "sp-offset.h" +#include "sp-flowtext.h" +#include "preferences.h" +#include "style.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "sp-namedview.h" +#include "live_effects/effect.h" +#include "sp-pattern.h" +#include "sp-path.h" +#include +#include "ui/object-edit.h" +#include "xml/repr.h" +#include <2geom/math-utils.h> +#include "knot-holder-entity.h" + +#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) + +namespace { + +static KnotHolder *sp_lpe_knot_holder(SPItem *item, SPDesktop *desktop) +{ + KnotHolder *knot_holder = new KnotHolder(desktop, item, NULL); + + Inkscape::LivePathEffect::Effect *effect = SP_LPE_ITEM(item)->getCurrentLPE(); + effect->addHandles(knot_holder, desktop, item); + + return knot_holder; +} + +} // namespace + +namespace Inkscape { +namespace UI { + +KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) +{ + KnotHolder *knotholder = NULL; + + if (SP_IS_LPE_ITEM(item) && + SP_LPE_ITEM(item)->getCurrentLPE() && + SP_LPE_ITEM(item)->getCurrentLPE()->isVisible() && + SP_LPE_ITEM(item)->getCurrentLPE()->providesKnotholder()) { + knotholder = sp_lpe_knot_holder(item, desktop); + } else if (SP_IS_RECT(item)) { + knotholder = new RectKnotHolder(desktop, item, NULL); + } else if (SP_IS_BOX3D(item)) { + knotholder = new Box3DKnotHolder(desktop, item, NULL); + } else if (SP_IS_GENERICELLIPSE(item)) { + knotholder = new ArcKnotHolder(desktop, item, NULL); + } else if (SP_IS_STAR(item)) { + knotholder = new StarKnotHolder(desktop, item, NULL); + } else if (SP_IS_SPIRAL(item)) { + knotholder = new SpiralKnotHolder(desktop, item, NULL); + } else if (SP_IS_OFFSET(item)) { + knotholder = new OffsetKnotHolder(desktop, item, NULL); + } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { + knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL); + } else if ((item->style->fill.isPaintserver() && SP_IS_PATTERN(item->style->getFillPaintServer())) || + (item->style->stroke.isPaintserver() && SP_IS_PATTERN(item->style->getStrokePaintServer()))) { + knotholder = new KnotHolder(desktop, item, NULL); + knotholder->add_pattern_knotholder(); + } + + return knotholder; +} + +} +} // namespace Inkscape + +/* SPRect */ + +/* handle for horizontal rounding radius */ +class RectKnotHolderEntityRX : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +/* handle for vertical rounding radius */ +class RectKnotHolderEntityRY : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +/* handle for width/height adjustment */ +class RectKnotHolderEntityWH : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + +protected: + void set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +/* handle for x/y adjustment */ +class RectKnotHolderEntityXY : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +Geom::Point +RectKnotHolderEntityRX::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed - rect->rx.computed, rect->y.computed); +} + +void +RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + //In general we cannot just snap this radius to an arbitrary point, as we have only a single + //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap + //the radius then we should have a constrained snap. snap_knot_position() is unconstrained + Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(-1, 0)), state); + + if (state & GDK_CONTROL_MASK) { + gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; + rect->rx.computed = rect->ry.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, temp); + rect->rx._set = rect->ry._set = true; + + } else { + rect->rx.computed = CLAMP(rect->x.computed + rect->width.computed - s[Geom::X], 0.0, rect->width.computed / 2.0); + rect->rx._set = true; + } + + update_knot(); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +RectKnotHolderEntityRX::knot_click(unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_SHIFT_MASK) { + /* remove rounding from rectangle */ + rect->getRepr()->setAttribute("rx", NULL); + rect->getRepr()->setAttribute("ry", NULL); + } else if (state & GDK_CONTROL_MASK) { + /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ + rect->getRepr()->setAttribute("ry", rect->getRepr()->attribute("rx")); + } + +} + +Geom::Point +RectKnotHolderEntityRY::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->ry.computed); +} + +void +RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + //In general we cannot just snap this radius to an arbitrary point, as we have only a single + //degree of freedom. For snapping to an arbitrary point we need two DOF. If we're going to snap + //the radius then we should have a constrained snap. snap_knot_position() is unconstrained + Geom::Point const s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed), Geom::Point(0, 1)), state); + + if (state & GDK_CONTROL_MASK) { // When holding control then rx will be kept equal to ry, + // resulting in a perfect circle (and not an ellipse) + gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; + rect->rx.computed = rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, 0.0, temp); + rect->ry._set = rect->rx._set = true; + } else { + if (!rect->rx._set || rect->rx.computed == 0) { + rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, + 0.0, + MIN(rect->height.computed / 2.0, rect->width.computed / 2.0)); + } else { + rect->ry.computed = CLAMP(s[Geom::Y] - rect->y.computed, + 0.0, + rect->height.computed / 2.0); + } + + rect->ry._set = true; + } + + update_knot(); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +RectKnotHolderEntityRY::knot_click(unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_SHIFT_MASK) { + /* remove rounding */ + rect->getRepr()->setAttribute("rx", NULL); + rect->getRepr()->setAttribute("ry", NULL); + } else if (state & GDK_CONTROL_MASK) { + /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ + rect->getRepr()->setAttribute("rx", rect->getRepr()->attribute("ry")); + } +} + +#define SGN(x) ((x)>0?1:((x)<0?-1:0)) + +static void sp_rect_clamp_radii(SPRect *rect) +{ + // clamp rounding radii so that they do not exceed width/height + if (2 * rect->rx.computed > rect->width.computed) { + rect->rx.computed = 0.5 * rect->width.computed; + rect->rx._set = true; + } + if (2 * rect->ry.computed > rect->height.computed) { + rect->ry.computed = 0.5 * rect->height.computed; + rect->ry._set = true; + } +} + +Geom::Point +RectKnotHolderEntityWH::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); +} + +void +RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + Geom::Point s = p; + + if (state & GDK_CONTROL_MASK) { + // original width/height when drag started + gdouble const w_orig = (origin[Geom::X] - rect->x.computed); + gdouble const h_orig = (origin[Geom::Y] - rect->y.computed); + + //original ratio + gdouble ratio = (w_orig / h_orig); + + // mouse displacement since drag started + gdouble minx = p[Geom::X] - origin[Geom::X]; + gdouble miny = p[Geom::Y] - origin[Geom::Y]; + + Geom::Point p_handle(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); + + if (fabs(minx) > fabs(miny)) { + // snap to horizontal or diagonal + if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->height.computed = MAX(h_orig + minx / ratio, 0); + } else { + // closer to the horizontal, change only width, height is h_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->height.computed = MAX(h_orig, 0); + } + rect->width.computed = MAX(w_orig + minx, 0); + + } else { + // snap to vertical or diagonal + if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->width.computed = MAX(w_orig + miny * ratio, 0); + } else { + // closer to the vertical, change only height, width is w_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->width.computed = MAX(w_orig, 0); + } + rect->height.computed = MAX(h_orig + miny, 0); + + } + + rect->width._set = rect->height._set = true; + + } else { + // move freely + s = snap_knot_position(p, state); + rect->width.computed = MAX(s[Geom::X] - rect->x.computed, 0); + rect->height.computed = MAX(s[Geom::Y] - rect->y.computed, 0); + rect->width._set = rect->height._set = true; + } + + sp_rect_clamp_radii(rect); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +RectKnotHolderEntityWH::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + set_internal(p, origin, state); + update_knot(); +} + +Geom::Point +RectKnotHolderEntityXY::knot_get() const +{ + SPRect *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed, rect->y.computed); +} + +void +RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + SPRect *rect = SP_RECT(item); + + // opposite corner (unmoved) + gdouble opposite_x = (rect->x.computed + rect->width.computed); + gdouble opposite_y = (rect->y.computed + rect->height.computed); + + // original width/height when drag started + gdouble w_orig = opposite_x - origin[Geom::X]; + gdouble h_orig = opposite_y - origin[Geom::Y]; + + Geom::Point s = p; + Geom::Point p_handle(rect->x.computed, rect->y.computed); + + // mouse displacement since drag started + gdouble minx = p[Geom::X] - origin[Geom::X]; + gdouble miny = p[Geom::Y] - origin[Geom::Y]; + + if (state & GDK_CONTROL_MASK) { + //original ratio + gdouble ratio = (w_orig / h_orig); + + if (fabs(minx) > fabs(miny)) { + // snap to horizontal or diagonal + if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->y.computed = MIN(origin[Geom::Y] + minx / ratio, opposite_y); + rect->height.computed = MAX(h_orig - minx / ratio, 0); + } else { + // closer to the horizontal, change only width, height is h_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-1, 0)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->y.computed = MIN(origin[Geom::Y], opposite_y); + rect->height.computed = MAX(h_orig, 0); + } + rect->x.computed = MIN(s[Geom::X], opposite_x); + rect->width.computed = MAX(w_orig - minx, 0); + } else { + // snap to vertical or diagonal + if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(-ratio, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->x.computed = MIN(origin[Geom::X] + miny * ratio, opposite_x); + rect->width.computed = MAX(w_orig - miny * ratio, 0); + } else { + // closer to the vertical, change only height, width is w_orig + s = snap_knot_position_constrained(p, Inkscape::Snapper::SnapConstraint(p_handle, Geom::Point(0, -1)), state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + rect->x.computed = MIN(origin[Geom::X], opposite_x); + rect->width.computed = MAX(w_orig, 0); + } + rect->y.computed = MIN(s[Geom::Y], opposite_y); + rect->height.computed = MAX(h_orig - miny, 0); + } + + rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + + } else { + // move freely + s = snap_knot_position(p, state); + minx = s[Geom::X] - origin[Geom::X]; + miny = s[Geom::Y] - origin[Geom::Y]; + + rect->x.computed = MIN(s[Geom::X], opposite_x); + rect->width.computed = MAX(w_orig - minx, 0); + rect->y.computed = MIN(s[Geom::Y], opposite_y); + rect->height.computed = MAX(h_orig - miny, 0); + rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + } + + sp_rect_clamp_radii(rect); + + update_knot(); + + (static_cast(rect))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +RectKnotHolder::RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + RectKnotHolderEntityRX *entity_rx = new RectKnotHolderEntityRX(); + RectKnotHolderEntityRY *entity_ry = new RectKnotHolderEntityRY(); + RectKnotHolderEntityWH *entity_wh = new RectKnotHolderEntityWH(); + RectKnotHolderEntityXY *entity_xy = new RectKnotHolderEntityXY(); + + entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Adjust the horizontal rounding radius; with Ctrl " + "to make the vertical radius the same"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity_ry->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Adjust the vertical rounding radius; with Ctrl " + "to make the horizontal radius the same"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity_wh->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust the width and height of the rectangle; with Ctrl " + "to lock ratio or stretch in one dimension only"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust the width and height of the rectangle; with Ctrl " + "to lock ratio or stretch in one dimension only"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity.push_back(entity_rx); + entity.push_back(entity_ry); + entity.push_back(entity_wh); + entity.push_back(entity_xy); + + add_pattern_knotholder(); +} + +/* Box3D (= the new 3D box structure) */ + +class Box3DKnotHolderEntity : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const = 0; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) = 0; + + Geom::Point knot_get_generic(SPItem *item, unsigned int knot_id) const; + void knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &p, unsigned int state); +}; + +Geom::Point +Box3DKnotHolderEntity::knot_get_generic(SPItem *item, unsigned int knot_id) const +{ + return box3d_get_corner_screen(SP_BOX3D(item), knot_id); +} + +void +Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, unsigned int state) +{ + Geom::Point const s = snap_knot_position(new_pos, state); + + g_assert(item != NULL); + SPBox3D *box = SP_BOX3D(item); + Geom::Affine const i2dt (item->i2dt_affine ()); + + Box3D::Axis movement; + if ((knot_id < 4) != (state & GDK_SHIFT_MASK)) { + movement = Box3D::XY; + } else { + movement = Box3D::Z; + } + + box3d_set_corner (box, knot_id, s * i2dt, movement, (state & GDK_CONTROL_MASK)); + box3d_set_z_orders(box); + box3d_position_set(box); +} + +class Box3DKnotHolderEntity0 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity1 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity2 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity3 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity4 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity5 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity6 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntity7 : public Box3DKnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +class Box3DKnotHolderEntityCenter : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +Geom::Point +Box3DKnotHolderEntity0::knot_get() const +{ + return knot_get_generic(item, 0); +} + +Geom::Point +Box3DKnotHolderEntity1::knot_get() const +{ + return knot_get_generic(item, 1); +} + +Geom::Point +Box3DKnotHolderEntity2::knot_get() const +{ + return knot_get_generic(item, 2); +} + +Geom::Point +Box3DKnotHolderEntity3::knot_get() const +{ + return knot_get_generic(item, 3); +} + +Geom::Point +Box3DKnotHolderEntity4::knot_get() const +{ + return knot_get_generic(item, 4); +} + +Geom::Point +Box3DKnotHolderEntity5::knot_get() const +{ + return knot_get_generic(item, 5); +} + +Geom::Point +Box3DKnotHolderEntity6::knot_get() const +{ + return knot_get_generic(item, 6); +} + +Geom::Point +Box3DKnotHolderEntity7::knot_get() const +{ + return knot_get_generic(item, 7); +} + +Geom::Point +Box3DKnotHolderEntityCenter::knot_get() const +{ + return box3d_get_center_screen(SP_BOX3D(item)); +} + +void +Box3DKnotHolderEntity0::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 0, new_pos, state); +} + +void +Box3DKnotHolderEntity1::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 1, new_pos, state); +} + +void +Box3DKnotHolderEntity2::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 2, new_pos, state); +} + +void +Box3DKnotHolderEntity3::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 3, new_pos, state); +} + +void +Box3DKnotHolderEntity4::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 4, new_pos, state); +} + +void +Box3DKnotHolderEntity5::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 5, new_pos, state); +} + +void +Box3DKnotHolderEntity6::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 6, new_pos, state); +} + +void +Box3DKnotHolderEntity7::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) +{ + knot_set_generic(item, 7, new_pos, state); +} + +void +Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, unsigned int state) +{ + Geom::Point const s = snap_knot_position(new_pos, state); + + SPBox3D *box = SP_BOX3D(item); + Geom::Affine const i2dt (item->i2dt_affine ()); + + box3d_set_center (SP_BOX3D(item), s * i2dt, origin * i2dt, !(state & GDK_SHIFT_MASK) ? Box3D::XY : Box3D::Z, + state & GDK_CONTROL_MASK); + + box3d_set_z_orders(box); + box3d_position_set(box); +} + +Box3DKnotHolder::Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + Box3DKnotHolderEntity0 *entity_corner0 = new Box3DKnotHolderEntity0(); + Box3DKnotHolderEntity1 *entity_corner1 = new Box3DKnotHolderEntity1(); + Box3DKnotHolderEntity2 *entity_corner2 = new Box3DKnotHolderEntity2(); + Box3DKnotHolderEntity3 *entity_corner3 = new Box3DKnotHolderEntity3(); + Box3DKnotHolderEntity4 *entity_corner4 = new Box3DKnotHolderEntity4(); + Box3DKnotHolderEntity5 *entity_corner5 = new Box3DKnotHolderEntity5(); + Box3DKnotHolderEntity6 *entity_corner6 = new Box3DKnotHolderEntity6(); + Box3DKnotHolderEntity7 *entity_corner7 = new Box3DKnotHolderEntity7(); + Box3DKnotHolderEntityCenter *entity_center = new Box3DKnotHolderEntityCenter(); + + entity_corner0->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner2->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner3->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box in X/Y direction; with Shift along the Z axis; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner4->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner5->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner6->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_corner7->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Resize box along the Z axis; with Shift in X/Y direction; " + "with Ctrl to constrain to the directions of edges or diagonals")); + + entity_center->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT, + _("Move the box in perspective"), + SP_KNOT_SHAPE_CROSS); + + entity.push_back(entity_corner0); + entity.push_back(entity_corner1); + entity.push_back(entity_corner2); + entity.push_back(entity_corner3); + entity.push_back(entity_corner4); + entity.push_back(entity_corner5); + entity.push_back(entity_corner6); + entity.push_back(entity_corner7); + entity.push_back(entity_center); + + add_pattern_knotholder(); +} + +/* SPArc */ + +class ArcKnotHolderEntityStart : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class ArcKnotHolderEntityEnd : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class ArcKnotHolderEntityRX : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class ArcKnotHolderEntityRY : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +/* + * return values: + * 1 : inside + * 0 : on the curves + * -1 : outside + */ +static gint +sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p) +{ + gdouble dx = (p[Geom::X] - ellipse->cx.computed) / ellipse->rx.computed; + gdouble dy = (p[Geom::Y] - ellipse->cy.computed) / ellipse->ry.computed; + + gdouble s = dx * dx + dy * dy; + if (s < 1.0) return 1; + if (s > 1.0) return -1; + return 0; +} + +void +ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); + + SPGenericEllipse *arc = SP_GENERICELLIPSE(item); + + arc->setClosed(sp_genericellipse_side(arc, p) == -1); + + Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); + Geom::Scale sc(arc->rx.computed, arc->ry.computed); + + arc->start = atan2(delta * sc.inverse()); + + if ((state & GDK_CONTROL_MASK) && snaps) { + arc->start = sp_round(arc->start, M_PI / snaps); + } + + arc->normalize(); + arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityStart::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return ge->getPointAtAngle(ge->start); +} + +void +ArcKnotHolderEntityStart::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_SHIFT_MASK) { + ge->end = ge->start = 0; + (static_cast(ge))->updateRepr(); + } +} + +void +ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); + + SPGenericEllipse *arc = SP_GENERICELLIPSE(item); + + arc->setClosed(sp_genericellipse_side(arc, p) == -1); + + Geom::Point delta = p - Geom::Point(arc->cx.computed, arc->cy.computed); + Geom::Scale sc(arc->rx.computed, arc->ry.computed); + + arc->end = atan2(delta * sc.inverse()); + + if ((state & GDK_CONTROL_MASK) && snaps) { + arc->end = sp_round(arc->end, M_PI/snaps); + } + + arc->normalize(); + arc->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityEnd::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return ge->getPointAtAngle(ge->end); +} + + +void +ArcKnotHolderEntityEnd::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_SHIFT_MASK) { + ge->end = ge->start = 0; + (static_cast(ge))->updateRepr(); + } +} + + +void +ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + Geom::Point const s = snap_knot_position(p, state); + + ge->rx.computed = fabs( ge->cx.computed - s[Geom::X] ); + + if ( state & GDK_CONTROL_MASK ) { + ge->ry.computed = ge->rx.computed; + } + + (static_cast(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityRX::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(ge->rx.computed, 0)); +} + +void +ArcKnotHolderEntityRX::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_CONTROL_MASK) { + ge->ry.computed = ge->rx.computed; + (static_cast(ge))->updateRepr(); + } +} + +void +ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + Geom::Point const s = snap_knot_position(p, state); + + ge->ry.computed = fabs( ge->cy.computed - s[Geom::Y] ); + + if ( state & GDK_CONTROL_MASK ) { + ge->rx.computed = ge->ry.computed; + } + + (static_cast(item))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +ArcKnotHolderEntityRY::knot_get() const +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + return (Geom::Point(ge->cx.computed, ge->cy.computed) - Geom::Point(0, ge->ry.computed)); +} + +void +ArcKnotHolderEntityRY::knot_click(unsigned int state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_CONTROL_MASK) { + ge->rx.computed = ge->ry.computed; + (static_cast(ge))->updateRepr(); + } +} + +ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + ArcKnotHolderEntityRX *entity_rx = new ArcKnotHolderEntityRX(); + ArcKnotHolderEntityRY *entity_ry = new ArcKnotHolderEntityRY(); + ArcKnotHolderEntityStart *entity_start = new ArcKnotHolderEntityStart(); + ArcKnotHolderEntityEnd *entity_end = new ArcKnotHolderEntityEnd(); + + entity_rx->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust ellipse width, with Ctrl to make circle"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_ry->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Adjust ellipse height, with Ctrl to make circle"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_start->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Position the start point of the arc or segment; with Ctrl " + "to snap angle; drag inside the ellipse for arc, outside for segment"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity_end->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Position the end point of the arc or segment; with Ctrl to snap angle; " + "drag inside the ellipse for arc, outside for segment"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity.push_back(entity_rx); + entity.push_back(entity_ry); + entity.push_back(entity_start); + entity.push_back(entity_end); + + add_pattern_knotholder(); +} + +/* SPStar */ + +class StarKnotHolderEntity1 : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class StarKnotHolderEntity2 : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +void +StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPStar *star = SP_STAR(item); + + Geom::Point const s = snap_knot_position(p, state); + + Geom::Point d = s - star->center; + + double arg1 = atan2(d); + double darg1 = arg1 - star->arg[0]; + + if (state & GDK_MOD1_MASK) { + star->randomized = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_CONTROL_MASK) { + star->r[0] = L2(d); + } else { + star->r[0] = L2(d); + star->arg[0] = arg1; + star->arg[1] += darg1; + } + (static_cast(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + SPStar *star = SP_STAR(item); + + Geom::Point const s = snap_knot_position(p, state); + + if (star->flatsided == false) { + Geom::Point d = s - star->center; + + double arg1 = atan2(d); + double darg1 = arg1 - star->arg[1]; + + if (state & GDK_MOD1_MASK) { + star->randomized = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = fabs(darg1/(star->arg[0] - star->arg[1])); + } else if (state & GDK_CONTROL_MASK) { + star->r[1] = L2(d); + star->arg[1] = star->arg[0] + M_PI / star->sides; + } + else { + star->r[1] = L2(d); + star->arg[1] = atan2(d); + } + (static_cast(star))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + +Geom::Point +StarKnotHolderEntity1::knot_get() const +{ + g_assert(item != NULL); + + SPStar const *star = SP_STAR(item); + + return sp_star_get_xy(star, SP_STAR_POINT_KNOT1, 0); + +} + +Geom::Point +StarKnotHolderEntity2::knot_get() const +{ + g_assert(item != NULL); + + SPStar const *star = SP_STAR(item); + + return sp_star_get_xy(star, SP_STAR_POINT_KNOT2, 0); +} + +static void +sp_star_knot_click(SPItem *item, unsigned int state) +{ + SPStar *star = SP_STAR(item); + + if (state & GDK_MOD1_MASK) { + star->randomized = 0; + (static_cast(star))->updateRepr(); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = 0; + (static_cast(star))->updateRepr(); + } else if (state & GDK_CONTROL_MASK) { + star->arg[1] = star->arg[0] + M_PI / star->sides; + (static_cast(star))->updateRepr(); + } +} + +void +StarKnotHolderEntity1::knot_click(unsigned int state) +{ + sp_star_knot_click(item, state); +} + +void +StarKnotHolderEntity2::knot_click(unsigned int state) +{ + sp_star_knot_click(item, state); +} + +StarKnotHolder::StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + SPStar *star = SP_STAR(item); + + StarKnotHolderEntity1 *entity1 = new StarKnotHolderEntity1(); + entity1->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the tip radius of the star or polygon; " + "with Shift to round; with Alt to randomize")); + + entity.push_back(entity1); + + if (star->flatsided == false) { + StarKnotHolderEntity2 *entity2 = new StarKnotHolderEntity2(); + entity2->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the base radius of the star; with Ctrl to keep star rays " + "radial (no skew); with Shift to round; with Alt to randomize")); + entity.push_back(entity2); + } + + add_pattern_knotholder(); +} + +/* SPSpiral */ + +class SpiralKnotHolderEntityInner : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); +}; + +class SpiralKnotHolderEntityOuter : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + + +/* + * set attributes via inner (t=t0) knot point: + * [default] increase/decrease inner point + * [shift] increase/decrease inner and outer arg synchronizely + * [control] constrain inner arg to round per PI/4 + */ +void +SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); + + SPSpiral *spiral = SP_SPIRAL(item); + + gdouble dx = p[Geom::X] - spiral->cx; + gdouble dy = p[Geom::Y] - spiral->cy; + + gdouble moved_y = p[Geom::Y] - origin[Geom::Y]; + + if (state & GDK_MOD1_MASK) { + // adjust divergence by vertical drag, relative to rad + if (spiral->rad > 0) { + double exp_delta = 0.1*moved_y/(spiral->rad); // arbitrary multiplier to slow it down + spiral->exp += exp_delta; + if (spiral->exp < 1e-3) + spiral->exp = 1e-3; + } + } else { + // roll/unroll from inside + gdouble arg_t0; + spiral->getPolar(spiral->t0, NULL, &arg_t0); + + gdouble arg_tmp = atan2(dy, dx) - arg_t0; + gdouble arg_t0_new = arg_tmp - floor((arg_tmp+M_PI)/(2.0*M_PI))*2.0*M_PI + arg_t0; + spiral->t0 = (arg_t0_new - spiral->arg) / (2.0*M_PI*spiral->revo); + + /* round inner arg per PI/snaps, if CTRL is pressed */ + if ( ( state & GDK_CONTROL_MASK ) + && ( fabs(spiral->revo) > SP_EPSILON_2 ) + && ( snaps != 0 ) ) { + gdouble arg = 2.0*M_PI*spiral->revo*spiral->t0 + spiral->arg; + spiral->t0 = (sp_round(arg, M_PI/snaps) - spiral->arg)/(2.0*M_PI*spiral->revo); + } + + spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); + } + + (static_cast(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* + * set attributes via outer (t=1) knot point: + * [default] increase/decrease revolution factor + * [control] constrain inner arg to round per PI/4 + */ +void +SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); + + SPSpiral *spiral = SP_SPIRAL(item); + + gdouble dx = p[Geom::X] - spiral->cx; + gdouble dy = p[Geom::Y] - spiral->cy; + + if (state & GDK_SHIFT_MASK) { // rotate without roll/unroll + spiral->arg = atan2(dy, dx) - 2.0*M_PI*spiral->revo; + if (!(state & GDK_MOD1_MASK)) { + // if alt not pressed, change also rad; otherwise it is locked + spiral->rad = MAX(hypot(dx, dy), 0.001); + } + if ( ( state & GDK_CONTROL_MASK ) + && snaps ) { + spiral->arg = sp_round(spiral->arg, M_PI/snaps); + } + } else { // roll/unroll + // arg of the spiral outer end + double arg_1; + spiral->getPolar(1, NULL, &arg_1); + + // its fractional part after the whole turns are subtracted + double arg_r = arg_1 - sp_round(arg_1, 2.0*M_PI); + + // arg of the mouse point relative to spiral center + double mouse_angle = atan2(dy, dx); + if (mouse_angle < 0) + mouse_angle += 2*M_PI; + + // snap if ctrl + if ( ( state & GDK_CONTROL_MASK ) && snaps ) { + mouse_angle = sp_round(mouse_angle, M_PI/snaps); + } + + // by how much we want to rotate the outer point + double diff = mouse_angle - arg_r; + if (diff > M_PI) + diff -= 2*M_PI; + else if (diff < -M_PI) + diff += 2*M_PI; + + // calculate the new rad; + // the value of t corresponding to the angle arg_1 + diff: + double t_temp = ((arg_1 + diff) - spiral->arg)/(2*M_PI*spiral->revo); + // the rad at that t: + double rad_new = 0; + if (t_temp > spiral->t0) + spiral->getPolar(t_temp, &rad_new, NULL); + + // change the revo (converting diff from radians to the number of turns) + spiral->revo += diff/(2*M_PI); + if (spiral->revo < 1e-3) + spiral->revo = 1e-3; + + // if alt not pressed and the values are sane, change the rad + if (!(state & GDK_MOD1_MASK) && rad_new > 1e-3 && rad_new/spiral->rad < 2) { + // adjust t0 too so that the inner point stays unmoved + double r0; + spiral->getPolar(spiral->t0, &r0, NULL); + spiral->rad = rad_new; + spiral->t0 = pow(r0 / spiral->rad, 1.0/spiral->exp); + } + if (!IS_FINITE(spiral->t0)) spiral->t0 = 0.0; + spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); + } + + (static_cast(spiral))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +Geom::Point +SpiralKnotHolderEntityInner::knot_get() const +{ + SPSpiral const *spiral = SP_SPIRAL(item); + + return spiral->getXY(spiral->t0); +} + +Geom::Point +SpiralKnotHolderEntityOuter::knot_get() const +{ + SPSpiral const *spiral = SP_SPIRAL(item); + + return spiral->getXY(1.0); +} + +void +SpiralKnotHolderEntityInner::knot_click(unsigned int state) +{ + SPSpiral *spiral = SP_SPIRAL(item); + + if (state & GDK_MOD1_MASK) { + spiral->exp = 1; + (static_cast(spiral))->updateRepr(); + } else if (state & GDK_SHIFT_MASK) { + spiral->t0 = 0; + (static_cast(spiral))->updateRepr(); + } +} + +SpiralKnotHolder::SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + SpiralKnotHolderEntityInner *entity_inner = new SpiralKnotHolderEntityInner(); + SpiralKnotHolderEntityOuter *entity_outer = new SpiralKnotHolderEntityOuter(); + + entity_inner->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Roll/unroll the spiral from inside; with Ctrl to snap angle; " + "with Alt to converge/diverge")); + + entity_outer->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Roll/unroll the spiral from outside; with Ctrl to snap angle; " + "with Shift to scale/rotate; with Alt to lock radius")); + + entity.push_back(entity_inner); + entity.push_back(entity_outer); + + add_pattern_knotholder(); +} + +/* SPOffset */ + +class OffsetKnotHolderEntity : public KnotHolderEntity { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +void +OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int /*state*/) +{ + SPOffset *offset = SP_OFFSET(item); + + offset->rad = sp_offset_distance_to_original(offset, p); + offset->knot = p; + offset->knotSet = true; + + (static_cast(offset))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + + +Geom::Point +OffsetKnotHolderEntity::knot_get() const +{ + SPOffset const *offset = SP_OFFSET(item); + + Geom::Point np; + sp_offset_top_point(offset,&np); + return np; +} + +OffsetKnotHolder::OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + OffsetKnotHolderEntity *entity_offset = new OffsetKnotHolderEntity(); + entity_offset->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Adjust the offset distance")); + entity.push_back(entity_offset); + + add_pattern_knotholder(); +} + +// TODO: this is derived from RectKnotHolderEntityWH because it used the same static function +// set_internal as the latter before KnotHolderEntity was C++ified. Check whether this also makes +// sense logically. +class FlowtextKnotHolderEntity : public RectKnotHolderEntityWH { +public: + virtual Geom::Point knot_get() const; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); +}; + +Geom::Point +FlowtextKnotHolderEntity::knot_get() const +{ + SPRect const *rect = SP_RECT(item); + + return Geom::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); +} + +void +FlowtextKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) +{ + set_internal(p, origin, state); +} + +FlowtextKnotHolder::FlowtextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) : + KnotHolder(desktop, item, relhandler) +{ + g_assert(item != NULL); + + FlowtextKnotHolderEntity *entity_flowtext = new FlowtextKnotHolderEntity(); + entity_flowtext->create(desktop, item, this, Inkscape::CTRL_TYPE_SHAPER, + _("Drag to resize the flowed text frame")); + entity.push_back(entity_flowtext); +} + +/* + 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 : diff --git a/src/ui/object-edit.h b/src/ui/object-edit.h new file mode 100644 index 000000000..75f3ce12b --- /dev/null +++ b/src/ui/object-edit.h @@ -0,0 +1,84 @@ +#ifndef OBJECT_EDIT_H_SEEN +#define OBJECT_EDIT_H_SEEN + +/* + * Node editing extension to objects + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * Jon A. Cruz + * + * Licensed under GNU GPL + */ + +#include "knotholder.h" + +namespace Inkscape { +namespace UI { + +KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop); + +} +} + +class RectKnotHolder : public KnotHolder { +public: + RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~RectKnotHolder() {}; +}; + +class Box3DKnotHolder : public KnotHolder { +public: + Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~Box3DKnotHolder() {}; +}; + +class ArcKnotHolder : public KnotHolder { +public: + ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~ArcKnotHolder() {}; +}; + +class StarKnotHolder : public KnotHolder { +public: + StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~StarKnotHolder() {}; +}; + +class SpiralKnotHolder : public KnotHolder { +public: + SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~SpiralKnotHolder() {}; +}; + +class OffsetKnotHolder : public KnotHolder { +public: + OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~OffsetKnotHolder() {}; +}; + +class FlowtextKnotHolder : public KnotHolder { +public: + FlowtextKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~FlowtextKnotHolder() {}; +}; + +class MiscKnotHolder : public KnotHolder { +public: + MiscKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + virtual ~MiscKnotHolder() {}; +}; + +#endif // OBJECT_EDIT_H_SEEN + +/* + 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 : diff --git a/src/ui/shape-editor.cpp b/src/ui/shape-editor.cpp new file mode 100644 index 000000000..0b9fc24c5 --- /dev/null +++ b/src/ui/shape-editor.cpp @@ -0,0 +1,177 @@ +/* + * Inkscape::ShapeEditor + * + * Authors: + * bulia byak + * Krzysztof Kosiński + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "desktop-handles.h" +#include "document.h" +#include "gc-anchored.h" +#include "knotholder.h" +#include "ui/object-edit.h" +#include "sp-item.h" +#include "sp-object.h" +#include "ui/shape-editor.h" +#include "xml/node-event-vector.h" + +//using Inkscape::createKnotHolder; + +namespace Inkscape { +namespace UI { + +bool ShapeEditor::_blockSetItem = false; + +ShapeEditor::ShapeEditor(SPDesktop *dt) { + this->desktop = dt; + this->knotholder = NULL; + this->knotholder_listener_attached_for = NULL; +} + +ShapeEditor::~ShapeEditor() { + unset_item(); +} + +void ShapeEditor::unset_item(bool keep_knotholder) { + if (this->knotholder) { + Inkscape::XML::Node *old_repr = this->knotholder->repr; + if (old_repr && old_repr == knotholder_listener_attached_for) { + sp_repr_remove_listener_by_data(old_repr, this); + Inkscape::GC::release(old_repr); + knotholder_listener_attached_for = NULL; + } + + if (!keep_knotholder) { + delete this->knotholder; + this->knotholder = NULL; + } + } +} + +bool ShapeEditor::has_knotholder() { + return this->knotholder != NULL; +} + +void ShapeEditor::update_knotholder() { + if (this->knotholder) + this->knotholder->update_knots(); +} + +bool ShapeEditor::has_local_change() { + return (this->knotholder && this->knotholder->local_change != 0); +} + +void ShapeEditor::decrement_local_change() { + if (this->knotholder) { + this->knotholder->local_change = FALSE; + } +} + +const SPItem *ShapeEditor::get_item() { + const SPItem *item = NULL; + if (this->has_knotholder()) { + item = this->knotholder->getItem(); + } + return item; +} + +void ShapeEditor::event_attr_changed(Inkscape::XML::Node *, gchar const *name, gchar const *, gchar const *, bool, void *data) +{ + g_assert(data); + ShapeEditor *sh = static_cast(data); + bool changed_kh = false; + + if (sh->has_knotholder()) + { + changed_kh = !sh->has_local_change(); + sh->decrement_local_change(); + if (changed_kh) { + // this can happen if an LPEItem's knotholder handle was dragged, in which case we want + // to keep the knotholder; in all other cases (e.g., if the LPE itself changes) we delete it + sh->reset_item(!strcmp(name, "d")); + } + } +} + +static Inkscape::XML::NodeEventVector shapeeditor_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + ShapeEditor::event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + + +void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { + if (_blockSetItem) { + return; + } + + // this happens (and should only happen) when for an LPEItem having both knotholder and + // nodepath the knotholder is adapted; in this case we don't want to delete the knotholder + // since this freezes the handles + unset_item(keep_knotholder); + + if (item) { + Inkscape::XML::Node *repr; + if (!this->knotholder) { + // only recreate knotholder if none is present + this->knotholder = createKnotHolder(item, desktop); + } + if (this->knotholder) { + this->knotholder->update_knots(); + // setting new listener + repr = this->knotholder->repr; + if (repr != knotholder_listener_attached_for) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &shapeeditor_repr_events, this); + knotholder_listener_attached_for = repr; + } + } + } +} + + +/** FIXME: This thing is only called when the item needs to be updated in response to repr change. + Why not make a reload function in KnotHolder? */ +void ShapeEditor::reset_item(bool keep_knotholder) +{ + if (knotholder) { + SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + set_item(SP_ITEM(obj), keep_knotholder); + } +} + +/** + * Returns true if this ShapeEditor has a knot above which the mouse currently hovers. + */ +bool ShapeEditor::knot_mouseover() const { + if (this->knotholder) { + return knotholder->knot_mouseover(); + } + + return false; +} + +} // namespace UI +} // 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 : diff --git a/src/ui/shape-editor.h b/src/ui/shape-editor.h new file mode 100644 index 000000000..142a2493b --- /dev/null +++ b/src/ui/shape-editor.h @@ -0,0 +1,71 @@ +#ifndef SEEN_SHAPE_EDITOR_H +#define SEEN_SHAPE_EDITOR_H + +/* + * Inkscape::ShapeEditor + * + * This is a container class which contains a knotholder for shapes. + * It is attached to a single item. + * + * Authors: + * bulia byak + * + */ + +class KnotHolder; +class LivePathEffectObject; +class SPDesktop; +class SPItem; + +namespace Inkscape { namespace XML { class Node; } +namespace UI { + +class ShapeEditor { +public: + + ShapeEditor(SPDesktop *desktop); + ~ShapeEditor(); + + void set_item(SPItem *item, bool keep_knotholder = false); + void unset_item(bool keep_knotholder = false); + + void update_knotholder(); //((deprecated)) + + bool has_local_change(); + void decrement_local_change(); + + bool knot_mouseover() const; + + static void blockSetItem(bool b) { _blockSetItem = b; } // kludge + + static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, + char const * /*new_value*/, bool /*is_interactive*/, void *data); +private: + bool has_knotholder(); + void reset_item (bool keep_knotholder = true); + const SPItem *get_item(); + + static bool _blockSetItem; + + SPDesktop *desktop; + KnotHolder *knotholder; + Inkscape::XML::Node *knotholder_listener_attached_for; +}; + +} // namespace UI +} // namespace Inkscape + +#endif // SEEN_SHAPE_EDITOR_H + + +/* + 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 : + diff --git a/src/ui/tool-factory.h b/src/ui/tool-factory.h new file mode 100644 index 000000000..726706732 --- /dev/null +++ b/src/ui/tool-factory.h @@ -0,0 +1,40 @@ +/** @file + * Factory for ToolBase tree + *//* + * Authors: + * Markus Engel + * + * Copyright (C) 2013 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef TOOL_FACTORY_SEEN +#define TOOL_FACTORY_SEEN + +#include "factory.h" + +namespace Inkscape { +namespace UI { +namespace Tools { + +class ToolBase; + +} +} +} + +typedef Singleton< Factory > ToolFactory; + + +#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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 5d6e96588..4abc901d2 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,7 +28,7 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include "ui/tools/node-tool.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include #include diff --git a/src/ui/tools-switch.cpp b/src/ui/tools-switch.cpp new file mode 100644 index 000000000..048252788 --- /dev/null +++ b/src/ui/tools-switch.cpp @@ -0,0 +1,196 @@ +/* + * Utility functions for switching tools (= contexts) + * + * Authors: + * bulia byak + * Josh Andler + * + * Copyright (C) 2003-2007 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include // prevents deprecation warnings + +#include +#include + +#include "inkscape-private.h" +#include "desktop.h" +#include "desktop-handles.h" +#include + +#include + +#include "ui/tools-switch.h" + +#include "box3d.h" +#include "sp-ellipse.h" +#include "sp-flowtext.h" +#include "sp-offset.h" +#include "sp-path.h" +#include "sp-rect.h" +#include "sp-star.h" +#include "sp-spiral.h" +#include "sp-text.h" + +// TODO: How many of these are actually needed? +#include "ui/tools/arc-tool.h" +#include "ui/tools/box3d-tool.h" +#include "ui/tools/calligraphic-tool.h" +#include "ui/tools/connector-tool.h" +#include "ui/tools/dropper-tool.h" +#include "ui/tools/eraser-tool.h" +#include "ui/tools/flood-tool.h" +#include "ui/tools/gradient-tool.h" +#include "ui/tools/lpe-tool.h" +#include "ui/tools/measure-tool.h" +#include "ui/tools/mesh-tool.h" +#include "ui/tools/node-tool.h" +#include "ui/tools/pen-tool.h" +#include "ui/tools/pencil-tool.h" +#include "ui/tools/rect-tool.h" +#include "ui/tools/select-tool.h" +#include "ui/tools/spiral-tool.h" +#include "ui/tools/spray-tool.h" +#include "ui/tools/text-tool.h" +#include "ui/tools/tweak-tool.h" +#include "ui/tools/zoom-tool.h" + +#include "message-context.h" + +static char const *const tool_names[] = { + NULL, + "/tools/select", + "/tools/nodes", + "/tools/tweak", + "/tools/spray", + "/tools/shapes/rect", + "/tools/shapes/3dbox", + "/tools/shapes/arc", + "/tools/shapes/star", + "/tools/shapes/spiral", + "/tools/freehand/pencil", + "/tools/freehand/pen", + "/tools/calligraphic", + "/tools/text", + "/tools/gradient", + "/tools/mesh", + "/tools/zoom", + "/tools/measure", + "/tools/dropper", + "/tools/connector", + "/tools/paintbucket", + "/tools/eraser", + "/tools/lpetool", + NULL +}; + +// TODO: HEY! these belong to the tools themselves! +static char const *const tool_msg[] = { + NULL, + N_("Click to Select and Transform objects, Drag to select many objects."), + N_("Modify selected path points (nodes) directly."), + N_("To tweak a path by pushing, select it and drag over it."), + N_("Drag, click or click and scroll to spray the selected objects."), + N_("Drag to create a rectangle. Drag controls to round corners and resize. Click to select."), + N_("Drag to create a 3D box. Drag controls to resize in perspective. Click to select (with Ctrl+Alt for single faces)."), + N_("Drag to create an ellipse. Drag controls to make an arc or segment. Click to select."), + N_("Drag to create a star. Drag controls to edit the star shape. Click to select."), + N_("Drag to create a spiral. Drag controls to edit the spiral shape. Click to select."), + N_("Drag to create a freehand line. Shift appends to selected path, Alt activates sketch mode."), + N_("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots (straight line modes only)."), + N_("Drag to draw a calligraphic stroke; with Ctrl to track a guide path. Arrow keys adjust width (left/right) and angle (up/down)."), + N_("Click to select or create text, drag to create flowed text; then type."), + N_("Drag or double click to create a gradient on selected objects, drag handles to adjust gradients."), + N_("Drag or double click to create a mesh on selected objects, drag handles to adjust meshes."), + N_("Click or drag around an area to zoom in, Shift+click to zoom out."), + N_("Drag to measure the dimensions of objects."), + N_("Click to set fill, Shift+click to set stroke; drag to average color in area; with Alt to pick inverse color; Ctrl+C to copy the color under mouse to clipboard"), + N_("Click and drag between shapes to create a connector."), + N_("Click to paint a bounded area, Shift+click to union the new fill with the current selection, Ctrl+click to change the clicked object's fill and stroke to the current setting."), + N_("Drag to erase."), + N_("Choose a subtool from the toolbar"), +}; + +static int +tools_prefpath2num(char const *id) +{ + int i = 1; + while (tool_names[i]) { + if (strcmp(tool_names[i], id) == 0) + return i; + else i++; + } + g_assert( 0 == TOOLS_INVALID ); + return 0; //nothing found +} + +int +tools_isactive(SPDesktop *dt, unsigned num) +{ + g_assert( num < G_N_ELEMENTS(tool_names) ); + if (SP_IS_EVENT_CONTEXT(dt->event_context)) + return dt->event_context->pref_observer->observed_path == tool_names[num]; + else return FALSE; +} + +int +tools_active(SPDesktop *dt) +{ + return tools_prefpath2num(dt->event_context->pref_observer->observed_path.data()); +} + +void +tools_switch(SPDesktop *dt, int num) +{ + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, gettext( tool_msg[num] ) ); + if (dt) { + // This event may change the above message + dt->_tool_changed.emit(num); + } + + dt->set_event_context2(tool_names[num]); + /* fixme: This is really ugly hack. We should bind and unbind class methods */ + /* First 4 tools use guides, first is undefined but we don't care */ + dt->activate_guides(num < 5); + inkscape_eventcontext_set(dt->getEventContext()); +} + +void tools_switch_by_item(SPDesktop *dt, SPItem *item, Geom::Point const p) +{ + if (SP_IS_RECT(item)) { + tools_switch(dt, TOOLS_SHAPES_RECT); + } else if (SP_IS_BOX3D(item)) { + tools_switch(dt, TOOLS_SHAPES_3DBOX); + } else if (SP_IS_GENERICELLIPSE(item)) { + tools_switch(dt, TOOLS_SHAPES_ARC); + } else if (SP_IS_STAR(item)) { + tools_switch(dt, TOOLS_SHAPES_STAR); + } else if (SP_IS_SPIRAL(item)) { + tools_switch(dt, TOOLS_SHAPES_SPIRAL); + } else if (SP_IS_PATH(item)) { + if (Inkscape::UI::Tools::cc_item_is_connector(item)) { + tools_switch(dt, TOOLS_CONNECTOR); + } + else { + tools_switch(dt, TOOLS_NODES); + } + } else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + tools_switch(dt, TOOLS_TEXT); + sp_text_context_place_cursor_at (SP_TEXT_CONTEXT(dt->event_context), SP_OBJECT(item), p); + } else if (SP_IS_OFFSET(item)) { + tools_switch(dt, TOOLS_NODES); + } +} + +/* + 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 : diff --git a/src/ui/tools-switch.h b/src/ui/tools-switch.h new file mode 100644 index 000000000..280837e87 --- /dev/null +++ b/src/ui/tools-switch.h @@ -0,0 +1,64 @@ +/* + * Utility functions for switching tools (= contexts) + * + * Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TOOLS_SWITCH_H +#define SEEN_TOOLS_SWITCH_H + +class SPDesktop; +class SPItem; +namespace Geom { +class Point; +} + + +enum { + TOOLS_INVALID, + TOOLS_SELECT, + TOOLS_NODES, + TOOLS_TWEAK, + TOOLS_SPRAY, + TOOLS_SHAPES_RECT, + TOOLS_SHAPES_3DBOX, + TOOLS_SHAPES_ARC, + TOOLS_SHAPES_STAR, + TOOLS_SHAPES_SPIRAL, + TOOLS_FREEHAND_PENCIL, + TOOLS_FREEHAND_PEN, + TOOLS_CALLIGRAPHIC, + TOOLS_TEXT, + TOOLS_GRADIENT, + TOOLS_MESH, + TOOLS_ZOOM, + TOOLS_MEASURE, + TOOLS_DROPPER, + TOOLS_CONNECTOR, + TOOLS_PAINTBUCKET, + TOOLS_ERASER, + TOOLS_LPETOOL +}; + +int tools_isactive(SPDesktop *dt, unsigned num); +int tools_active(SPDesktop *dt); +void tools_switch(SPDesktop *dt, int num); +void tools_switch_by_item (SPDesktop *dt, SPItem *item, Geom::Point const p); + +#endif // !SEEN_TOOLS_SWITCH_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 9fd68f1b9..4f64ade25 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -40,7 +40,7 @@ #include "desktop-style.h" #include "context-fns.h" #include "verbs.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "ui/tools/tool-base.h" #include "ui/tools/arc-tool.h" @@ -48,7 +48,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index b998267c2..0a20a0842 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -47,12 +47,12 @@ #include "box3d-side.h" #include "document-private.h" #include "line-geometry.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp index 64097e834..d297fe5e1 100644 --- a/src/ui/tools/calligraphic-tool.cpp +++ b/src/ui/tools/calligraphic-tool.cpp @@ -82,7 +82,7 @@ using Inkscape::DocumentUndo; #define DYNA_MIN_WIDTH 1.0e-6 -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index d1355e807..7b5c84c16 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -109,7 +109,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/dropper-tool.cpp b/src/ui/tools/dropper-tool.cpp index 99d42a211..6c55f7484 100644 --- a/src/ui/tools/dropper-tool.cpp +++ b/src/ui/tools/dropper-tool.cpp @@ -52,7 +52,7 @@ using Inkscape::DocumentUndo; static GdkCursor *cursor_dropper_fill = NULL; static GdkCursor *cursor_dropper_stroke = NULL; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 4106785e7..bf4015b4c 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -84,7 +84,7 @@ using Inkscape::DocumentUndo; #define DRAG_DEFAULT 1.0 #define DRAG_MAX 1.0 -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 3fb56b2ad..5745fc9cc 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -50,7 +50,7 @@ #include "preferences.h" #include "rubberband.h" #include "selection.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-defs.h" #include "sp-item.h" #include "splivarot.h" @@ -74,7 +74,7 @@ using Inkscape::Display::ExtractARGB32; using Inkscape::Display::ExtractRGB32; using Inkscape::Display::AssembleARGB32; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 46ab53eef..6434c30d2 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -30,7 +30,7 @@ #include "desktop-handles.h" #include "desktop-style.h" #include "document.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "macros.h" #include "message-stack.h" #include "ui/tools/pen-tool.h" diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index 4f9a7b59b..9c853917e 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -51,7 +51,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index e9b9421f1..1fd1ebf8c 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -28,7 +28,7 @@ #include "desktop.h" #include "message-context.h" #include "preferences.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "selection.h" #include "desktop-handles.h" #include "document.h" @@ -59,7 +59,7 @@ SubtoolEntry lpesubtools[] = { }; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index feeb68288..6b5cbeccd 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -49,7 +49,7 @@ using Inkscape::ControlManager; using Inkscape::CTLINE_SECONDARY; using Inkscape::Util::unit_table; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 7d6d3bc23..8a1fb7c72 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -53,7 +53,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 0b98bacc1..e2bb85d11 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -23,7 +23,7 @@ #include "live_effects/lpeobject.h" #include "message-context.h" #include "selection.h" -#include "shape-editor.h" // temporary! +#include "ui/shape-editor.h" // temporary! #include "live_effects/effect.h" #include "display/curve.h" #include "sp-clippath.h" @@ -107,7 +107,7 @@ using Inkscape::ControlManager; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 2c5ffc182..92937a135 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -26,7 +26,7 @@ #include "desktop-handles.h" #include "selection.h" #include "selection-chemistry.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "message-stack.h" #include "message-context.h" #include "preferences.h" @@ -40,7 +40,7 @@ #include #include "macros.h" #include "context-fns.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "ui/control-manager.h" // we include the necessary files for BSpline & Spiro #include "live_effects/effect.h" @@ -70,7 +70,7 @@ #include "live_effects/lpe-bspline.h" #include <2geom/nearest-point.h> -#include "tool-factory.h" +#include "ui/tool-factory.h" #include "live_effects/effect.h" diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index ca6dffc12..3ea2ae843 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -23,7 +23,7 @@ #include "desktop-handles.h" #include "selection.h" #include "selection-chemistry.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "message-stack.h" #include "message-context.h" #include "sp-path.h" @@ -43,7 +43,7 @@ #include "display/sp-canvas.h" #include "display/curve.h" #include "livarot/Path.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" #include "ui/tool/event-utils.h" namespace Inkscape { diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 819671dd6..de91dcff4 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -40,13 +40,13 @@ #include "xml/node-event-vector.h" #include "preferences.h" #include "context-fns.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" #include "display/sp-canvas-item.h" using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 83bef17c9..394b0b369 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -41,7 +41,7 @@ #include "desktop-handles.h" #include "sp-root.h" #include "preferences.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "message-stack.h" #include "selection-describer.h" #include "seltrans.h" @@ -49,7 +49,7 @@ #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" #include "display/drawing-item.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" using Inkscape::DocumentUndo; diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 83712457a..18c3e4e2d 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -39,13 +39,13 @@ #include "xml/node-event-vector.h" #include "preferences.h" #include "context-fns.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" #include "display/sp-canvas-item.h" using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 29f1b9a73..933da6fb1 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -84,7 +84,7 @@ using namespace std; // Please enable again when working on 1.0 #define ENABLE_SPRAY_MODE_SINGLE_PATH -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index ed28c0a8d..7604ba04e 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -41,7 +41,7 @@ #include "xml/repr.h" #include "xml/node-event-vector.h" #include "context-fns.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "verbs.h" #include "display/sp-canvas-item.h" @@ -49,7 +49,7 @@ using Inkscape::DocumentUndo; -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index b60a39e5d..a72748733 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -40,7 +40,7 @@ #include "rubberband.h" #include "selection-chemistry.h" #include "selection.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-flowtext.h" #include "sp-namedview.h" #include "sp-text.h" @@ -52,7 +52,7 @@ #include "xml/node-event-vector.h" #include "xml/repr.h" #include -#include "tool-factory.h" +#include "ui/tool-factory.h" using Inkscape::ControlManager; using Inkscape::DocumentUndo; diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 150e899ce..37ca5eeea 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -46,7 +46,7 @@ #include "selection.h" #include "ui/interface.h" #include "macros.h" -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "preferences.h" #include "message-context.h" #include "gradient-drag.h" @@ -55,7 +55,7 @@ #include "selcue.h" #include "ui/tools/lpe-tool.h" #include "ui/tool/control-point.h" -#include "shape-editor.h" +#include "ui/shape-editor.h" #include "sp-guide.h" #include "color.h" #include "knot.h" diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h index b27de9030..7a6ab83e7 100644 --- a/src/ui/tools/tool-base.h +++ b/src/ui/tools/tool-base.h @@ -30,7 +30,6 @@ namespace Glib { class GrDrag; class SPDesktop; class SPItem; -class ShapeEditor; namespace Inkscape { class MessageContext; @@ -42,6 +41,9 @@ namespace Inkscape { namespace Inkscape { namespace UI { + +class ShapeEditor; + namespace Tools { class ToolBase; diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 75650d3af..340f64a0b 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -91,7 +91,7 @@ using Inkscape::DocumentUndo; #define DYNA_MIN_WIDTH 1.0e-6 -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { diff --git a/src/ui/tools/zoom-tool.cpp b/src/ui/tools/zoom-tool.cpp index 9f99cfe2e..b3fb78c8f 100644 --- a/src/ui/tools/zoom-tool.cpp +++ b/src/ui/tools/zoom-tool.cpp @@ -25,7 +25,7 @@ #include "selection-chemistry.h" #include "ui/tools/zoom-tool.h" -#include "tool-factory.h" +#include "ui/tool-factory.h" namespace Inkscape { namespace UI { -- cgit v1.2.3 From 353c191bebb3ab57c09873efdb56481427d70d9d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 5 Oct 2014 19:35:28 -0400 Subject: Add missing file to CMakeLists (bzr r13341.1.254) --- src/ui/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 8bae15fa5..ad6dfbac6 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -171,6 +171,7 @@ set(ui_SRC previewfillable.h previewholder.h shape-editor.h + tool-factory.h tools-switch.h uxmanager.h -- cgit v1.2.3 From 8e6879acee859f216f5e63d97a4ba80c7cb0b94b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 8 Oct 2014 18:56:12 -0400 Subject: Fix gtk3 build at risk of breaking windows build (bzr r13341.1.262) --- src/ui/widget/highlight-picker.cpp | 10 +--------- src/ui/widget/insertordericon.cpp | 9 --------- src/ui/widget/insertordericon.h | 4 ++-- 3 files changed, 3 insertions(+), 20 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index c03f526dc..8593f0bdf 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -7,19 +7,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - +#include #include - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif #include "display/cairo-utils.h" - #include "highlight-picker.h" #include "widgets/icon.h" #include "widgets/toolbox.h" diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp index 17930daa2..a28b0f834 100644 --- a/src/ui/widget/insertordericon.cpp +++ b/src/ui/widget/insertordericon.cpp @@ -9,15 +9,6 @@ #include "ui/widget/insertordericon.h" -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - - #include #include "widgets/icon.h" diff --git a/src/ui/widget/insertordericon.h b/src/ui/widget/insertordericon.h index e6c2e1c5b..fb3412d3f 100644 --- a/src/ui/widget/insertordericon.h +++ b/src/ui/widget/insertordericon.h @@ -10,12 +10,12 @@ */ #if HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif +#include #include #include -#include namespace Inkscape { namespace UI { -- cgit v1.2.3 From 259976c863ccdd6c28698125179b20b91da32ec0 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 9 Oct 2014 14:27:49 +0200 Subject: Apply cx, cy, etc. from template to newly created document window. (bzr r13341.1.264) --- src/ui/dialog/template-widget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index 9758b35ac..f79d166f2 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -24,6 +24,7 @@ #include "document.h" #include "document-undo.h" #include "file.h" +#include "sp-namedview.h" #include "extension/implementation/implementation.h" #include "inkscape.h" @@ -69,7 +70,10 @@ void TemplateWidget::create() _current_template.tpl_effect->effect(desc); DocumentUndo::clearUndo(sp_desktop_document(desc)); sp_desktop_document(desc)->setModifiedSinceSave(false); - + + // Apply cx,cy etc. from document + sp_namedview_window_from_document( desc ); + if (desktop) desktop->clearWaitingCursor(); } -- cgit v1.2.3 From 01a8acb49126aa37fee65b3e350ce69e87abecc8 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 9 Oct 2014 14:32:16 +0200 Subject: Apply cx, cy, etc. from template to newly created document window. (bzr r13586) --- src/ui/dialog/template-widget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index 9758b35ac..f79d166f2 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -24,6 +24,7 @@ #include "document.h" #include "document-undo.h" #include "file.h" +#include "sp-namedview.h" #include "extension/implementation/implementation.h" #include "inkscape.h" @@ -69,7 +70,10 @@ void TemplateWidget::create() _current_template.tpl_effect->effect(desc); DocumentUndo::clearUndo(sp_desktop_document(desc)); sp_desktop_document(desc)->setModifiedSinceSave(false); - + + // Apply cx,cy etc. from document + sp_namedview_window_from_document( desc ); + if (desktop) desktop->clearWaitingCursor(); } -- cgit v1.2.3 From a2c47e60a02938013ab913bfee2ef9c9fa5ea870 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 13 Oct 2014 11:11:01 +0200 Subject: Fixed: "Called C++ object pointer is null" (bzr r13609) --- src/ui/dialog/clonetiler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index e5f18216c..9b67132c0 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2235,7 +2235,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) gdk_window_process_all_updates(); SPObject *obj = selection->singleItem(); - SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + if (!obj) { + // Should never happen (empty selection checked above). + std::cerr << "CloneTiler::clonetile_apply(): No object in single item selection!!!" << std::endl; + return; + } Inkscape::XML::Node *obj_repr = obj->getRepr(); const char *id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); SPObject *parent = obj->parent; @@ -2326,6 +2330,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); + SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; if (dotrace) { clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); } -- cgit v1.2.3 From 35153b45814dcc844213951352f410b2fc13e2ad Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Mon, 13 Oct 2014 20:49:44 -0700 Subject: Fix crash with GTK+ 3.14 on launch Patch from Liam to check for undefined desktop during startup. ** (inkscape:57708): CRITICAL **: SPCanvas* sp_desktop_canvas(const SPDesktop*): assertion 'desktop != NULL' failed Fixes: https://bugs.launchpad.net/inkscape/+bug/1375085 Fixed bugs: - https://launchpad.net/bugs/1375085 (bzr r13611) --- src/ui/widget/selected-style.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index f01366e19..a575dd592 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -1199,7 +1199,9 @@ void SelectedStyle::on_opacity_menu (Gtk::Menu *menu) { menu->show_all(); } -void SelectedStyle::on_opacity_changed () { +void SelectedStyle::on_opacity_changed () +{ + g_return_if_fail(_desktop); // TODO this shouldn't happen! if (_opacity_blocked) return; _opacity_blocked = true; -- cgit v1.2.3 From 83e50305d77a98329ea2085f90b6a9f154e1509f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 15 Oct 2014 20:01:50 +0200 Subject: LiamW's initial font caching work. (bzr r13616.1.1) --- src/ui/dialog/text-edit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index a00db1715..9996fc0f9 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -343,9 +343,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - // This is done for us by text-toolbar. No need to do it twice. - // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); - // fontlister->selection_update(); + // This is normally done for us by text-toolbar but only when we are in text editing context + fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); -- cgit v1.2.3 From a7384aa7c43a5fe4b56e5d5d610ece0cafcaa748 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 15 Oct 2014 20:03:43 +0200 Subject: Fix strict build with Gtk+ 2 (experimental commit r13513) (bzr r13616.1.2) --- src/ui/tools/tool-base.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index f1d90f6c6..1c1e8a17a 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -18,6 +18,8 @@ # include "config.h" #endif +#include "widgets/desktop-widget.h" + #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif @@ -40,7 +42,6 @@ #include "desktop-handles.h" #include "desktop-events.h" #include "desktop-style.h" -#include "widgets/desktop-widget.h" #include "sp-namedview.h" #include "selection.h" #include "interface.h" -- cgit v1.2.3 From 43d418f2720546f501594e30e24151248b2a67e8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 21 Oct 2014 09:21:06 +0200 Subject: Updating translators list. (bzr r13631) --- src/ui/dialog/aboutbox.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index f3cffa244..fad10ae11 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -452,13 +452,13 @@ void AboutBox::initStrings() { */ gchar const *allTranslators = "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" -"Adib Taraben , 2004.\n" +"Adib Taraben , 2004-2014.\n" "Alan Monfort , 2009-2010.\n" "Alastair McKinstry , 2000.\n" "Aleksandar Urošević , 2004-2006.\n" "Alessio Frusciante , 2002, 2003.\n" "Alexander Shopov , 2006.\n" -"Alexandre Prokoudine , 2005, 2010-2013.\n" +"Alexandre Prokoudine , 2005, 2010-2014.\n" "Alexey Remizov , 2004.\n" "Ali Ghanavatian , 2010.\n" "Álvaro Lopes , 2001, 2002.\n" @@ -503,7 +503,7 @@ void AboutBox::initStrings() { "Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" -"Ivan Masár , 2006-2010. \n" +"Ivan Masár , 2006-2014. \n" "Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" "Jānis Eisaks , 2012-2014.\n" @@ -537,7 +537,7 @@ void AboutBox::initStrings() { "Mahesh subedi , 2006.\n" "Martin Srebotnjak, , 2005, 2010.\n" "Masatake YAMATO , 2002.\n" -"Masato Hashimoto , 2009-2012.\n" +"Masato Hashimoto , 2009-2014.\n" "Matiphas , 2004-2006.\n" "Mattias Hultgren , 2005, 2006.\n" "Maxim Dziumanenko , 2004.\n" @@ -553,7 +553,7 @@ void AboutBox::initStrings() { "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" "Raymond Ostertag , 2002, 2003.\n" -"Riku Leino , 2006.\n" +"Riku Leino , 2006-2011.\n" "Rune Rønde Laursen , 2006.\n" "Ruud Steltenpool , 2006.\n" "Serdar Soytetir , 2005.\n" @@ -569,9 +569,11 @@ void AboutBox::initStrings() { "Thiago Pimentel , 2006.\n" "Toshifumi Sato , 2005.\n" "Jon South , 2006. \n" -"Uwe Schöler , 2006-2013.\n" +"Uwe Schöler , 2006-2014.\n" "Valek Filippov , 2000, 2003.\n" "Victor Dachev , 2006.\n" +"Victor Westmann , 2011, 2014.\n" +"Ville Pätsi, 2013.\n" "Vincent van Adrighem , 2003.\n" "Vital Khilko , 2003.\n" "Vitaly Lipatov , 2002, 2004.\n" @@ -584,7 +586,7 @@ void AboutBox::initStrings() { "Yaron Shahrabani , 2009.\n" "Yukihiro Nakai , 2000, 2003.\n" "Yuri Beznos , 2006.\n" -"Yuri Chornoivan , 2007-2013.\n" +"Yuri Chornoivan , 2007-2014.\n" "Yuri Syrota , 2000.\n" "Yves Guillou , 2004.\n" "Zdenko Podobný , 2003, 2004." -- cgit v1.2.3 From e2ae473da92a1f96e307e3f1f3e206cad7bd1c38 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 23 Oct 2014 19:33:47 -0700 Subject: Initial removal of box3d outdated GTKish macros. (bzr r13634) --- src/ui/clipboard.cpp | 131 ++++++++++++++++++++++++++----------------- src/ui/tools/select-tool.cpp | 78 ++++++++++++++++---------- src/ui/tools/spray-tool.cpp | 32 +++++++---- src/ui/tools/tweak-tool.cpp | 86 ++++++++++++++++------------ 4 files changed, 195 insertions(+), 132 deletions(-) (limited to 'src/ui') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 1209b19cd..031a92924 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -505,12 +505,15 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a // resize each object in the selection if (separately) { for (GSList *i = const_cast(selection->itemList()) ; i ; i = i->next) { - SPItem *item = SP_ITEM(i->data); - Geom::OptRect obj_size = item->desktopVisualBounds(); - if ( !obj_size ) { - continue; + SPItem *item = dynamic_cast(static_cast(i->data)); + if (item) { + Geom::OptRect obj_size = item->desktopVisualBounds(); + if ( obj_size ) { + sp_item_scale_rel(item, _getScale(desktop, min, max, *obj_size, apply_x, apply_y)); + } + } else { + g_assert_not_reached(); } - sp_item_scale_rel(item, _getScale(desktop, min, max, *obj_size, apply_x, apply_y)); } } // resize the selection as a whole @@ -640,7 +643,12 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) GSList const *items = selection->itemList(); // copy the defs used by all items for (GSList *i = const_cast(items) ; i != NULL ; i = i->next) { - _copyUsedDefs(SP_ITEM (i->data)); + SPItem *item = dynamic_cast(static_cast(i->data)); + if (item) { + _copyUsedDefs(item); + } else { + g_assert_not_reached(); + } } // copy the representation of the items @@ -648,36 +656,38 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) sorted_items = g_slist_sort(sorted_items, (GCompareFunc) sp_object_compare_position); for (GSList *i = sorted_items ; i ; i = i->next) { - if (!SP_IS_ITEM(i->data)) { - continue; + SPItem *item = dynamic_cast(static_cast(i->data)); + if (item) { + Inkscape::XML::Node *obj = item->getRepr(); + Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); + + // copy complete inherited style + SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); + sp_repr_css_set(obj_copy, css, "style"); + sp_repr_css_attr_unref(css); + + // write the complete accumulated transform passed to us + // (we're dealing with unattached representations, so we write to their attributes + // instead of using sp_item_set_transform) + gchar *transform_str = sp_svg_transform_write(item->i2doc_affine()); + obj_copy->setAttribute("transform", transform_str); + g_free(transform_str); } - Inkscape::XML::Node *obj = reinterpret_cast(i->data)->getRepr(); - Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); - - // copy complete inherited style - SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); - sp_repr_css_set(obj_copy, css, "style"); - sp_repr_css_attr_unref(css); - - // write the complete accumulated transform passed to us - // (we're dealing with unattached representations, so we write to their attributes - // instead of using sp_item_set_transform) - gchar *transform_str = sp_svg_transform_write(SP_ITEM(i->data)->i2doc_affine()); - obj_copy->setAttribute("transform", transform_str); - g_free(transform_str); } // copy style for Paste Style action if (sorted_items) { - if (SP_IS_ITEM(sorted_items->data)) { - SPCSSAttr *style = take_style_from_item((SPItem *) sorted_items->data); + SPObject *object = static_cast(sorted_items->data); + SPItem *item = dynamic_cast(object); + if (item) { + SPCSSAttr *style = take_style_from_item(item); sp_repr_css_set(_clipnode, style, "style"); sp_repr_css_attr_unref(style); } // copy path effect from the first path - if (SP_IS_OBJECT(sorted_items->data)) { - gchar const *effect = reinterpret_cast(sorted_items->data)->getRepr()->attribute("inkscape:path-effect"); + if (object) { + gchar const *effect =object->getRepr()->attribute("inkscape:path-effect"); if (effect) { _clipnode->setAttribute("inkscape:path-effect", effect); } @@ -704,35 +714,38 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) if (style && (style->fill.isPaintserver())) { SPPaintServer *server = item->style->getFillPaintServer(); - if ( SP_IS_LINEARGRADIENT(server) || SP_IS_RADIALGRADIENT(server) ) { - _copyGradient(SP_GRADIENT(server)); + if ( dynamic_cast(server) || dynamic_cast(server) ) { + _copyGradient(dynamic_cast(server)); } - if ( SP_IS_PATTERN(server) ) { - _copyPattern(SP_PATTERN(server)); + SPPattern *pattern = dynamic_cast(server); + if ( pattern ) { + _copyPattern(pattern); } } if (style && (style->stroke.isPaintserver())) { SPPaintServer *server = item->style->getStrokePaintServer(); - if ( SP_IS_LINEARGRADIENT(server) || SP_IS_RADIALGRADIENT(server) ) { - _copyGradient(SP_GRADIENT(server)); + if ( dynamic_cast(server) || dynamic_cast(server) ) { + _copyGradient(dynamic_cast(server)); } - if ( SP_IS_PATTERN(server) ) { - _copyPattern(SP_PATTERN(server)); + SPPattern *pattern = dynamic_cast(server); + if ( pattern ) { + _copyPattern(pattern); } } // For shapes, copy all of the shape's markers - if (SP_IS_SHAPE(item)) { - SPShape *shape = SP_SHAPE (item); + SPShape *shape = dynamic_cast(item); + if (shape) { for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { if (shape->_marker[i]) { _copyNode(shape->_marker[i]->getRepr(), _doc, _defs); } } } + // For lpe items, copy lpe stack if applicable - if (SP_IS_LPE_ITEM(item)) { - SPLPEItem *lpeitem = SP_LPE_ITEM (item); + SPLPEItem *lpeitem = dynamic_cast(item); + if (lpeitem) { if (lpeitem->hasPathEffect()) { for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it) { @@ -743,14 +756,24 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) } } } + // For 3D boxes, copy perspectives - if (SP_IS_BOX3D(item)) { - _copyNode(box3d_get_perspective(SP_BOX3D(item))->getRepr(), _doc, _defs); + { + SPBox3D *box = dynamic_cast(item); + if (box) { + _copyNode(box3d_get_perspective(box)->getRepr(), _doc, _defs); + } } + // Copy text paths - if (SP_IS_TEXT_TEXTPATH(item)) { - _copyTextPath(SP_TEXTPATH(item->firstChild())); + { + SPText *text = dynamic_cast(item); + SPTextPath *textpath = (text) ? dynamic_cast(text->firstChild()) : NULL; + if (textpath) { + _copyTextPath(textpath); + } } + // Copy clipping objects if (item->clip_ref){ if (item->clip_ref->getObject()) { @@ -764,8 +787,9 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) _copyNode(mask->getRepr(), _doc, _defs); // recurse into the mask for its gradients etc. for (SPObject *o = mask->children ; o != NULL ; o = o->next) { - if (SP_IS_ITEM(o)) { - _copyUsedDefs(SP_ITEM(o)); + SPItem *childItem = dynamic_cast(o); + if (childItem) { + _copyUsedDefs(childItem); } } } @@ -774,15 +798,16 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) // Copy filters if (style->getFilter()) { SPObject *filter = style->getFilter(); - if (SP_IS_FILTER(filter)) { + if (dynamic_cast(filter)) { _copyNode(filter->getRepr(), _doc, _defs); } } // recurse for (SPObject *o = item->children ; o != NULL ; o = o->next) { - if (SP_IS_ITEM(o)) { - _copyUsedDefs(SP_ITEM(o)); + SPItem *childItem = dynamic_cast(o); + if (childItem) { + _copyUsedDefs(childItem); } } } @@ -817,10 +842,10 @@ void ClipboardManagerImpl::_copyPattern(SPPattern *pattern) // items in the pattern may also use gradients and other patterns, so recurse for ( SPObject *child = pattern->firstChild() ; child ; child = child->getNext() ) { - if (!SP_IS_ITEM (child)) { - continue; + SPItem *childItem = dynamic_cast(child); + if (childItem) { + _copyUsedDefs(childItem); } - _copyUsedDefs(SP_ITEM(child)); } if (pattern->ref){ pattern = pattern->ref->getObject(); @@ -939,13 +964,13 @@ void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effectsta if ( item == NULL ) { return; } - if ( SP_IS_RECT(item) ) { + if ( dynamic_cast(item) ) { return; } - if (SP_IS_LPE_ITEM(item)) + SPLPEItem *lpeitem = dynamic_cast(item); + if (lpeitem) { - SPLPEItem *lpeitem = SP_LPE_ITEM(item); // for each effect in the stack, check if we need to fork it before adding it to the item lpeitem->forkPathEffectsIfNecessary(1); diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 83bef17c9..21f37e83d 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -264,15 +264,16 @@ sp_select_context_up_one_layer(SPDesktop *desktop) SPObject *const current_layer = desktop->currentLayer(); if (current_layer) { SPObject *const parent = current_layer->parent; + SPGroup *current_group = dynamic_cast(current_layer); if ( parent && ( parent->parent - || !( SP_IS_GROUP(current_layer) - && ( SPGroup::LAYER - == SP_GROUP(current_layer)->layerMode() ) ) ) ) + || !( current_group + && ( SPGroup::LAYER == current_group->layerMode() ) ) ) ) { desktop->setCurrentLayer(parent); - if (SP_IS_GROUP(current_layer) && SPGroup::LAYER != SP_GROUP(current_layer)->layerMode()) + if (current_group && (SPGroup::LAYER != current_group->layerMode())) { sp_desktop_selection(desktop)->set(current_layer); + } } } } @@ -403,7 +404,8 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele } Inkscape::DrawingItem *arenaitem; - SPItem *item = SP_ITEM(this->cycling_cur_item->data); + SPItem *item = dynamic_cast(static_cast(cycling_cur_item->data)); + g_assert(item != NULL); // Deactivate current item if (!g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) { @@ -427,7 +429,8 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele if (next) { this->cycling_cur_item = next; - item = SP_ITEM(this->cycling_cur_item->data); + item = dynamic_cast(static_cast(this->cycling_cur_item->data)); + g_assert(item != NULL); } arenaitem = item->get_arenaitem(desktop->dkey); @@ -442,8 +445,13 @@ void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *sele void SelectTool::sp_select_context_reset_opacities() { for (GList *l = this->cycling_items; l != NULL; l = g_list_next(l)) { - Inkscape::DrawingItem *arenaitem = SP_ITEM(l->data)->get_arenaitem(this->desktop->dkey); - arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(SP_ITEM(l->data)->style->opacity.value)); + SPItem *item = dynamic_cast(static_cast(l->data)); + if (item) { + Inkscape::DrawingItem *arenaitem = item->get_arenaitem(desktop->dkey); + arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(item->style->opacity.value)); + } else { + g_assert_not_reached(); + } } g_list_free(this->cycling_items); @@ -475,8 +483,8 @@ bool SelectTool::root_handler(GdkEvent* event) { if (!selection->isEmpty()) { SPItem *clicked_item = static_cast(selection->itemList()->data); - if (SP_IS_GROUP(clicked_item) && !SP_IS_BOX3D(clicked_item)) { // enter group if it's not a 3D box - desktop->setCurrentLayer(reinterpret_cast(clicked_item)); + if (dynamic_cast(clicked_item) && !dynamic_cast(clicked_item)) { // enter group if it's not a 3D box + desktop->setCurrentLayer(clicked_item); sp_desktop_selection(desktop)->clear(); this->dragging = false; sp_event_context_discard_delayed_snap_event(this); @@ -591,8 +599,11 @@ bool SelectTool::root_handler(GdkEvent* event) { item_in_group = desktop->getItemAtPoint(Geom::Point(event->button.x, event->button.y), TRUE); group_at_point = desktop->getGroupAtPoint(Geom::Point(event->button.x, event->button.y)); - if (SP_IS_LAYER(selection->single())) { - group_at_point = SP_GROUP(selection->single()); + { + SPGroup *selGroup = dynamic_cast(selection->single()); + if (selGroup && (selGroup->layerMode() == SPGroup::LAYER)) { + group_at_point = selGroup; + } } // group-at-point is meant to be topmost item if it's a group, @@ -673,10 +684,11 @@ bool SelectTool::root_handler(GdkEvent* event) { selection->toggle(this->item); } else { SPObject* single = selection->single(); + SPGroup *singleGroup = dynamic_cast(single); // without shift, increase state (i.e. toggle scale/rotation handles) if (selection->includes(this->item)) { _seltrans->increaseState(); - } else if (SP_IS_LAYER(single) && single->isAncestorOf(this->item)) { + } else if (singleGroup && (singleGroup->layerMode() == SPGroup::LAYER) && single->isAncestorOf(this->item)) { _seltrans->increaseState(); } else { _seltrans->resetState(); @@ -818,7 +830,7 @@ bool SelectTool::root_handler(GdkEvent* event) { SPItem *item = desktop->getItemAtPoint(p, true, NULL); // Save pointer to current cycle-item so that we can find it again later, in the freshly built list - SPItem *tmp_cur_item = this->cycling_cur_item ? SP_ITEM(this->cycling_cur_item->data) : NULL; + SPItem *tmp_cur_item = this->cycling_cur_item ? dynamic_cast(static_cast(this->cycling_cur_item->data)) : NULL; g_list_free(this->cycling_items); this->cycling_items = NULL; this->cycling_cur_item = NULL; @@ -851,11 +863,14 @@ bool SelectTool::root_handler(GdkEvent* event) { Inkscape::DrawingItem *arenaitem; for(GList *l = this->cycling_items_cmp; l != NULL; l = l->next) { - arenaitem = SP_ITEM(l->data)->get_arenaitem(desktop->dkey); - arenaitem->setOpacity(1.0); - //if (!shift_pressed && !g_list_find(this->cycling_items_selected_before, SP_ITEM(l->data)) && selection->includes(SP_ITEM(l->data))) - if (!g_list_find(this->cycling_items_selected_before, SP_ITEM(l->data)) && selection->includes(SP_ITEM(l->data))) { - selection->remove(SP_ITEM(l->data)); + SPItem *item = dynamic_cast(static_cast(l->data)); + if (item) { + arenaitem = item->get_arenaitem(desktop->dkey); + arenaitem->setOpacity(1.0); + //if (!shift_pressed && !g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) + if (!g_list_find(this->cycling_items_selected_before, item) && selection->includes(item)) { + selection->remove(item); + } } } @@ -869,16 +884,19 @@ bool SelectTool::root_handler(GdkEvent* event) { // ... and rebuild them with the new items. this->cycling_items_cmp = g_list_copy(this->cycling_items); - SPItem *item; for(GList *l = this->cycling_items; l != NULL; l = l->next) { - item = SP_ITEM(l->data); - arenaitem = item->get_arenaitem(desktop->dkey); - arenaitem->setOpacity(0.3); - - if (selection->includes(item)) { - // already selected items are stored separately, too - this->cycling_items_selected_before = g_list_append(this->cycling_items_selected_before, item); + SPItem *item = dynamic_cast(static_cast(l->data)); + if (item) { + arenaitem = item->get_arenaitem(desktop->dkey); + arenaitem->setOpacity(0.3); + + if (selection->includes(item)) { + // already selected items are stored separately, too + this->cycling_items_selected_before = g_list_append(this->cycling_items_selected_before, item); + } + } else { + g_assert_not_reached(); } } @@ -1134,9 +1152,9 @@ bool SelectTool::root_handler(GdkEvent* event) { if (MOD__CTRL_ONLY(event)) { if (selection->singleItem()) { SPItem *clicked_item = selection->singleItem(); - - if ( SP_IS_GROUP(clicked_item) || SP_IS_BOX3D(clicked_item)) { // enter group or a 3D box - desktop->setCurrentLayer(reinterpret_cast(clicked_item)); + SPGroup *clickedGroup = dynamic_cast(clicked_item); + if ( (clickedGroup && (clickedGroup->layerMode() == SPGroup::LAYER)) || dynamic_cast(clicked_item)) { // enter group or a 3D box + desktop->setCurrentLayer(clicked_item); sp_desktop_selection(desktop)->clear(); } else { this->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selected object is not a group. Cannot enter.")); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 29f1b9a73..e15dbb59f 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -384,11 +384,14 @@ static bool sp_spray_recursive(SPDesktop *desktop, gint _distrib) { bool did = false; - - if (SP_IS_BOX3D(item) ) { - // convert 3D boxes to ordinary groups before spraying their shapes - item = box3d_convert_to_group(SP_BOX3D(item)); - selection->add(item); + + { + SPBox3D *box = dynamic_cast(item); + if (box) { + // convert 3D boxes to ordinary groups before spraying their shapes + item = box3d_convert_to_group(box); + selection->add(item); + } } double _fid = g_random_double_range(0, 1); @@ -413,7 +416,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, parent->appendChild(copy); SPObject *new_obj = doc->getObjectByRepr(copy); - item_copied = SP_ITEM(new_obj); // Convertion object->item + item_copied = dynamic_cast(new_obj); // Convertion object->item Geom::Point center=item->getCenter(); sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(_scale,_scale)); sp_spray_scale_rel(center,desktop, item_copied, Geom::Scale(scale,scale)); @@ -437,7 +440,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, items != NULL; items = items->next) { - SPItem *item1 = SP_ITEM(items->data); + SPItem *item1 = dynamic_cast(static_cast(items->data)); if (i == 1) { parent_item = item1; } @@ -458,7 +461,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); parent->appendChild(copy); SPObject *new_obj = doc->getObjectByRepr(copy); - item_copied = SP_ITEM(new_obj); + item_copied = dynamic_cast(new_obj); // Move around the cursor Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio), -sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint()); @@ -503,7 +506,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, SPObject *clone_object = doc->getObjectByRepr(clone); // Conversion object->item - item_copied = SP_ITEM(clone_object); + item_copied = dynamic_cast(clone_object); Geom::Point center = item->getCenter(); sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(_scale, _scale)); sp_spray_scale_rel(center, desktop, item_copied, Geom::Scale(scale, scale)); @@ -554,13 +557,16 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for (GSList *items = original_selection; items != NULL; items = items->next) { - sp_object_ref(SP_ITEM(items->data)); + SPItem *item = dynamic_cast(static_cast(items->data)); + g_assert(item != NULL); + sp_object_ref(item); } for (GSList *items = original_selection; items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); + SPItem *item = dynamic_cast(static_cast(items->data)); + g_assert(item != NULL); if (is_transform_modes(tc->mode)) { if (sp_spray_recursive(desktop, selection, item, p, vector, tc->mode, radius, move_force, tc->population, tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation, tc->ratio, tc->tilt, tc->rotation_variation, tc->distrib)) { @@ -576,7 +582,9 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point for (GSList *items = original_selection; items != NULL; items = items->next) { - sp_object_unref(SP_ITEM(items->data)); + SPItem *item = dynamic_cast(static_cast(items->data)); + g_assert(item != NULL); + sp_object_unref(item); } } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 75650d3af..571a17b70 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -372,13 +372,16 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P { bool did = false; - if (SP_IS_BOX3D(item) && !is_transform_mode(mode) && !is_color_mode(mode)) { - // convert 3D boxes to ordinary groups before tweaking their shapes - item = box3d_convert_to_group(SP_BOX3D(item)); - selection->add(item); + { + SPBox3D *box = dynamic_cast(item); + if (box && !is_transform_mode(mode) && !is_color_mode(mode)) { + // convert 3D boxes to ordinary groups before tweaking their shapes + item = box3d_convert_to_group(box); + selection->add(item); + } } - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast(item) || dynamic_cast(item)) { GSList *items = g_slist_prepend (NULL, item); GSList *selected = NULL; GSList *to_select = NULL; @@ -387,22 +390,25 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P g_slist_free (items); SPObject* newObj = doc->getObjectByRepr(static_cast(to_select->data)); g_slist_free (to_select); - item = SP_ITEM(newObj); + item = dynamic_cast(newObj); + g_assert(item != NULL); selection->add(item); } - if (SP_IS_GROUP(item) && !SP_IS_BOX3D(item)) { + if (dynamic_cast(item) && !dynamic_cast(item)) { GSList *children = NULL; for (SPObject *child = item->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { + if (dynamic_cast(static_cast(child))) { children = g_slist_prepend(children, child); } } for (GSList *i = children; i; i = i->next) { - SPItem *child = SP_ITEM(i->data); - if (sp_tweak_dilate_recursive (selection, SP_ITEM(child), p, vector, mode, radius, force, fidelity, reverse)) + SPItem *child = dynamic_cast(static_cast(i->data)); + g_assert(child != NULL); + if (sp_tweak_dilate_recursive (selection, child, p, vector, mode, radius, force, fidelity, reverse)) { did = true; + } } g_slist_free(children); @@ -509,13 +515,13 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P } } - } else if (SP_IS_PATH(item) || SP_IS_SHAPE(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item)) { Inkscape::XML::Node *newrepr = NULL; gint pos = 0; Inkscape::XML::Node *parent = NULL; char const *id = NULL; - if (!SP_IS_PATH(item)) { + if (!dynamic_cast(item)) { newrepr = sp_selected_item_to_curved_repr(item, 0); if (!newrepr) { return false; @@ -631,7 +637,8 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P if (newrepr) { newrepr->setAttribute("d", str); } else { - if (SP_IS_LPE_ITEM(item) && SP_LPE_ITEM(item)->hasPathEffectRecursive()) { + SPLPEItem *lpeitem = dynamic_cast(item); + if (lpeitem && lpeitem->hasPathEffectRecursive()) { item->getRepr()->setAttribute("inkscape:original-d", str); } else { item->getRepr()->setAttribute("d", str); @@ -769,7 +776,7 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or { SPGradient *gradient = getGradient(item, fill_or_stroke); - if (!gradient || !SP_IS_GRADIENT(gradient)) { + if (!gradient || !dynamic_cast(gradient)) { return; } @@ -780,9 +787,9 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or double pos = 0; double r = 0; - if (SP_IS_LINEARGRADIENT(gradient)) { - SPLinearGradient *lg = SP_LINEARGRADIENT(gradient); + SPLinearGradient *lg = dynamic_cast(gradient); + if (lg) { Geom::Point p1(lg->x1.computed, lg->y1.computed); Geom::Point p2(lg->x2.computed, lg->y2.computed); Geom::Point pdiff(p2 - p1); @@ -800,11 +807,13 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or // Calculate radius in lenfth-of-gradient-line units r = radius / vl; - } else if (SP_IS_RADIALGRADIENT(gradient)) { - SPRadialGradient *rg = SP_RADIALGRADIENT(gradient); - Geom::Point c (rg->cx.computed, rg->cy.computed); - pos = Geom::L2(p - c) / rg->r.computed; - r = radius / rg->r.computed; + } else { + SPRadialGradient *rg = dynamic_cast(gradient); + if (rg) { + Geom::Point c (rg->cx.computed, rg->cy.computed); + pos = Geom::L2(p - c) / rg->r.computed; + r = radius / rg->r.computed; + } } // Normalize pos to 0..1, taking into accound gradient spread: @@ -836,14 +845,16 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or double offset_h = 0; SPObject *child_prev = NULL; for (SPObject *child = vector->firstChild(); child; child = child->getNext()) { - if (!SP_IS_STOP(child)) { + SPStop *stop = dynamic_cast(child); + if (!stop) { continue; } - SPStop *stop = SP_STOP (child); offset_h = stop->offset; if (child_prev) { + SPStop *prevStop = dynamic_cast(child_prev); + g_assert(prevStop != NULL); if (offset_h - offset_l > r && pos_e >= offset_l && pos_e <= offset_h) { // the summit falls in this interstop, and the radius is small, @@ -853,9 +864,9 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or tweak_color (mode, stop->specified_color.v.c, rgb_goal, force * (pos_e - offset_l) / (offset_h - offset_l), do_h, do_s, do_l); - tweak_color (mode, SP_STOP(child_prev)->specified_color.v.c, rgb_goal, - force * (offset_h - pos_e) / (offset_h - offset_l), - do_h, do_s, do_l); + tweak_color(mode, prevStop->specified_color.v.c, rgb_goal, + force * (offset_h - pos_e) / (offset_h - offset_l), + do_h, do_s, do_l); stop->updateRepr(); child_prev->updateRepr(); break; @@ -863,9 +874,9 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or // wide brush, may affect more than 2 stops, // paint each stop by the force from the profile curve if (offset_l <= pos_e && offset_l > pos_e - r) { - tweak_color (mode, SP_STOP(child_prev)->specified_color.v.c, rgb_goal, - force * tweak_profile (fabs (pos_e - offset_l), r), - do_h, do_s, do_l); + tweak_color(mode, prevStop->specified_color.v.c, rgb_goal, + force * tweak_profile (fabs (pos_e - offset_l), r), + do_h, do_s, do_l); child_prev->updateRepr(); } @@ -894,10 +905,11 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, { bool did = false; - if (SP_IS_GROUP(item)) { + if (dynamic_cast(item)) { for (SPObject *child = item->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - if (sp_tweak_color_recursive (mode, SP_ITEM(child), item_at_point, + SPItem *childItem = dynamic_cast(child); + if (childItem) { + if (sp_tweak_color_recursive (mode, childItem, item_at_point, fill_goal, do_fill, stroke_goal, do_stroke, opacity_goal, do_opacity, @@ -953,11 +965,11 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, //cycle through filter primitives SPObject *primitive_obj = style->getFilter()->children; while (primitive_obj) { - if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { - SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); + SPFilterPrimitive *primitive = dynamic_cast(primitive_obj); + if (primitive) { //if primitive is gaussianblur - if(SP_IS_GAUSSIANBLUR(primitive)) { - SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive); + SPGaussianBlur * spblur = dynamic_cast(primitive); + if (spblur) { float num = spblur->stdDeviation.getNumber(); blur_now += num * i2dt.descrim(); // sum all blurs in the filter } @@ -1080,7 +1092,7 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); + SPItem *item = dynamic_cast(static_cast(items->data)); if (is_color_mode (tc->mode)) { if (do_fill || do_stroke || do_opacity) { -- cgit v1.2.3 From 0d7c3ee0a778bfc2f5e5cbc1701ee6cd12e62012 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Fri, 24 Oct 2014 21:50:14 -0700 Subject: Cleaned casts from sp-shape by fixing member type. (bzr r13638) --- src/ui/clipboard.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ui') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 031a92924..4b4b14c22 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -54,6 +54,7 @@ #include <2geom/transforms.h> #include "box3d.h" #include "gradient-drag.h" +#include "marker.h" #include "sp-item.h" #include "sp-item-transform.h" // for sp_item_scale_rel, used in _pasteSize #include "sp-path.h" -- cgit v1.2.3 From 1784329fa3ac4a56944fe03a3b439c4fcd31dea1 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 1 Nov 2014 13:47:00 -0700 Subject: Warning cleanup. (bzr r13653) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- src/ui/dialog/lpe-powerstroke-properties.cpp | 2 +- src/ui/dialog/objects.cpp | 2 +- src/ui/dialog/tags.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index ad8b66b8c..a8870e69b 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -177,7 +177,7 @@ void FilletChamferPropertiesDialog::_close() ); } -bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) { return false; } diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index c34351511..55f938a48 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -152,7 +152,7 @@ PowerstrokePropertiesDialog::_close() ); } -bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey *event) +bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/) { /*switch (get_group0_keyval(event)) { diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 93d5dfbd5..c95529a56 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -988,7 +988,7 @@ void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) /* * Drap and drop within the tree */ -bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& /*context*/, int x, int y, guint /*time*/) { int cell_x = 0, cell_y = 0; Gtk::TreeModel::Path target_path; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 127e4d95e..ba1052ede 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -380,7 +380,7 @@ void TagsPanel::_objectsSelected( Selection *sel ) { _checkTreeSelection(); } -bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +bool TagsPanel::_checkForSelected(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) { Gtk::TreeModel::Row row = *iter; SPObject * it = row[_model->_colObject]; @@ -754,7 +754,7 @@ void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) * Drap and drop within the tree * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer */ -bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& /*context*/, int x, int y, guint /*time*/) { int cell_x = 0, cell_y = 0; Gtk::TreeModel::Path target_path; @@ -885,7 +885,7 @@ void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name } } -bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) { return false; } -- cgit v1.2.3 From db7a155b8fdaeff84faba30e953df1cfd2cacc1a Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 1 Nov 2014 18:57:10 -0700 Subject: Warning cleanup. (bzr r13657) --- src/ui/dialog/tags.cpp | 1 + src/ui/widget/addtoicon.cpp | 13 ++++++------- src/ui/widget/clipmaskicon.cpp | 13 ++++++------- src/ui/widget/highlight-picker.cpp | 13 ++++++------- src/ui/widget/insertordericon.cpp | 13 ++++++------- src/ui/widget/registered-widget.cpp | 2 +- 6 files changed, 26 insertions(+), 29 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index ba1052ede..8a104d137 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -393,6 +393,7 @@ bool TagsPanel::_checkForSelected(const Gtk::TreePath &/*path*/, const Gtk::Tree return false; } +// TODO does not look good that we're ignoring the passed in root. Investigate. void TagsPanel::_objectsChanged(SPObject* root) { while (!_objectWatchers.empty()) diff --git a/src/ui/widget/addtoicon.cpp b/src/ui/widget/addtoicon.cpp index ce665295b..0798d1c98 100644 --- a/src/ui/widget/addtoicon.cpp +++ b/src/ui/widget/addtoicon.cpp @@ -127,13 +127,12 @@ void AddToIcon::render_vfunc( const Glib::RefPtr& window, #endif } -bool -AddToIcon::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool AddToIcon::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/clipmaskicon.cpp b/src/ui/widget/clipmaskicon.cpp index 6331d70d8..943b1bebc 100644 --- a/src/ui/widget/clipmaskicon.cpp +++ b/src/ui/widget/clipmaskicon.cpp @@ -154,13 +154,12 @@ void ClipMaskIcon::render_vfunc( const Glib::RefPtr& window, #endif } -bool -ClipMaskIcon::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool ClipMaskIcon::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index 8593f0bdf..09999b52d 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -147,13 +147,12 @@ void HighlightPicker::render_vfunc( const Glib::RefPtr& window, #endif } -bool -HighlightPicker::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool HighlightPicker::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp index a28b0f834..9aec7d135 100644 --- a/src/ui/widget/insertordericon.cpp +++ b/src/ui/widget/insertordericon.cpp @@ -135,13 +135,12 @@ void InsertOrderIcon::render_vfunc( const Glib::RefPtr& window, #endif } -bool -InsertOrderIcon::activate_vfunc(GdkEvent* event, - Gtk::Widget& /*widget*/, - const Glib::ustring& path, - const Gdk::Rectangle& /*background_area*/, - const Gdk::Rectangle& /*cell_area*/, - Gtk::CellRendererState /*flags*/) +bool InsertOrderIcon::activate_vfunc(GdkEvent* /*event*/, + Gtk::Widget& /*widget*/, + const Glib::ustring& /*path*/, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) { return false; } diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 44d8dcbf3..e97285de4 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -108,7 +108,7 @@ RegisteredToggleButton::~RegisteredToggleButton() _toggled_connection.disconnect(); } -RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) +RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& /*label*/, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) : RegisteredWidget() , _active_str(active_str) , _inactive_str(inactive_str) -- cgit v1.2.3 From dd6537989eab9f89d15163dd96d7c87256b3e9ce Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 2 Nov 2014 06:14:30 -0800 Subject: Correct check-for-layer that should have been check-for-group. Fixes bug #1388297. Fixed bugs: - https://launchpad.net/bugs/1388297 (bzr r13658) --- src/ui/tools/select-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 21459e5d0..a8267ea1d 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -1153,7 +1153,7 @@ bool SelectTool::root_handler(GdkEvent* event) { if (selection->singleItem()) { SPItem *clicked_item = selection->singleItem(); SPGroup *clickedGroup = dynamic_cast(clicked_item); - if ( (clickedGroup && (clickedGroup->layerMode() == SPGroup::LAYER)) || dynamic_cast(clicked_item)) { // enter group or a 3D box + if ( (clickedGroup && (clickedGroup->layerMode() != SPGroup::LAYER)) || dynamic_cast(clicked_item)) { // enter group or a 3D box desktop->setCurrentLayer(clicked_item); sp_desktop_selection(desktop)->clear(); } else { -- cgit v1.2.3 From 3dfff76972208b0328ac7937bb9e9fe037560a26 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 3 Nov 2014 21:54:01 +0100 Subject: Update fillet/chamfer to allow subdivisions in chamfer mode. Still happends bug affecting only selected nodes in document:units diferent than "px". I think the problem is node->position() send me a bad data if document units not px. (bzr r13665) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 28 +++++++++++++++---------- src/ui/dialog/lpe-fillet-chamfer-properties.h | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index a8870e69b..85a2ccd3f 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -46,7 +46,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() Gtk::Box *mainVBox = get_vbox(); mainVBox->set_homogeneous(false); _layout_table.set_spacings(4); - _layout_table.resize(2, 2); + _layout_table.resize(3, 3); // Layer name widgets _fillet_chamfer_position_numeric.set_digits(4); @@ -61,20 +61,30 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() Gtk::FILL); _layout_table.attach(_fillet_chamfer_position_numeric, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _fillet_chamfer_chamfer_subdivisions.set_digits(0); + _fillet_chamfer_chamfer_subdivisions.set_increments(1,1); + //todo: get tha max aloable infinity freeze the widget + _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999); + + _fillet_chamfer_chamfer_subdivisions_label.set_label(_("Chamfer subdivisions:")); + _fillet_chamfer_chamfer_subdivisions_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_fillet_chamfer_chamfer_subdivisions_label, 0, 1, 1, 2, Gtk::FILL, + Gtk::FILL); + _layout_table.attach(_fillet_chamfer_chamfer_subdivisions, 1, 2, 1, 2, + Gtk::FILL | Gtk::EXPAND, Gtk::FILL); _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); - _fillet_chamfer_type_double_chamfer.set_label(_("Double chamfer")); - _fillet_chamfer_type_double_chamfer.set_group(_fillet_chamfer_type_group); + mainVBox->pack_start(_layout_table, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); - mainVBox->pack_start(_fillet_chamfer_type_double_chamfer, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -146,10 +156,8 @@ void FilletChamferPropertiesDialog::_apply() d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { d_width = 2; - } else if (_fillet_chamfer_type_chamfer.get_active() == true) { - d_width = 3; } else { - d_width = 4; + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3; } if (_flexible) { if (d_pos > 99.99999 || d_pos < 0) { @@ -218,10 +226,8 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { _fillet_chamfer_type_inverse_fillet.set_active(true); - } else if (knotpoint.y() == 3) { - _fillet_chamfer_type_chamfer.set_active(true); - } else if (knotpoint.y() == 1) { - _fillet_chamfer_type_double_chamfer.set_active(true); + } else if (knotpoint.y() >= 3) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 47ff97b00..deae0cee0 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -46,7 +46,8 @@ protected: Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; - Gtk::RadioButton _fillet_chamfer_type_double_chamfer; + Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; + Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; Gtk::Table _layout_table; bool _position_visible; -- cgit v1.2.3 From 72cca0fc9e6e25af69ebaa8c82f2ad282eaabf53 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 4 Nov 2014 00:10:33 +0100 Subject: Remove unused variable and put well a constant (bzr r13669) --- src/ui/tool/path-manipulator.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 52ff5d42c..8b99c33b8 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -59,7 +59,7 @@ enum PathChange { const double handleCubicGap = 0.01; const double noPower = 0.0; const double defaultStartPower = 0.3334; -const double defaultEndPower = 0.6667; + /** * Notifies the path manipulator when something changes the path being edited @@ -1000,7 +1000,6 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d n->front()->setPosition(seg2[1]); n->setType(NODE_SMOOTH, false); } else { - const double handleCubicGap = 0.01; Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); if(second->back()->isDegenerate()){ @@ -1251,7 +1250,6 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ h = h2; } double pos = noPower; - const double handleCubicGap = 0.01; Node *n = h->parent(); Node * nextNode = NULL; nextNode = n->nodeToward(h); @@ -1279,7 +1277,6 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; - const double handleCubicGap = 0.01; Geom::Point ret = h->position(); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; -- cgit v1.2.3 From ff6f0db21af7e564e205dcec40a886ce2b674608 Mon Sep 17 00:00:00 2001 From: Masato Hashimoto Date: Wed, 5 Nov 2014 07:01:12 +0100 Subject: i18n. Fix for bug #1389509 (typos in trunk-r13669). (bzr r13670) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index 85a2ccd3f..fa909924d 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -202,7 +202,7 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) double position; std::string distance_or_radius = std::string(_("Radius ")); if(aprox){ - distance_or_radius = std::string(_("Radius aproximated ")); + distance_or_radius = std::string(_("Radius approximated ")); } if(use_distance){ distance_or_radius = std::string(_("Knot distance ")); -- cgit v1.2.3 From f51e8d7c6b4e2caa9e470af674949f3cd1695bf5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Nov 2014 19:30:49 +0100 Subject: Refactor to remove references to Desktop/Ui in Effect, bspline and fillet-chamfer. Also fixed the selected node problem in units not px. Also fixed two var to not allow NULL pointed by Johan Engelen. (bzr r13672) --- src/ui/tools/node-tool.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index e2bb85d11..99d60e2b7 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -305,6 +305,16 @@ void NodeTool::update_helperpath () { if (SP_IS_LPE_ITEM(selection->singleItem())) { Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + Inkscape::UI::ControlPointSelection::Set &selectionNodes = _selected_nodes->allPoints(); + std::vector selectedNodesPositions; + for (Inkscape::UI::ControlPointSelection::Set::iterator i = selectionNodes.begin(); i != selectionNodes.end(); ++i) { + if ((*i)->selected()) { + Inkscape::UI::Node *n = dynamic_cast(*i); + selectedNodesPositions.push_back(desktop->doc2dt(n->position())); + } + } + lpe->setSelectedNodePoints(selectedNodesPositions); + lpe->setCurrentZoom(this->desktop->current_zoom()); SPCurve *c = new SPCurve(); SPCurve *cc = new SPCurve(); std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); -- cgit v1.2.3 From 42eb288d19390918f05c6f0754e45d25f9881a19 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 5 Nov 2014 22:06:17 +0100 Subject: Fixing typos found by Firas Hanife. (bzr r13673) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index c2da12058..a98494e18 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -838,7 +838,7 @@ void InkscapePreferences::initPageIO() _save_use_current_dir.init( _("Use current directory for \"Save As ...\""), "/dialogs/save_as/use_current_dir", true); _page_io.add_line( false, "", _save_use_current_dir, "", - _("When this option is on, the \"Save as...\" and \"Save a Copy\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true); + _("When this option is on, the \"Save as...\" and \"Save a Copy...\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true); _misc_comment.init( _("Add label comments to printing output"), "/printing/debug/show-label-comments", false); _page_io.add_line( false, "", _misc_comment, "", -- cgit v1.2.3 From ff6dc09cde0fcbcf1064d94c9161643a163b1f91 Mon Sep 17 00:00:00 2001 From: Ryan Lerch Date: Fri, 7 Nov 2014 17:46:20 -0500 Subject: fixed typo in src/ui/dialog/Makefile_insert -- dialpg to dialog (bzr r13675) --- src/ui/dialog/Makefile_insert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 26a59ce2c..cbdae1cb0 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -101,7 +101,7 @@ ink_common_sources += \ ui/dialog/template-widget.cpp \ ui/dialog/template-widget.h \ ui/dialog/tags.cpp \ - ui/dialpg/tags.h \ + ui/dialog/tags.h \ ui/dialog/text-edit.cpp \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ -- cgit v1.2.3 From 965e178e307b4c82ad8b618cf6af6d3c3c31d2cb Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 8 Nov 2014 12:25:15 +0100 Subject: Black list some properties that shouldn't appear in default styles. (bzr r13679) --- src/ui/dialog/inkscape-preferences.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index a98494e18..75cfe5bfe 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -234,6 +234,9 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc if (!css) return; + // remove black-listed properties + css = sp_css_attr_unset_blacklist (css); + // only store text style for the text tool if (prefs_path != "/tools/text") { css = sp_css_attr_unset_text (css); -- cgit v1.2.3 From d8559463c6b3e2656bb0726e9dcb7680c4ae3283 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 8 Nov 2014 22:53:49 +0100 Subject: export dialog, small code cleanup, should be a noop. (check if pointer is nullptr, instead of checking the pre-condition for newing into the pointer) (bzr r13687) --- src/ui/dialog/export.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index a4d8801f7..b044a6e2c 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -537,7 +537,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl sb->set_sensitive (sensitive); pos++; - if (!ll.empty()) { + if (l) { l->set_mnemonic_widget(*sb); } -- cgit v1.2.3 From 05a8ca8653fefcdc59e3ee1d1416829ec2712c8f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 10 Nov 2014 00:50:46 +0100 Subject: fix a bug pointed by su_v in fillet chamfer dialog, about units (bzr r13697) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 34 +++++++++++++++---------- src/ui/dialog/lpe-fillet-chamfer-properties.h | 13 ++++++---- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index fa909924d..e9d69b464 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -116,7 +116,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() { - _setDesktop(NULL); + _set_desktop(NULL); } void FilletChamferPropertiesDialog::showDialog( @@ -125,16 +125,18 @@ void FilletChamferPropertiesDialog::showDialog( FilletChamferPointArrayParamKnotHolderEntity *pt, const gchar *unit, bool use_distance, - bool aprox_radius) + bool aprox_radius, + Glib::ustring const * documentUnit) { FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); - dialog->_setDesktop(desktop); - dialog->_setUnit(unit); + dialog->_set_desktop(desktop); + dialog->_set_unit(unit); dialog->_set_use_distance(use_distance); dialog->_set_aprox(aprox_radius); - dialog->_setKnotPoint(knotpoint); - dialog->_setPt(pt); + dialog->_set_document_unit(documentUnit); + dialog->_set_knot_point(knotpoint); + dialog->_set_pt(pt); dialog->set_title(_("Modify Fillet-Chamfer")); dialog->_apply_button.set_label(_("_Modify")); @@ -165,7 +167,7 @@ void FilletChamferPropertiesDialog::_apply() } d_pos = _index + (d_pos / 100); } else { - d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, "px"); + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, *document_unit); d_pos = d_pos * -1; } _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); @@ -175,7 +177,7 @@ void FilletChamferPropertiesDialog::_apply() void FilletChamferPropertiesDialog::_close() { - _setDesktop(NULL); + _set_desktop(NULL); destroy_(); Glib::signal_idle().connect( sigc::bind_return( @@ -197,7 +199,7 @@ void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) } } -void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) { double position; std::string distance_or_radius = std::string(_("Radius ")); @@ -219,7 +221,8 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) std::string(_("(")) + std::string(unit) + std::string(")"); _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); position = knotpoint[Geom::X] * -1; - position = Inkscape::Util::Quantity::convert(position, "px", unit); + + position = Inkscape::Util::Quantity::convert(position, *document_unit, unit); } _fillet_chamfer_position_numeric.set_value(position); if (knotpoint.y() == 1) { @@ -231,7 +234,7 @@ void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) } } -void FilletChamferPropertiesDialog::_setPt( +void FilletChamferPropertiesDialog::_set_pt( const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt) { @@ -240,11 +243,16 @@ void FilletChamferPropertiesDialog::_setPt( pt); } -void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) +void FilletChamferPropertiesDialog::_set_unit(const gchar *abbr) { unit = abbr; } +void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring const *abbr) +{ + document_unit = abbr; +} + void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance) { use_distance = use_knot_distance; @@ -255,7 +263,7 @@ void FilletChamferPropertiesDialog::_set_aprox(bool aprox_radius) aprox = aprox_radius; } -void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) +void FilletChamferPropertiesDialog::_set_desktop(SPDesktop *desktop) { if (desktop) { Inkscape::GC::anchor(desktop); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index deae0cee0..ec87addc5 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -32,7 +32,8 @@ public: FilletChamferPointArrayParamKnotHolderEntity *pt, const gchar *unit, bool use_distance, - bool aprox_radius); + bool aprox_radius, + Glib::ustring const * documentUnit); protected: @@ -63,19 +64,21 @@ protected: return instance; } - void _setDesktop(SPDesktop *desktop); - void _setPt(const Inkscape::LivePathEffect:: + void _set_desktop(SPDesktop *desktop); + void _set_pt(const Inkscape::LivePathEffect:: FilletChamferPointArrayParamKnotHolderEntity *pt); - void _setUnit(const gchar *abbr); + void _set_unit(const gchar *abbr); + void _set_document_unit(Glib::ustring const * abbr); void _set_use_distance(bool use_knot_distance); void _set_aprox(bool aprox_radius); void _apply(); void _close(); bool _flexible; const gchar *unit; + Glib::ustring const * document_unit; bool use_distance; bool aprox; - void _setKnotPoint(Geom::Point knotpoint); + void _set_knot_point(Geom::Point knotpoint); void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); bool _handleKeyEvent(GdkEventKey *event); -- cgit v1.2.3 From 46314979be91405f5a1fb31b1ac8b5c62b622948 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 10 Nov 2014 09:04:48 -0800 Subject: Fix 32-bit build break. (bzr r13699) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index e9d69b464..e55c9f8df 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -64,7 +64,7 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() _fillet_chamfer_chamfer_subdivisions.set_digits(0); _fillet_chamfer_chamfer_subdivisions.set_increments(1,1); //todo: get tha max aloable infinity freeze the widget - _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999); + _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999.0); _fillet_chamfer_chamfer_subdivisions_label.set_label(_("Chamfer subdivisions:")); _fillet_chamfer_chamfer_subdivisions_label.set_alignment(1.0, 0.5); -- cgit v1.2.3 From e179290f049d5c34ae2b9c05fdfeab830b7c39e7 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Mon, 10 Nov 2014 09:39:33 -0800 Subject: Removed SP_USE/SP_IS_USE Gtk-ish macros and cleaned affected files. (bzr r13700) --- src/ui/dialog/clonetiler.cpp | 22 ++++-- src/ui/dialog/find.cpp | 93 ++++++++++++++--------- src/ui/dialog/livepatheffect-editor.cpp | 127 +++++++++++++++++--------------- src/ui/dialog/symbols.cpp | 22 +++--- 4 files changed, 152 insertions(+), 112 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 5ef885ab2..d1a675735 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1,5 +1,6 @@ -/** @file +/** + * @file * Clone tiling dialog */ /* Authors: @@ -2002,7 +2003,7 @@ bool CloneTiler::clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj) id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); } - if (SP_IS_USE(tile) && + if (dynamic_cast(tile) && tile->getRepr()->attribute("xlink:href") && (!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) && tile->getRepr()->attribute("inkscape:tiled-clone-of") && @@ -2025,8 +2026,10 @@ void CloneTiler::clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) return; for (SPObject *o = from->firstChild(); o != NULL; o = o->next) { - if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL)) - SP_ITEM(o)->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + SPItem *item = dynamic_cast(o); + if (item && clonetiler_is_a_clone_of(o, NULL)) { + item->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + } clonetiler_trace_hide_tiled_clones_recursively (o); } } @@ -2160,7 +2163,9 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d } } for (GSList *i = to_delete; i; i = i->next) { - SP_OBJECT(i->data)->deleteObject(); + SPObject *obj = reinterpret_cast(i->data); + g_assert(obj != NULL); + obj->deleteObject(); } g_slist_free (to_delete); @@ -2330,7 +2335,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); - SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + SPItem *item = dynamic_cast(obj); if (dotrace) { clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); } @@ -2621,9 +2626,10 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) if (center_set) { SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); - if (clone_object && SP_IS_ITEM(clone_object)) { + SPItem *item = dynamic_cast(clone_object); + if (clone_object && item) { clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - SP_ITEM(clone_object)->setCenter(desktop->doc2dt(new_center)); + item->setCenter(desktop->doc2dt(new_center)); clone_object->updateRepr(); } } diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 1a4823e4a..1a7832688 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -241,7 +241,7 @@ Find::Find() Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); SPItem *item = selection->singleItem(); if (item) { - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast(item) || dynamic_cast(item)) { gchar *str; str = sp_te_get_string_multiline (item); entry_find.getEntry()->set_text(str); @@ -343,7 +343,7 @@ bool Find::item_text_match (SPItem *item, const gchar *find, bool exact, bool ca return false; } - if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + if (dynamic_cast(item) || dynamic_cast(item)) { const gchar *item_text = sp_te_get_string_multiline (item); if (item_text == NULL) { return false; @@ -388,7 +388,7 @@ bool Find::item_id_match (SPItem *item, const gchar *id, bool exact, bool casema return false; } - if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching + if (dynamic_cast(item)) { // SPStrings have "on demand" ids which are useless for searching return false; } @@ -561,11 +561,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (check_searchin_text.get_active()) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_text_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_text_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_text_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_text_match(item, text, exact, casematch, _action_replace); } } } @@ -581,11 +584,13 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (ids) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_id_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + if (item_id_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_id_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_id_match(item, text, exact, casematch, _action_replace); } } } @@ -595,12 +600,15 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (style) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_style_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_style_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_style_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_style_match(item, text, exact, casematch, _action_replace); } } } @@ -610,11 +618,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (attrname) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_attr_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_attr_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_attr_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_attr_match(item, text, exact, casematch, _action_replace); } } } @@ -624,11 +635,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (attrvalue) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_attrvalue_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_attrvalue_match(item, text, exact, casematch, _action_replace); } } } @@ -638,11 +652,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch) if (font) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_font_match (SP_ITEM(i->data), text, exact, casematch)) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_font_match(item, text, exact, casematch)) { if (!g_slist_find(out, i->data)) { out = g_slist_prepend (out, i->data); if (_action_replace) { - item_font_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + item_font_match(item, text, exact, casematch, _action_replace); } } } @@ -661,34 +678,34 @@ bool Find::item_type_match (SPItem *item) { bool all =check_alltypes.get_active(); - if ( SP_IS_RECT(item)) { + if ( dynamic_cast(item)) { return ( all ||check_rects.get_active()); - } else if (SP_IS_GENERICELLIPSE(item)) { + } else if (dynamic_cast(item)) { return ( all || check_ellipses.get_active()); - } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item)) { return ( all || check_stars.get_active()); - } else if (SP_IS_SPIRAL(item)) { + } else if (dynamic_cast(item)) { return ( all || check_spirals.get_active()); - } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item) || dynamic_cast(item)) { return (all || check_paths.get_active()); - } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item)) { + } else if (dynamic_cast(item) || dynamic_cast(item) || dynamic_cast(item) || dynamic_cast(item)) { return (all || check_texts.get_active()); - } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers! + } else if (dynamic_cast(item) && !desktop->isLayer(item) ) { // never select layers! return (all || check_groups.get_active()); - } else if (SP_IS_USE(item)) { + } else if (dynamic_cast(item)) { return (all || check_clones.get_active()); - } else if (SP_IS_IMAGE(item)) { + } else if (dynamic_cast(item)) { return (all || check_images.get_active()); - } else if (SP_IS_OFFSET(item)) { + } else if (dynamic_cast(item)) { return (all || check_offsets.get_active()); } @@ -699,7 +716,10 @@ GSList *Find::filter_types (GSList *l) { GSList *n = NULL; for (GSList *i = l; i != NULL; i = i->next) { - if (item_type_match (SP_ITEM(i->data))) { + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item_type_match(item)) { n = g_slist_prepend (n, i->data); } } @@ -716,7 +736,7 @@ GSList *Find::filter_list (GSList *l, bool exact, bool casematch) GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) { - if (SP_IS_DEFS(r)) { + if (dynamic_cast(r)) { return l; // we're not interested in items in defs } @@ -725,8 +745,8 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) } for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - if (SP_IS_ITEM(child) && !child->cloned && !desktop->isLayer(SP_ITEM(child))) { - SPItem *item = reinterpret_cast(child); + SPItem *item = dynamic_cast(child); + if (item && !child->cloned && !desktop->isLayer(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, child); } @@ -739,16 +759,18 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) GSList *Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked) { for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) { - if (SP_IS_ITEM (i->data) && !reinterpret_cast(i->data)->cloned && !desktop->isLayer(SP_ITEM(i->data))) { - SPItem *item = reinterpret_cast(i->data); + SPObject *obj = reinterpret_cast(i->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + if (item && !item->cloned && !desktop->isLayer(item)) { if (!ancestor || ancestor->isAncestorOf(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, i->data); } } } - if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) { - l = all_items (SP_OBJECT (i->data), l, hidden, locked); + if (!ancestor || ancestor->isAncestorOf(item)) { + l = all_items(item, l, hidden, locked); } } return l; @@ -831,7 +853,10 @@ void Find::onAction() Inkscape::Selection *selection = sp_desktop_selection (desktop); selection->clear(); selection->setList(n); - scroll_to_show_item (desktop, SP_ITEM(n->data)); + SPObject *obj = reinterpret_cast(n->data); + SPItem *item = dynamic_cast(obj); + g_assert(item != NULL); + scroll_to_show_item(desktop, item); if (_action_replace) { DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Replace text or property")); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 9a569725c..eb3857ee7 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -295,9 +295,8 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); if ( item ) { - if ( SP_IS_LPE_ITEM(item) ) { - SPLPEItem *lpeitem = SP_LPE_ITEM(item); - + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { effect_list_reload(lpeitem); current_lpeitem = lpeitem; @@ -318,25 +317,28 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) button_up.set_sensitive(false); button_down.set_sensitive(false); } - } else if ( SP_IS_USE(item) ) { - // test whether linked object is supported by the CLONE_ORIGINAL LPE - SPItem *orig = SP_USE(item)->get_original(); - if ( SP_IS_SHAPE(orig) || - SP_IS_TEXT(orig) ) - { - // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case. - set_sensitize_all(true); - showText(_("Click add button to convert clone")); - button_remove.set_sensitive(false); - button_up.set_sensitive(false); - button_down.set_sensitive(false); + } else { + SPUse *use = dynamic_cast(item); + if ( use ) { + // test whether linked object is supported by the CLONE_ORIGINAL LPE + SPItem *orig = use->get_original(); + if ( dynamic_cast(orig) || + dynamic_cast(orig) ) + { + // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case. + set_sensitize_all(true); + showText(_("Click add button to convert clone")); + button_remove.set_sensitive(false); + button_up.set_sensitive(false); + button_down.set_sensitive(false); + } else { + showText(_("Select a path or shape")); + set_sensitize_all(false); + } } else { showText(_("Select a path or shape")); set_sensitize_all(false); } - } else { - showText(_("Select a path or shape")); - set_sensitize_all(false); } } else { showText(_("Only one item can be selected")); @@ -423,7 +425,7 @@ LivePathEffectEditor::onAdd() if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); if (item) { - if ( SP_IS_LPE_ITEM(item) ) { + if ( dynamic_cast(item) ) { // show effectlist dialog using Inkscape::UI::Dialog::LivePathEffectAdd; LivePathEffectAdd::show(current_desktop); @@ -439,7 +441,7 @@ LivePathEffectEditor::onAdd() } // If item is a SPRect, convert it to path first: - if ( SP_IS_RECT(item) ) { + if ( dynamic_cast(item) ) { sp_selected_path_to_curves(sel, current_desktop, false); item = sel->singleItem(); // get new item } @@ -451,41 +453,43 @@ LivePathEffectEditor::onAdd() lpe_list_locked = false; onSelectionChanged(sel); - } - else if ( SP_IS_USE(item) ) { - // item is a clone. do not show effectlist dialog. - // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path - - // test whether linked object is supported by the CLONE_ORIGINAL LPE - SPItem *orig = SP_USE(item)->get_original(); - if ( SP_IS_SHAPE(orig) || - SP_IS_TEXT(orig) ) - { - // select original - sel->set(orig); - - // delete clone but remember its id and transform - gchar *id = g_strdup(item->getRepr()->attribute("id")); - gchar *transform = g_strdup(item->getRepr()->attribute("transform")); - item->deleteObject(false); - item = NULL; - - // run sp_selection_clone_original_path_lpe - sp_selection_clone_original_path_lpe(current_desktop); - SPItem *new_item = sel->singleItem(); - new_item->getRepr()->setAttribute("id", id); - new_item->getRepr()->setAttribute("transform", transform); - g_free(id); - g_free(transform); - - /// \todo Add the LPE stack of the original path? - - SPDocument *doc = current_desktop->doc(); - DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Create and apply Clone original path effect")); - - lpe_list_locked = false; - onSelectionChanged(sel); + } else { + SPUse *use = dynamic_cast(item); + if ( use ) { + // item is a clone. do not show effectlist dialog. + // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path + + // test whether linked object is supported by the CLONE_ORIGINAL LPE + SPItem *orig = use->get_original(); + if ( dynamic_cast(orig) || + dynamic_cast(orig) ) + { + // select original + sel->set(orig); + + // delete clone but remember its id and transform + gchar *id = g_strdup(item->getRepr()->attribute("id")); + gchar *transform = g_strdup(item->getRepr()->attribute("transform")); + item->deleteObject(false); + item = NULL; + + // run sp_selection_clone_original_path_lpe + sp_selection_clone_original_path_lpe(current_desktop); + SPItem *new_item = sel->singleItem(); + new_item->getRepr()->setAttribute("id", id); + new_item->getRepr()->setAttribute("transform", transform); + g_free(id); + g_free(transform); + + /// \todo Add the LPE stack of the original path? + + SPDocument *doc = current_desktop->doc(); + DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Create and apply Clone original path effect")); + + lpe_list_locked = false; + onSelectionChanged(sel); + } } } } @@ -498,13 +502,14 @@ LivePathEffectEditor::onRemove() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( item && SP_IS_LPE_ITEM(item) ) { - SP_LPE_ITEM(item)->removeCurrentPathEffect(false); + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { + lpeitem->removeCurrentPathEffect(false); DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Remove path effect") ); - effect_list_reload(SP_LPE_ITEM(item)); + effect_list_reload(lpeitem); } } @@ -515,7 +520,8 @@ void LivePathEffectEditor::onUp() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) { + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { lpeitem->upCurrentPathEffect(); DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, @@ -531,7 +537,8 @@ void LivePathEffectEditor::onDown() Inkscape::Selection *sel = _getSelection(); if ( sel && !sel->isEmpty() ) { SPItem *item = sel->singleItem(); - if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) { + SPLPEItem *lpeitem = dynamic_cast(item); + if ( lpeitem ) { lpeitem->downCurrentPathEffect(); DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index a9cf8d068..a17a03861 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -298,8 +298,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : // This might need to be a global variable so setTargetDesktop can modify it SPDefs *defs = currentDocument->getDefs(); - sigc::connection defsModifiedConn = (SP_OBJECT(defs))->connectModified( - sigc::mem_fun(*this, &SymbolsDialog::defsModified)); + sigc::connection defsModifiedConn = defs->connectModified(sigc::mem_fun(*this, &SymbolsDialog::defsModified)); instanceConns.push_back(defsModifiedConn); sigc::connection selectionChangedConn = currentDesktop->selection->connectChanged( @@ -658,11 +657,11 @@ GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l) g_return_val_if_fail(r != NULL, l); // Stop multiple counting of same symbol - if( SP_IS_USE(r) ) { + if ( dynamic_cast(r) ) { return l; } - if( SP_IS_SYMBOL(r) ) { + if ( dynamic_cast(r) ) { l = g_slist_prepend (l, r); } @@ -684,7 +683,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l) { - if( SP_IS_USE(r) ) { + if ( dynamic_cast(r) ) { l = g_slist_prepend (l, r); } @@ -709,8 +708,9 @@ gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* documen gchar const* style = 0; GSList* l = use_in_doc( document ); for( ; l != NULL; l = l->next ) { - SPObject* use = SP_OBJECT(l->data); - if( SP_IS_USE( use ) ) { + SPObject *obj = reinterpret_cast(l->data); + SPUse *use = dynamic_cast(obj); + if ( use ) { gchar const *href = use->getRepr()->attribute("xlink:href"); if( href ) { Glib::ustring href2(href); @@ -730,8 +730,9 @@ void SymbolsDialog::add_symbols( SPDocument* symbolDocument ) { GSList* l = symbols_in_doc( symbolDocument ); for( ; l != NULL; l = l->next ) { - SPObject* symbol = SP_OBJECT(l->data); - if (SP_IS_SYMBOL(symbol)) { + SPObject *obj = reinterpret_cast(l->data); + SPSymbol *symbol = dynamic_cast(obj); + if (symbol) { add_symbol( symbol ); } } @@ -820,7 +821,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); previewDocument->ensureUpToDate(); - SPItem *item = SP_ITEM(object_temp); + SPItem *item = dynamic_cast(object_temp); + g_assert(item != NULL); unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); -- cgit v1.2.3 From 7ff4799d9ecde4286c94e76f4005e18db5a60055 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 12 Nov 2014 01:12:35 +0100 Subject: Fixed bug in node point selection to LPE. (bzr r13704) --- src/ui/tools/node-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index 99d60e2b7..838c2a884 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -310,7 +310,7 @@ void NodeTool::update_helperpath () { for (Inkscape::UI::ControlPointSelection::Set::iterator i = selectionNodes.begin(); i != selectionNodes.end(); ++i) { if ((*i)->selected()) { Inkscape::UI::Node *n = dynamic_cast(*i); - selectedNodesPositions.push_back(desktop->doc2dt(n->position())); + selectedNodesPositions.push_back(n->position()); } } lpe->setSelectedNodePoints(selectedNodesPositions); -- cgit v1.2.3 From 87469d81799b58681b91800234f266ea8b19b30b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Nov 2014 01:08:40 +0100 Subject: Add inverse subdivision chamfer to fillet chamfer LPE, feature sugested by Ivan Louette. (bzr r13708) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 15 ++++++++++++--- src/ui/dialog/lpe-fillet-chamfer-properties.h | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index e55c9f8df..55a19fc51 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -79,12 +79,15 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_chamfer.set_label(_("Inverse chamfer")); + _fillet_chamfer_type_inverse_chamfer.set_group(_fillet_chamfer_type_group); mainVBox->pack_start(_layout_table, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_chamfer, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -158,8 +161,10 @@ void FilletChamferPropertiesDialog::_apply() d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { d_width = 2; + } else if (_fillet_chamfer_type_inverse_chamfer.get_active() == true) { + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 4000; } else { - d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3; + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3000; } if (_flexible) { if (d_pos > 99.99999 || d_pos < 0) { @@ -229,8 +234,12 @@ void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { _fillet_chamfer_type_inverse_fillet.set_active(true); - } else if (knotpoint.y() >= 3) { - _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3); + } else if (knotpoint.y() >= 3000 && knotpoint.y() < 4000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3000); + _fillet_chamfer_type_chamfer.set_active(true); + } else if (knotpoint.y() >= 4000 && knotpoint.y() < 5000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 4000); + _fillet_chamfer_type_inverse_chamfer.set_active(true); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index ec87addc5..3807e98c8 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -47,6 +47,7 @@ protected: Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; + Gtk::RadioButton _fillet_chamfer_type_inverse_chamfer; Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; -- cgit v1.2.3 From 510c80b1b2d9a4ee700bd152d320c6963bccd358 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sat, 15 Nov 2014 07:52:51 -0500 Subject: scale symbols when changing document units (Bug 1365451) Fixed bugs: - https://launchpad.net/bugs/1365451 (bzr r13709) --- src/ui/clipboard.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/ui') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 931a295d8..153ed9830 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -330,6 +330,13 @@ void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* use->setAttribute("xlink:href", id.c_str() ); // Set a default style in rather than so it can be changed. use->setAttribute("style", style ); + + Inkscape::XML::Node *nv_repr = sp_desktop_namedview(inkscape_active_desktop())->getRepr(); + gdouble scale_units = Inkscape::Util::Quantity::convert(1, nv_repr->attribute("inkscape:document-units"), "px"); + gchar *transform_str = sp_svg_transform_write(Geom::Scale(scale_units, scale_units)); + use->setAttribute("transform", transform_str); + g_free(transform_str); + _root->appendChild(use); // This min and max sets offsets, we don't have any so set to zero. -- cgit v1.2.3 From 692ee3551c1a101b16134b0b446ab98231fa4d1f Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 15 Nov 2014 10:37:38 -0800 Subject: Purged GTKish macros SP_SCRIPT/SP_IS_SCRIPT. (bzr r13712) --- src/ui/dialog/document-properties.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/ui') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index dc8a0fee2..6064c2a5e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1205,10 +1205,10 @@ void DocumentProperties::removeExternalScript(){ const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); while ( current ) { - if (current->data && SP_IS_OBJECT(current->data)) { - SPObject* obj = SP_OBJECT(current->data); - SPScript* script = SP_SCRIPT(obj); - if (name == script->xlinkhref){ + SPObject* obj = reinterpret_cast(current->data); + if (obj) { + SPScript* script = dynamic_cast(obj); + if (script && (name == script->xlinkhref)) { //XML Tree being used directly here while it shouldn't be. Inkscape::XML::Node *repr = obj->getRepr(); @@ -1354,10 +1354,15 @@ void DocumentProperties::populate_script_lists(){ _ExternalScriptsListStore->clear(); _EmbeddedScriptsListStore->clear(); const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - if (current) _scripts_observer.set(SP_OBJECT(current->data)->parent); + if (current) { + SPObject *obj = reinterpret_cast(current->data); + g_assert(obj != NULL); + _scripts_observer.set(obj->parent); + } while ( current ) { - SPObject* obj = SP_OBJECT(current->data); - SPScript* script = SP_SCRIPT(obj); + SPObject* obj = reinterpret_cast(current->data); + SPScript* script = dynamic_cast(obj); + g_assert(script != NULL); if (script->xlinkhref) { Gtk::TreeModel::Row row = *(_ExternalScriptsListStore->append()); -- cgit v1.2.3 From f6740d03736aa790dbd2b0441337ce97cef843fb Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 15 Nov 2014 10:52:22 -0800 Subject: Purged GTKish SP_IS_RECT_CONTEXT/SP_RECT_CONTEXT macros. (bzr r13713) --- src/ui/tools/rect-tool.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tools/rect-tool.h b/src/ui/tools/rect-tool.h index a50fd7b24..a22f1caa8 100644 --- a/src/ui/tools/rect-tool.h +++ b/src/ui/tools/rect-tool.h @@ -6,6 +6,7 @@ * * Author: * Lauris Kaplinski + * Jon A. Cruz * * Copyright (C) 2000 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. @@ -21,9 +22,6 @@ #include "sp-rect.h" -#define SP_RECT_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) -#define SP_IS_RECT_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) - namespace Inkscape { namespace UI { namespace Tools { -- cgit v1.2.3 From 90e57a25353694141b0b15b9678e382d59b978ca Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 17 Nov 2014 23:56:27 +0100 Subject: commented unused variables (bzr r13728) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 4abc901d2..8a1ca0b90 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -60,10 +60,10 @@ Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) namespace Inkscape { namespace UI { -const double handleCubicGap = 0.01; +/*const double handleCubicGap = 0.01;*/ const double noPower = 0.0; const double defaultStartPower = 0.3334; -const double defaultEndPower = 0.6667; +/*const double defaultEndPower = 0.6667;*/ ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke -- cgit v1.2.3 From 39eb601008ddcd01b4e05ec2d6efb49a7732d5e3 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Wed, 19 Nov 2014 14:31:03 -0500 Subject: modify sequence of events. (Bug 1247801) Fixed bugs: - https://launchpad.net/bugs/1247801 (bzr r13735) --- src/ui/tools/freehand-base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 6434c30d2..bd84e0efb 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -703,8 +703,8 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) dc->selection->set(repr); Inkscape::GC::release(repr); item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - item->doWriteTransform(item->getRepr(), item->transform, NULL, true); item->updateRepr(); + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); } DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, -- cgit v1.2.3 From f0f92e6aad8d897fa206474754a7bd09220c993d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 20 Nov 2014 10:22:42 +0100 Subject: Rename variable to better express its use. (units -> page_size_units) (bzr r13740) --- src/ui/widget/page-sizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui') diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index 89b0b8f7e..32e357c57 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -311,8 +311,8 @@ PageSizer::PageSizer(Registry & _wr) SPDesktop *dt = SP_ACTIVE_DESKTOP; SPNamedView *nv = sp_desktop_namedview(dt); _wr.setUpdating (true); - if (nv->units) { - _dimensionUnits.setUnit(nv->units->abbr); + if (nv->page_size_units) { + _dimensionUnits.setUnit(nv->page_size_units->abbr); } else if (nv->doc_units) { _dimensionUnits.setUnit(nv->doc_units->abbr); } -- cgit v1.2.3