diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 8369c2a743..f89f8d63dd 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -21,36 +21,45 @@ UM.MainWindow // Cura application window title title: catalog.i18nc("@title:window", "Ultimaker Cura") - viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) + //viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) + viewportRect: Qt.rect(0, 0, 1.0, 1.0) backgroundColor: UM.Theme.getColor("viewport_background") UM.I18nCatalog { id: catalog - name: "cura" + name:"cura" } - onWidthChanged: + function showTooltip(item, position, text) + { + tooltip.text = text; + position = item.mapToItem(backgroundItem, position.x - UM.Theme.getSize("default_arrow").width, position.y); + tooltip.show(position); + } + + function hideTooltip() + { + tooltip.hide(); + } + + /*onWidthChanged: { // If slidebar is collapsed then it should be invisible // otherwise after the main_window resize the sidebar will be fully re-drawn - if (sidebar.collapsed) - { - if (sidebar.visible == true) - { + if (sidebar.collapsed){ + if (sidebar.visible == true){ sidebar.visible = false sidebar.initialWidth = 0 } } - else - { - if (sidebar.visible == false) - { + else{ + if (sidebar.visible == false){ sidebar.visible = true sidebar.initialWidth = UM.Theme.getSize("sidebar").width } } - } + }*/ Component.onCompleted: { @@ -69,11 +78,16 @@ UM.MainWindow CuraApplication.purgeWindows() } - Column + Item { id: backgroundItem anchors.fill: parent + SidebarTooltip + { + id: tooltip + } + signal hasMesh(string name) //this signal sends the filebase name so it can be used for the JobSpecs.qml function getMeshName(path) { @@ -94,26 +108,34 @@ UM.MainWindow ApplicationMenu { - id: menu + id: applicationMenu window: base } TopHeader { id: topHeader - anchors.left: parent.left - anchors.right: parent.right + anchors + { + left: parent.left + right: parent.right + top: applicationMenu.bottom + } } Item { id: contentItem - width: parent.width - height: parent.height - menu.height - topHeader.height - z: topHeader.z - 1 + anchors + { + top: topHeader.bottom + bottom: parent.bottom + left: parent.left + right: parent.right + } - Keys.forwardTo: menu + Keys.forwardTo: applicationMenu DropArea { @@ -145,41 +167,39 @@ UM.MainWindow } } + Loader + { + // The stage menu is, as the name implies, a menu that is defined by the active stage. + // Note that this menu does not need to be set at all! It's perfectly acceptable to have a stage + // without this menu! + id: stageMenu + + anchors + { + left: parent.left + right: parent.right + top: parent.top + margins: UM.Theme.getSize("default_margin").height + } + + height: 50 + + source: UM.Controller.activeStage.stageMenuComponent + } + JobSpecs { id: jobSpecs anchors { bottom: parent.bottom - right: sidebar.left + //right: sidebar.left bottomMargin: UM.Theme.getSize("default_margin").height rightMargin: UM.Theme.getSize("default_margin").width } } - Button - { - id: openFileButton - text: catalog.i18nc("@action:button", "Open File") - iconSource: UM.Theme.getIcon("load") - style: UM.Theme.styles.tool_button - tooltip: "" - anchors - { - top: parent.top - topMargin: UM.Theme.getSize("default_margin").height - left: parent.left - } - action: Cura.Actions.open - } - MachineAndConfigurationSelector - { - anchors.left: openFileButton.right - //anchors.right: sidebar.left - anchors.leftMargin: UM.Theme.getSize("default_margin").height - anchors.top: openFileButton.top - } Toolbar { @@ -189,7 +209,7 @@ UM.MainWindow property int mouseY: base.mouseY anchors { - top: openFileButton.bottom + top: stageMenu.bottom topMargin: UM.Theme.getSize("window_margin").height left: parent.left } @@ -206,7 +226,7 @@ UM.MainWindow } } - ApplicationViews + /*ApplicationViews { id: applicationViews @@ -216,7 +236,7 @@ UM.MainWindow top: parent.top right: sidebar.left } - } + }*/ Loader { @@ -227,7 +247,7 @@ UM.MainWindow top: parent.top bottom: parent.bottom left: parent.left - right: sidebar.left + right: parent.right } MouseArea @@ -241,7 +261,7 @@ UM.MainWindow source: UM.Controller.activeStage.mainComponent } - Loader + /*Loader { id: sidebar @@ -311,7 +331,7 @@ UM.MainWindow acceptedButtons: Qt.AllButtons onWheel: wheel.accepted = true } - } + }*/ UM.MessageStack { @@ -338,15 +358,33 @@ UM.MainWindow bottom: parent.bottom } } + + + ProgressAndSaveWidget + { + anchors.right: parent.right + anchors.bottom: parent.bottom + width: UM.Theme.getSize("sidebar").width + anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + onShowTooltip: + { + base.showTooltip(item, location, text) + } + onHideTooltip: + { + base.hideTooltip() + } + } } } // Expand or collapse sidebar - Connections + /*Connections { target: Cura.Actions.expandSidebar onTriggered: sidebar.callExpandOrCollapse() - } + }*/ UM.PreferencesDialog { @@ -356,10 +394,10 @@ UM.MainWindow { //; Remove & re-add the general page as we want to use our own instead of uranium standard. removePage(0); - insertPage(0, catalog.i18nc("@title:tab", "General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); + insertPage(0, catalog.i18nc("@title:tab","General"), Qt.resolvedUrl("Preferences/GeneralPage.qml")); removePage(1); - insertPage(1, catalog.i18nc("@title:tab", "Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); + insertPage(1, catalog.i18nc("@title:tab","Settings"), Qt.resolvedUrl("Preferences/SettingVisibilityPage.qml")); insertPage(2, catalog.i18nc("@title:tab", "Printers"), Qt.resolvedUrl("Preferences/MachinesPage.qml")); @@ -532,7 +570,7 @@ UM.MainWindow id: openDialog; //: File open dialog title - title: catalog.i18nc("@title:window", "Open file(s)") + title: catalog.i18nc("@title:window","Open file(s)") modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal; selectMultiple: true nameFilters: UM.MeshFileHandler.supportedReadFileTypes; @@ -638,7 +676,8 @@ UM.MainWindow modality: Qt.ApplicationModal } - MessageDialog { + MessageDialog + { id: infoMultipleFilesWithGcodeDialog title: catalog.i18nc("@title:window", "Open File(s)") icon: StandardIcon.Information diff --git a/resources/qml/ExtruderIcon.qml b/resources/qml/ExtruderIcon.qml index 2c2edcb492..580ff5dce9 100644 --- a/resources/qml/ExtruderIcon.qml +++ b/resources/qml/ExtruderIcon.qml @@ -4,7 +4,6 @@ import UM 1.2 as UM Item { - id: extruderIconItem implicitWidth: UM.Theme.getSize("button").width diff --git a/resources/qml/MaterialAndVariantSelector.qml b/resources/qml/MaterialAndVariantSelector.qml index 325ffa85a5..fff3ef1100 100644 --- a/resources/qml/MaterialAndVariantSelector.qml +++ b/resources/qml/MaterialAndVariantSelector.qml @@ -17,7 +17,7 @@ Rectangle id: base color: UM.Theme.getColor("sidebar") - + // Height has an extra 2x margin for the top & bottom margin. height: childrenRect.height + 2 * UM.Theme.getSize("default_margin").width diff --git a/resources/qml/PrepareSidebar.qml b/resources/qml/ProfileAndSettingComponent.qml similarity index 66% rename from resources/qml/PrepareSidebar.qml rename to resources/qml/ProfileAndSettingComponent.qml index 7c99e6e145..33c2f37fb1 100644 --- a/resources/qml/PrepareSidebar.qml +++ b/resources/qml/ProfileAndSettingComponent.qml @@ -16,14 +16,10 @@ Rectangle { id: base + height: childrenRect.height + property int currentModeIndex: -1 property bool hideSettings: PrintInformation.preSliced - property bool hideView: Cura.MachineManager.activeMachineName == "" - - // Is there an output device for this printer? - property bool printerConnected: Cura.MachineManager.printerConnected - property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands - property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null property variant printDuration: PrintInformation.currentPrintTime property variant printMaterialLengths: PrintInformation.materialLengths @@ -34,7 +30,8 @@ Rectangle color: UM.Theme.getColor("sidebar") UM.I18nCatalog { id: catalog; name:"cura"} - Timer { + Timer + { id: tooltipDelayTimer interval: 500 repeat: false @@ -59,7 +56,8 @@ Rectangle tooltip.hide(); } - function strPadLeft(string, pad, length) { + function strPadLeft(string, pad, length) + { return (new Array(length + 1).join(pad) + string).slice(-length); } @@ -86,35 +84,9 @@ Rectangle } } - SidebarHeader - { - id: header - width: parent.width - visible: !hideSettings && (machineExtruderCount.properties.value > 1 || Cura.MachineManager.hasMaterials || Cura.MachineManager.hasVariants) - anchors.top: parent.top - - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - - Rectangle - { - id: headerSeparator - width: parent.width - visible: settingsModeSelection.visible && header.visible - height: visible ? UM.Theme.getSize("sidebar_lining").height : 0 - color: UM.Theme.getColor("sidebar_lining") - anchors.top: header.bottom - anchors.topMargin: visible ? UM.Theme.getSize("sidebar_margin").height : 0 - } - onCurrentModeIndexChanged: { UM.Preferences.setValue("cura/active_mode", currentModeIndex); - if(modesListModel.count > base.currentModeIndex) - { - sidebarContents.replace(modesListModel.get(base.currentModeIndex).item, { "replace": true }) - } } Label @@ -122,176 +94,129 @@ Rectangle id: settingsModeLabel text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified") renderType: Text.NativeRendering - anchors.left: parent.left - anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width - anchors.top: hideSettings ? machineSelection.bottom : headerSeparator.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + + anchors + { + left: parent.left + top: parent.top + margins: UM.Theme.getSize("sidebar_margin").width + } + width: Math.round(parent.width * 0.45) + height: contentHeight font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") - visible: !hideView } - // Settings mode selection toggle - Item - { - id: settingsModeSelection + ListView + { + // Settings mode selection toggle + id: settingsModeSelection + model: modesListModel width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("sidebar_header_mode_toggle").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - anchors.top: - { - if (settingsModeLabel.contentWidth >= parent.width - width - UM.Theme.getSize("sidebar_margin").width * 2) - { - return settingsModeLabel.bottom; - } - else - { - return headerSeparator.bottom; - } - } - visible: !hideSettings && !hideView - - Component - { - id: wizardDelegate - - Button - { - id: control - - height: settingsModeSelection.height - width: Math.round(parent.width / 2) - - anchors.left: parent.left - anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) - anchors.verticalCenter: parent.verticalCenter - - ButtonGroup.group: modeMenuGroup - - checkable: true - checked: base.currentModeIndex == index - onClicked: base.currentModeIndex = index - - onHoveredChanged: - { - if (hovered) - { - tooltipDelayTimer.item = settingsModeSelection - tooltipDelayTimer.text = model.tooltipText - tooltipDelayTimer.start() - } - else - { - tooltipDelayTimer.stop() - base.hideTooltip() - } - } - - background: Rectangle - { - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border") - - // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") - } - - contentItem: Label - { - text: model.text - font: UM.Theme.getFont("default") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - renderType: Text.NativeRendering - elide: Text.ElideRight - color: - { - if(control.pressed) - { - return UM.Theme.getColor("action_button_active_text"); - } - else if(control.hovered) - { - return UM.Theme.getColor("action_button_hovered_text"); - } - return UM.Theme.getColor("action_button_text"); - } - } - } - } + anchors.top: settingsModeLabel.top ButtonGroup { id: modeMenuGroup } - ListView + delegate: Button { - id: modesList - model: modesListModel - delegate: wizardDelegate - anchors.top: parent.top + id: control + + height: settingsModeSelection.height + width: Math.round(parent.width / 2) + anchors.left: parent.left - width: parent.width - } - } + anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2) + anchors.verticalCenter: parent.verticalCenter - StackView - { - id: sidebarContents + ButtonGroup.group: modeMenuGroup - anchors.bottom: footerSeparator.top - anchors.top: settingsModeSelection.bottom - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height - anchors.left: base.left - anchors.right: base.right - visible: !hideSettings + checkable: true + checked: base.currentModeIndex == index + onClicked: base.currentModeIndex = index - replaceEnter: Transition { - PropertyAnimation { - property: "opacity" - from: 0 - to:1 - duration: 100 + onHoveredChanged: + { + if (hovered) + { + tooltipDelayTimer.item = settingsModeSelection + tooltipDelayTimer.text = model.tooltipText + tooltipDelayTimer.start() + } + else + { + tooltipDelayTimer.stop() + base.hideTooltip() + } + } + + background: Rectangle + { + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border") + + // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is + color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + } + + contentItem: Label + { + text: model.text + font: UM.Theme.getFont("default") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + renderType: Text.NativeRendering + elide: Text.ElideRight + color: + { + if(control.pressed) + { + return UM.Theme.getColor("action_button_active_text"); + } + else if(control.hovered) + { + return UM.Theme.getColor("action_button_hovered_text"); + } + return UM.Theme.getColor("action_button_text"); + } } } - - replaceExit: Transition { - PropertyAnimation { - property: "opacity" - from: 1 - to:0 - duration: 100 - } - } - } - - Loader - { - anchors.bottom: footerSeparator.top - anchors.top: headerSeparator.bottom - anchors.left: base.left - anchors.right: base.right - source: "SidebarContents.qml" - } - - Rectangle - { - id: footerSeparator - width: parent.width - height: UM.Theme.getSize("sidebar_lining").height - color: UM.Theme.getColor("sidebar_lining") - anchors.bottom: printSpecs.top - anchors.bottomMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2 + UM.Theme.getSize("progressbar").height + UM.Theme.getFont("default_bold").pixelSize) } Item + { + id: sidebarContents + anchors.top: settingsModeSelection.bottom + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + anchors.left: parent.left + anchors.right: parent.right + height: 500 + + // We load both of them at once (instead of using a loader) because the advanced sidebar can take + // quite some time to load. So in this case we sacrifice memory for speed. + SidebarAdvanced + { + anchors.fill: parent + visible: currentModeIndex == 1 + } + + SidebarSimple + { + anchors.fill: parent + visible: currentModeIndex != 1 + } + } + + /*Item { id: printSpecs anchors.left: parent.left @@ -499,22 +424,23 @@ Rectangle } } } - } + }*/ // SaveButton is actually the bottom footer panel. - SaveButton + /*SaveButton { id: saveButton implicitWidth: base.width anchors.top: footerSeparator.bottom anchors.topMargin: UM.Theme.getSize("sidebar_margin").height anchors.bottom: parent.bottom - } + }*/ + /* SidebarTooltip { id: tooltip - } + }*/ // Setting mode: Recommended or Custom ListModel @@ -522,35 +448,15 @@ Rectangle id: modesListModel } - SidebarSimple - { - id: sidebarSimple - visible: false - - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - - SidebarAdvanced - { - id: sidebarAdvanced - visible: false - - onShowTooltip: base.showTooltip(item, location, text) - onHideTooltip: base.hideTooltip() - } - Component.onCompleted: { modesListModel.append({ text: catalog.i18nc("@title:tab", "Recommended"), - tooltipText: catalog.i18nc("@tooltip", "Recommended Print Setup

Print with the recommended settings for the selected printer, material and quality."), - item: sidebarSimple + tooltipText: catalog.i18nc("@tooltip", "Recommended Print Setup

Print with the recommended settings for the selected printer, material and quality.") }) modesListModel.append({ text: catalog.i18nc("@title:tab", "Custom"), - tooltipText: catalog.i18nc("@tooltip", "Custom Print Setup

Print with finegrained control over every last bit of the slicing process."), - item: sidebarAdvanced + tooltipText: catalog.i18nc("@tooltip", "Custom Print Setup

Print with finegrained control over every last bit of the slicing process.") }) var index = Math.round(UM.Preferences.getValue("cura/active_mode")) @@ -564,24 +470,4 @@ Rectangle currentModeIndex = 0; } } - - UM.SettingPropertyProvider - { - id: machineExtruderCount - - containerStack: Cura.MachineManager.activeMachine - key: "machine_extruder_count" - watchedProperties: [ "value" ] - storeIndex: 0 - } - - UM.SettingPropertyProvider - { - id: machineHeatedBed - - containerStack: Cura.MachineManager.activeMachine - key: "machine_heated_bed" - watchedProperties: [ "value" ] - storeIndex: 0 - } } diff --git a/resources/qml/ProgressAndSaveWidget.qml b/resources/qml/ProgressAndSaveWidget.qml new file mode 100644 index 0000000000..88819af759 --- /dev/null +++ b/resources/qml/ProgressAndSaveWidget.qml @@ -0,0 +1,237 @@ +// Copyright (c) 2017 Ultimaker B.V. +// Cura is released under the terms of the LGPLv3 or higher. + +import QtQuick 2.7 +import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.3 + +import UM 1.2 as UM +import Cura 1.0 as Cura + +Rectangle +{ + id: base + + // We need a whole lot of print duration information. + property variant printDuration: PrintInformation.currentPrintTime + + // This widget doesn't show tooltips by itself. Instead it emits signals so others can do something with it. + signal showTooltip(Item item, point location, string text) + signal hideTooltip() + + // Also add an extra margin, as we ant some breathing room around the edges. + height: childrenRect.height + UM.Theme.getSize("sidebar_margin").height + Label + { + id: timeDetails + anchors.left: parent.left + anchors.bottom: costSpec.top + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + + font: UM.Theme.getFont("large") + color: UM.Theme.getColor("text_subtext") + text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short) + renderType: Text.NativeRendering + + MouseArea + { + id: timeDetailsMouseArea + anchors.fill: parent + hoverEnabled: true + + onEntered: + { + if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) + { + // All the time information for the different features is achieved + var print_time = PrintInformation.getFeaturePrintTimes(); + var total_seconds = parseInt(base.printDuration.getDisplayString(UM.DurationFormat.Seconds)) + + // A message is created and displayed when the user hover the time label + var tooltip_html = "%1
".arg(catalog.i18nc("@tooltip", "Time specification")); + for(var feature in print_time) + { + if(!print_time[feature].isTotalDurationZero) + { + tooltip_html += "" + + "".arg(print_time[feature].getDisplayString(UM.DurationFormat.ISO8601).slice(0,-3)) + + "".arg(Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds)) + + ""; + } + } + tooltip_html += "
" + feature + ":  %1  %1%
"; + //print("trying to show tooltip", base, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), tooltip_html) + base.showTooltip(parent, Qt.point(0, 0), tooltip_html); + } + } + onExited: + { + base.hideTooltip(); + } + } + } + + Label + { + function formatRow(items) + { + var row_html = ""; + for(var item = 0; item < items.length; item++) + { + if (item == 0) + { + row_html += "%1".arg(items[item]); + } + else + { + row_html += "  %1".arg(items[item]); + } + } + row_html += ""; + return row_html; + } + + function getSpecsData() + { + var lengths = []; + var total_length = 0; + var weights = []; + var total_weight = 0; + var costs = []; + var total_cost = 0; + var some_costs_known = false; + var names = []; + if(base.printMaterialLengths) + { + for(var index = 0; index < base.printMaterialLengths.length; index++) + { + if(base.printMaterialLengths[index] > 0) + { + names.push(base.printMaterialNames[index]); + lengths.push(base.printMaterialLengths[index].toFixed(2)); + weights.push(String(Math.round(base.printMaterialWeights[index]))); + var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); + costs.push(cost); + if(cost > 0) + { + some_costs_known = true; + } + + total_length += base.printMaterialLengths[index]; + total_weight += base.printMaterialWeights[index]; + total_cost += base.printMaterialCosts[index]; + } + } + } + if(lengths.length == 0) + { + lengths = ["0.00"]; + weights = ["0"]; + costs = ["0.00"]; + } + + var tooltip_html = "%1
".arg(catalog.i18nc("@label", "Cost specification")); + for(var index = 0; index < lengths.length; index++) + { + tooltip_html += formatRow([ + "%1:".arg(names[index]), + catalog.i18nc("@label m for meter", "%1m").arg(lengths[index]), + catalog.i18nc("@label g for grams", "%1g").arg(weights[index]), + "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(costs[index]), + ]); + } + if(lengths.length > 1) + { + tooltip_html += formatRow([ + catalog.i18nc("@label", "Total:"), + catalog.i18nc("@label m for meter", "%1m").arg(total_length.toFixed(2)), + catalog.i18nc("@label g for grams", "%1g").arg(Math.round(total_weight)), + "%1 %2".arg(UM.Preferences.getValue("cura/currency")).arg(total_cost.toFixed(2)), + ]); + } + tooltip_html += "
"; + tooltipText = tooltip_html; + + return tooltipText + } + + id: costSpec + + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + + font: UM.Theme.getFont("very_small") + renderType: Text.NativeRendering + color: UM.Theme.getColor("text_subtext") + elide: Text.ElideMiddle + width: parent.width + property string tooltipText + text: + { + var lengths = []; + var weights = []; + var costs = []; + var someCostsKnown = false; + if(base.printMaterialLengths) { + for(var index = 0; index < base.printMaterialLengths.length; index++) + { + if(base.printMaterialLengths[index] > 0) + { + lengths.push(base.printMaterialLengths[index].toFixed(2)); + weights.push(String(Math.round(base.printMaterialWeights[index]))); + var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2); + costs.push(cost); + if(cost > 0) + { + someCostsKnown = true; + } + } + } + } + if(lengths.length == 0) + { + lengths = ["0.00"]; + weights = ["0"]; + costs = ["0.00"]; + } + var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g"; + if(someCostsKnown) + { + result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency"); + } + return result; + } + + MouseArea + { + id: costSpecMouseArea + anchors.fill: parent + hoverEnabled: true + + onEntered: + { + + if(base.printDuration.valid && !base.printDuration.isTotalDurationZero) + { + var show_data = costSpec.getSpecsData() + + base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), show_data); + } + } + onExited: + { + base.hideTooltip(); + } + } + } + + SaveButton + { + id: saveButton + width: parent.width + height: 100 + anchors.bottom: parent.bottom + } +} \ No newline at end of file diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 2a0a523026..8c561b0d00 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -9,7 +9,9 @@ import QtQuick.Layouts 1.1 import UM 1.1 as UM import Cura 1.0 as Cura -Item { +// This widget does so much more than "just" being a save button, so it should be refactored at some point in time. +Item +{ id: base; UM.I18nCatalog { id: catalog; name:"cura"} @@ -27,10 +29,6 @@ Item { return catalog.i18nc("@label:PrintjobStatus", "Please load a 3D model"); } - if (base.backendState == "undefined") { - return "" - } - switch(base.backendState) { case 1: @@ -48,19 +46,23 @@ Item { } } - function sliceOrStopSlicing() { + function sliceOrStopSlicing() + { try { - if ([1, 5].indexOf(base.backendState) != -1) { + if ([1, 5].indexOf(base.backendState) != -1) + { CuraApplication.backend.forceSlice(); } else { CuraApplication.backend.stopSlicing(); } - } catch (e) { + } catch (e) + { console.log('Could not start or stop slicing', e) } } - Label { + Label + { id: statusLabel width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width anchors.top: parent.top @@ -72,7 +74,8 @@ Item { text: statusText; } - Rectangle { + Rectangle + { id: progressBar width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width height: UM.Theme.getSize("progressbar").height @@ -83,32 +86,37 @@ Item { radius: UM.Theme.getSize("progressbar_radius").width color: UM.Theme.getColor("progressbar_background") - Rectangle { + Rectangle + { width: Math.max(parent.width * base.progress) height: parent.height color: UM.Theme.getColor("progressbar_control") radius: UM.Theme.getSize("progressbar_radius").width - visible: (base.backendState != "undefined" && base.backendState == 2) ? true : false + visible: base.backendState == 2 } } // Shortcut for "save as/print/..." - Action { + Action + { shortcut: "Ctrl+P" onTriggered: { // only work when the button is enabled - if (saveToButton.enabled) { + if (saveToButton.enabled) + { saveToButton.clicked(); } // prepare button - if (prepareButton.enabled) { + if (prepareButton.enabled) + { sliceOrStopSlicing(); } } } - Item { + Item + { id: saveRow width: { // using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect @@ -129,7 +137,8 @@ Item { anchors.right: parent.right clip: true - Row { + Row + { id: additionalComponentsRow anchors.top: parent.top anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right) @@ -138,24 +147,30 @@ Item { spacing: UM.Theme.getSize("default_margin").width } - Component.onCompleted: { + Component.onCompleted: + { saveRow.addAdditionalComponents("saveButton") } - Connections { + Connections + { target: CuraApplication onAdditionalComponentsChanged: saveRow.addAdditionalComponents("saveButton") } - function addAdditionalComponents (areaId) { - if(areaId == "saveButton") { - for (var component in CuraApplication.additionalComponents["saveButton"]) { + function addAdditionalComponents (areaId) + { + if(areaId == "saveButton") + { + for (var component in CuraApplication.additionalComponents["saveButton"]) + { CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow } } } - Connections { + Connections + { target: UM.Preferences onPreferenceChanged: { @@ -166,13 +181,14 @@ Item { } // Prepare button, only shows if auto_slice is off - Button { + Button + { id: prepareButton tooltip: [1, 5].indexOf(base.backendState) != -1 ? catalog.i18nc("@info:tooltip","Slice current printjob") : catalog.i18nc("@info:tooltip","Cancel slicing process") // 1 = not started, 2 = Processing - enabled: base.backendState != "undefined" && ([1, 2].indexOf(base.backendState) != -1) && base.activity - visible: base.backendState != "undefined" && !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity + enabled: ([1, 2].indexOf(base.backendState) != -1) && base.activity + visible: !autoSlice && ([1, 2, 4].indexOf(base.backendState) != -1) && base.activity property bool autoSlice height: UM.Theme.getSize("save_button_save_to_button").height @@ -236,11 +252,12 @@ Item { text: control.text; } } - label: Item { } + label: Item {} } } - Button { + Button + { id: saveToButton tooltip: UM.OutputDeviceManager.activeDeviceDescription; @@ -262,7 +279,8 @@ Item { { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); } - style: ButtonStyle { + style: ButtonStyle + { background: Rectangle { border.width: UM.Theme.getSize("default_lining").width @@ -296,17 +314,7 @@ Item { Label { id: actualLabel anchors.centerIn: parent - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_text"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_text"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_text"); - else - return UM.Theme.getColor("print_button_ready_text"); - } + color:control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") font: UM.Theme.getFont("action_button") text: control.text; } @@ -324,36 +332,49 @@ Item { anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width width: UM.Theme.getSize("save_button_save_to_button").height height: UM.Theme.getSize("save_button_save_to_button").height + // 3 = Done, 5 = Disabled - enabled: base.backendState != "undefined" && (base.backendState == 3 || base.backendState == 5) && base.activity == true - visible: base.backendState != "undefined" && (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true + enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true + visible: (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true - style: ButtonStyle { - background: Rectangle { + style: ButtonStyle + { + background: Rectangle + { id: deviceSelectionIcon border.width: UM.Theme.getSize("default_lining").width border.color: { if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_border"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_pressed_border"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_hovered_border"); - else - return UM.Theme.getColor("print_button_ready_border"); + { + return UM.Theme.getColor("action_button_disabled_border") + } else if(control.pressed) + { + return UM.Theme.getColor("print_button_ready_pressed_border") + } else if(control.hovered) + { + return UM.Theme.getColor("print_button_ready_hovered_border") + } else + { + return UM.Theme.getColor("print_button_ready_border") + } } color: { if(!control.enabled) - return UM.Theme.getColor("action_button_disabled"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_pressed"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_hovered"); - else - return UM.Theme.getColor("print_button_ready"); + { + return UM.Theme.getColor("action_button_disabled") + } else if(control.pressed) + { + return UM.Theme.getColor("print_button_ready_pressed") + } else if(control.hovered) + { + return UM.Theme.getColor("print_button_ready_hovered") + } else + { + return UM.Theme.getColor("print_button_ready") + } } Behavior on color { ColorAnimation { duration: 50; } } anchors.left: parent.left @@ -361,40 +382,34 @@ Item { width: parent.height height: parent.height - UM.RecolorImage { + UM.RecolorImage + { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter width: UM.Theme.getSize("standard_arrow").width height: UM.Theme.getSize("standard_arrow").height sourceSize.width: width sourceSize.height: height - color: - { - if(!control.enabled) - return UM.Theme.getColor("action_button_disabled_text"); - else if(control.pressed) - return UM.Theme.getColor("print_button_ready_text"); - else if(control.hovered) - return UM.Theme.getColor("print_button_ready_text"); - else - return UM.Theme.getColor("print_button_ready_text"); - } + color: control.enabled ? UM.Theme.getColor("print_button_ready_text") : UM.Theme.getColor("action_button_disabled_text") source: UM.Theme.getIcon("arrow_bottom"); } } - label: Label{ } } - menu: Menu { + menu: Menu + { id: devicesMenu; - Instantiator { + Instantiator + { model: devicesModel; - MenuItem { + MenuItem + { text: model.description checkable: true; checked: model.id == UM.OutputDeviceManager.activeDevice; exclusiveGroup: devicesMenuGroup; - onTriggered: { + onTriggered: + { UM.OutputDeviceManager.setActiveDevice(model.id); } } diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index da50b430ac..5a6811926e 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -25,7 +25,6 @@ Item { id: globalProfileRow height: UM.Theme.getSize("sidebar_setup").height - visible: !sidebar.hideSettings anchors { @@ -54,7 +53,6 @@ Item id: globalProfileSelection text: generateActiveQualityText() - enabled: !header.currentExtruderVisible || header.currentExtruderIndex > -1 width: Math.round(parent.width * 0.55) height: UM.Theme.getSize("setting_control").height anchors.left: globalProfileLabel.right @@ -177,9 +175,7 @@ Item right: settingVisibilityMenu.left rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2) } - height: visible ? UM.Theme.getSize("setting_control").height : 0 - Behavior on height { NumberAnimation { duration: 100 } } - + height: UM.Theme.getSize("setting_control").height Timer { id: settingsSearchTimer @@ -292,8 +288,7 @@ Item anchors.bottom: parent.bottom; anchors.right: parent.right; anchors.left: parent.left; - anchors.topMargin: filterContainer.visible ? UM.Theme.getSize("sidebar_margin").height : 0 - Behavior on anchors.topMargin { NumberAnimation { duration: 100 } } + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height style: UM.Theme.styles.scrollview; flickableItem.flickableDirection: Flickable.VerticalFlick; diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index df4f493ea5..15ca60e6e3 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -90,7 +90,8 @@ Column } } - Rectangle { + Rectangle + { id: headerSeparator width: parent.width visible: printerTypeSelectionRow.visible diff --git a/resources/qml/Skeleton/TopHeader.qml b/resources/qml/Skeleton/TopHeader.qml index c24fe86af0..f08a0aaca3 100644 --- a/resources/qml/Skeleton/TopHeader.qml +++ b/resources/qml/Skeleton/TopHeader.qml @@ -15,7 +15,8 @@ Rectangle { id: base - height: UM.Theme.getSize("topheader").height + implicitHeight: UM.Theme.getSize("topheader").height + implicitWidth: UM.Theme.getSize("topheader").width color: UM.Theme.getColor("topheader_background") Image