summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e89a077)
raw | patch | inline | side by side (parent: e89a077)
author | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Wed, 20 Jan 2010 15:06:54 +0000 (16:06 +0100) | ||
committer | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Wed, 20 Jan 2010 15:06:54 +0000 (16:06 +0100) |
src/ui/tool/path-manipulator.cpp | patch | blob | history |
index 9eabd899227498b816033a4a33f8b8b896d1bf61..3be332b80a3a291cdf8a5a7ee541460cd2f7d6b4 100644 (file)
, _dragpoint(new CurveDragPoint(*this))
, _observer(new PathManipulatorObserver(this))
, _edit_transform(et)
+ , _num_selected(0)
, _show_handles(true)
, _show_outline(false)
, _lpe_key(lpe_key)
void PathManipulator::shiftSelection(int dir)
{
if (dir == 0) return;
+ if (_num_selected == 0) {
+ // select the first node of the path.
+ SubpathList::iterator s = _subpaths.begin();
+ if (s == _subpaths.end()) return;
+ NodeList::iterator n = (*s)->begin();
+ if (n != (*s)->end())
+ _selection.insert(n.ptr());
+ return;
+ }
// We cannot do any tricks here, like iterating in different directions based on
// the sign and only setting the selection of nodes behind us, because it would break
// for closed paths.
_selection.erase(j.ptr());
++num;
}
- if (num == 0) continue; // should never happen!
+ if (num == 0) continue; // should never happen! zero-node subpaths are not allowed
num = 0;
// In closed subpath, shift the selection cyclically. In an open one,
/** Insert a new node in the middle of each selected segment. */
void PathManipulator::insertNodes()
{
- if (!_num_selected) return;
+ if (_num_selected < 2) return;
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
/** Replace contiguous selections of nodes in each subpath with one node. */
void PathManipulator::weldNodes(NodeList::iterator preserve_pos)
{
- if (!_num_selected) return;
- _dragpoint->setVisible(false);
+ if (_num_selected < 2) return;
+ hideDragPoint();
bool pos_valid = preserve_pos;
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
/** Remove nodes in the middle of selected segments. */
void PathManipulator::weldSegments()
{
- if (!_num_selected) return;
- _dragpoint->setVisible(false);
+ if (_num_selected < 2) return;
+ hideDragPoint();
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
SubpathPtr sp = *i;
* in a way that attempts to preserve the original shape of the curve. */
void PathManipulator::deleteNodes(bool keep_shape)
{
- if (!_num_selected) return;
+ if (_num_selected == 0) return;
hideDragPoint();
unsigned const samples_per_segment = 10;
/** Make selected segments curves / lines. */
void PathManipulator::setSegmentType(SegmentType type)
{
- if (!_num_selected) return;
+ if (_num_selected == 0) return;
for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
NodeList::iterator k = j.next();
_createGeometryFromControlPoints();
}
-/** Hide the curve drag point until the next motion event. */
+/** Hide the curve drag point until the next motion event.
+ * This should be called at the beginning of every method that can delete nodes.
+ * Otherwise the invalidated iterator in the dragpoint can cause crashes. */
void PathManipulator::hideDragPoint()
{
_dragpoint->setVisible(false);