summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2016-06-18 08:34:47 +0000
committerjabiertxof <info@marker.es>2016-06-18 08:34:47 +0000
commit2a97e646577aa34a4ec595d183d0b59dd79e3349 (patch)
treec85ca26652f12505e028993459073000e6a2e78e /src
parentattemp to simplify doeffect code on fillet chamfer (diff)
parent[Bug #1454910] Compressed SVG with media error. (diff)
downloadinkscape-2a97e646577aa34a4ec595d183d0b59dd79e3349.tar.gz
inkscape-2a97e646577aa34a4ec595d183d0b59dd79e3349.zip
update to trunk
(bzr r13645.1.160)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/sbasis-geometric.cpp9
-rw-r--r--src/live_effects/lpe-powerstroke.cpp25
-rw-r--r--src/ui/tools/freehand-base.cpp40
-rw-r--r--src/ui/tools/measure-tool.cpp4
-rw-r--r--src/ui/tools/select-tool.cpp257
-rw-r--r--src/ui/tools/select-tool.h3
6 files changed, 138 insertions, 200 deletions
diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp
index 8aaa15144..19eccc451 100644
--- a/src/2geom/sbasis-geometric.cpp
+++ b/src/2geom/sbasis-geometric.cpp
@@ -101,7 +101,7 @@ static SBasis divide_by_t1k(SBasis const &a, int k) {
static D2<SBasis> RescaleForNonVanishingEnds(D2<SBasis> const &MM, double ZERO=1.e-4){
D2<SBasis> M = MM;
//TODO: divide by all the s at once!!!
- while ((M[0].size()>0||M[1].size()>0) &&
+ while ((M[0].size()>1||M[1].size()>1) &&
fabs(M[0].at0())<ZERO &&
fabs(M[1].at0())<ZERO &&
fabs(M[0].at1())<ZERO &&
@@ -109,12 +109,12 @@ static D2<SBasis> RescaleForNonVanishingEnds(D2<SBasis> const &MM, double ZERO=1
M[0] = divide_by_sk(M[0],1);
M[1] = divide_by_sk(M[1],1);
}
- while ((M[0].size()>0||M[1].size()>0) &&
+ while ((M[0].size()>1||M[1].size()>1) &&
fabs(M[0].at0())<ZERO && fabs(M[1].at0())<ZERO){
M[0] = divide_by_t0k(M[0],1);
M[1] = divide_by_t0k(M[1],1);
}
- while ((M[0].size()>0||M[1].size()>0) &&
+ while ((M[0].size()>1||M[1].size()>1) &&
fabs(M[0].at1())<ZERO && fabs(M[1].at1())<ZERO){
M[0] = divide_by_t1k(M[0],1);
M[1] = divide_by_t1k(M[1],1);
@@ -227,9 +227,9 @@ Geom::unitVector(D2<SBasis> const &V_in, double tol, unsigned order){
// -This approach is numerically bad. Find a stable way to rescale V_in to have non vanishing ends.
// -This done, unitVector will have jumps at zeros: fill the gaps with arcs of circles.
D2<SBasis> V = RescaleForNonVanishingEnds(V_in);
-
if (V[0].isZero(0) && V[1].isZero(0))
return Piecewise<D2<SBasis> >(D2<SBasis>(Linear(1),SBasis()));
+
SBasis x = V[0], y = V[1];
SBasis r_eqn1, r_eqn2;
@@ -242,7 +242,6 @@ Geom::unitVector(D2<SBasis> const &V_in, double tol, unsigned order){
r_eqn1 = -(a*x+b*y);
r_eqn2 = Linear(1.)-(a*a+b*b);
-
for (unsigned k=1; k<=order; k++){
double r0 = (k<r_eqn1.size())? r_eqn1.at(k).at0() : 0;
double r1 = (k<r_eqn1.size())? r_eqn1.at(k).at1() : 0;
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index 03102a84a..66c8776b5 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -35,6 +35,7 @@
#include <2geom/ellipse.h>
#include <2geom/circle.h>
#include <2geom/math-utils.h>
+#include "helper/geom.h"
#include <math.h>
#include "spiro.h"
@@ -205,14 +206,13 @@ LPEPowerStroke::~LPEPowerStroke()
}
-
void
LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem)
{
- if (SP_IS_SHAPE(lpeitem)) {
+ if (SP_IS_SHAPE(lpeitem) && offset_points.data().empty()) {
SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem);
std::vector<Geom::Point> points;
- Geom::PathVector const &pathv = SP_SHAPE(lpeitem)->_curve->get_pathvector();
+ Geom::PathVector const &pathv = pathv_to_linear_and_cubic_beziers(SP_SHAPE(lpeitem)->_curve->get_pathvector());
double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed / 2 : 1.;
SPCSSAttr *css = sp_repr_css_attr_new ();
@@ -565,12 +565,11 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
if (path_in.empty()) {
return path_out;
}
-
- // for now, only regard first subpath and ignore the rest
- Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = path_in[0].toPwSb();
-
+ Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers(path_in);
+ Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = pathv[0].toPwSb();
Piecewise<D2<SBasis> > der = derivative(pwd2_in);
- Piecewise<D2<SBasis> > n = rot90(unitVector(der));
+ Piecewise<D2<SBasis> > n = unitVector(der,0.0001);
+ n = rot90(n);
offset_points.set_pwd2(pwd2_in, n);
LineCapType end_linecap = static_cast<LineCapType>(end_linecap_type.get_value());
@@ -583,7 +582,7 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
if (sort_points) {
sort(ts.begin(), ts.end(), compare_offsets);
}
- if (path_in[0].closed()) {
+ if (pathv[0].closed()) {
// add extra points for interpolation between first and last point
Point first_point = ts.front();
Point last_point = ts.back();
@@ -605,7 +604,6 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
for (std::size_t i = 0, e = ts.size(); i < e; ++i) {
ts[i][Geom::X] *= xcoord_scaling;
}
-
// create stroke path where points (x,y) := (t, offset)
Geom::Interpolate::Interpolator *interpolator = Geom::Interpolate::Interpolator::create(static_cast<Geom::Interpolate::InterpolatorType>(interpolator_type.get_value()));
if (Geom::Interpolate::CubicBezierJohan *johan = dynamic_cast<Geom::Interpolate::CubicBezierJohan*>(interpolator)) {
@@ -631,7 +629,6 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
x = portion(x, rtsmin.at(0), rtsmax.at(0));
y = portion(y, rtsmin.at(0), rtsmax.at(0));
}
-
LineJoinType jointype = static_cast<LineJoinType>(linejoin_type.get_value());
Piecewise<D2<SBasis> > pwd2_out = compose(pwd2_in,x) + y*compose(n,x);
@@ -639,8 +636,7 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
Geom::Path fixed_path = path_from_piecewise_fix_cusps( pwd2_out, y, jointype, miter_limit, LPE_CONVERSION_TOLERANCE);
Geom::Path fixed_mirrorpath = path_from_piecewise_fix_cusps( mirrorpath, reverse(y), jointype, miter_limit, LPE_CONVERSION_TOLERANCE);
-
- if (path_in[0].closed()) {
+ if (pathv[0].closed()) {
fixed_path.close(true);
path_out.push_back(fixed_path);
fixed_mirrorpath.close(true);
@@ -684,7 +680,6 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
}
fixed_path.append(fixed_mirrorpath);
-
switch (start_linecap) {
case LINECAP_ZERO_WIDTH:
// do nothing
@@ -720,11 +715,9 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in)
break;
}
}
-
fixed_path.close(true);
path_out.push_back(fixed_path);
}
-
return path_out;
}
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index c98ecb686..7697cd59c 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -236,38 +236,14 @@ static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points
Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE();
static_cast<LPEPowerStroke*>(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_ACTIVE_DOCUMENT);
- style.mergeString(style_str);
- stroke_width = style.stroke_width.computed;
- }
-
- std::ostringstream s;
- s.imbue(std::locale::classic());
- s << points[0][Geom::X] << "," << stroke_width / 2.;
-
// write powerstroke parameters:
lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth");
lpe->getRepr()->setAttribute("end_linecap_type", "zerowidth");
- lpe->getRepr()->setAttribute("cusp_linecap_type", "round");
lpe->getRepr()->setAttribute("sort_points", "true");
lpe->getRepr()->setAttribute("interpolator_type", "CubicBezierJohan");
lpe->getRepr()->setAttribute("interpolator_beta", "0.2");
- lpe->getRepr()->setAttribute("offset_points", s.str().c_str());
+ lpe->getRepr()->setAttribute("miter_limit", "4");
+ lpe->getRepr()->setAttribute("linejoin_type", "extrp_arc");
}
static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *item)
@@ -341,12 +317,14 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
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");
+ const char *stroke_width = sp_repr_css_property(css_item, "stroke-width", "0");
+ double swidth;
+ sp_svg_number_read_d(stroke_width, &swidth);
static SPItem *bend_item;
#define SHAPE_LENGTH 10
#define SHAPE_HEIGHT 10
-
if(shape == LAST_APPLIED){
shape = previous_shape_type;
@@ -363,7 +341,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
{
// "triangle in"
std::vector<Geom::Point> points(1);
- points[0] = Geom::Point(0., SHAPE_HEIGHT/2);
+ points[0] = Geom::Point(0., swidth/2);
+ points[0] *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse();
spdc_apply_powerstroke_shape(points, dc, item);
shape_applied = true;
@@ -374,7 +353,9 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
// "triangle out"
guint curve_length = curve->get_segment_count();
std::vector<Geom::Point> points(1);
- points[0] = Geom::Point((double)curve_length, SHAPE_HEIGHT/2);
+ points[0] = Geom::Point(0, swidth/2);
+ points[0] *= i2anc_affine(static_cast<SPItem *>(item->parent), NULL).inverse();
+ points[0][Geom::X] = (double)curve_length;
spdc_apply_powerstroke_shape(points, dc, item);
shape_applied = true;
@@ -455,7 +436,6 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
if(previous_shape_type == CLIPBOARD){
if(previous_shape_pathv.size() != 0){
spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item);
-
shape_applied = true;
shape = CLIPBOARD;
} else{
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index 0977729ae..63e2460ec 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -346,13 +346,13 @@ MeasureTool::MeasureTool()
end_p = readMeasurePoint(false);
dimension_offset = 35;
// create the knots
- this->knot_start = new SPKnot(desktop, N_("Measure start, <b>Shift+Click</b> for position dialog"));
+ this->knot_start = new SPKnot(desktop, _("Measure start, <b>Shift+Click</b> for position dialog"));
this->knot_start->setMode(SP_KNOT_MODE_XOR);
this->knot_start->setFill(MT_KNOT_COLOR_NORMAL, MT_KNOT_COLOR_MOUSEOVER, MT_KNOT_COLOR_MOUSEOVER);
this->knot_start->setStroke(0x0000007f, 0x0000007f, 0x0000007f);
this->knot_start->setShape(SP_KNOT_SHAPE_CIRCLE);
this->knot_start->updateCtrl();
- this->knot_end = new SPKnot(desktop, N_("Measure end, <b>Shift+Click</b> for position dialog"));
+ this->knot_end = new SPKnot(desktop, _("Measure end, <b>Shift+Click</b> for position dialog"));
this->knot_end->setMode(SP_KNOT_MODE_XOR);
this->knot_end->setFill(MT_KNOT_COLOR_NORMAL, MT_KNOT_COLOR_MOUSEOVER, MT_KNOT_COLOR_MOUSEOVER);
this->knot_end->setStroke(0x0000007f, 0x0000007f, 0x0000007f);
diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp
index 905e38f2b..b5ec3d88e 100644
--- a/src/ui/tools/select-tool.cpp
+++ b/src/ui/tools/select-tool.cpp
@@ -65,7 +65,7 @@ static gint rb_escaped = 0; // if non-zero, rubberband was canceled by esc, so t
static gint drag_escaped = 0; // if non-zero, drag was canceled by esc
const std::string& SelectTool::getPrefsPath() {
- return SelectTool::prefsPath;
+ return SelectTool::prefsPath;
}
const std::string SelectTool::prefsPath = "/tools/select";
@@ -111,7 +111,6 @@ SelectTool::SelectTool()
//static gint tolerance = 0;
//static bool within_tolerance = false;
static bool is_cycling = false;
-static bool moved_while_cycling = false;
SelectTool::~SelectTool() {
@@ -297,7 +296,7 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) {
} else {
GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas()));
- this->dragging = TRUE;
+ this->dragging = TRUE;
this->moved = FALSE;
gdk_window_set_cursor(window, CursorSelectDragging);
@@ -347,11 +346,11 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) {
break;
}
case GDK_LEAVE_NOTIFY:
- if (!desktop->isWaitingCursor() && !this->dragging) {
+ if (!desktop->isWaitingCursor() && !this->dragging) {
GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas()));
gdk_window_set_cursor(window, this->cursor);
- }
+ }
break;
case GDK_KEY_PRESS:
@@ -379,61 +378,75 @@ bool SelectTool::item_handler(SPItem* item, GdkEvent* event) {
}
if (!ret) {
- ret = ToolBase::item_handler(item, event);
+ ret = ToolBase::item_handler(item, event);
}
return ret;
}
void SelectTool::sp_select_context_cycle_through_items(Inkscape::Selection *selection, GdkEventScroll *scroll_event, bool shift_pressed) {
- if (this->cycling_cur_item == this->cycling_items.end()) {
+ if ( this->cycling_items.empty() )
return;
- }
Inkscape::DrawingItem *arenaitem;
- SPItem *item = *cycling_cur_item;
- g_assert(item != NULL);
- // Deactivate current item
- if (std::find(cycling_items_selected_before.begin(), cycling_items_selected_before.end(), item) == cycling_items_selected_before.end() && selection->includes(item)) {
- selection->remove(item);
+ if(cycling_cur_item) {
+ arenaitem = cycling_cur_item->get_arenaitem(desktop->dkey);
+ arenaitem->setOpacity(0.3);
}
- arenaitem = item->get_arenaitem(desktop->dkey);
- arenaitem->setOpacity(0.3);
-
// Find next item and activate it
- std::vector<SPItem *>::iterator next = this->cycling_cur_item;
+
+
+ std::vector<SPItem *>::iterator next = cycling_items.end();
+
if (scroll_event->direction == GDK_SCROLL_UP) {
- ++next;
- if (next == this->cycling_items.end() && this->cycling_wrap) {
- next = this->cycling_items.begin();
+ if (! cycling_cur_item) {
+ next = cycling_items.begin();
+ } else {
+ next = std::find( cycling_items.begin(), cycling_items.end(), cycling_cur_item );
+ g_assert (next != cycling_items.end());
+ next++;
+ if (next == cycling_items.end())
+ if ( cycling_wrap )
+ next = cycling_items.begin();
+ else
+ next--;
}
- } else {
- if(next == this->cycling_items.begin()) {
- next = this->cycling_items.end();
+ } else {
+ if (! cycling_cur_item) {
+ next = cycling_items.end();
+ next--;
+ } else {
+ next = std::find( cycling_items.begin(), cycling_items.end(), cycling_cur_item );
+ g_assert (next != cycling_items.end());
+ if (next == cycling_items.begin()){
+ if ( cycling_wrap ) {
+ next = cycling_items.end();
+ next--;
+ }
+ } else {
+ next--;
+ }
}
- --next;
}
- if (next!=this->cycling_items.end()) {
- this->cycling_cur_item = next;
- item = *next;
- g_assert(item != NULL);
- }
+ this->cycling_cur_item = *next;
+ g_assert(next != cycling_items.end());
+ g_assert(cycling_cur_item != NULL);
- arenaitem = item->get_arenaitem(desktop->dkey);
+ arenaitem = cycling_cur_item->get_arenaitem(desktop->dkey);
arenaitem->setOpacity(1.0);
if (shift_pressed) {
- selection->add(item);
+ selection->add(cycling_cur_item);
} else {
- selection->set(item);
+ selection->set(cycling_cur_item);
}
}
void SelectTool::sp_select_context_reset_opacities() {
- for (std::vector<SPItem *>::const_iterator l = this->cycling_items.begin(); l != this->cycling_items.end(); ++l ) {
+ for (std::vector<SPItem *>::const_iterator l = this->cycling_items_cmp.begin(); l != this->cycling_items_cmp.end(); ++l ) {
SPItem *item = *l;
if (item) {
Inkscape::DrawingItem *arenaitem = item->get_arenaitem(desktop->dkey);
@@ -443,10 +456,8 @@ void SelectTool::sp_select_context_reset_opacities() {
}
}
- this->cycling_items.clear();
- this->cycling_items_selected_before.clear();
- this->cycling_cur_item = this->cycling_items.end();
this->cycling_items_cmp.clear();
+ this->cycling_cur_item = NULL;
}
bool SelectTool::root_handler(GdkEvent* event) {
@@ -533,11 +544,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
case GDK_MOTION_NOTIFY:
{
- if (is_cycling) {
- moved_while_cycling = true;
- }
-
- tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+ tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
if ((event->motion.state & GDK_BUTTON1_MASK) && !this->space_panning) {
Geom::Point const motion_pt(event->motion.x, event->motion.y);
@@ -703,7 +710,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
if (r->is_started() && !within_tolerance) {
// this was a rubberband drag
- std::vector<SPItem*> items;
+ std::vector<SPItem*> items;
if (r->getMode() == RUBBERBAND_MODE_RECT) {
Geom::OptRect const b = r->getRectangle();
@@ -796,107 +803,67 @@ bool SelectTool::root_handler(GdkEvent* event) {
break;
case GDK_SCROLL: {
- GdkEventScroll *scroll_event = (GdkEventScroll*) event;
-
- if (scroll_event->state & GDK_MOD1_MASK) { // alt modified pressed
- if (moved_while_cycling) {
- moved_while_cycling = false;
- this->sp_select_context_reset_opacities();
- }
-
- is_cycling = true;
-
- bool shift_pressed = scroll_event->state & GDK_SHIFT_MASK;
-
- /* Rebuild list of items underneath the mouse pointer */
- Geom::Point p = desktop->d2w(desktop->point());
- 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!=this->cycling_items.end() ? (*(this->cycling_cur_item)) : NULL;
- this->cycling_items.clear();
- this->cycling_cur_item = this->cycling_items.end();
- while(item != NULL) {
- this->cycling_items.push_back(item);
- item = desktop->getItemAtPoint(p, true, item);
- }
-
- /* Compare current item list with item list during previous scroll ... */
- bool item_lists_differ = this->cycling_items != this->cycling_items_cmp;
- /* If list of items under mouse pointer hasn't changed ... */
- if (!item_lists_differ) {
- // ... find current item in the freshly built list and continue cycling ...
- // TODO: This wouldn't be necessary if cycling_cur_item pointed to an element of cycling_items_cmp instead
- this->cycling_cur_item = std::find(this->cycling_items.begin(), this->cycling_items.end(), tmp_cur_item);
- g_assert(this->cycling_cur_item != this->cycling_items.end() || this->cycling_items.empty());
- } else {
- // ... otherwise reset opacities for outdated items ...
- Inkscape::DrawingItem *arenaitem;
-
- for (std::vector<SPItem *>::const_iterator l = this->cycling_items_cmp.begin(); l != this->cycling_items_cmp.end(); ++l) {
- SPItem *item = *l;
- 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 (std::find(this->cycling_items_selected_before.begin(),this->cycling_items_selected_before.end(), item)==this->cycling_items_selected_before.end() && selection->includes(item)) {
- selection->remove(item);
- }
- }
- }
+ GdkEventScroll *scroll_event = (GdkEventScroll*) event;
- // ... clear the lists ...
+ if ( ! (scroll_event->state & GDK_MOD1_MASK)) // do nothing specific if alt was not pressed
+ break;
- this->cycling_items_cmp.clear();
- this->cycling_items_selected_before.clear();
- this->cycling_cur_item = this->cycling_items.end();
+ bool shift_pressed = scroll_event->state & GDK_SHIFT_MASK;
+ is_cycling = true;
- // ... and rebuild them with the new items.
- this->cycling_items_cmp = (this->cycling_items);
+ /* Rebuild list of items underneath the mouse pointer */
+ Geom::Point p = desktop->d2w(desktop->point());
+ SPItem *item = desktop->getItemAtPoint(p, true, NULL);
+ this->cycling_items.clear();
- for(std::vector<SPItem *>::const_iterator l = this->cycling_items.begin(); l != this->cycling_items.end(); ++l) {
- SPItem *item =*l;
- if (item) {
- arenaitem = item->get_arenaitem(desktop->dkey);
- arenaitem->setOpacity(0.3);
+ SPItem *tmp = NULL;
+ while(item != NULL) {
+ this->cycling_items.push_back(item);
+ item = desktop->getItemAtPoint(p, true, item);
+ if (selection->includes(item)) tmp = item;
+ }
- if (selection->includes(item)) {
- // already selected items are stored separately, too
- this->cycling_items_selected_before.push_back(item);
- }
- } else {
- g_assert_not_reached();
- }
+ /* Compare current item list with item list during previous scroll ... */
+ bool item_lists_differ = this->cycling_items != this->cycling_items_cmp;
+
+ if(item_lists_differ) {
+ this->sp_select_context_reset_opacities();
+ for (std::vector<SPItem *>::const_iterator l = this->cycling_items_cmp.begin(); l != this->cycling_items_cmp.end(); ++l)
+ selection->remove(*l); // deselects the previous content of the cycling loop
+ this->cycling_items_cmp = (this->cycling_items);
+
+ // set opacities in new stack
+ for(std::vector<SPItem *>::const_iterator l = this->cycling_items.begin(); l != this->cycling_items.end(); ++l) {
+ SPItem *item =*l;
+ if (item) {
+ Inkscape::DrawingItem *arenaitem = item->get_arenaitem(desktop->dkey);
+ arenaitem->setOpacity(0.3);
}
-
- // set the current item to the bottommost one so that the cycling step below re-starts at the top
- this->cycling_cur_item = this->cycling_items.end();
- this->cycling_cur_item--;
}
+ }
+ if(!cycling_cur_item) cycling_cur_item = tmp;
- this->cycling_wrap = prefs->getBool("/options/selection/cycleWrap", true);
+ this->cycling_wrap = prefs->getBool("/options/selection/cycleWrap", true);
- // Cycle through the items underneath the mouse pointer, one-by-one
- this->sp_select_context_cycle_through_items(selection, scroll_event, shift_pressed);
+ // Cycle through the items underneath the mouse pointer, one-by-one
+ this->sp_select_context_cycle_through_items(selection, scroll_event, shift_pressed);
- ret = TRUE;
+ ret = TRUE;
- GtkWindow *w =GTK_WINDOW(gtk_widget_get_toplevel( GTK_WIDGET(desktop->canvas) ));
- if (w)
- {
- gtk_window_present(w);
- gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
- }
+ GtkWindow *w =GTK_WINDOW(gtk_widget_get_toplevel( GTK_WIDGET(desktop->canvas) ));
+ if (w) {
+ gtk_window_present(w);
+ gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
}
break;
}
case GDK_KEY_PRESS: // keybindings for select context
- {
- {
- guint keyval = get_group0_keyval(&event->key);
-
+ {
+ {
+ guint keyval = get_group0_keyval(&event->key);
+
bool alt = ( MOD__ALT(event)
|| (keyval == GDK_KEY_Alt_L)
|| (keyval == GDK_KEY_Alt_R)
@@ -924,7 +891,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
// if Alt and nonempty selection, show moving cursor ("move selected"):
if (alt && !selection->isEmpty() && !desktop->isWaitingCursor()) {
- GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas()));
+ GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (desktop->getCanvas()));
gdk_window_set_cursor(window, CursorSelectDragging);
}
@@ -945,15 +912,15 @@ bool SelectTool::root_handler(GdkEvent* event) {
if (MOD__ALT(event)) { // alt
if (MOD__SHIFT(event)) {
- sp_selection_move_screen(desktop->getSelection(), mul*-10, 0); // shift
+ sp_selection_move_screen(desktop->getSelection(), mul*-10, 0); // shift
} else {
- sp_selection_move_screen(desktop->getSelection(), mul*-1, 0); // no shift
+ sp_selection_move_screen(desktop->getSelection(), mul*-1, 0); // no shift
}
} else { // no alt
if (MOD__SHIFT(event)) {
- sp_selection_move(desktop->getSelection(), mul*-10*nudge, 0); // shift
+ sp_selection_move(desktop->getSelection(), mul*-10*nudge, 0); // shift
} else {
- sp_selection_move(desktop->getSelection(), mul*-nudge, 0); // no shift
+ sp_selection_move(desktop->getSelection(), mul*-nudge, 0); // no shift
}
}
@@ -968,15 +935,15 @@ bool SelectTool::root_handler(GdkEvent* event) {
if (MOD__ALT(event)) { // alt
if (MOD__SHIFT(event)) {
- sp_selection_move_screen(desktop->getSelection(), 0, mul*10); // shift
+ sp_selection_move_screen(desktop->getSelection(), 0, mul*10); // shift
} else {
- sp_selection_move_screen(desktop->getSelection(), 0, mul*1); // no shift
+ sp_selection_move_screen(desktop->getSelection(), 0, mul*1); // no shift
}
} else { // no alt
if (MOD__SHIFT(event)) {
- sp_selection_move(desktop->getSelection(), 0, mul*10*nudge); // shift
+ sp_selection_move(desktop->getSelection(), 0, mul*10*nudge); // shift
} else {
- sp_selection_move(desktop->getSelection(), 0, mul*nudge); // no shift
+ sp_selection_move(desktop->getSelection(), 0, mul*nudge); // no shift
}
}
@@ -991,15 +958,15 @@ bool SelectTool::root_handler(GdkEvent* event) {
if (MOD__ALT(event)) { // alt
if (MOD__SHIFT(event)) {
- sp_selection_move_screen(desktop->getSelection(), mul*10, 0); // shift
+ sp_selection_move_screen(desktop->getSelection(), mul*10, 0); // shift
} else {
- sp_selection_move_screen(desktop->getSelection(), mul*1, 0); // no shift
+ sp_selection_move_screen(desktop->getSelection(), mul*1, 0); // no shift
}
} else { // no alt
if (MOD__SHIFT(event)) {
- sp_selection_move(desktop->getSelection(), mul*10*nudge, 0); // shift
+ sp_selection_move(desktop->getSelection(), mul*10*nudge, 0); // shift
} else {
- sp_selection_move(desktop->getSelection(), mul*nudge, 0); // no shift
+ sp_selection_move(desktop->getSelection(), mul*nudge, 0); // no shift
}
}
@@ -1014,15 +981,15 @@ bool SelectTool::root_handler(GdkEvent* event) {
if (MOD__ALT(event)) { // alt
if (MOD__SHIFT(event)) {
- sp_selection_move_screen(desktop->getSelection(), 0, mul*-10); // shift
+ sp_selection_move_screen(desktop->getSelection(), 0, mul*-10); // shift
} else {
- sp_selection_move_screen(desktop->getSelection(), 0, mul*-1); // no shift
+ sp_selection_move_screen(desktop->getSelection(), 0, mul*-1); // no shift
}
} else { // no alt
if (MOD__SHIFT(event)) {
- sp_selection_move(desktop->getSelection(), 0, mul*-10*nudge); // shift
+ sp_selection_move(desktop->getSelection(), 0, mul*-10*nudge); // shift
} else {
- sp_selection_move(desktop->getSelection(), 0, mul*-nudge); // no shift
+ sp_selection_move(desktop->getSelection(), 0, mul*-nudge); // no shift
}
}
@@ -1166,7 +1133,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
break;
}
break;
- }
+ }
case GDK_KEY_RELEASE: {
guint keyval = get_group0_keyval(&event->key);
if (key_is_a_modifier (keyval)) {
@@ -1207,7 +1174,7 @@ bool SelectTool::root_handler(GdkEvent* event) {
}
if (!ret) {
- ret = ToolBase::root_handler(event);
+ ret = ToolBase::root_handler(event);
}
return ret;
diff --git a/src/ui/tools/select-tool.h b/src/ui/tools/select-tool.h
index af183b1ca..420374661 100644
--- a/src/ui/tools/select-tool.h
+++ b/src/ui/tools/select-tool.h
@@ -42,8 +42,7 @@ public:
std::vector<SPItem *> cycling_items;
std::vector<SPItem *> cycling_items_cmp;
- std::vector<SPItem *> cycling_items_selected_before;
- std::vector<SPItem *>::iterator cycling_cur_item;
+ SPItem *cycling_cur_item;
bool cycling_wrap;
SPItem *item;