mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-16 03:07:53 -06:00
Implement switching sidebar views
This commit is contained in:
parent
3c863fc388
commit
caf56587fe
8 changed files with 121 additions and 72 deletions
|
@ -201,6 +201,10 @@ class CuraApplication(QtApplication):
|
|||
}
|
||||
)
|
||||
|
||||
## As of Cura 3.2, the sidebar is controlled by a controller.
|
||||
# This functionality was added to allow plugins registering custom sidebar views.
|
||||
self._sidebar_controller = SidebarController(self)
|
||||
|
||||
self._currently_loading_files = []
|
||||
self._non_sliceable_extensions = []
|
||||
|
||||
|
@ -221,14 +225,6 @@ class CuraApplication(QtApplication):
|
|||
|
||||
self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))
|
||||
|
||||
## As of Cura 3.2, the sidebar is controlled by a controller.
|
||||
# This functionality was added to allow plugins registering custom sidebar views.
|
||||
self._sidebar_controller = SidebarController(self)
|
||||
|
||||
## Register the default settings sidebar manually
|
||||
settings_sidebar_view = SettingsSidebarView()
|
||||
self._sidebar_controller.addSidebarView(settings_sidebar_view)
|
||||
|
||||
self.setRequiredPlugins([
|
||||
"CuraEngineBackend",
|
||||
"UserAgreement",
|
||||
|
@ -327,11 +323,6 @@ class CuraApplication(QtApplication):
|
|||
|
||||
self._need_to_show_user_agreement = not Preferences.getInstance().getValue("general/accepted_user_agreement")
|
||||
|
||||
# Set the active sidebar view based on user preferences
|
||||
preferences.addPreference("cura/active_sidebar_view", "default")
|
||||
active_sidebar_view = preferences.getValue("cura/active_sidebar_view")
|
||||
self._sidebar_controller.setActiveSidebarView(active_sidebar_view)
|
||||
|
||||
for key in [
|
||||
"dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin
|
||||
"dialog_profile_path",
|
||||
|
@ -737,6 +728,10 @@ class CuraApplication(QtApplication):
|
|||
if not run_headless:
|
||||
self.initializeEngine()
|
||||
|
||||
# Now that the SidebarViewModel has been created we can set the default sidebar view
|
||||
# TODO: put this in a more elegant place
|
||||
self._setDefaultSidebarView()
|
||||
|
||||
if run_headless or self._engine.rootObjects:
|
||||
self.closeSplash()
|
||||
|
||||
|
@ -1324,6 +1319,19 @@ class CuraApplication(QtApplication):
|
|||
def _addProfileWriter(self, profile_writer):
|
||||
pass
|
||||
|
||||
## Create and register the default sidebar component (settings)
|
||||
def _setDefaultSidebarView(self):
|
||||
|
||||
# Register the default settings sidebar manually
|
||||
settings_sidebar_view = SettingsSidebarView()
|
||||
self._sidebar_controller.addSidebarView(settings_sidebar_view)
|
||||
|
||||
# Set the default sidebar view depending on user preferences.
|
||||
preferences = Preferences.getInstance()
|
||||
preferences.addPreference("cura/active_sidebar_view", settings_sidebar_view.getPluginId())
|
||||
active_sidebar_view = preferences.getValue("cura/active_sidebar_view")
|
||||
self._sidebar_controller.setActiveSidebarView(active_sidebar_view)
|
||||
|
||||
@pyqtSlot("QSize")
|
||||
def setMinimumWindowSize(self, size):
|
||||
self.getMainWindow().setMinimumSize(size)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
import os.path
|
||||
from PyQt5.QtCore import QObject, QUrl
|
||||
from PyQt5.QtCore import QObject
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from cura.Sidebar.SidebarView import SidebarView
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
@ -19,11 +19,10 @@ class SettingsSidebarView(QObject, SidebarView):
|
|||
def getMetaData(self):
|
||||
return {
|
||||
"sidebar_view": {
|
||||
"name": i18n_catalog.i18nc("", "Print settings"),
|
||||
"name": i18n_catalog.i18nc("@item:inmenu", "Print settings"),
|
||||
"weight": 0
|
||||
}
|
||||
}
|
||||
|
||||
## As the default sidebar is not a plugin, we have a get component path method here to allow the sidebar controller to get the needed data.
|
||||
def getComponentPath(self):
|
||||
return QUrl("SidebarSettings.qml")
|
||||
def getComponent(self):
|
||||
return None
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# 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
|
||||
|
||||
|
@ -52,5 +53,7 @@ class SidebarController:
|
|||
|
||||
## Change the active sidebar view to one of the registered views.
|
||||
def setActiveSidebarView(self, sidebar_view_id: str):
|
||||
self._active_sidebar_view = self._sidebar_views[sidebar_view_id]
|
||||
self.activeSidebarViewChanged.emit()
|
||||
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()
|
||||
|
|
|
@ -4,33 +4,41 @@ 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._onActiveSidebarComponentChanged)
|
||||
self._controller.activeSidebarViewChanged.connect(self._onActiveSidebarViewChanged)
|
||||
|
||||
## Emitted when the active view changes.
|
||||
activeSidebarViewChanged = pyqtSignal()
|
||||
|
||||
@classmethod
|
||||
def createSidebarControllerProxy(self, engine, script_engine):
|
||||
return SidebarControllerProxy()
|
||||
|
||||
@pyqtSlot()
|
||||
def setActiveView(self, sidebar_view):
|
||||
self._controller.setActiveSidebarView(sidebar_view)
|
||||
@pyqtProperty(str, notify = activeSidebarViewChanged)
|
||||
def activeSidebarId(self):
|
||||
if self._controller.getActiveSidebarView() is not None:
|
||||
return self._controller.getActiveSidebarView().getPluginId()
|
||||
else:
|
||||
return "default"
|
||||
|
||||
@pyqtProperty(QUrl, notify = activeSidebarViewChanged)
|
||||
def activeComponentPath(self):
|
||||
if not self._controller.getActiveSidebarView():
|
||||
return QUrl()
|
||||
return self._controller.getActiveSidebarView().getComponentPath()
|
||||
@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(QUrl)
|
||||
@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):
|
||||
self._controller.getSidebarView(sidebar_id).getComponentPath()
|
||||
return self._controller.getSidebarView(sidebar_id).getComponentPath()
|
||||
|
||||
def _onActiveSidebarComponentChanged(self):
|
||||
def _onActiveSidebarViewChanged(self):
|
||||
self.activeSidebarViewChanged.emit()
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
from PyQt5.QtCore import QUrl
|
||||
import os.path
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Logger import Logger
|
||||
from UM.PluginObject import PluginObject
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
|
@ -14,11 +15,21 @@ class SidebarView(PluginObject):
|
|||
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 QUrl.fromLocalFile(sidebar_component_file_path)
|
||||
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 QUrl()
|
||||
return ""
|
||||
|
|
|
@ -26,17 +26,18 @@ class SidebarViewModel(ListModel):
|
|||
## Update the model when new views are added or another view is made the active view.
|
||||
def _onSidebarViewsChanged(self):
|
||||
items = []
|
||||
current_view_id = None
|
||||
|
||||
sidebar_views = self._controller.getAllSidebarViews()
|
||||
current_view = self._controller.getActiveSidebarView()
|
||||
if current_view:
|
||||
current_view_id = current_view.getPluginId()
|
||||
|
||||
for sidebar_view_id, sidebar_view in sidebar_views.items():
|
||||
plugin_metadata = PluginRegistry.getInstance().getMetaData(sidebar_view_id)
|
||||
if plugin_metadata:
|
||||
# Check if the registered view came from a plugin and extract the metadata if so.
|
||||
sidebar_view_metadata = plugin_metadata.get("sidebar_view", {})
|
||||
if sidebar_view_id != "default":
|
||||
sidebar_view_metadata = PluginRegistry.getInstance().getMetaData(sidebar_view_id).get("sidebar_view", {})
|
||||
else:
|
||||
# Get the meta data directly from the plugin
|
||||
sidebar_view_metadata = sidebar_view.getMetaData()
|
||||
sidebar_view_metadata = sidebar_view.getMetaData().get("sidebar_view", {})
|
||||
|
||||
# Skip view modes that are marked as not visible
|
||||
if "visible" in sidebar_view_metadata and not sidebar_view_metadata["visible"]:
|
||||
|
@ -48,7 +49,7 @@ class SidebarViewModel(ListModel):
|
|||
items.append({
|
||||
"id": sidebar_view_id,
|
||||
"name": name,
|
||||
"active": sidebar_view_id == current_view.getPluginId(),
|
||||
"active": sidebar_view_id == current_view_id,
|
||||
"weight": weight
|
||||
})
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ UM.MainWindow
|
|||
text: catalog.i18nc("@action:button","Open File");
|
||||
iconSource: UM.Theme.getIcon("load")
|
||||
style: UM.Theme.styles.tool_button
|
||||
tooltip: '';
|
||||
tooltip: ""
|
||||
anchors
|
||||
{
|
||||
top: topbar.bottom;
|
||||
|
@ -366,7 +366,7 @@ UM.MainWindow
|
|||
onStopMonitoringPrint: base.showPrintMonitor = false
|
||||
}
|
||||
|
||||
Loader
|
||||
Rectangle
|
||||
{
|
||||
id: sidebar
|
||||
|
||||
|
@ -379,11 +379,30 @@ UM.MainWindow
|
|||
|
||||
width: UM.Theme.getSize("sidebar").width
|
||||
|
||||
// all sidebar components will have access to the show print monitor flag
|
||||
property bool showPrintMonitor: base.showPrintMonitor
|
||||
// The sidebarRepeater exposes sidebar views provided by plugins.
|
||||
// Whenever a plugin sidebar view is active (e.g. not "default"), that sidebar view is shown.
|
||||
Repeater
|
||||
{
|
||||
id: sidebarRepeater
|
||||
|
||||
// dynamically get the component from the sidebar controller
|
||||
source: Cura.SidebarController.activeComponentPath
|
||||
model: Cura.SidebarViewModel { }
|
||||
|
||||
delegate: Loader
|
||||
{
|
||||
id: delegate
|
||||
asynchronous: true
|
||||
visible: model.active
|
||||
|
||||
// dynamically get the component from the sidebar controller or set the default sidebar
|
||||
sourceComponent: {
|
||||
if (model.id !== "default") {
|
||||
return Cura.SidebarController.getSidebarComponent(model.id)
|
||||
} else {
|
||||
return defaultSidebar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle
|
||||
|
@ -434,6 +453,27 @@ UM.MainWindow
|
|||
}
|
||||
}
|
||||
|
||||
// This is the default sidebar view.
|
||||
// It is used as sourceComponent for the default sidebar view.
|
||||
Component
|
||||
{
|
||||
id: defaultSidebar
|
||||
|
||||
Sidebar
|
||||
{
|
||||
// anchors {
|
||||
// top: parent.top
|
||||
// bottom: parent.bottom
|
||||
// left: parent.left
|
||||
// right: parent.right
|
||||
// }
|
||||
//
|
||||
// width: parent.width
|
||||
//
|
||||
// monitoringPrint: base.showPrintMonitor
|
||||
}
|
||||
}
|
||||
|
||||
UM.PreferencesDialog
|
||||
{
|
||||
id: preferences
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Sidebar
|
||||
{
|
||||
id: sidebarSettings
|
||||
|
||||
property bool showPrintMonitor: false
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
width: parent.width
|
||||
monitoringPrint: showPrintMonitor
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue