Skip to content

Commit

Permalink
Removed singleton UM.OperationStack, merged with CuraActions
Browse files Browse the repository at this point in the history
 Removed ActiveTool singleton added to controller singleton

CURA-7812
  • Loading branch information
saumyaj3 committed Jan 9, 2024
1 parent 4f8f2f1 commit 53e7b5d
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 61 deletions.
6 changes: 4 additions & 2 deletions UM/Qt/Bindings/ActiveToolProxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@

import os.path

from ...Decorators import deprecated


@deprecated("ActiveToolProxy is depricated and will be removed in major SDK release")
class ActiveToolProxy(QObject):
def __init__(self, parent = None):
super().__init__(parent)
Expand All @@ -21,8 +24,6 @@ def __init__(self, parent = None):
self._properties = {}
Application.getInstance().getController().activeToolChanged.connect(self._onActiveToolChanged)
self._onActiveToolChanged()


self._properties_proxy = ContainerProxy.ContainerProxy(self._properties)

activeToolChanged = pyqtSignal()
Expand Down Expand Up @@ -124,5 +125,6 @@ def _updateProperties(self):

self.propertiesChanged.emit()

@deprecated("createActiveToolProxy is depricated and will be removed in major SDK release")
def createActiveToolProxy(engine, script_engine):
return ActiveToolProxy()
2 changes: 1 addition & 1 deletion UM/Qt/Bindings/ApplicationProxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from UM.Application import Application
from UM.Decorators import deprecated

@deprecated
@deprecated("ApplicationProxy is deprecated and will be removed in major SDK release")
class ApplicationProxy(QObject):
def __init__(self, parent = None):
super().__init__(parent)
Expand Down
10 changes: 0 additions & 10 deletions UM/Qt/Bindings/Bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from . import ControllerProxy
from . import BackendProxy
from . import ResourcesProxy
from . import OperationStackProxy
from . import Window
from UM.Mesh.MeshFileHandler import MeshFileHandler
from UM.Workspace.WorkspaceFileHandler import WorkspaceFileHandler
Expand All @@ -21,7 +20,6 @@
from . import OpenGLContextProxy
from . import PointingRectangle
from UM.ColorImage import ColorImage
from . import ActiveToolProxy
from . import OutputDevicesModel
from . import SelectionProxy
from . import OutputDeviceManagerProxy
Expand All @@ -39,13 +37,11 @@
from UM.Settings.Models.SettingPreferenceVisibilityHandler import SettingPreferenceVisibilityHandler
from UM.Settings.Models.ContainerPropertyProvider import ContainerPropertyProvider


class Bindings:
@classmethod
def createControllerProxy(self, engine, script_engine):
return ControllerProxy.ControllerProxy()


@classmethod
def createBackendProxy(self, engine, script_engine):
return BackendProxy.BackendProxy()
Expand All @@ -54,10 +50,6 @@ def createBackendProxy(self, engine, script_engine):
def createResourcesProxy(cls, engine, script_engine):
return ResourcesProxy.ResourcesProxy()

@classmethod
def createOperationStackProxy(cls, engine, script_engine):
return OperationStackProxy.OperationStackProxy()

@classmethod
def createOpenGLContextProxy(cls, engine, script_engine):
return OpenGLContextProxy.OpenGLContextProxy()
Expand All @@ -76,11 +68,9 @@ def register(self):
qmlRegisterSingletonType(ControllerProxy.ControllerProxy, "UM", 1, 0, Bindings.createControllerProxy, "Controller")
qmlRegisterSingletonType(BackendProxy.BackendProxy, "UM", 1, 0, Bindings.createBackendProxy, "Backend")
qmlRegisterSingletonType(ResourcesProxy.ResourcesProxy, "UM", 1, 0, Bindings.createResourcesProxy, "Resources")
qmlRegisterSingletonType(OperationStackProxy.OperationStackProxy, "UM", 1, 0, Bindings.createOperationStackProxy, "OperationStack")
qmlRegisterSingletonType(MeshFileHandler, "UM", 1, 0, MeshFileHandler.getInstance, "MeshFileHandler")
qmlRegisterSingletonType(PreferencesProxy.PreferencesProxy, "UM", 1, 0, PreferencesProxy.createPreferencesProxy, "Preferences")
qmlRegisterSingletonType(Theme.Theme, "UM", 1, 0, Theme.createTheme, "Theme")
qmlRegisterSingletonType(ActiveToolProxy.ActiveToolProxy, "UM", 1, 0, ActiveToolProxy.createActiveToolProxy, "ActiveTool")
qmlRegisterSingletonType(SelectionProxy.SelectionProxy, "UM", 1, 0, SelectionProxy.createSelectionProxy, "Selection")

qmlRegisterUncreatableType(Duration, "UM", 1, 0, "", "Duration")
Expand Down
115 changes: 114 additions & 1 deletion UM/Qt/Bindings/ControllerProxy.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# Copyright (c) 2022 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.
import os
from typing import Any

from PyQt6.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty
from PyQt6.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty, QUrl, QVariant

from UM.Application import Application
from UM.Scene.Selection import Selection
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation

from . import ContainerProxy
from ...Logger import Logger
from ...PluginRegistry import PluginRegistry


class ControllerProxy(QObject):
def __init__(self, parent = None):
Expand All @@ -17,6 +23,14 @@ def __init__(self, parent = None):
self._selection_pass = None
self._tools_enabled = True

self._active_tool = None
self._properties = {}
Application.getInstance().getController().activeToolChanged.connect(self._onActiveToolChanged)
self._onActiveToolChanged()


self._properties_proxy = ContainerProxy.ContainerProxy(self._properties)

# bind needed signals
self._controller.toolOperationStarted.connect(self._onToolOperationStarted)
self._controller.toolOperationStopped.connect(self._onToolOperationStopped)
Expand All @@ -26,6 +40,7 @@ def __init__(self, parent = None):
toolsEnabledChanged = pyqtSignal()
activeStageChanged = pyqtSignal()
activeViewChanged = pyqtSignal()
activeToolChanged = pyqtSignal()

@pyqtProperty(bool, notify = toolsEnabledChanged)
def toolsEnabled(self):
Expand Down Expand Up @@ -116,3 +131,101 @@ def _onActiveStageChanged(self):

def _onActiveViewChanged(self):
self.activeViewChanged.emit()


@pyqtProperty(bool, notify = activeToolChanged)
def valid(self):
return self._active_tool != None

@pyqtProperty(QUrl, notify = activeToolChanged)
def activeToolPanel(self):
if not self._active_tool:
return QUrl()
try:
panel_file = self._active_tool.getMetaData()["tool_panel"]
except KeyError:
return QUrl()

return QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self._active_tool.getPluginId()), panel_file))

@pyqtSlot(str)
def triggerAction(self, action):
if not self._active_tool:
return
if not hasattr(self._active_tool, action):
Logger.log("w", "Trying to call non-existing action {action} of tool {tool}.".format(action = action, tool = self._active_tool.getPluginId()))
return

action = getattr(self._active_tool, action)
if action:
action()

@pyqtSlot(str, QVariant)
def triggerActionWithData(self, action: str, data: Any):
"""Triggers one of the tools' actions and provides additional parameters to the action.
The additional data is passed as a parameter to the function call of the
action.
:param action: The action to trigger.
:param data: The additional data to call
"""

if not self._active_tool:
return
if not hasattr(self._active_tool, action):
Logger.log("w", "Trying to call non-existing action {action} of tool {tool}.".format(action = action, tool = self._active_tool.getPluginId()))
return

if hasattr(self._active_tool, action):
getattr(self._active_tool, action)(data)

propertiesChanged = pyqtSignal()
@pyqtProperty(QObject, notify = propertiesChanged)
def properties(self):
return self._properties_proxy

@pyqtSlot()
def forceUpdate(self):
self._updateProperties()

@pyqtSlot(str, "QVariant")
def setProperty(self, property, value):
if not self._active_tool:
return
if hasattr(self._active_tool, "set" + property):
option_setter = getattr(self._active_tool, "set" + property)
if option_setter:
try:
option_setter(value)
except Exception as e:
Logger.logException("e", f"Unable to set value '{value}' to property '{property}'.")

if hasattr(self._active_tool, property):
setattr(self._active_tool, property, value)

def _onPropertyChanged(self):
self._updateProperties()

def _onActiveToolChanged(self):
if self._active_tool:
self._active_tool.propertyChanged.disconnect(self._onPropertyChanged)

self._active_tool = Application.getInstance().getController().getActiveTool()
if self._active_tool is not None:
self._active_tool.propertyChanged.connect(self._onPropertyChanged)
self._updateProperties()

self.activeToolChanged.emit()

def _updateProperties(self):
self._properties.clear()

for name in self._active_tool.getExposedProperties():
property_getter = getattr(self._active_tool, "get" + name)
if property_getter:
self._properties[name] = property_getter()

if hasattr(self._active_tool, name):
self._properties[name] = getattr(self._active_tool, name)

self.propertiesChanged.emit()
2 changes: 2 additions & 0 deletions UM/Qt/Bindings/OperationStackProxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from PyQt6.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal

from UM.Application import Application
from UM.Decorators import deprecated


@deprecated("OperationStackProxy is deprecated and will be removed in major SDK release")
class OperationStackProxy(QObject):
def __init__(self, parent = None):
super().__init__(parent)
Expand Down
20 changes: 10 additions & 10 deletions plugins/Tools/RotateTool/RotateTool.qml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Item

z: 2

onClicked: UM.ActiveTool.triggerAction("resetRotation")
onClicked: UM.Controller.triggerAction("resetRotation")
}

UM.ToolbarButton
Expand All @@ -47,10 +47,10 @@ Item

z: 1

onClicked: UM.ActiveTool.triggerAction("layFlat");
onClicked: UM.Controller.triggerAction("layFlat");

// (Not yet:) Alternative 'lay flat' when legacy OpenGL makes selection of a face in an indexed model impossible.
// visible: ! UM.ActiveTool.properties.getValue("SelectFaceSupported");
// visible: ! UM.Controller.properties.getValue("SelectFaceSupported");
}

UM.ToolbarButton{
Expand All @@ -71,10 +71,10 @@ Item
checkable: true

enabled: UM.Selection.selectionCount == 1
checked: UM.ActiveTool.properties.getValue("SelectFaceToLayFlatMode")
onClicked: UM.ActiveTool.setProperty("SelectFaceToLayFlatMode", checked)
checked: UM.Controller.properties.getValue("SelectFaceToLayFlatMode")
onClicked: UM.Controller.setProperty("SelectFaceToLayFlatMode", checked)

visible: UM.ActiveTool.properties.getValue("SelectFaceSupported") == true //Might be undefined if we're switching away from the RotateTool!
visible: UM.Controller.properties.getValue("SelectFaceSupported") == true //Might be undefined if we're switching away from the RotateTool!
}

UM.CheckBox
Expand All @@ -86,21 +86,21 @@ Item
//: Snap Rotation checkbox
text: catalog.i18nc("@action:checkbox","Snap Rotation")

checked: UM.ActiveTool.properties.getValue("RotationSnap")
onClicked: UM.ActiveTool.setProperty("RotationSnap", checked)
checked: UM.Controller.properties.getValue("RotationSnap")
onClicked: UM.Controller.setProperty("RotationSnap", checked)
}

Binding
{
target: snapRotationCheckbox
property: "checked"
value: UM.ActiveTool.properties.getValue("RotationSnap")
value: UM.Controller.properties.getValue("RotationSnap")
}

Binding
{
target: alignFaceButton
property: "checked"
value: UM.ActiveTool.properties.getValue("SelectFaceToLayFlatMode")
value: UM.Controller.properties.getValue("SelectFaceToLayFlatMode")
}
}
Loading

0 comments on commit 53e7b5d

Please sign in to comment.