mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
Make sidebar view working for active stage
This commit is contained in:
parent
0e1c9146cf
commit
a57a5aab6b
14 changed files with 605 additions and 812 deletions
|
@ -721,6 +721,7 @@ class CuraApplication(QtApplication):
|
||||||
run_headless = self.getCommandLineOption("headless", False)
|
run_headless = self.getCommandLineOption("headless", False)
|
||||||
if not run_headless:
|
if not run_headless:
|
||||||
self.initializeEngine()
|
self.initializeEngine()
|
||||||
|
controller.setActiveStage("PrepareStage")
|
||||||
|
|
||||||
if run_headless or self._engine.rootObjects:
|
if run_headless or self._engine.rootObjects:
|
||||||
self.closeSplash()
|
self.closeSplash()
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Preferences import Preferences
|
|
||||||
from UM.Signal import Signal
|
|
||||||
from UM.PluginRegistry import PluginRegistry
|
|
||||||
|
|
||||||
# The sidebar controller manages available sidebar components and decides which one to display.
|
|
||||||
# The cura.qml file uses this controller to repeat over the sidebars and show the active index.
|
|
||||||
class SidebarController:
|
|
||||||
|
|
||||||
def __init__(self, application):
|
|
||||||
self._application = application
|
|
||||||
self._sidebar_views = {"default": {}} # default is needed for the default settings sidebar
|
|
||||||
self._active_sidebar_view = None
|
|
||||||
|
|
||||||
# Register the sidebar_view plugin type so plugins can expose custom sidebar views.
|
|
||||||
PluginRegistry.addType("sidebar_view", self.addSidebarView)
|
|
||||||
|
|
||||||
## Emitted when the list of views changes.
|
|
||||||
sidebarViewsChanged = Signal()
|
|
||||||
|
|
||||||
## Emitted when the active view changes.
|
|
||||||
activeSidebarViewChanged = Signal()
|
|
||||||
|
|
||||||
## Get the active application instance.
|
|
||||||
def getApplication(self):
|
|
||||||
return self._application
|
|
||||||
|
|
||||||
## Get all sidebar views registered in this controller.
|
|
||||||
def getAllSidebarViews(self):
|
|
||||||
return self._sidebar_views
|
|
||||||
|
|
||||||
## Add a sidebar view to the registry.
|
|
||||||
# It get's a unique name based on the plugin ID.
|
|
||||||
def addSidebarView(self, sidebar_view):
|
|
||||||
sidebar_view_id = sidebar_view.getPluginId()
|
|
||||||
if sidebar_view_id not in self._sidebar_views:
|
|
||||||
self._sidebar_views[sidebar_view_id] = sidebar_view
|
|
||||||
self.sidebarViewsChanged.emit()
|
|
||||||
|
|
||||||
## Get a registered sidebar view by name.
|
|
||||||
# The name is the ID of the plugin that registered the view.
|
|
||||||
def getSidebarView(self, name: str):
|
|
||||||
try:
|
|
||||||
return self._sidebar_views[name]
|
|
||||||
except KeyError:
|
|
||||||
Logger.log("e", "Unable to find %s in sidebar view list", name)
|
|
||||||
return None
|
|
||||||
|
|
||||||
## Get the active sidebar view.
|
|
||||||
def getActiveSidebarView(self):
|
|
||||||
return self._active_sidebar_view
|
|
||||||
|
|
||||||
## Get the ID of the active sidebar view.
|
|
||||||
def getActiveSidebarViewId(self):
|
|
||||||
if self._active_sidebar_view:
|
|
||||||
if hasattr(self._active_sidebar_view, "getPluginId"):
|
|
||||||
return self._active_sidebar_view.getPluginId()
|
|
||||||
return "default"
|
|
||||||
|
|
||||||
## Change the active sidebar view to one of the registered views.
|
|
||||||
def setActiveSidebarView(self, sidebar_view_id: str):
|
|
||||||
if sidebar_view_id in self._sidebar_views:
|
|
||||||
self._active_sidebar_view = self._sidebar_views[sidebar_view_id]
|
|
||||||
Preferences.getInstance().setValue("cura/active_sidebar_view", sidebar_view_id)
|
|
||||||
self.activeSidebarViewChanged.emit()
|
|
|
@ -1,41 +0,0 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSlot, QUrl, pyqtProperty, pyqtSignal
|
|
||||||
from UM.Application import Application
|
|
||||||
|
|
||||||
|
|
||||||
## The sidebar controller proxy acts a proxy between the sidebar controller and the QMl context of the controller.
|
|
||||||
from UM.Logger import Logger
|
|
||||||
|
|
||||||
|
|
||||||
class SidebarControllerProxy(QObject):
|
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self._controller = Application.getInstance().getSidebarController()
|
|
||||||
self._controller.activeSidebarViewChanged.connect(self._onActiveSidebarViewChanged)
|
|
||||||
|
|
||||||
activeSidebarViewChanged = pyqtSignal()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def createSidebarControllerProxy(self, engine, script_engine):
|
|
||||||
return SidebarControllerProxy()
|
|
||||||
|
|
||||||
@pyqtProperty(str, notify = activeSidebarViewChanged)
|
|
||||||
def activeSidebarId(self):
|
|
||||||
return self._controller.getActiveSidebarViewId()
|
|
||||||
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def setActiveSidebarView(self, sidebar_view_id):
|
|
||||||
Logger.log("d", "Setting active sidebar view to %s", sidebar_view_id)
|
|
||||||
self._controller.setActiveSidebarView(sidebar_view_id)
|
|
||||||
|
|
||||||
@pyqtSlot(str, result = QObject)
|
|
||||||
def getSidebarComponent(self, sidebar_id):
|
|
||||||
return self._controller.getSidebarView(sidebar_id).getComponent()
|
|
||||||
|
|
||||||
@pyqtSlot(str, result = QUrl)
|
|
||||||
def getSidebarComponentPath(self, sidebar_id):
|
|
||||||
return self._controller.getSidebarView(sidebar_id).getComponentPath()
|
|
||||||
|
|
||||||
def _onActiveSidebarViewChanged(self):
|
|
||||||
self.activeSidebarViewChanged.emit()
|
|
|
@ -1,35 +0,0 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from UM.Application import Application
|
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.PluginObject import PluginObject
|
|
||||||
from UM.PluginRegistry import PluginRegistry
|
|
||||||
|
|
||||||
# Abstract class for sidebar view objects.
|
|
||||||
# By default the sidebar is Cura's settings, slicing and printing overview.
|
|
||||||
# The last plugin to claim the sidebar QML target will be displayed.
|
|
||||||
class SidebarView(PluginObject):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self._view = None
|
|
||||||
|
|
||||||
def getComponent(self):
|
|
||||||
if not self._view:
|
|
||||||
self.createView()
|
|
||||||
return self._view
|
|
||||||
|
|
||||||
def createView(self):
|
|
||||||
component_path = self.getComponentPath()
|
|
||||||
self._view = Application.getInstance().createQmlComponent(component_path, {"manager": self})
|
|
||||||
|
|
||||||
## Get the path to the component QML file as QUrl
|
|
||||||
def getComponentPath(self):
|
|
||||||
try:
|
|
||||||
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
|
|
||||||
sidebar_component_file_path = PluginRegistry.getInstance().getMetaData(self.getPluginId())["sidebar_view"]["sidebar_component"]
|
|
||||||
return os.path.join(plugin_path, sidebar_component_file_path)
|
|
||||||
except KeyError:
|
|
||||||
Logger.log("w", "Could not find sidebar component QML file for %s", self.getPluginId())
|
|
||||||
return ""
|
|
|
@ -1,66 +0,0 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
|
||||||
from PyQt5.QtCore import Qt
|
|
||||||
from UM.Qt.ListModel import ListModel
|
|
||||||
from UM.Application import Application
|
|
||||||
from UM.PluginRegistry import PluginRegistry
|
|
||||||
|
|
||||||
## The SidebarViewModel is the default sidebar view in Cura with all the print settings and print button.
|
|
||||||
class SidebarViewModel(ListModel):
|
|
||||||
IdRole = Qt.UserRole + 1
|
|
||||||
NameRole = Qt.UserRole + 2
|
|
||||||
ActiveRole = Qt.UserRole + 3
|
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
# connect views changed signals
|
|
||||||
self._controller = Application.getInstance().getSidebarController()
|
|
||||||
self._controller.sidebarViewsChanged.connect(self._onSidebarViewsChanged)
|
|
||||||
self._controller.activeSidebarViewChanged.connect(self._onSidebarViewsChanged)
|
|
||||||
|
|
||||||
# register Qt list roles
|
|
||||||
self.addRoleName(self.IdRole, "id")
|
|
||||||
self.addRoleName(self.NameRole, "name")
|
|
||||||
self.addRoleName(self.ActiveRole, "active")
|
|
||||||
|
|
||||||
## Update the model when new views are added or another view is made the active view.
|
|
||||||
def _onSidebarViewsChanged(self):
|
|
||||||
items = []
|
|
||||||
current_view_id = "default"
|
|
||||||
|
|
||||||
sidebar_views = self._controller.getAllSidebarViews()
|
|
||||||
current_view = self._controller.getActiveSidebarView()
|
|
||||||
if current_view and hasattr(current_view, "getPluginId"):
|
|
||||||
current_view_id = current_view.getPluginId()
|
|
||||||
|
|
||||||
for sidebar_view_id, sidebar_view in sidebar_views.items():
|
|
||||||
|
|
||||||
# Override fields for default settings sidebar
|
|
||||||
if sidebar_view_id == "default":
|
|
||||||
items.append({
|
|
||||||
"id": "default",
|
|
||||||
"name": "Print settings sidebar",
|
|
||||||
"active": sidebar_view_id == current_view_id,
|
|
||||||
"weight": 0
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
|
|
||||||
sidebar_view_metadata = PluginRegistry.getInstance().getMetaData(sidebar_view_id).get("sidebar_view", {})
|
|
||||||
|
|
||||||
# Skip view modes that are marked as not visible
|
|
||||||
if "visible" in sidebar_view_metadata and not sidebar_view_metadata["visible"]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
name = sidebar_view_metadata.get("name", sidebar_view_id)
|
|
||||||
weight = sidebar_view_metadata.get("weight", 1)
|
|
||||||
|
|
||||||
items.append({
|
|
||||||
"id": sidebar_view_id,
|
|
||||||
"name": name,
|
|
||||||
"active": sidebar_view_id == current_view_id,
|
|
||||||
"weight": weight
|
|
||||||
})
|
|
||||||
|
|
||||||
# Sort the views by weight
|
|
||||||
items.sort(key=lambda t: t["weight"])
|
|
||||||
self.setItems(items)
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
from PyQt5.QtCore import pyqtProperty, QObject
|
||||||
|
|
||||||
from UM.Stage import Stage
|
from UM.Stage import Stage
|
||||||
|
|
||||||
|
@ -8,8 +9,10 @@ class CuraStage(Stage):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def getMainView(self):
|
@pyqtProperty(QObject, constant = True)
|
||||||
return self.getView("main")
|
def mainComponent(self):
|
||||||
|
return self.getDisplayComponent("main")
|
||||||
|
|
||||||
def getSidebarView(self):
|
@pyqtProperty(QObject, constant = True)
|
||||||
return self.getView("sidebar")
|
def sidebarComponent(self):
|
||||||
|
return self.getDisplayComponent("sidebar")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
from UM.Application import Application
|
||||||
from cura.Stages.CuraStage import CuraStage
|
from cura.Stages.CuraStage import CuraStage
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,3 +9,7 @@ class MonitorStage(CuraStage):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
Application.getInstance().engineCreatedSignal.connect(self._engineCreated)
|
||||||
|
|
||||||
|
def _engineCreated(self):
|
||||||
|
self.setIconSource(Application.getInstance().getTheme().getIcon("tab_status_connected"))
|
||||||
|
|
|
@ -10,10 +10,11 @@ def getMetaData():
|
||||||
return {
|
return {
|
||||||
"stage": {
|
"stage": {
|
||||||
"name": i18n_catalog.i18nc("@item:inmenu", "Monitor"),
|
"name": i18n_catalog.i18nc("@item:inmenu", "Monitor"),
|
||||||
"weight": 1,
|
"weight": 1
|
||||||
"icon": ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def register(app):
|
def register(app):
|
||||||
return { "stage": MonitorStage.MonitorStage() }
|
return {
|
||||||
|
"stage": MonitorStage.MonitorStage()
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
import os.path
|
||||||
|
from UM.Application import Application
|
||||||
|
from UM.Resources import Resources
|
||||||
from cura.Stages.CuraStage import CuraStage
|
from cura.Stages.CuraStage import CuraStage
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,3 +11,9 @@ class PrepareStage(CuraStage):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
Application.getInstance().engineCreatedSignal.connect(self._engineCreated)
|
||||||
|
|
||||||
|
def _engineCreated(self):
|
||||||
|
sidebar_component_path = os.path.join(Resources.getPath(Application.getInstance().ResourceTypes.QmlFiles), "Sidebar.qml")
|
||||||
|
sidebar_component = Application.getInstance().createQmlComponent(sidebar_component_path)
|
||||||
|
self.addDisplayComponent("sidebar", sidebar_component)
|
||||||
|
|
|
@ -15,4 +15,6 @@ def getMetaData():
|
||||||
}
|
}
|
||||||
|
|
||||||
def register(app):
|
def register(app):
|
||||||
return { "stage": PrepareStage.PrepareStage() }
|
return {
|
||||||
|
"stage": PrepareStage.PrepareStage()
|
||||||
|
}
|
||||||
|
|
|
@ -366,8 +366,7 @@ UM.MainWindow
|
||||||
onStopMonitoringPrint: base.showPrintMonitor = false
|
onStopMonitoringPrint: base.showPrintMonitor = false
|
||||||
}
|
}
|
||||||
|
|
||||||
Sidebar
|
Loader {
|
||||||
{
|
|
||||||
id: sidebar
|
id: sidebar
|
||||||
|
|
||||||
anchors
|
anchors
|
||||||
|
@ -379,7 +378,8 @@ UM.MainWindow
|
||||||
|
|
||||||
width: UM.Theme.getSize("sidebar").width
|
width: UM.Theme.getSize("sidebar").width
|
||||||
z: 1
|
z: 1
|
||||||
monitoringPrint: base.showPrintMonitor
|
|
||||||
|
sourceComponent: UM.Controller.activeStage.sidebarComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
|
|
|
@ -10,8 +10,10 @@ import UM 1.2 as UM
|
||||||
import Cura 1.0 as Cura
|
import Cura 1.0 as Cura
|
||||||
import "Menus"
|
import "Menus"
|
||||||
|
|
||||||
Rectangle
|
Component
|
||||||
{
|
{
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
id: base;
|
id: base;
|
||||||
|
|
||||||
property int currentModeIndex;
|
property int currentModeIndex;
|
||||||
|
@ -609,4 +611,5 @@ Rectangle
|
||||||
watchedProperties: [ "value" ]
|
watchedProperties: [ "value" ]
|
||||||
storeIndex: 0
|
storeIndex: 0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import QtQuick.Controls 1.1
|
||||||
import QtQuick.Controls.Styles 1.1
|
import QtQuick.Controls.Styles 1.1
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.4 as UM
|
||||||
import Cura 1.0 as Cura
|
import Cura 1.0 as Cura
|
||||||
import "Menus"
|
import "Menus"
|
||||||
|
|
||||||
|
@ -83,33 +83,12 @@ Rectangle
|
||||||
style: UM.Theme.styles.topbar_header_tab
|
style: UM.Theme.styles.topbar_header_tab
|
||||||
height: UM.Theme.getSize("sidebar_header").height
|
height: UM.Theme.getSize("sidebar_header").height
|
||||||
onClicked: UM.Controller.setActiveStage(model.id)
|
onClicked: UM.Controller.setActiveStage(model.id)
|
||||||
}
|
iconSource: model.stage.iconSource
|
||||||
}
|
|
||||||
|
|
||||||
// Button
|
property color overlayColor: "transparent"
|
||||||
// {
|
property string overlayIconSource: ""
|
||||||
// id: showSettings
|
}
|
||||||
// height: UM.Theme.getSize("sidebar_header").height
|
}
|
||||||
// text: catalog.i18nc("@title:tab", "Prepare")
|
|
||||||
// checkable: true
|
|
||||||
// checked: isChecked()
|
|
||||||
// exclusiveGroup: sidebarHeaderBarGroup
|
|
||||||
// style: UM.Theme.styles.topbar_header_tab
|
|
||||||
//
|
|
||||||
// // We use a Qt.binding to re-bind the checkbox state after manually setting it
|
|
||||||
// // https://stackoverflow.com/questions/38798450/qt-5-7-qml-why-are-my-checkbox-property-bindings-disappearing
|
|
||||||
// onClicked: {
|
|
||||||
// base.stopMonitoringPrint()
|
|
||||||
// checked = Qt.binding(isChecked)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// function isChecked () {
|
|
||||||
// return !base.monitoringPrint
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// property color overlayColor: "transparent"
|
|
||||||
// property string overlayIconSource: ""
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Button
|
// Button
|
||||||
// {
|
// {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue