summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorchr <chr>2017-05-23 19:48:22 +0000
committerchr <chr>2017-05-23 19:48:22 +0000
commitdc80e5d0bf82f005628881134b929aa4838308d5 (patch)
tree0cbe1a5aaf0673816abe5ac2674a7fc3f327b87b /src
parentobject panel: don't scroll to layer when leaving object group (diff)
downloadinkscape-dc80e5d0bf82f005628881134b929aa4838308d5.tar.gz
inkscape-dc80e5d0bf82f005628881134b929aa4838308d5.zip
selection chemistry: implement z-stack order
Bug #1395452 "raise and lower objects" used to stack objects above/below the next overlapping object, which makes it impossible to change the z-order of objects that don't overlap. Fixes also the object manager panel Conflicts: src/selection-chemistry.cpp src/selection-chemistry.h src/sp-item.cpp (bzr r15698.1.7)
Diffstat (limited to 'src')
-rw-r--r--src/object-set.h2
-rw-r--r--src/selection-chemistry.cpp39
-rw-r--r--src/sp-item.cpp8
-rw-r--r--src/sp-item.h4
-rw-r--r--src/ui/dialog/objects.cpp12
-rw-r--r--src/verbs.cpp14
-rw-r--r--src/verbs.h2
7 files changed, 71 insertions, 10 deletions
diff --git a/src/object-set.h b/src/object-set.h
index 02259824c..82d2988c7 100644
--- a/src/object-set.h
+++ b/src/object-set.h
@@ -377,8 +377,10 @@ public:
//z-order management
//in selection-chemistry.cpp
+ void stackUp(bool skip_undo = false);
void raise(bool skip_undo = false);
void raiseToTop(bool skip_undo = false);
+ void stackDown(bool skip_undo = false);
void lower(bool skip_undo = false);
void lowerToBottom(bool skip_undo = false);
void toNextLayer(bool skip_undo = false);
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 39846ba2c..7d5d921b0 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1140,6 +1140,45 @@ void ObjectSet::lowerToBottom(bool skip_undo){
}
}
+void ObjectSet::stackUp(bool skip_undo) {
+ if (isEmpty()) {
+ selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to stack up."));
+ return;
+ }
+
+ std::vector<SPItem*> selection(items().begin(), items().end());
+ sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool);
+
+ for (auto item: selection | boost::adaptors::reversed) {
+ if (!item->raiseOne()) // stop if top was reached
+ break;
+ }
+
+ if(document() && !skip_undo)
+ DocumentUndo::done(document(), SP_VERB_SELECTION_STACK_UP,
+ //TRANSLATORS: undo history: "stack up" means to raise an object of its ordinal position by 1
+ C_("Undo action", "stack up"));
+}
+
+void ObjectSet::stackDown(bool skip_undo) {
+ if (isEmpty()) {
+ selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to stack down."));
+ return;
+ }
+
+ std::vector<SPItem*> selection(items().begin(), items().end());
+ sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool);
+
+ for (auto item: selection) {
+ if (!item->lowerOne()) // stop if bottom was reached
+ break;
+ }
+
+ if(document() && !skip_undo)
+ DocumentUndo::done(document(), SP_VERB_SELECTION_STACK_DOWN,
+ //TRANSLATORS: undo history: "stack down" means to lower an object of its ordinal position by 1
+ C_("Undo action", "stack down"));
+}
void
sp_undo(SPDesktop *desktop, SPDocument *)
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index e2f678957..368f8896c 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -306,15 +306,17 @@ void SPItem::raiseToTop() {
}
}
-void SPItem::raiseOne() {
+bool SPItem::raiseOne() {
auto next_higher = std::find_if(++parent->children.iterator_to(*this), parent->children.end(), &is_item);
if (next_higher != parent->children.end()) {
Inkscape::XML::Node *ref = next_higher->getRepr();
getRepr()->parent()->changeOrder(getRepr(), ref);
+ return true;
}
+ return false;
}
-void SPItem::lowerOne() {
+bool SPItem::lowerOne() {
using Inkscape::Algorithms::find_last_if;
auto next_lower = find_last_if(parent->children.begin(), parent->children.iterator_to(*this), &is_item);
@@ -325,7 +327,9 @@ void SPItem::lowerOne() {
ref = next_lower->getRepr();
}
getRepr()->parent()->changeOrder(getRepr(), ref);
+ return true;
}
+ return false;
}
void SPItem::lowerToBottom() {
diff --git a/src/sp-item.h b/src/sp-item.h
index a03bab9f3..c4d353a1d 100644
--- a/src/sp-item.h
+++ b/src/sp-item.h
@@ -212,8 +212,8 @@ public:
Geom::Affine getRelativeTransform(SPObject const *obj) const;
- void raiseOne();
- void lowerOne();
+ bool raiseOne();
+ bool lowerOne();
void raiseToTop();
void lowerToBottom();
diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp
index c624a8435..55a944afb 100644
--- a/src/ui/dialog/objects.cpp
+++ b/src/ui/dialog/objects.cpp
@@ -722,14 +722,14 @@ bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event)
case GDK_KEY_Page_Up:
{
//Move item(s) up in containing group/layer
- int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_RAISE;
+ int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_STACK_UP;
_fireAction( empty ? SP_VERB_LAYER_RAISE : ch );
break;
}
case GDK_KEY_Page_Down:
{
//Move item(s) down in containing group/layer
- int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_LOWER;
+ int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_STACK_DOWN;
_fireAction( empty ? SP_VERB_LAYER_LOWER : ch );
break;
}
@@ -1182,7 +1182,7 @@ bool ObjectsPanel::_executeAction()
}
else
{
- _fireAction( SP_VERB_SELECTION_RAISE );
+ _fireAction( SP_VERB_SELECTION_STACK_UP );
}
}
break;
@@ -1194,7 +1194,7 @@ bool ObjectsPanel::_executeAction()
}
else
{
- _fireAction( SP_VERB_SELECTION_LOWER );
+ _fireAction( SP_VERB_SELECTION_STACK_DOWN );
}
}
break;
@@ -1903,8 +1903,8 @@ ObjectsPanel::ObjectsPanel() :
_popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
- _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, "gtk-go-up", _("Up"), (int)BUTTON_UP ) );
- _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, "gtk-go-down", _("Down"), (int)BUTTON_DOWN ) );
+ _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_STACK_UP, "gtk-go-up", _("Up"), (int)BUTTON_UP ) );
+ _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_STACK_DOWN, "gtk-go-down", _("Down"), (int)BUTTON_DOWN ) );
_popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
diff --git a/src/verbs.cpp b/src/verbs.cpp
index b7b6da340..22ded60b3 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1179,6 +1179,12 @@ void SelectionVerb::perform(SPAction *action, void *data)
case SP_VERB_SELECTION_LOWER:
selection->lower();
break;
+ case SP_VERB_SELECTION_STACK_UP:
+ selection->stackUp();
+ break;
+ case SP_VERB_SELECTION_STACK_DOWN:
+ selection->stackDown();
+ break;
case SP_VERB_SELECTION_GROUP:
selection->group();
break;
@@ -2685,6 +2691,14 @@ Verb *Verb::_base_verbs[] = {
N_("Raise selection one step"), INKSCAPE_ICON("selection-raise")),
new SelectionVerb(SP_VERB_SELECTION_LOWER, "SelectionLower", N_("_Lower"),
N_("Lower selection one step"), INKSCAPE_ICON("selection-lower")),
+
+
+ new SelectionVerb(SP_VERB_SELECTION_STACK_UP, "SelectionStackUp", N_("_Stack up"),
+ N_("Stack selection one step up"), INKSCAPE_ICON("layer-raise")),
+ new SelectionVerb(SP_VERB_SELECTION_STACK_DOWN, "SelectionStackDown", N_("_Stack down"),
+ N_("Stack selection one step down"), INKSCAPE_ICON("layer-lower")),
+
+
new SelectionVerb(SP_VERB_SELECTION_GROUP, "SelectionGroup", N_("_Group"),
N_("Group selected objects"), INKSCAPE_ICON("object-group")),
new SelectionVerb(SP_VERB_SELECTION_UNGROUP, "SelectionUnGroup", N_("_Ungroup"),
diff --git a/src/verbs.h b/src/verbs.h
index 6846f1f40..a383bc365 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -116,6 +116,8 @@ enum {
SP_VERB_SELECTION_TO_BACK,
SP_VERB_SELECTION_RAISE,
SP_VERB_SELECTION_LOWER,
+ SP_VERB_SELECTION_STACK_UP,
+ SP_VERB_SELECTION_STACK_DOWN,
SP_VERB_SELECTION_GROUP,
SP_VERB_SELECTION_UNGROUP,
SP_VERB_SELECTION_UNGROUP_POP_SELECTION,