Merge branch 'master' into container_stack_improvements

This commit is contained in:
ChrisTerBeke 2017-11-06 09:49:44 +01:00
commit d32b7f0091
19 changed files with 616 additions and 57 deletions

1
.gitignore vendored
View File

@ -43,6 +43,7 @@ plugins/ProfileFlattener
plugins/cura-god-mode-plugin
plugins/cura-big-flame-graph
plugins/cura-siemensnx-plugin
plugins/CuraVariSlicePlugin
#Build stuff
CMakeCache.txt

View File

@ -56,6 +56,7 @@ class PrintInformation(QObject):
self._material_lengths = []
self._material_weights = []
self._material_costs = []
self._material_names = []
self._pre_sliced = False
@ -139,6 +140,12 @@ class PrintInformation(QObject):
def materialCosts(self):
return self._material_costs
materialNamesChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialNamesChanged)
def materialNames(self):
return self._material_names
def _onPrintDurationMessage(self, print_time, material_amounts):
self._updateTotalPrintTimePerFeature(print_time)
@ -170,6 +177,7 @@ class PrintInformation(QObject):
self._material_lengths = []
self._material_weights = []
self._material_costs = []
self._material_names = []
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
@ -188,8 +196,10 @@ class PrintInformation(QObject):
weight = float(amount) * float(density) / 1000
cost = 0
material_name = catalog.i18nc("@label unknown material", "Unknown")
if material:
material_guid = material.getMetaDataEntry("GUID")
material_name = material.getName()
if material_guid in material_preference_values:
material_values = material_preference_values[material_guid]
@ -208,10 +218,12 @@ class PrintInformation(QObject):
self._material_weights.append(weight)
self._material_lengths.append(length)
self._material_costs.append(cost)
self._material_names.append(material_name)
self.materialLengthsChanged.emit()
self.materialWeightsChanged.emit()
self.materialCostsChanged.emit()
self.materialNamesChanged.emit()
def _onPreferencesChanged(self, preference):
if preference != "cura/material_settings":

View File

@ -74,6 +74,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
self._can_pause = True
self._can_abort = True
self._can_pre_heat_bed = True
self._can_control_manually = True
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None):
raise NotImplementedError("requestWrite needs to be implemented")
@ -144,6 +145,11 @@ class PrinterOutputDevice(QObject, OutputDevice):
def canAbort(self):
return self._can_abort
# Does the printer support manual control at all
@pyqtProperty(bool, constant=True)
def canControlManually(self):
return self._can_control_manually
@pyqtProperty(QObject, constant=True)
def monitorItem(self):
# Note that we specifically only check if the monitor component is created.

View File

@ -293,7 +293,7 @@ class CuraEngineBackend(QObject, Backend):
error_labels.add(definitions[0].label)
error_labels = ", ".join(error_labels)
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}".format(error_labels)),
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}").format(error_labels),
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.backendStateChange.emit(BackendState.Error)

View File

@ -112,7 +112,6 @@ class LayerView(View):
self._layer_pass = LayerPass.LayerPass(1, 1)
self._compatibility_mode = OpenGLContext.isLegacyOpenGL() or bool(Preferences.getInstance().getValue("view/force_layer_view_compatibility_mode"))
self._layer_pass.setLayerView(self)
self.getRenderer().addRenderPass(self._layer_pass)
return self._layer_pass
def getCurrentLayer(self):
@ -310,7 +309,8 @@ class LayerView(View):
if event.type == Event.ViewActivateEvent:
# Make sure the LayerPass is created
self.getLayerPass()
layer_pass = self.getLayerPass()
self.getRenderer().addRenderPass(layer_pass)
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
self._onGlobalStackChanged()
@ -335,6 +335,7 @@ class LayerView(View):
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
self.getRenderer().removeRenderPass(self._layer_pass)
self._composite_pass.setLayerBindings(self._old_layer_bindings)
self._composite_pass.setCompositeShader(self._old_composite_shader)

View File

@ -103,6 +103,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte
self._can_pause = True
self._can_abort = True
self._can_pre_heat_bed = False
self._can_control_manually = False
self._cluster_size = int(properties.get(b"cluster_size", 0))
self._cleanupRequest()

View File

@ -102,6 +102,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
self._target_bed_temperature = 0
self._processing_preheat_requests = True
self._can_control_manually = False
self.setPriority(3) # Make sure the output device gets selected above local file output
self.setName(key)
self.setShortDescription(i18n_catalog.i18nc("@action:button Preceded by 'Ready to'.", "Print over network"))

View File

@ -56,7 +56,8 @@ class XRayView(View):
# Currently the RenderPass constructor requires a size > 0
# This should be fixed in RenderPass's constructor.
self._xray_pass = XRayPass.XRayPass(1, 1)
self.getRenderer().addRenderPass(self._xray_pass)
self.getRenderer().addRenderPass(self._xray_pass)
if not self._xray_composite_shader:
self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader"))
@ -74,5 +75,6 @@ class XRayView(View):
self._composite_pass.setCompositeShader(self._xray_composite_shader)
if event.type == Event.ViewDeactivateEvent:
self.getRenderer().removeRenderPass(self._xray_pass)
self._composite_pass.setLayerBindings(self._old_layer_bindings)
self._composite_pass.setCompositeShader(self._old_composite_shader)

View File

@ -33,9 +33,10 @@ class XmlMaterialProfile(InstanceContainer):
#
# \param xml_version: The version number found in an XML file.
# \return The corresponding setting_version.
def xmlVersionToSettingVersion(self, xml_version: str) -> int:
@classmethod
def xmlVersionToSettingVersion(cls, xml_version: str) -> int:
if xml_version == "1.3":
return 4
return CuraApplication.SettingVersion
return 0 #Older than 1.3.
def getInheritedFiles(self):
@ -407,15 +408,16 @@ class XmlMaterialProfile(InstanceContainer):
def getConfigurationTypeFromSerialized(self, serialized: str) -> Optional[str]:
return "materials"
def getVersionFromSerialized(self, serialized: str) -> Optional[int]:
@classmethod
def getVersionFromSerialized(cls, serialized: str) -> Optional[int]:
data = ET.fromstring(serialized)
version = 1
version = XmlMaterialProfile.Version
# get setting version
if "version" in data.attrib:
setting_version = self.xmlVersionToSettingVersion(data.attrib["version"])
setting_version = XmlMaterialProfile.xmlVersionToSettingVersion(data.attrib["version"])
else:
setting_version = self.xmlVersionToSettingVersion("1.2")
setting_version = XmlMaterialProfile.xmlVersionToSettingVersion("1.2")
return version * 1000000 + setting_version

View File

@ -5,24 +5,16 @@ import xml.etree.ElementTree as ET
from UM.VersionUpgrade import VersionUpgrade
from cura.CuraApplication import CuraApplication
from .XmlMaterialProfile import XmlMaterialProfile
class XmlMaterialUpgrader(VersionUpgrade):
def getXmlVersion(self, serialized):
data = ET.fromstring(serialized)
version = 1
# get setting version
if "version" in data.attrib:
setting_version = self._xmlVersionToSettingVersion(data.attrib["version"])
else:
setting_version = self._xmlVersionToSettingVersion("1.2")
return version * 1000000 + setting_version
return XmlMaterialProfile.getVersionFromSerialized(serialized)
def _xmlVersionToSettingVersion(self, xml_version: str) -> int:
if xml_version == "1.3":
return 2
return 0 #Older than 1.3.
return XmlMaterialProfile.xmlVersionToSettingVersion(xml_version)
def upgradeMaterial(self, serialised, filename):
data = ET.fromstring(serialised)

View File

@ -19,7 +19,7 @@ def getMetaData():
"mimetype": "application/x-ultimaker-material-profile"
},
"version_upgrade": {
("materials", 1000000): ("materials", 1000003, upgrader.upgradeMaterial),
("materials", 1000000): ("materials", 1000004, upgrader.upgradeMaterial),
},
"sources": {
"materials": {

View File

@ -3974,16 +3974,6 @@
"limit_to_extruder": "support_infill_extruder_nr",
"enabled": "support_enable and support_use_towers",
"settable_per_mesh": true
},
"remove_empty_first_layers":
{
"label": "Remove Empty First Layers",
"description": "Remove empty layers beneath the first printed layer if they are present.",
"type": "bool",
"default_value": true,
"enabled": "not support_enable",
"settable_per_mesh": false,
"settable_per_extruder": false
}
}
},
@ -4894,6 +4884,16 @@
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": true
},
"remove_empty_first_layers":
{
"label": "Remove Empty First Layers",
"description": "Remove empty layers beneath the first printed layer if they are present. Disabling this setting can cause empty first layers if the Slicing Tolerance setting is set to Exclusive or Middle.",
"type": "bool",
"default_value": true,
"enabled": "not support_enable",
"settable_per_mesh": false,
"settable_per_extruder": false
}
}
},

View File

@ -18,7 +18,6 @@ Item {
UM.I18nCatalog { id: catalog; name:"cura"}
height: childrenRect.height
width: childrenRect.width
Connections
{

View File

@ -677,6 +677,341 @@ Column
watchedProperties: ["value"]
}
Column
{
visible: connectedPrinter != null ? connectedPrinter.canControlManually : false
enabled:
{
if (connectedPrinter == null)
{
return false; //Can't control the printer if not connected.
}
if (!connectedPrinter.acceptsCommands)
{
return false; //Not allowed to do anything.
}
if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline")
{
return false; //Printer is in a state where it can't react to manual control
}
return true;
}
Loader
{
sourceComponent: monitorSection
property string label: catalog.i18nc("@label", "Printer control")
}
Row
{
width: base.width - 2 * UM.Theme.getSize("default_margin").width
height: childrenRect.height + UM.Theme.getSize("default_margin").width
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
Label
{
text: catalog.i18nc("@label", "Jog Position")
color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default")
width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
verticalAlignment: Text.AlignVCenter
}
GridLayout
{
columns: 3
rows: 4
rowSpacing: UM.Theme.getSize("default_lining").width
columnSpacing: UM.Theme.getSize("default_lining").height
Label
{
text: catalog.i18nc("@label", "X/Y")
color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default")
width: height
height: UM.Theme.getSize("setting_control").height
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
Layout.row: 1
Layout.column: 2
Layout.preferredWidth: width
Layout.preferredHeight: height
}
Button
{
Layout.row: 2
Layout.column: 2
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_top");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.moveHead(0, distancesRow.currentDistance, 0)
}
}
Button
{
Layout.row: 3
Layout.column: 1
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_left");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.moveHead(-distancesRow.currentDistance, 0, 0)
}
}
Button
{
Layout.row: 3
Layout.column: 3
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_right");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.moveHead(distancesRow.currentDistance, 0, 0)
}
}
Button
{
Layout.row: 4
Layout.column: 2
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("arrow_bottom");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.moveHead(0, -distancesRow.currentDistance, 0)
}
}
Button
{
Layout.row: 3
Layout.column: 2
Layout.preferredWidth: width
Layout.preferredHeight: height
iconSource: UM.Theme.getIcon("home");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.homeHead()
}
}
}
Column
{
spacing: UM.Theme.getSize("default_lining").height
Label
{
text: catalog.i18nc("@label", "Z")
color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default")
width: UM.Theme.getSize("section").height
height: UM.Theme.getSize("setting_control").height
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
Button
{
iconSource: UM.Theme.getIcon("arrow_top");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.moveHead(0, 0, distancesRow.currentDistance)
}
}
Button
{
iconSource: UM.Theme.getIcon("home");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.homeBed()
}
}
Button
{
iconSource: UM.Theme.getIcon("arrow_bottom");
style: monitorButtonStyle
width: height
height: UM.Theme.getSize("setting_control").height
onClicked:
{
connectedPrinter.moveHead(0, 0, -distancesRow.currentDistance)
}
}
}
}
Row
{
id: distancesRow
width: base.width - 2 * UM.Theme.getSize("default_margin").width
height: childrenRect.height + UM.Theme.getSize("default_margin").width
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
property real currentDistance: 10
Label
{
text: catalog.i18nc("@label", "Jog Distance")
color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default")
width: Math.floor(parent.width * 0.4) - UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("setting_control").height
verticalAlignment: Text.AlignVCenter
}
Row
{
Repeater
{
model: distancesModel
delegate: Button
{
height: UM.Theme.getSize("setting_control").height
width: height + UM.Theme.getSize("default_margin").width
text: model.label
exclusiveGroup: distanceGroup
checkable: true
checked: distancesRow.currentDistance == model.value
onClicked: distancesRow.currentDistance = model.value
style: ButtonStyle {
background: Rectangle {
border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_border");
}
else if (control.checked || control.pressed)
{
return UM.Theme.getColor("action_button_active_border");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_border");
}
return UM.Theme.getColor("action_button_border");
}
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled");
}
else if (control.checked || control.pressed)
{
return UM.Theme.getColor("action_button_active");
}
else if (control.hovered)
{
return UM.Theme.getColor("action_button_hovered");
}
return UM.Theme.getColor("action_button");
}
Behavior on color { ColorAnimation { duration: 50; } }
Label {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2
anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_text");
}
else if (control.checked || 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");
}
font: UM.Theme.getFont("default")
text: control.text
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideMiddle
}
}
label: Item { }
}
}
}
}
}
ListModel
{
id: distancesModel
ListElement { label: "0.1"; value: 0.1 }
ListElement { label: "1"; value: 1 }
ListElement { label: "10"; value: 10 }
ListElement { label: "100"; value: 100 }
}
ExclusiveGroup { id: distanceGroup }
}
Loader
{
sourceComponent: monitorSection
@ -754,4 +1089,86 @@ Column
}
}
}
Component
{
id: monitorButtonStyle
ButtonStyle
{
background: Rectangle
{
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("action_button_active_border");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_border");
}
return UM.Theme.getColor("action_button_border");
}
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered");
}
return UM.Theme.getColor("action_button");
}
Behavior on color
{
ColorAnimation
{
duration: 50
}
}
}
label: Item
{
UM.RecolorImage
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: Math.floor(control.width / 2)
height: Math.floor(control.height / 2)
sourceSize.width: width
sourceSize.height: width
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_text");
}
else 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");
}
source: control.iconSource
}
}
}
}
}

View File

@ -18,6 +18,8 @@ Item {
property var backend: CuraApplication.getBackend();
property bool activity: CuraApplication.platformActivity;
property alias buttonRowWidth: saveRow.width
property string fileBaseName
property string statusText:
{
@ -89,17 +91,30 @@ Item {
Item {
id: saveRow
width: base.width
width: {
// using childrenRect.width directly causes a binding loop, because setting the width affects the childrenRect
var children_width = UM.Theme.getSize("default_margin").width;
for (var index in children)
{
var child = children[index];
if(child.visible)
{
children_width += child.width + child.anchors.rightMargin;
}
}
return Math.min(children_width, base.width - UM.Theme.getSize("sidebar_margin").width);
}
height: saveToButton.height
anchors.bottom: parent.bottom
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
anchors.left: parent.left
anchors.right: parent.right
clip: true
Row {
id: additionalComponentsRow
anchors.top: parent.top
anchors.right: saveToButton.visible ? saveToButton.left : parent.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
anchors.rightMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
}

View File

@ -30,6 +30,7 @@ Rectangle
property variant printMaterialLengths: PrintInformation.materialLengths
property variant printMaterialWeights: PrintInformation.materialWeights
property variant printMaterialCosts: PrintInformation.materialCosts
property variant printMaterialNames: PrintInformation.materialNames
color: UM.Theme.getColor("sidebar")
UM.I18nCatalog { id: catalog; name:"cura"}
@ -313,31 +314,32 @@ Rectangle
anchors.bottomMargin: Math.floor(UM.Theme.getSize("sidebar_margin").height * 2 + UM.Theme.getSize("progressbar").height + UM.Theme.getFont("default_bold").pixelSize)
}
Rectangle
Item
{
id: printSpecs
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.bottomMargin: UM.Theme.getSize("sidebar_margin").height
height: timeDetails.height + timeSpecDescription.height + lengthSpec.height
height: timeDetails.height + costSpec.height
width: base.width - (saveButton.buttonRowWidth + UM.Theme.getSize("sidebar_margin").width)
visible: !monitoringPrint
clip: true
Label
{
id: timeDetails
anchors.left: parent.left
anchors.bottom: timeSpecDescription.top
anchors.bottom: costSpec.top
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)
MouseArea
{
id: infillMouseArea
id: timeDetailsMouseArea
anchors.fill: parent
hoverEnabled: true
//enabled: base.settingsEnabled
onEntered:
{
@ -345,19 +347,35 @@ Rectangle
if(base.printDuration.valid && !base.printDuration.isTotalDurationZero)
{
// All the time information for the different features is achieved
var print_time = PrintInformation.getFeaturePrintTimes()
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 content = catalog.i18nc("@tooltip", "<b>Time information</b>")
var content = catalog.i18nc("@tooltip", "<b>Time specification</b><br/><table>");
for(var feature in print_time)
{
if(!print_time[feature].isTotalDurationZero)
{
content += "<br /><i>" + feature + "</i>: " + print_time[feature].getDisplayString(UM.DurationFormat.Short)
var feature_name = "";
if (feature.length <= 11)
{
feature_name = feature
}
else{
feature_name = feature.substring(0, 8) + "..."
}
content += "<tr><td>" + feature_name + ":" +
"&nbsp;&nbsp;</td><td>" + print_time[feature].getDisplayString(UM.DurationFormat.Short) +
"&nbsp;&nbsp;</td><td>" + Math.round(100 * parseInt(print_time[feature].getDisplayString(UM.DurationFormat.Seconds)) / total_seconds) + "%" +
"</td></tr>";
}
}
content += "</table>";
base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), content)
base.showTooltip(parent, Qt.point(-UM.Theme.getSize("sidebar_margin").width, 0), content);
}
}
onExited:
@ -369,20 +387,84 @@ Rectangle
Label
{
id: timeSpecDescription
anchors.left: parent.left
anchors.bottom: lengthSpec.top
font: UM.Theme.getFont("very_small")
color: UM.Theme.getColor("text_subtext")
text: catalog.i18nc("@description", "Print time")
}
Label
{
id: lengthSpec
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.floor(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 = "<b>%1</b><br/><table>".arg(catalog.i18nc("@label", "Cost specification"));
for(var index = 0; index < lengths.length; index++)
{
var item_strings = [
"%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]),
];
tooltip_html += "<tr>";
for(var item = 0; item < item_strings.length; item++) {
tooltip_html += "<td>%1&nbsp;&nbsp;</td>".arg(item_strings[item]);
}
}
var item_strings = [
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 += "<tr>";
for(var item = 0; item < item_strings.length; item++) {
tooltip_html += "<td>%1&nbsp;&nbsp;</td>".arg(item_strings[item]);
}
tooltip_html += "</tr></table>";
tooltipText = tooltip_html;
return tooltipText
}
id: costSpec
anchors.left: parent.left
anchors.bottom: parent.bottom
font: UM.Theme.getFont("very_small")
color: UM.Theme.getColor("text_subtext")
elide: Text.ElideMiddle
width: parent.width
property string tooltipText
text:
{
var lengths = [];
@ -421,6 +503,27 @@ Rectangle
return catalog.i18nc("@label Print estimates: m for meters, g for grams", "%1m / ~ %2g").arg(lengths.join(" + ")).arg(weights.join(" + "));
}
}
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();
}
}
}
}

View File

@ -54,6 +54,7 @@ UM.PointingRectangle {
rightMargin: UM.Theme.getSize("tooltip_margins").width;
}
wrapMode: Text.Wrap;
textFormat: Text.RichText
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("tooltip_text");
}

View File

@ -30,9 +30,11 @@ Rectangle
Component.onCompleted: {
startMonitoringPrint.connect(function () {
base.monitoringPrint = true
UM.Controller.disableModelRendering()
})
stopMonitoringPrint.connect(function () {
base.monitoringPrint = false
UM.Controller.enableModelRendering()
})
}

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10">
<path d="m 8.5727081,5.62578 v 2.97725 q 0,0.16127 -0.1178498,0.27912 Q 8.3370085,9 8.1757405,9 H 5.7939349 V 6.61819 H 4.2060646 V 9 H 1.824259 Q 1.6629909,9 1.5451412,8.88215 1.4272914,8.7643 1.4272914,8.60303 V 5.62578 q 0,-0.006 0.0031,-0.0186 0.0031,-0.0124 0.0031,-0.0186 L 4.9999998,2.64852 8.5665054,5.58856 q 0.0062,0.0124 0.0062,0.0372 z M 9.955892,5.19779 9.5713297,5.65679 q -0.049621,0.0558 -0.130255,0.0682 h -0.018608 q -0.080634,0 -0.130255,-0.0434 L 4.9999998,2.10269 0.70778771,5.6816 Q 0.63335631,5.7312 0.55892486,5.725 0.47829087,5.7126 0.42866987,5.6568 L 0.04410752,5.1978 Q -0.00551343,5.1358 6.8917799e-4,5.05204 0.00689178,4.96834 0.06891799,4.91869 L 4.5286008,1.20331 q 0.1984838,-0.16127 0.471399,-0.16127 0.2729153,0 0.471399,0.16127 L 6.9848377,2.46864 V 1.25913 q 0,-0.0868 0.055824,-0.14266 0.055824,-0.0558 0.1426602,-0.0558 h 1.1909028 q 0.086837,0 0.1426602,0.0558 0.055824,0.0558 0.055824,0.14266 V 3.7898 l 1.3583734,1.12888 q 0.062026,0.0496 0.068229,0.13335 0.0062,0.0837 -0.043418,0.14576 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB