Show machine actions page optionally

This commit is contained in:
Lipu Fei 2019-03-27 09:34:48 +01:00
parent 56a3b2dfa7
commit 6dbae6f088
3 changed files with 136 additions and 54 deletions

View file

@ -1,9 +1,9 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 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 typing import Optional from typing import Optional, Dict, Any
from PyQt5.QtCore import QObject, Qt from PyQt5.QtCore import QObject, Qt, pyqtProperty, pyqtSignal, pyqtSlot
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -27,6 +27,8 @@ class FirstStartMachineActionsModel(ListModel):
self.addRoleName(self.ContentRole, "content") self.addRoleName(self.ContentRole, "content")
self.addRoleName(self.ActionRole, "action") self.addRoleName(self.ActionRole, "action")
self._current_action_index = 0
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
self._application = CuraApplication.getInstance() self._application = CuraApplication.getInstance()
@ -36,6 +38,47 @@ class FirstStartMachineActionsModel(ListModel):
self._application.getMachineManager().globalContainerChanged.connect(self._update) self._application.getMachineManager().globalContainerChanged.connect(self._update)
self._update() self._update()
currentActionIndexChanged = pyqtSignal()
allFinished = pyqtSignal() # Emitted when all actions have been finished.
@pyqtProperty(int, notify = currentActionIndexChanged)
def currentActionIndex(self) -> int:
return self._current_action_index
@pyqtProperty("QVariantMap", notify = currentActionIndexChanged)
def currentItem(self) -> Optional[Dict[str, Any]]:
if self._current_action_index >= self.count:
return dict()
else:
return self.getItem(self._current_action_index)
@pyqtProperty(bool, notify = currentActionIndexChanged)
def hasMoreActions(self) -> bool:
return self._current_action_index < self.count - 1
@pyqtSlot()
def goToNextAction(self) -> None:
# finish the current item
if "action" in self.currentItem:
self.currentItem["action"].setFinished()
if not self.hasMoreActions:
self.allFinished.emit()
self.reset()
return
self._current_action_index += 1
self.currentActionIndexChanged.emit()
# Resets the current action index to 0 so the wizard panel can show actions from the beginning.
@pyqtSlot()
def reset(self) -> None:
self._current_action_index = 0
self.currentActionIndexChanged.emit()
if self.count == 0:
self.allFinished.emit()
def _update(self) -> None: def _update(self) -> None:
global_stack = self._application.getMachineManager().activeMachine global_stack = self._application.getMachineManager().activeMachine
if global_stack is None: if global_stack is None:
@ -53,6 +96,7 @@ class FirstStartMachineActionsModel(ListModel):
}) })
self.setItems(item_list) self.setItems(item_list)
self.reset()
__all__ = ["FirstStartMachineActionsModel"] __all__ = ["FirstStartMachineActionsModel"]

View file

@ -13,7 +13,20 @@ from UM.Resources import Resources
if TYPE_CHECKING: if TYPE_CHECKING:
from PyQt5.QtCore import QObject from PyQt5.QtCore import QObject
#
# This is the Qt ListModel that contains all welcome pages data. Each page is a page that can be shown as a step in the
# welcome wizard dialog. Each item in this ListModel represents a page, which contains the following fields:
#
# - id : A unique page_id which can be used in function goToPage(page_id)
# - page_url : The QUrl to the QML file that contains the content of this page
# - next_page_id : (OPTIONAL) The next page ID to go to when this page finished. This is optional. If this is not
# provided, it will go to the page with the current index + 1
# - should_show_function : (OPTIONAL) An optional function that returns True/False indicating if this page should be
# shown. By default all pages should be shown. If a function returns False, that page will
# be skipped and its next page will be shown.
#
# Note that in any case, a page that has its "should_show_function" == False will ALWAYS be skipped.
#
class WelcomePagesModel(ListModel): class WelcomePagesModel(ListModel):
IdRole = Qt.UserRole + 1 # Page ID IdRole = Qt.UserRole + 1 # Page ID
@ -57,13 +70,19 @@ class WelcomePagesModel(ListModel):
self.currentPageIndexChanged.emit() self.currentPageIndexChanged.emit()
# Goes to the next page. # Goes to the next page.
# If "from_index" is given, it will look for the next page to show starting from the "from_index" page instead of
# the "self._current_page_index".
@pyqtSlot() @pyqtSlot()
def goToNextPage(self) -> None: def goToNextPage(self, from_index: Optional[int] = None) -> None:
page_item = self._items[self._current_page_index] # Look for the next page that should be shown
current_index = self._current_page_index if from_index is None else from_index
while True:
page_item = self._items[current_index]
# Check if there's a "next_page_id" assigned. If so, go to that page. Otherwise, go to the page with the # Check if there's a "next_page_id" assigned. If so, go to that page. Otherwise, go to the page with the
# current index + 1. # current index + 1.
next_page_id = page_item.get("next_page_id") next_page_id = page_item.get("next_page_id")
next_page_index = self._current_page_index + 1 next_page_index = current_index + 1
if next_page_id: if next_page_id:
idx = self.getPageIndexById(next_page_id) idx = self.getPageIndexById(next_page_id)
if idx is None: if idx is None:
@ -78,6 +97,14 @@ class WelcomePagesModel(ListModel):
self.resetState() self.resetState()
return return
# Check if the this page should be shown (default yes), if not, keep looking for the next one.
next_page_item = self.getItem(next_page_index)
if self._shouldPageBeShown(next_page_index):
break
Logger.log("d", "Page [%s] should not be displayed, look for the next page.", next_page_item["id"])
current_index = next_page_index
# Move to the next page # Move to the next page
self._setCurrentPageIndex(next_page_index) self._setCurrentPageIndex(next_page_index)
@ -101,8 +128,19 @@ class WelcomePagesModel(ListModel):
Logger.log("e", "Cannot find page with ID [%s]", page_index) Logger.log("e", "Cannot find page with ID [%s]", page_index)
return return
# Move to that page if self._shouldPageBeShown(page_index):
# Move to that page if it should be shown
self._setCurrentPageIndex(page_index) self._setCurrentPageIndex(page_index)
else:
# Find the next page to show starting from the "page_index"
self.goToNextPage(from_index = page_index)
# Checks if the page with the given index should be shown by calling the "should_show_function" associated with it.
# If the function is not present, returns True (show page by default).
def _shouldPageBeShown(self, page_index: int) -> bool:
next_page_item = self.getItem(page_index)
should_show_function = next_page_item.get("should_show_function", lambda: True)
return should_show_function()
# Resets the state of the WelcomePagesModel. This functions does the following: # Resets the state of the WelcomePagesModel. This functions does the following:
# - Resets current_page_index to 0 # - Resets current_page_index to 0
@ -154,6 +192,7 @@ class WelcomePagesModel(ListModel):
self._pages.append({"id": "machine_actions", self._pages.append({"id": "machine_actions",
"page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"), "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
"next_page_id": "cloud", "next_page_id": "cloud",
"should_show_function": self.shouldShowMachineActions,
}) })
self._pages.append({"id": "cloud", self._pages.append({"id": "cloud",
"page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"), "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
@ -161,6 +200,19 @@ class WelcomePagesModel(ListModel):
self.setItems(self._pages) self.setItems(self._pages)
# Indicates if the machine action panel should be shown by checking if there's any first start machine actions
# available.
def shouldShowMachineActions(self) -> bool:
from cura.CuraApplication import CuraApplication
application = CuraApplication.getInstance()
global_stack = application.getMachineManager().activeMachine
if global_stack is None:
return False
definition_id = global_stack.definition.getId()
first_start_actions = application.getMachineActionManager().getFirstStartActions(definition_id)
return len(first_start_actions) > 0
def addPage(self) -> None: def addPage(self) -> None:
pass pass

View file

@ -17,25 +17,19 @@ Item
property var machineActionsModel: CuraApplication.getFirstStartMachineActionsModel() property var machineActionsModel: CuraApplication.getFirstStartMachineActionsModel()
property int currentActionIndex: 0 Component.onCompleted:
property var currentActionItem: currentActionIndex >= machineActionsModel.count {
? null : machineActionsModel.getItem(currentActionIndex) // Reset the action to start from the beginning when it is shown.
property bool hasActions: machineActionsModel.count > 0 machineActionsModel.reset()
}
// Reset to the first page if the model gets changed. // Go to the next page when all machine actions have been finished
Connections Connections
{ {
target: machineActionsModel target: machineActionsModel
onItemsChanged: currentActionIndex = 0 onAllFinished:
}
onVisibleChanged:
{ {
if (visible) if (visible)
{
// Reset the action to start from the beginning when it is shown.
currentActionIndex = 0
if (!hasActions)
{ {
base.showNextPage() base.showNextPage()
} }
@ -49,7 +43,7 @@ Item
anchors.topMargin: UM.Theme.getSize("welcome_pages_default_margin").height anchors.topMargin: UM.Theme.getSize("welcome_pages_default_margin").height
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: currentActionItem == null ? "" : currentActionItem.title text: machineActionsModel.currentItem.title == undefined ? "" : machineActionsModel.currentItem.title
color: UM.Theme.getColor("primary_button") color: UM.Theme.getColor("primary_button")
font: UM.Theme.getFont("large_bold") font: UM.Theme.getFont("large_bold")
renderType: Text.NativeRendering renderType: Text.NativeRendering
@ -63,7 +57,13 @@ Item
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
data: currentActionItem == undefined ? null : currentActionItem.content data: machineActionsModel.currentItem.content == undefined ? emptyItem : machineActionsModel.currentItem.content
}
// An empty item in case there's no currentItem.content to show
Item
{
id: emptyItem
} }
Cura.PrimaryButton Cura.PrimaryButton
@ -75,20 +75,6 @@ Item
text: catalog.i18nc("@button", "Next") text: catalog.i18nc("@button", "Next")
width: UM.Theme.getSize("welcome_pages_button").width width: UM.Theme.getSize("welcome_pages_button").width
fixedWidthMode: true fixedWidthMode: true
onClicked: onClicked: machineActionsModel.goToNextAction()
{
// If no more first-start actions to show, go to the next page.
if (currentActionIndex + 1 >= machineActionsModel.count)
{
currentActionIndex = 0
base.showNextPage()
return
}
// notify the current MachineAction that it has finished
currentActionItem.action.setFinished()
// move on to the next MachineAction
currentActionIndex++
}
} }
} }