diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py index b816833d67..3c2d0503ab 100644 --- a/cura/UI/WelcomePagesModel.py +++ b/cura/UI/WelcomePagesModel.py @@ -239,9 +239,6 @@ class WelcomePagesModel(ListModel): {"id": "user_agreement", "page_url": self._getBuiltinWelcomePagePath("UserAgreementContent.qml"), }, - {"id": "whats_new", - "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"), - }, {"id": "data_collections", "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"), }, @@ -259,13 +256,21 @@ class WelcomePagesModel(ListModel): }, {"id": "add_cloud_printers", "page_url": self._getBuiltinWelcomePagePath("AddCloudPrintersView.qml"), - "is_final_page": True, # If we end up in this page, the next button will close the dialog - "next_page_button_text": self._catalog.i18nc("@action:button", "Finish"), + "next_page_button_text": self._catalog.i18nc("@action:button", "Next"), + "next_page_id": "whats_new", }, {"id": "machine_actions", "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"), "should_show_function": self.shouldShowMachineActions, }, + {"id": "whats_new", + "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"), + "next_page_button_text": self._catalog.i18nc("@action:button", "Skip"), + }, + {"id": "changelog", + "page_url": self._getBuiltinWelcomePagePath("ChangelogContent.qml"), + "next_page_button_text": self._catalog.i18nc("@action:button", "Finish"), + }, ] pages_to_show = all_pages_list diff --git a/cura/UI/WhatsNewPagesModel.py b/cura/UI/WhatsNewPagesModel.py index 5b968ae574..db0f4b3a74 100644 --- a/cura/UI/WhatsNewPagesModel.py +++ b/cura/UI/WhatsNewPagesModel.py @@ -1,8 +1,12 @@ -# Copyright (c) 2019 Ultimaker B.V. +# Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - from .WelcomePagesModel import WelcomePagesModel +import os +from typing import Optional, Dict, List, Tuple +from PyQt5.QtCore import pyqtProperty, pyqtSlot +from UM.Logger import Logger +from UM.Resources import Resources # # This Qt ListModel is more or less the same the WelcomePagesModel, except that this model is only for showing the @@ -10,13 +14,84 @@ from .WelcomePagesModel import WelcomePagesModel # class WhatsNewPagesModel(WelcomePagesModel): + image_formats = [".png", ".jpg", ".jpeg", ".gif", ".svg"] + text_formats = [".txt", ".htm", ".html"] + image_key = "image" + text_key = "text" + + @staticmethod + def _collectOrdinalFiles(resource_type: int, include: List[str]) -> Tuple[Dict[int, str], int]: + result = {} #type: Dict[int, str] + highest = -1 + try: + folder_path = Resources.getPath(resource_type, "whats_new") + for _, _, files in os.walk(folder_path): + for filename in files: + basename = os.path.basename(filename) + base, ext = os.path.splitext(basename) + if ext not in include or not base.isdigit(): + continue + page_no = int(base) + highest = max(highest, page_no) + result[page_no] = os.path.join(folder_path, filename) + except FileNotFoundError: + Logger.logException("w", "Could not find 'whats_new' folder for resource-type {0}".format(resource_type)) + return result, highest + + @staticmethod + def _loadText(filename: str) -> str: + result = "" + try: + with open(filename, "r", encoding="utf-8") as file: + result = file.read() + except OSError: + Logger.logException("w", "Could not open {0}".format(filename)) + return result + def initialize(self) -> None: self._pages = [] self._pages.append({"id": "whats_new", "page_url": self._getBuiltinWelcomePagePath("WhatsNewContent.qml"), + "next_page_button_text": self._catalog.i18nc("@action:button", "Skip"), + "next_page_id": "changelog" + }) + self._pages.append({"id": "changelog", + "page_url": self._getBuiltinWelcomePagePath("ChangelogContent.qml"), "next_page_button_text": self._catalog.i18nc("@action:button", "Close"), }) self.setItems(self._pages) + images, max_image = WhatsNewPagesModel._collectOrdinalFiles(Resources.Images, WhatsNewPagesModel.image_formats) + texts, max_text = WhatsNewPagesModel._collectOrdinalFiles(Resources.Texts, WhatsNewPagesModel.text_formats) + highest = max(max_image, max_text) + + self._subpages = [] #type: List[Dict[str, Optional[str]]] + for n in range(0, highest + 1): + self._subpages.append({ + WhatsNewPagesModel.image_key: None if n not in images else images[n], + WhatsNewPagesModel.text_key: None if n not in texts else self._loadText(texts[n]) + }) + if len(self._subpages) == 0: + self._subpages.append({WhatsNewPagesModel.text_key: "~ There Is Nothing New Under The Sun ~"}) + + def _getSubpageItem(self, page: int, item: str) -> Optional[str]: + if 0 <= page < self.subpageCount and item in self._subpages[page]: + return self._subpages[page][item] + else: + return None + + @pyqtProperty(int, constant = True) + def subpageCount(self) -> int: + return len(self._subpages) + + @pyqtSlot(int, result = str) + def getSubpageImageSource(self, page: int) -> str: + result = self._getSubpageItem(page, WhatsNewPagesModel.image_key) + return "file:///" + (result if result else Resources.getPath(Resources.Images, "cura-icon.png")) + + @pyqtSlot(int, result = str) + def getSubpageText(self, page: int) -> str: + result = self._getSubpageItem(page, WhatsNewPagesModel.text_key) + return result if result else "* * *" __all__ = ["WhatsNewPagesModel"] diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py index 69a67990fe..eea4d38560 100644 --- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py +++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py @@ -338,11 +338,6 @@ class PauseAtHeight(Script): if current_layer < pause_layer - nbr_negative_layers: continue - # Get X and Y from the next layer (better position for - # the nozzle) - next_layer = data[index + 1] - x, y = self.getNextXY(next_layer) - prev_layer = data[index - 1] prev_lines = prev_layer.split("\n") current_e = 0. @@ -353,6 +348,13 @@ class PauseAtHeight(Script): current_e = self.getValue(prevLine, "E", -1) if current_e >= 0: break + # and also find last X,Y + for prevLine in reversed(prev_lines): + if prevLine.startswith(("G0", "G1", "G2", "G3")): + if self.getValue(prevLine, "X") is not None and self.getValue(prevLine, "Y") is not None: + x = self.getValue(prevLine, "X") + y = self.getValue(prevLine, "Y") + break # Maybe redo the last layer. if redo_layer: @@ -454,7 +456,7 @@ class PauseAtHeight(Script): prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = 6000) + "\n" #Move the head back - prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n" + prepend_gcode += self.putValue(G = 1, Z = current_z, F = 300) + "\n" prepend_gcode += self.putValue(G = 1, X = x, Y = y, F = 9000) + "\n" if retraction_amount != 0: prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = 6000) + "\n" diff --git a/resources/images/whats_new/0.png b/resources/images/whats_new/0.png new file mode 100644 index 0000000000..b2b56a3bf2 Binary files /dev/null and b/resources/images/whats_new/0.png differ diff --git a/resources/images/whats_new/1.png b/resources/images/whats_new/1.png new file mode 100644 index 0000000000..8d61045b40 Binary files /dev/null and b/resources/images/whats_new/1.png differ diff --git a/resources/images/whats_new/2.png b/resources/images/whats_new/2.png new file mode 100644 index 0000000000..3220bd29a9 Binary files /dev/null and b/resources/images/whats_new/2.png differ diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml index 78c4958598..46a876003e 100644 --- a/resources/qml/Actions.qml +++ b/resources/qml/Actions.qml @@ -262,7 +262,7 @@ Item Action { id: deleteSelectionAction; - text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete Selected Model", "Delete Selected Models", UM.Selection.selectionCount); + text: catalog.i18nc("@action:inmenu menubar:edit", "Delete Selected"); enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection; iconName: "edit-delete"; shortcut: StandardKey.Delete | "Backspace" @@ -272,7 +272,7 @@ Item Action { id: centerSelectionAction; - text: catalog.i18ncp("@action:inmenu menubar:edit", "Center Selected Model", "Center Selected Models", UM.Selection.selectionCount); + text: catalog.i18nc("@action:inmenu menubar:edit", "Center Selected"); enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection; iconName: "align-vertical-center"; onTriggered: CuraActions.centerSelection(); @@ -281,7 +281,7 @@ Item Action { id: multiplySelectionAction; - text: catalog.i18ncp("@action:inmenu menubar:edit", "Multiply Selected Model", "Multiply Selected Models", UM.Selection.selectionCount); + text: catalog.i18nc("@action:inmenu menubar:edit", "Multiply Selected"); enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection; iconName: "edit-duplicate"; shortcut: "Ctrl+M" diff --git a/resources/qml/TableView.qml b/resources/qml/TableView.qml index dd80304b83..1b084be5a0 100644 --- a/resources/qml/TableView.qml +++ b/resources/qml/TableView.qml @@ -18,7 +18,7 @@ OldControls.TableView Label { id: tableCellLabel - color: UM.Theme.getColor("text") + color: styleData.selected ? UM.Theme.getColor("primary_button_text") : UM.Theme.getColor("text") elide: Text.ElideRight text: styleData.value anchors.fill: parent @@ -29,7 +29,7 @@ OldControls.TableView rowDelegate: Rectangle { - color: styleData.selected ? UM.Theme.getColor("secondary") : UM.Theme.getColor("main_background") + color: styleData.selected ? UM.Theme.getColor("primary_button") : UM.Theme.getColor("main_background") height: UM.Theme.getSize("table_row").height } diff --git a/resources/qml/WelcomePages/AddCloudPrintersView.qml b/resources/qml/WelcomePages/AddCloudPrintersView.qml index 32e6ffec39..524bf288a0 100644 --- a/resources/qml/WelcomePages/AddCloudPrintersView.qml +++ b/resources/qml/WelcomePages/AddCloudPrintersView.qml @@ -215,7 +215,7 @@ Item id: finishButton anchors.right: parent.right anchors.bottom: parent.bottom - text: catalog.i18nc("@button", "Finish") + text: base.currentItem.next_page_button_text onClicked: { discoveredCloudPrintersModel.clear() diff --git a/resources/qml/WelcomePages/ChangelogContent.qml b/resources/qml/WelcomePages/ChangelogContent.qml new file mode 100644 index 0000000000..d3eebe72e4 --- /dev/null +++ b/resources/qml/WelcomePages/ChangelogContent.qml @@ -0,0 +1,59 @@ +// Copyright (c) 2021 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.10 +import QtQuick.Controls 2.3 + +import UM 1.3 as UM +import Cura 1.1 as Cura + + +// +// This component contains the content for the "What's new in Ultimaker Cura" page of the welcome on-boarding process. +// +Item +{ + UM.I18nCatalog { id: catalog; name: "cura" } + + Label + { + id: titleLabel + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + text: catalog.i18nc("@label", "Release Notes / 'Changelog'") + color: UM.Theme.getColor("primary_button") + font: UM.Theme.getFont("huge") + renderType: Text.NativeRendering + } + + Cura.ScrollableTextArea + { + id: changelogTextArea + + anchors.top: titleLabel.bottom + anchors.bottom: getStartedButton.top + anchors.topMargin: UM.Theme.getSize("wide_margin").height + anchors.bottomMargin: UM.Theme.getSize("wide_margin").height + anchors.left: parent.left + anchors.right: parent.right + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + textArea.text: CuraApplication.getTextManager().getChangeLogText() + textArea.textFormat: Text.RichText + textArea.wrapMode: Text.WordWrap + textArea.readOnly: true + textArea.font: UM.Theme.getFont("medium") + textArea.onLinkActivated: Qt.openUrlExternally(link) + } + + Cura.PrimaryButton + { + id: getStartedButton + anchors.right: parent.right + anchors.bottom: parent.bottom + text: base.currentItem.next_page_button_text + onClicked: base.showNextPage() + } +} diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml index 48410f7f12..692ad12a29 100644 --- a/resources/qml/WelcomePages/CloudContent.qml +++ b/resources/qml/WelcomePages/CloudContent.qml @@ -34,93 +34,167 @@ Item } } - Label - { - id: titleLabel - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@label", "Ultimaker Account") - color: UM.Theme.getColor("primary_button") - font: UM.Theme.getFont("huge") - renderType: Text.NativeRendering - } - // Area where the cloud contents can be put. Pictures, texts and such. Item { id: cloudContentsArea anchors { - top: titleLabel.bottom + top: parent.top bottom: skipButton.top left: parent.left right: parent.right - topMargin: UM.Theme.getSize("default_margin").height } // Pictures and texts are arranged using Columns with spacing. The whole picture and text area is centered in // the cloud contents area. Column { - anchors.centerIn: parent + anchors.horizontalCenter: parent.horizontalCenter width: parent.width height: childrenRect.height - spacing: 20 * screenScaleFactor + spacing: UM.Theme.getSize("thick_margin").height - Image // Cloud image + Label + { + id: titleLabel + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + text: catalog.i18nc("@label", "Sign in to the Ultimaker platform") + color: UM.Theme.getColor("primary_button") + font: UM.Theme.getFont("huge") + renderType: Text.NativeRendering + } + + // Filler item + Item + { + height: UM.Theme.getSize("default_margin").height + width: parent.width + } + + // Cloud image + Image { id: cloudImage anchors.horizontalCenter: parent.horizontalCenter source: UM.Theme.getImage("first_run_ultimaker_cloud") + fillMode: Image.PreserveAspectFit + width: UM.Theme.getSize("welcome_wizard_content_image_big").width + sourceSize.width: width + sourceSize.height: height } - Label // A title-ish text + + // Filler item + Item { - id: highlightTextLabel - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@text", "Your key to connected 3D printing") - textFormat: Text.RichText - color: UM.Theme.getColor("primary") - font: UM.Theme.getFont("medium") - renderType: Text.NativeRendering + height: UM.Theme.getSize("default_margin").height + width: parent.width } - Label // A number of text items + // Motivational icons + Row { - id: textLabel - anchors.horizontalCenter: parent.horizontalCenter - text: + id: motivationRow + width: parent.width + + Column { - // There are 3 text items, each of which is translated separately as a single piece of text. - var full_text = "" - var t = "" + id: marketplaceColumn + width: Math.round(parent.width / 3) + spacing: UM.Theme.getSize("default_margin").height - t = catalog.i18nc("@text", "- Customize your experience with more print profiles and plugins") - full_text += "
" + t + "
" - - t = catalog.i18nc("@text", "- Stay flexible by syncing your setup and loading it anywhere") - full_text += "" + t + "
" - - t = catalog.i18nc("@text", "- Increase efficiency with a remote workflow on Ultimaker printers") - full_text += "" + t + "
" - - return full_text + Image + { + id: marketplaceImage + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + width: UM.Theme.getSize("welcome_wizard_cloud_content_image").width + source: UM.Theme.getIcon("package") + sourceSize.width: width + sourceSize.height: height + } + Label + { + id: marketplaceTextLabel + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + text: catalog.i18nc("@text", "Add material settings and plugins from the Marketplace") + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + } + } + + Column + { + id: syncColumn + width: Math.round(parent.width / 3) + spacing: UM.Theme.getSize("default_margin").height + + Image + { + id: syncImage + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + width: UM.Theme.getSize("welcome_wizard_cloud_content_image").width + source: UM.Theme.getIcon("material_spool") + sourceSize.width: width + sourceSize.height: height + } + Label + { + id: syncTextLabel + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + text: catalog.i18nc("@text", "Backup and sync your material settings and plugins") + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + } + } + + Column + { + id: communityColumn + width: Math.round(parent.width / 3) + spacing: UM.Theme.getSize("default_margin").height + + Image + { + id: communityImage + anchors.horizontalCenter: communityColumn.horizontalCenter + fillMode: Image.PreserveAspectFit + width: UM.Theme.getSize("welcome_wizard_cloud_content_image").width + source: UM.Theme.getIcon("group") + sourceSize.width: width + sourceSize.height: height + } + Label + { + id: communityTextLabel + anchors.horizontalCenter: communityColumn.horizontalCenter + width: parent.width + text: catalog.i18nc("@text", "Share ideas and get help from 48,000+ users in the Ultimaker Community") + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + color: UM.Theme.getColor("text") + font: UM.Theme.getFont("default") + renderType: Text.NativeRendering + } } - textFormat: Text.RichText - font: UM.Theme.getFont("medium") - color: UM.Theme.getColor("text") - renderType: Text.NativeRendering } - // "Sign in" and "Create an account" exist inside the column + // Sign in Button Cura.PrimaryButton { id: signInButton - height: createAccountButton.height - width: createAccountButton.width anchors.horizontalCenter: parent.horizontalCenter text: catalog.i18nc("@button", "Sign in") onClicked: Cura.API.account.login() @@ -135,16 +209,15 @@ Item } } - Cura.SecondaryButton + // Create an account button + Cura.TertiaryButton { id: createAccountButton anchors.horizontalCenter: parent.horizontalCenter - text: catalog.i18nc("@button","Create account") - onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create") + text: catalog.i18nc("@text", "Create a free Ultimaker Account") + onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create") } } - - } // The "Skip" button exists on the bottom right diff --git a/resources/qml/WelcomePages/WelcomeContent.qml b/resources/qml/WelcomePages/WelcomeContent.qml index 1464e363a8..45a0bf4a7c 100644 --- a/resources/qml/WelcomePages/WelcomeContent.qml +++ b/resources/qml/WelcomePages/WelcomeContent.qml @@ -7,7 +7,6 @@ import QtQuick.Controls 2.3 import UM 1.3 as UM import Cura 1.1 as Cura - // // This component contains the content for the "Welcome" page of the welcome on-boarding process. // @@ -15,11 +14,39 @@ Item { UM.I18nCatalog { id: catalog; name: "cura" } - Column // Arrange the items vertically and put everything in the center + // Arrange the items vertically and put everything in the center + Column { - anchors.centerIn: parent - width: parent.width - spacing: 2 * UM.Theme.getSize("wide_margin").height + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + spacing: UM.Theme.getSize("thick_margin").height + width:parent.width + + + // Filler item + Item + { + height: UM.Theme.getSize("thick_margin").width + width: parent.width + } + + Image + { + id: curaImage + anchors.horizontalCenter: parent.horizontalCenter + source: UM.Theme.getImage("first_run_welcome_cura") + fillMode: Image.PreserveAspectFit + width: UM.Theme.getSize("welcome_wizard_content_image_big").width + sourceSize.width: width + sourceSize.height: height + } + + // Filler item + Item + { + height: UM.Theme.getSize("thick_margin").width + width: parent.width + } Label { @@ -28,35 +55,43 @@ Item horizontalAlignment: Text.AlignHCenter text: catalog.i18nc("@label", "Welcome to Ultimaker Cura") color: UM.Theme.getColor("primary_button") - font: UM.Theme.getFont("huge") + font: UM.Theme.getFont("huge_bold") renderType: Text.NativeRendering } - Image - { - id: curaImage - anchors.horizontalCenter: parent.horizontalCenter - source: UM.Theme.getImage("first_run_welcome_cura") - } - Label { id: textLabel anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@text", "Please follow these steps to set up\nUltimaker Cura. This will only take a few moments.") + width: titleLabel.width + 2 * UM.Theme.getSize("thick_margin").width + text: catalog.i18nc("@text", "Please follow these steps to set up Ultimaker Cura. This will only take a few moments.") + wrapMode: Text.Wrap font: UM.Theme.getFont("medium") color: UM.Theme.getColor("text") renderType: Text.NativeRendering } + // Filler item + Item + { + height: UM.Theme.getSize("thick_margin").height + width: parent.width + } + Cura.PrimaryButton { id: getStartedButton anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: UM.Theme.getSize("wide_margin").width text: catalog.i18nc("@button", "Get started") onClicked: base.showNextPage() } + + // Filler item + Item + { + height: UM.Theme.getSize("thick_margin").height + width: parent.width + } } } diff --git a/resources/qml/WelcomePages/WhatsNewContent.qml b/resources/qml/WelcomePages/WhatsNewContent.qml index 0fc5fa06ba..68be6379d6 100644 --- a/resources/qml/WelcomePages/WhatsNewContent.qml +++ b/resources/qml/WelcomePages/WhatsNewContent.qml @@ -1,8 +1,9 @@ -// Copyright (c) 2019 Ultimaker B.V. +// Copyright (c) 2021 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.10 import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 import UM 1.3 as UM import Cura 1.1 as Cura @@ -10,9 +11,12 @@ import Cura 1.1 as Cura // // This component contains the content for the "What's new in Ultimaker Cura" page of the welcome on-boarding process. +// Previously this was just the changelog, but now it will just have the larger stories, the changelog has its own page. // Item { + property var manager: CuraApplication.getWhatsNewPagesModel() + UM.I18nCatalog { id: catalog; name: "cura" } Label @@ -21,39 +25,164 @@ Item anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter horizontalAlignment: Text.AlignHCenter - text: catalog.i18nc("@label", "What's new in Ultimaker Cura") + text: catalog.i18nc("@label", "What's New") color: UM.Theme.getColor("primary_button") font: UM.Theme.getFont("huge") renderType: Text.NativeRendering } - Cura.ScrollableTextArea + Item { - id: whatsNewTextArea - + id: topSpacer anchors.top: titleLabel.bottom - anchors.bottom: getStartedButton.top - anchors.topMargin: UM.Theme.getSize("wide_margin").height - anchors.bottomMargin: UM.Theme.getSize("wide_margin").height - anchors.left: parent.left - anchors.right: parent.right - - ScrollBar.horizontal.policy: ScrollBar.AlwaysOff - - textArea.text: CuraApplication.getTextManager().getChangeLogText() - textArea.textFormat: Text.RichText - textArea.wrapMode: Text.WordWrap - textArea.readOnly: true - textArea.font: UM.Theme.getFont("medium") - textArea.onLinkActivated: Qt.openUrlExternally(link) + height: UM.Theme.getSize("default_margin").height + width: UM.Theme.getSize("default_margin").width } - Cura.PrimaryButton + Rectangle { - id: getStartedButton - anchors.right: parent.right + anchors + { + top: topSpacer.bottom + bottom: whatsNewDots.top + left: parent.left + right: parent.right + margins: UM.Theme.getSize("default_margin").width * 2 + } + + color: UM.Theme.getColor("viewport_overlay") + + StackLayout + { + id: whatsNewViewport + + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("default_margin").width + horizontalCenter: parent.horizontalCenter + } + height: parent.height + width: parent.width + + currentIndex: whatsNewDots.currentIndex + + Repeater + { + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("default_margin").width / 2 + horizontalCenter: parent.horizontalCenter + } + + model: manager.subpageCount + + Rectangle + { + Layout.alignment: Qt.AlignHCenter + color: UM.Theme.getColor("viewport_overlay") + + Image + { + id: subpageImage + + anchors + { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: UM.Theme.getSize("default_margin").width + } + width: parent.width - (UM.Theme.getSize("default_margin").width * 2) + height: (parent.height - UM.Theme.getSize("default_margin").height) * 0.75 + fillMode: Image.PreserveAspectFit + + source: manager.getSubpageImageSource(index) + } + + Cura.ScrollableTextArea + { + id: subpageText + + anchors + { + top: subpageImage.bottom + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + width: parent.width - (UM.Theme.getSize("default_margin").width * 2) + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + back_color: UM.Theme.getColor("viewport_overlay") + do_borders: false + + textArea.wrapMode: TextEdit.Wrap + textArea.text: manager.getSubpageText(index) + textArea.textFormat: Text.RichText + textArea.readOnly: true + textArea.font: UM.Theme.getFont("medium") + textArea.onLinkActivated: Qt.openUrlExternally(link) + } + } + } + } + } + + PageIndicator + { + id: whatsNewDots + + currentIndex: whatsNewViewport.currentIndex + count: whatsNewViewport.count + interactive: true + + anchors + { + bottom: bottomSpacer.top + horizontalCenter: parent.horizontalCenter + } + + delegate: + Rectangle + { + width: UM.Theme.getSize("thin_margin").width + height: UM.Theme.getSize("thin_margin").height + + radius: width / 2 + color: + index === whatsNewViewport.currentIndex ? + UM.Theme.getColor("primary") : + UM.Theme.getColor("secondary_button_shadow") + } + } + + Item + { + id: bottomSpacer + anchors.bottom: whatsNewNextButton.top + height: UM.Theme.getSize("default_margin").height / 2 + width: UM.Theme.getSize("default_margin").width / 2 + } + + Cura.TertiaryButton + { + id: whatsNewNextButton + anchors.left: parent.left anchors.bottom: parent.bottom text: base.currentItem.next_page_button_text onClicked: base.showNextPage() } + + Cura.PrimaryButton + { + id: whatsNewSubpageButton + anchors.right: parent.right + anchors.bottom: parent.bottom + text: catalog.i18nc("@button", "Next") + onClicked: + whatsNewDots.currentIndex === (whatsNewDots.count - 1) ? + base.showNextPage() : + ++whatsNewDots.currentIndex + } } diff --git a/resources/qml/Widgets/ScrollableTextArea.qml b/resources/qml/Widgets/ScrollableTextArea.qml index 48a7f49255..86dcad8112 100644 --- a/resources/qml/Widgets/ScrollableTextArea.qml +++ b/resources/qml/Widgets/ScrollableTextArea.qml @@ -15,13 +15,16 @@ ScrollView { property alias textArea: _textArea + property var back_color: UM.Theme.getColor("main_background") + property var do_borders: true + clip: true background: Rectangle // Border { - color: UM.Theme.getColor("main_background") + color: back_color border.color: UM.Theme.getColor("thick_lining") - border.width: UM.Theme.getSize("default_lining").width + border.width: do_borders ? UM.Theme.getSize("default_lining").width : 0 } TextArea diff --git a/resources/texts/whats_new/0.html b/resources/texts/whats_new/0.html new file mode 100644 index 0000000000..6dae7bfa35 --- /dev/null +++ b/resources/texts/whats_new/0.html @@ -0,0 +1,5 @@ +
+ Lorem ipsum et cetera ad infinitum dolce et gabana carpe diem.
+ Link to EXAMPLE.
+
Pa's wijze lynx bezag vroom het fikse aquaduct.
diff --git a/resources/texts/whats_new/2.html b/resources/texts/whats_new/2.html new file mode 100644 index 0000000000..1260befcb5 --- /dev/null +++ b/resources/texts/whats_new/2.html @@ -0,0 +1,2 @@ +The quick brown fox jumps over the lazy dog.
diff --git a/resources/themes/cura-light/icons/group.svg b/resources/themes/cura-light/icons/group.svg new file mode 100644 index 0000000000..0debb0f300 --- /dev/null +++ b/resources/themes/cura-light/icons/group.svg @@ -0,0 +1,12 @@ + + + diff --git a/resources/themes/cura-light/icons/material_spool.svg b/resources/themes/cura-light/icons/material_spool.svg new file mode 100644 index 0000000000..66cc02a57b --- /dev/null +++ b/resources/themes/cura-light/icons/material_spool.svg @@ -0,0 +1,8 @@ + + + diff --git a/resources/themes/cura-light/icons/package.svg b/resources/themes/cura-light/icons/package.svg new file mode 100644 index 0000000000..4f74a43c42 --- /dev/null +++ b/resources/themes/cura-light/icons/package.svg @@ -0,0 +1,7 @@ + + + diff --git a/resources/themes/cura-light/images/first_run_ultimaker_cloud.svg b/resources/themes/cura-light/images/first_run_ultimaker_cloud.svg index 1e9b313862..1476e7705d 100644 --- a/resources/themes/cura-light/images/first_run_ultimaker_cloud.svg +++ b/resources/themes/cura-light/images/first_run_ultimaker_cloud.svg @@ -1,12 +1,17 @@ - - \ No newline at end of file + diff --git a/resources/themes/cura-light/images/first_run_welcome_cura.svg b/resources/themes/cura-light/images/first_run_welcome_cura.svg index fddb073c82..3d957884b4 100644 --- a/resources/themes/cura-light/images/first_run_welcome_cura.svg +++ b/resources/themes/cura-light/images/first_run_welcome_cura.svg @@ -1,11 +1,17 @@ - - diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 5a99b023eb..789161f9fc 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -34,6 +34,11 @@ "weight": 50, "family": "Noto Sans" }, + "huge_bold": { + "size": 1.8, + "weight": 63, + "family": "Noto Sans" + }, "medium": { "size": 1.16, "weight": 40, @@ -576,7 +581,7 @@ "monitor_preheat_temperature_control": [4.5, 2.0], - "welcome_wizard_window": [46.0, 45], + "welcome_wizard_window": [46, 45], "modal_window_minimum": [60.0, 45], "license_window_minimum": [45, 45], "wizard_progress": [10.0, 0.0], @@ -633,6 +638,9 @@ "monitor_progress_bar": [16.5, 1.0], "monitor_margin": [1.5, 1.5], - "table_row": [2.0, 2.0] + "table_row": [2.0, 2.0], + + "welcome_wizard_content_image_big": [18, 15], + "welcome_wizard_cloud_content_image": [4, 4] } }