index d10045c623598dffffaf1ae545837c2aeed5fc0f..de19fef8d0268d47b37aa05f4603f8f3c6f1f260 100644 (file)
, _dragging(false)
, _handles_visible(true)
, _one_node_handles(false)
, _dragging(false)
, _handles_visible(true)
, _one_node_handles(false)
- , _sculpt_enabled(false)
- , _sculpting(false)
{
signal_update.connect( sigc::bind(
sigc::mem_fun(*this, &ControlPointSelection::_updateTransformHandles),
{
signal_update.connect( sigc::bind(
sigc::mem_fun(*this, &ControlPointSelection::_updateTransformHandles),
return std::pair<iterator, bool>(found, false);
}
return std::pair<iterator, bool>(found, false);
}
- boost::shared_ptr<connlist_type> clist(new connlist_type());
-
- // hide event param and always return false
- clist->push_back(
- x->signal_grabbed.connect(
- sigc::bind_return(
- sigc::bind<0>(
- sigc::mem_fun(*this, &ControlPointSelection::_selectionGrabbed),
- x),
- false)));
- clist->push_back(
- x->signal_dragged.connect(
- sigc::mem_fun(*this, &ControlPointSelection::_selectionDragged)));
- // hide event parameter
- clist->push_back(
- x->signal_ungrabbed.connect(
- sigc::hide(
- sigc::mem_fun(*this, &ControlPointSelection::_selectionUngrabbed))));
-
- found = _points.insert(std::make_pair(x, clist)).first;
+ found = _points.insert(x).first;
x->updateState();
_rot_radius.reset();
x->updateState();
_rot_radius.reset();
@@ -111,11 +90,7 @@ std::pair<ControlPointSelection::iterator, bool> ControlPointSelection::insert(c
/** Remove a point from the selection. */
void ControlPointSelection::erase(iterator pos)
{
/** Remove a point from the selection. */
void ControlPointSelection::erase(iterator pos)
{
- SelectableControlPoint *erased = pos->first;
- boost::shared_ptr<connlist_type> clist = pos->second;
- for (connlist_type::iterator i = clist->begin(); i != clist->end(); ++i) {
- i->disconnect();
- }
+ SelectableControlPoint *erased = *pos;
_points.erase(pos);
erased->updateState();
_rot_radius.reset();
_points.erase(pos);
erased->updateState();
_rot_radius.reset();
erase(i++);
}
erase(i++);
}
-/** Transform all selected control points by the supplied affine transformation. */
+/** 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);
+ }
+}
+/** Select all points inside the given rectangle (in desktop coordinates). */
+void ControlPointSelection::selectArea(Geom::Rect const &r)
+{
+ for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) {
+ if (r.contains(**i))
+ insert(*i);
+ }
+}
+/** Unselect all selected points and select all unselected points. */
+void ControlPointSelection::invertSelection()
+{
+ for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) {
+ if ((*i)->selected()) erase(*i);
+ else insert(*i);
+ }
+}
+void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir)
+{
+ bool grow = (dir > 0);
+ Geom::Point p = origin->position();
+ double best_dist = grow ? HUGE_VAL : 0;
+ SelectableControlPoint *match = NULL;
+ for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) {
+ bool selected = (*i)->selected();
+ if (grow && !selected) {
+ double dist = Geom::distance((*i)->position(), p);
+ if (dist < best_dist) {
+ best_dist = dist;
+ match = *i;
+ }
+ }
+ if (!grow && selected) {
+ double dist = Geom::distance((*i)->position(), p);
+ // use >= to also deselect the origin node when it's the last one selected
+ if (dist >= best_dist) {
+ best_dist = dist;
+ match = *i;
+ }
+ }
+ }
+ if (match) {
+ if (grow) insert(match);
+ else erase(match);
+ }
+}
+
+/** Transform all selected control points by the given affine transformation. */
void ControlPointSelection::transform(Geom::Matrix const &m)
{
for (iterator i = _points.begin(); i != _points.end(); ++i) {
void ControlPointSelection::transform(Geom::Matrix const &m)
{
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = *i;
cur->transform(m);
}
// TODO preserving the rotation radius needs some rethinking...
cur->transform(m);
}
// TODO preserving the rotation radius needs some rethinking...
Geom::OptInterval bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
Geom::OptInterval bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- bound.unionWith(Geom::OptInterval(i->first->position()[d]));
+ bound.unionWith(Geom::OptInterval((*i)->position()[d]));
}
double new_coord = bound->middle();
for (iterator i = _points.begin(); i != _points.end(); ++i) {
}
double new_coord = bound->middle();
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- Geom::Point pos = i->first->position();
+ Geom::Point pos = (*i)->position();
pos[d] = new_coord;
pos[d] = new_coord;
- i->first->move(pos);
+ (*i)->move(pos);
}
}
}
}
// first we insert all points into a multimap keyed by the aligned coord to sort them
// simultaneously we compute the extent of selection
for (iterator i = _points.begin(); i != _points.end(); ++i) {
// first we insert all points into a multimap keyed by the aligned coord to sort them
// simultaneously we compute the extent of selection
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- Geom::Point pos = i->first->position();
- sm.insert(std::make_pair(pos[d], i->first));
+ Geom::Point pos = (*i)->position();
+ sm.insert(std::make_pair(pos[d], (*i)));
bound.unionWith(Geom::OptInterval(pos[d]));
}
bound.unionWith(Geom::OptInterval(pos[d]));
}
{
Geom::OptRect bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
{
Geom::OptRect bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = (*i);
Geom::Point p = cur->position();
if (!bound) {
bound = Geom::Rect(p, p);
Geom::Point p = cur->position();
if (!bound) {
bound = Geom::Rect(p, p);
{
Geom::OptRect bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
{
Geom::OptRect bound;
for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
+ SelectableControlPoint *cur = (*i);
Geom::OptRect r = cur->bounds();
bound.unionWith(r);
}
Geom::OptRect r = cur->bounds();
bound.unionWith(r);
}
_updateTransformHandles(true);
}
_updateTransformHandles(true);
}
-void ControlPointSelection::_selectionGrabbed(SelectableControlPoint *p, GdkEventMotion *event)
+void ControlPointSelection::toggleTransformHandlesMode()
{
{
- hideTransformHandles();
- _dragging = true;
- if (held_alt(*event) && _sculpt_enabled) {
- _sculpting = true;
- _grabbed_point = p;
+ if (_handles->mode() == TransformHandleSet::MODE_SCALE) {
+ _handles->setMode(TransformHandleSet::MODE_ROTATE_SKEW);
+ if (size() == 1) _handles->rotationCenter().setVisible(false);
} else {
} else {
- _sculpting = false;
+ _handles->setMode(TransformHandleSet::MODE_SCALE);
}
}
}
}
-void ControlPointSelection::_selectionDragged(Geom::Point const &old_pos, Geom::Point &new_pos,
- GdkEventMotion *event)
+void ControlPointSelection::_pointGrabbed()
{
{
- Geom::Point delta = new_pos - old_pos;
- /*if (_sculpting) {
- // for now we only support the default sculpting profile (bell)
- // others will be added when preferences will be able to store enumerated values
- double pressure, alpha;
- if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &pressure)) {
- pressure = CLAMP(pressure, 0.2, 0.8);
- } else {
- pressure = 0.5;
- }
-
- alpha = 1 - 2 * fabs(pressure - 0.5);
- if (pressure > 0.5) alpha = 1/alpha;
+ hideTransformHandles();
+ _dragging = true;
+}
- for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
- double dist = Geom::distance(cur->position(), _grabbed_point->position());
-
- cur->move(cur->position() + delta);
- }
- } else*/ {
- for (iterator i = _points.begin(); i != _points.end(); ++i) {
- SelectableControlPoint *cur = i->first;
- cur->move(cur->position() + delta);
- }
- _handles->rotationCenter().move(_handles->rotationCenter().position() + delta);
+void ControlPointSelection::_pointDragged(Geom::Point const &old_pos, Geom::Point &new_pos,
+ GdkEventMotion */*event*/)
+{
+ Geom::Point delta = new_pos - old_pos;
+ for (iterator i = _points.begin(); i != _points.end(); ++i) {
+ SelectableControlPoint *cur = (*i);
+ cur->move(cur->position() + delta);
}
}
+ _handles->rotationCenter().move(_handles->rotationCenter().position() + delta);
signal_update.emit();
}
signal_update.emit();
}
-void ControlPointSelection::_selectionUngrabbed()
+void ControlPointSelection::_pointUngrabbed()
{
_dragging = false;
_grabbed_point = NULL;
{
_dragging = false;
_grabbed_point = NULL;
signal_commit.emit(COMMIT_MOUSE_MOVE);
}
signal_commit.emit(COMMIT_MOUSE_MOVE);
}
+bool ControlPointSelection::_pointClicked(SelectableControlPoint *p, GdkEventButton *event)
+{
+ // clicking a selected node should toggle the transform handles between rotate and scale mode,
+ // if they are visible
+ if (held_no_modifiers(*event) && _handles_visible && p->selected()) {
+ toggleTransformHandlesMode();
+ return true;
+ }
+ return false;
+}
+
void ControlPointSelection::_updateTransformHandles(bool preserve_center)
{
if (_dragging) return;
void ControlPointSelection::_updateTransformHandles(bool preserve_center)
{
if (_dragging) return;
_handles->setBounds(*b, preserve_center);
_handles->setVisible(true);
} else if (_one_node_handles && size() == 1) { // only one control point in selection
_handles->setBounds(*b, preserve_center);
_handles->setVisible(true);
} else if (_one_node_handles && size() == 1) { // only one control point in selection
- SelectableControlPoint *p = begin()->first;
+ SelectableControlPoint *p = *begin();
_handles->setBounds(p->bounds());
_handles->rotationCenter().move(p->position());
_handles->rotationCenter().setVisible(false);
_handles->setBounds(p->bounds());
_handles->rotationCenter().move(p->position());
_handles->rotationCenter().setVisible(false);
case GDK_h:
case GDK_H:
if (held_shift(event->key)) {
case GDK_h:
case GDK_H:
if (held_shift(event->key)) {
- // TODO make a method for mode switching
- if (_handles->mode() == TransformHandleSet::MODE_SCALE) {
- _handles->setMode(TransformHandleSet::MODE_ROTATE_SKEW);
- if (size() == 1) _handles->rotationCenter().setVisible(false);
- } else {
- _handles->setMode(TransformHandleSet::MODE_SCALE);
- }
+ toggleTransformHandlesMode();
return true;
}
// any modifiers except shift should cause no action
return true;
}
// any modifiers except shift should cause no action