From 01eb0fed31992f7278b4bad5559f693804293db0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 23 Jun 2015 17:19:44 +0200 Subject: [PATCH] Properly track the selection center and use it for the tool handle position Fixes #34 --- UM/Scene/Selection.py | 41 ++++++++++---------- UM/Scene/ToolHandle.py | 7 ++++ UM/Tool.py | 7 ---- plugins/Tools/RotateTool/RotateTool.py | 1 - plugins/Tools/ScaleTool/ScaleTool.py | 1 - plugins/Tools/TranslateTool/TranslateTool.py | 1 - 6 files changed, 28 insertions(+), 30 deletions(-) diff --git a/UM/Scene/Selection.py b/UM/Scene/Selection.py index b8b0e05d9b..e1c0ea104b 100644 --- a/UM/Scene/Selection.py +++ b/UM/Scene/Selection.py @@ -9,12 +9,16 @@ class Selection: def add(cls, object): if object not in cls.__selection: cls.__selection.append(object) + object.transformationChanged.connect(cls._onTransformationChanged) + cls._onTransformationChanged(object) cls.selectionChanged.emit() @classmethod def remove(cls, object): if object in cls.__selection: cls.__selection.remove(object) + object.transformationChanged.disconnect(cls._onTransformationChanged) + cls._onTransformationChanged(object) cls.selectionChanged.emit() @classmethod @@ -44,29 +48,14 @@ def hasSelection(cls): selectionChanged = Signal() - ## Calculate the average position of the selection. + selectionCenterChanged = Signal() + @classmethod - def getAveragePosition(cls): + def getSelectionCenter(cls): if not cls.__selection: - return Vector(0, 0, 0) - - if len(cls.__selection) == 1: - node = cls.__selection[0] - if node.getBoundingBox() and node.getBoundingBox().isValid(): - return node.getBoundingBox().center - else: - return node.getWorldPosition() - - pos = Vector() - for node in cls.__selection: - if node.getBoundingBox() and node.getBoundingBox().isValid(): - pos += node.getBoundingBox().center - else: - pos += node.getWorldPosition() - - pos /= len(cls.__selection) + cls.__selection_center = Vector(0, 0, 0) - return pos + return cls.__selection_center ## Apply an operation to the entire selection # @@ -96,4 +85,16 @@ def applyOperation(cls, operation, *args, **kwargs): op.push() + @classmethod + def _onTransformationChanged(cls, node): + cls.__selection_center = Vector(0, 0, 0) + + for object in cls.__selection: + cls.__selection_center += object.getWorldPosition() + + cls.__selection_center /= len(cls.__selection) + + cls.selectionCenterChanged.emit() + __selection = [] + __selection_center = Vector(0, 0, 0) diff --git a/UM/Scene/ToolHandle.py b/UM/Scene/ToolHandle.py index b4a73a0297..d92f1344fb 100644 --- a/UM/Scene/ToolHandle.py +++ b/UM/Scene/ToolHandle.py @@ -10,6 +10,8 @@ from UM.Math.Color import Color from UM.Math.Vector import Vector +from UM.Scene.Selection import Selection + class ToolHandle(SceneNode.SceneNode): NoAxis = 1 XAxis = 2 @@ -39,6 +41,8 @@ def __init__(self, parent = None): self.setCalculateBoundingBox(False) + Selection.selectionCenterChanged.connect(self._onSelectionCenterChanged) + def getLineMesh(self): return self._line_mesh @@ -114,3 +118,6 @@ def isAxis(cls, value): ZAxis: ZAxisColor, AllAxis: AllAxisColor } + + def _onSelectionCenterChanged(self): + self.setPosition(Selection.getSelectionCenter()) diff --git a/UM/Tool.py b/UM/Tool.py index ad5a04e091..413906946b 100644 --- a/UM/Tool.py +++ b/UM/Tool.py @@ -43,7 +43,6 @@ def event(self, event): if event.type == Event.ToolActivateEvent: if Selection.hasSelection() and self._handle: self._handle.setParent(self.getController().getScene().getRoot()) - self._handle.setPosition(Selection.getAveragePosition()) if event.type == Event.MouseMoveEvent and self._handle: if self._locked_axis: @@ -61,12 +60,6 @@ def event(self, event): return False - ## Update the position of the ToolHandle - # \sa ToolHandle - def updateHandlePosition(self): - if Selection.hasSelection(): - self._handle.setPosition(Selection.getAveragePosition()) - ## Convenience function def getController(self): return self._controller diff --git a/plugins/Tools/RotateTool/RotateTool.py b/plugins/Tools/RotateTool/RotateTool.py index 2b2e0f379d..aabb16f439 100644 --- a/plugins/Tools/RotateTool/RotateTool.py +++ b/plugins/Tools/RotateTool/RotateTool.py @@ -112,7 +112,6 @@ def event(self, event): Selection.applyOperation(RotateOperation, rotation) self.setDragStart(event.x, event.y) - self.updateHandlePosition() if event.type == Event.MouseReleaseEvent: if self.getDragPlane(): diff --git a/plugins/Tools/ScaleTool/ScaleTool.py b/plugins/Tools/ScaleTool/ScaleTool.py index ed33ecab96..b25193e1ec 100644 --- a/plugins/Tools/ScaleTool/ScaleTool.py +++ b/plugins/Tools/ScaleTool/ScaleTool.py @@ -124,7 +124,6 @@ def event(self, event): Selection.applyOperation(ScaleOperation, scale) self._drag_length = (handle_position - drag_position).length() - self.updateHandlePosition() return True if event.type == Event.MouseReleaseEvent: diff --git a/plugins/Tools/TranslateTool/TranslateTool.py b/plugins/Tools/TranslateTool/TranslateTool.py index c08af902ce..dd7661a67a 100644 --- a/plugins/Tools/TranslateTool/TranslateTool.py +++ b/plugins/Tools/TranslateTool/TranslateTool.py @@ -87,7 +87,6 @@ def event(self, event): Selection.applyOperation(TranslateOperation, drag) self.setDragStart(event.x, event.y) - self.updateHandlePosition() return True if event.type == Event.MouseReleaseEvent: