diff --git a/README.md b/README.md
index 70466e9c22..93abcc0c61 100644
--- a/README.md
+++ b/README.md
@@ -20,8 +20,9 @@ Dependencies
------------
* [Uranium](https://github.com/Ultimaker/Uranium) Cura is built on top of the Uranium framework.
* [CuraEngine](https://github.com/Ultimaker/CuraEngine) This will be needed at runtime to perform the actual slicing.
+* [fdm_materials](https://github.com/Ultimaker/fdm_materials) Required to load a printer that has swappable material profiles.
* [PySerial](https://github.com/pyserial/pyserial) Only required for USB printing support.
-* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers
+* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers.
Build scripts
-------------
diff --git a/cura.desktop.in b/cura.desktop.in
index fbe8b30fed..b0195015a5 100644
--- a/cura.desktop.in
+++ b/cura.desktop.in
@@ -13,6 +13,6 @@ TryExec=@CMAKE_INSTALL_FULL_BINDIR@/cura
Icon=cura-icon
Terminal=false
Type=Application
-MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;image/bmp;image/gif;image/jpeg;image/png;model/x3d+xml;
+MimeType=model/stl;application/vnd.ms-3mfdocument;application/prs.wavefront-obj;image/bmp;image/gif;image/jpeg;image/png;model/x3d+xml;text/x-gcode;
Categories=Graphics;
Keywords=3D;Printing;Slicer;
diff --git a/cura.sharedmimeinfo b/cura.sharedmimeinfo
index 23d38795eb..ed9099d425 100644
--- a/cura.sharedmimeinfo
+++ b/cura.sharedmimeinfo
@@ -19,4 +19,12 @@
+
+
+ Gcode file
+
+
+
+
+
\ No newline at end of file
diff --git a/cura/Backups/Backup.py b/cura/Backups/Backup.py
index 897d5fa979..714d6527fe 100644
--- a/cura/Backups/Backup.py
+++ b/cura/Backups/Backup.py
@@ -46,12 +46,13 @@ class Backup:
# We copy the preferences file to the user data directory in Linux as it's in a different location there.
# When restoring a backup on Linux, we move it back.
- if Platform.isLinux():
+ if Platform.isLinux(): #TODO: This should check for the config directory not being the same as the data directory, rather than hard-coding that to Linux systems.
preferences_file_name = self._application.getApplicationName()
preferences_file = Resources.getPath(Resources.Preferences, "{}.cfg".format(preferences_file_name))
backup_preferences_file = os.path.join(version_data_dir, "{}.cfg".format(preferences_file_name))
- Logger.log("d", "Copying preferences file from %s to %s", preferences_file, backup_preferences_file)
- shutil.copyfile(preferences_file, backup_preferences_file)
+ if os.path.exists(preferences_file) and (not os.path.exists(backup_preferences_file) or not os.path.samefile(preferences_file, backup_preferences_file)):
+ Logger.log("d", "Copying preferences file from %s to %s", preferences_file, backup_preferences_file)
+ shutil.copyfile(preferences_file, backup_preferences_file)
# Create an empty buffer and write the archive to it.
buffer = io.BytesIO()
diff --git a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml
index 437a2ef351..0c04dc2bab 100644
--- a/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml
+++ b/plugins/Toolbox/resources/qml/ToolboxDetailPage.qml
@@ -37,7 +37,7 @@ Item
leftMargin: UM.Theme.getSize("wide_margin").width
topMargin: UM.Theme.getSize("wide_margin").height
}
- color: white //Always a white background for image (regardless of theme).
+ color: "white" //Always a white background for image (regardless of theme).
Image
{
anchors.fill: parent
diff --git a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py
index 9c070f2de2..daea696cd1 100644
--- a/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py
+++ b/plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
@@ -325,13 +325,12 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
## Handler for zeroConf detection.
# Return True or False indicating if the process succeeded.
- # Note that this function can take over 3 seconds to complete. Be carefull calling it from the main thread.
+ # Note that this function can take over 3 seconds to complete. Be careful
+ # calling it from the main thread.
def _onServiceChanged(self, zero_conf, service_type, name, state_change):
if state_change == ServiceStateChange.Added:
- Logger.log("d", "Bonjour service added: %s" % name)
-
# First try getting info from zero-conf cache
- info = ServiceInfo(service_type, name, properties={})
+ info = ServiceInfo(service_type, name, properties = {})
for record in zero_conf.cache.entries_with_name(name.lower()):
info.update_record(zero_conf, time(), record)
diff --git a/resources/qml/Account/GeneralOperations.qml b/resources/qml/Account/GeneralOperations.qml
index 4614c4ba88..b9f1025d5e 100644
--- a/resources/qml/Account/GeneralOperations.qml
+++ b/resources/qml/Account/GeneralOperations.qml
@@ -11,20 +11,16 @@ Row
{
spacing: UM.Theme.getSize("default_margin").width
- Cura.ActionButton
+ Cura.SecondaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Create account")
- color: UM.Theme.getColor("secondary")
- hoverColor: UM.Theme.getColor("secondary")
- textColor: UM.Theme.getColor("main_window_header_button_text_active")
- textHoverColor: UM.Theme.getColor("main_window_header_button_text_active")
onClicked: Qt.openUrlExternally("https://account.ultimaker.com/app/create")
fixedWidthMode: true
}
- Cura.ActionButton
+ Cura.PrimaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
diff --git a/resources/qml/Account/UserOperations.qml b/resources/qml/Account/UserOperations.qml
index c167813425..b9ffa395d6 100644
--- a/resources/qml/Account/UserOperations.qml
+++ b/resources/qml/Account/UserOperations.qml
@@ -11,20 +11,16 @@ Row
{
spacing: UM.Theme.getSize("default_margin").width
- Cura.ActionButton
+ Cura.SecondaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Manage account")
- color: UM.Theme.getColor("secondary")
- hoverColor: UM.Theme.getColor("secondary")
- textColor: UM.Theme.getColor("main_window_header_button_text_active")
- textHoverColor: UM.Theme.getColor("main_window_header_button_text_active")
onClicked: Qt.openUrlExternally("https://account.ultimaker.com")
fixedWidthMode: true
}
- Cura.ActionButton
+ Cura.PrimaryButton
{
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
diff --git a/resources/qml/ActionButton.qml b/resources/qml/ActionButton.qml
index ff8ee4b149..b9a04f3b46 100644
--- a/resources/qml/ActionButton.qml
+++ b/resources/qml/ActionButton.qml
@@ -4,25 +4,33 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
+import QtGraphicalEffects 1.0 // For the dropshadow
+
import UM 1.1 as UM
Button
{
id: button
- property alias cursorShape: mouseArea.cursorShape
property alias iconSource: buttonIcon.source
property alias textFont: buttonText.font
property alias cornerRadius: backgroundRect.radius
property alias tooltip: tooltip.text
- property var color: UM.Theme.getColor("primary")
- property var hoverColor: UM.Theme.getColor("primary_hover")
- property var disabledColor: color
- property var textColor: UM.Theme.getColor("button_text")
- property var textHoverColor: UM.Theme.getColor("button_text_hover")
- property var textDisabledColor: textColor
- property var outlineColor: color
- property var outlineHoverColor: hoverColor
- property var outlineDisabledColor: outlineColor
+
+ property color color: UM.Theme.getColor("primary")
+ property color hoverColor: UM.Theme.getColor("primary_hover")
+ property color disabledColor: color
+ property color textColor: UM.Theme.getColor("button_text")
+ property color textHoverColor: textColor
+ property color textDisabledColor: textColor
+ property color outlineColor: color
+ property color outlineHoverColor: hoverColor
+ property color outlineDisabledColor: outlineColor
+
+ hoverEnabled: true
+
+ property alias shadowColor: shadow.color
+ property alias shadowEnabled: shadow.visible
+
// This property is used to indicate whether the button has a fixed width or the width would depend on the contents
// Be careful when using fixedWidthMode, the translated texts can be too long that they won't fit. In any case,
// we elide the text to the right so the text will be cut off with the three dots at the end.
@@ -67,6 +75,19 @@ Button
border.color: button.enabled ? (button.hovered ? button.outlineHoverColor : button.outlineColor) : button.outlineDisabledColor
}
+ DropShadow
+ {
+ id: shadow
+ // Don't blur the shadow
+ radius: 0
+ anchors.fill: backgroundRect
+ source: backgroundRect
+ verticalOffset: 2
+ visible: false
+ // Should always be drawn behind the background.
+ z: backgroundRect.z - 1
+ }
+
ToolTip
{
id: tooltip
@@ -74,12 +95,4 @@ Button
delay: 500
visible: text != "" && button.hovered
}
-
- MouseArea
- {
- id: mouseArea
- anchors.fill: parent
- onPressed: mouse.accepted = false
- hoverEnabled: true
- }
}
diff --git a/resources/qml/ActionPanel/OutputDevicesActionButton.qml b/resources/qml/ActionPanel/OutputDevicesActionButton.qml
index be79a1893e..2111038cfc 100644
--- a/resources/qml/ActionPanel/OutputDevicesActionButton.qml
+++ b/resources/qml/ActionPanel/OutputDevicesActionButton.qml
@@ -12,7 +12,7 @@ Item
{
id: widget
- Cura.ActionButton
+ Cura.PrimaryButton
{
id: saveToButton
height: parent.height
@@ -42,6 +42,9 @@ Item
id: deviceSelectionMenu
height: parent.height
+ shadowEnabled: true
+ shadowColor: UM.Theme.getColor("primary_shadow")
+
anchors
{
top: parent.top
@@ -65,7 +68,7 @@ Item
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
- contentItem: Column
+ contentItem: ColumnLayout
{
Repeater
{
@@ -77,7 +80,7 @@ Item
color: "transparent"
cornerRadius: 0
hoverColor: UM.Theme.getColor("primary")
-
+ Layout.fillWidth: true
onClicked:
{
UM.OutputDeviceManager.setActiveDevice(model.id)
@@ -91,10 +94,7 @@ Item
{
opacity: visible ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
- radius: UM.Theme.getSize("default_radius").width
color: UM.Theme.getColor("action_panel_secondary")
- border.color: UM.Theme.getColor("lining")
- border.width: UM.Theme.getSize("default_lining").width
}
}
}
diff --git a/resources/qml/ActionPanel/OutputProcessWidget.qml b/resources/qml/ActionPanel/OutputProcessWidget.qml
index 3c4386f079..ddbe709a84 100644
--- a/resources/qml/ActionPanel/OutputProcessWidget.qml
+++ b/resources/qml/ActionPanel/OutputProcessWidget.qml
@@ -101,20 +101,18 @@ Column
spacing: UM.Theme.getSize("default_margin").width
width: parent.width
- Cura.ActionButton
+ Cura.SecondaryButton
{
id: previewStageShortcut
- leftPadding: UM.Theme.getSize("default_margin").width
- rightPadding: UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("action_panel_button").height
text: catalog.i18nc("@button", "Preview")
- color: UM.Theme.getColor("secondary")
- hoverColor: UM.Theme.getColor("secondary")
- textColor: UM.Theme.getColor("primary")
- textHoverColor: UM.Theme.getColor("text")
+
onClicked: UM.Controller.setActiveStage("PreviewStage")
visible: UM.Controller.activeStage != null && UM.Controller.activeStage.stageId != "PreviewStage"
+
+ shadowEnabled: true
+ shadowColor: UM.Theme.getColor("action_button_disabled_shadow")
}
Cura.OutputDevicesActionButton
diff --git a/resources/qml/ActionPanel/SliceProcessWidget.qml b/resources/qml/ActionPanel/SliceProcessWidget.qml
index 2d4a7b6b89..3329ac4b23 100644
--- a/resources/qml/ActionPanel/SliceProcessWidget.qml
+++ b/resources/qml/ActionPanel/SliceProcessWidget.qml
@@ -40,9 +40,21 @@ Column
}
}
+ Label
+ {
+ id: autoSlicingLabel
+ width: parent.width
+ visible: prepareButtons.autoSlice && widget.backendState == UM.Backend.Processing
+
+ text: catalog.i18nc("@label:PrintjobStatus", "Auto slicing...")
+ color: UM.Theme.getColor("text")
+ font: UM.Theme.getFont("very_small")
+ renderType: Text.NativeRendering
+ }
+
Cura.IconLabel
{
- id: message
+ id: unableToSliceMessage
width: parent.width
visible: widget.backendState == UM.Backend.Error
@@ -81,38 +93,41 @@ Column
}
}
- Cura.ActionButton
- {
- id: prepareButton
- width: parent.width
- height: UM.Theme.getSize("action_panel_button").height
- fixedWidthMode: true
- text:
- {
- if ([UM.Backend.NotStarted, UM.Backend.Error].indexOf(widget.backendState) != -1)
- {
- return catalog.i18nc("@button", "Slice")
- }
- if (autoSlice)
- {
- return catalog.i18nc("@button", "Auto slicing...")
- }
- return catalog.i18nc("@button", "Cancel")
- }
- enabled: !autoSlice && !disabledSlice
+ Item
+ {
+ id: prepareButtons
// Get the current value from the preferences
property bool autoSlice: UM.Preferences.getValue("general/auto_slice")
// Disable the slice process when
- property bool disabledSlice: [UM.Backend.Done, UM.Backend.Error].indexOf(widget.backendState) != -1
- disabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled") : "transparent"
- textDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_text") : UM.Theme.getColor("primary")
- outlineDisabledColor: disabledSlice ? UM.Theme.getColor("action_button_disabled_border") : "transparent"
+ width: parent.width
+ height: UM.Theme.getSize("action_panel_button").height
+ visible: !autoSlice
+ Cura.PrimaryButton
+ {
+ id: sliceButton
+ fixedWidthMode: true
+ anchors.fill: parent
+ text: catalog.i18nc("@button", "Slice")
+ enabled: widget.backendState != UM.Backend.Error
+ visible: widget.backendState == UM.Backend.NotStarted || widget.backendState == UM.Backend.Error
+ onClicked: sliceOrStopSlicing()
+ }
- onClicked: sliceOrStopSlicing()
+ Cura.SecondaryButton
+ {
+ id: cancelButton
+ fixedWidthMode: true
+ anchors.fill: parent
+ text: catalog.i18nc("@button", "Cancel")
+ enabled: sliceButton.enabled
+ visible: !sliceButton.visible
+ onClicked: sliceOrStopSlicing()
+ }
}
+
// React when the user changes the preference of having the auto slice enabled
Connections
{
@@ -120,7 +135,7 @@ Column
onPreferenceChanged:
{
var autoSlice = UM.Preferences.getValue("general/auto_slice")
- prepareButton.autoSlice = autoSlice
+ prepareButtons.autoSlice = autoSlice
}
}
diff --git a/resources/qml/MainWindow/MainWindowHeader.qml b/resources/qml/MainWindow/MainWindowHeader.qml
index 59ec542e6b..a24af7ee45 100644
--- a/resources/qml/MainWindow/MainWindowHeader.qml
+++ b/resources/qml/MainWindow/MainWindowHeader.qml
@@ -2,6 +2,7 @@
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
+import QtQuick.Controls 2.0 as Controls2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.1
@@ -73,25 +74,37 @@ Rectangle
}
// Shortcut button to quick access the Toolbox
- Cura.ActionButton
+ Controls2.Button
{
+ id: marketplaceButton
+ text: catalog.i18nc("@action:button", "Marketplace")
+ height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height)
+ onClicked: Cura.Actions.browsePackages.trigger()
+
+ hoverEnabled: true
+
+ background: Rectangle
+ {
+ radius: UM.Theme.getSize("action_button_radius").width
+ color: marketplaceButton.hovered ? UM.Theme.getColor("primary_text") : UM.Theme.getColor("main_window_header_background")
+ border.width: UM.Theme.getSize("default_lining").width
+ border.color: UM.Theme.getColor("primary_text")
+ }
+
+ contentItem: Label
+ {
+ id: label
+ text: marketplaceButton.text
+ color: marketplaceButton.hovered ? UM.Theme.getColor("main_window_header_background") : UM.Theme.getColor("primary_text")
+ width: contentWidth
+ }
+
anchors
{
right: accountWidget.left
rightMargin: UM.Theme.getSize("default_margin").width
verticalCenter: parent.verticalCenter
}
- leftPadding: UM.Theme.getSize("default_margin").width
- rightPadding: UM.Theme.getSize("default_margin").width
- text: catalog.i18nc("@action:button", "Marketplace")
- height: Math.round(0.5 * UM.Theme.getSize("main_window_header").height)
- color: UM.Theme.getColor("main_window_header_secondary_button_background_active")
- hoverColor: UM.Theme.getColor("main_window_header_secondary_button_background_hovered")
- outlineColor: UM.Theme.getColor("main_window_header_secondary_button_outline_active")
- outlineHoverColor: UM.Theme.getColor("main_window_header_secondary_button_outline_hovered")
- textColor: UM.Theme.getColor("main_window_header_secondary_button_text_active")
- textHoverColor: UM.Theme.getColor("main_window_header_secondary_button_text_hovered")
- onClicked: Cura.Actions.browsePackages.trigger()
}
AccountWidget
diff --git a/resources/qml/PrimaryButton.qml b/resources/qml/PrimaryButton.qml
new file mode 100644
index 0000000000..fca63d2cdb
--- /dev/null
+++ b/resources/qml/PrimaryButton.qml
@@ -0,0 +1,20 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.2
+
+import UM 1.4 as UM
+import Cura 1.1 as Cura
+
+
+Cura.ActionButton
+{
+ shadowEnabled: true
+ shadowColor: enabled ? UM.Theme.getColor("primary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow")
+ color: UM.Theme.getColor("primary_button")
+ textColor: UM.Theme.getColor("primary_button_text")
+ outlineColor: "transparent"
+ disabledColor: UM.Theme.getColor("action_button_disabled")
+ textDisabledColor: UM.Theme.getColor("action_button_disabled_text")
+ hoverColor: UM.Theme.getColor("primary_button_hover")
+}
\ No newline at end of file
diff --git a/resources/qml/SecondaryButton.qml b/resources/qml/SecondaryButton.qml
new file mode 100644
index 0000000000..f03d8acdfa
--- /dev/null
+++ b/resources/qml/SecondaryButton.qml
@@ -0,0 +1,20 @@
+// Copyright (c) 2018 Ultimaker B.V.
+// Cura is released under the terms of the LGPLv3 or higher.
+
+import QtQuick 2.2
+
+import UM 1.4 as UM
+import Cura 1.1 as Cura
+
+
+Cura.ActionButton
+{
+ shadowEnabled: true
+ shadowColor: enabled ? UM.Theme.getColor("secondary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow")
+ color: UM.Theme.getColor("secondary_button")
+ textColor: UM.Theme.getColor("secondary_button_text")
+ outlineColor: "transparent"
+ disabledColor: UM.Theme.getColor("action_button_disabled")
+ textDisabledColor: UM.Theme.getColor("action_button_disabled_text")
+ hoverColor: UM.Theme.getColor("secondary_button_hover")
+}
\ No newline at end of file
diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json
index 23b1ffcada..6755d91cc7 100644
--- a/resources/themes/cura-light/theme.json
+++ b/resources/themes/cura-light/theme.json
@@ -82,10 +82,22 @@
"viewport_overlay": [0, 0, 0, 192],
"primary": [50, 130, 255, 255],
+ "primary_shadow": [64, 47, 205, 255],
"primary_hover": [48, 182, 231, 255],
"primary_text": [255, 255, 255, 255],
"border": [127, 127, 127, 255],
"secondary": [245, 245, 245, 255],
+ "secondary_shadow": [228, 228, 228, 255],
+
+ "primary_button": [38, 113, 231, 255],
+ "primary_button_shadow": [27, 95, 202, 255],
+ "primary_button_hover": [81, 145, 247, 255],
+ "primary_button_text": [255, 255, 255, 255],
+
+ "secondary_button": [240, 240, 240, 255],
+ "secondary_button_shadow": [228, 228, 228, 255],
+ "secondary_button_hover": [228, 228, 228, 255],
+ "secondary_button_text": [30, 102, 215, 255],
"main_window_header_background": [10, 8, 80, 255],
"main_window_header_button_text_active": [10, 8, 80, 255],
@@ -95,13 +107,6 @@
"main_window_header_button_background_inactive": [255, 255, 255, 0],
"main_window_header_button_background_hovered": [255, 255, 255, 102],
- "main_window_header_secondary_button_text_active": [255, 255, 255, 255],
- "main_window_header_secondary_button_text_hovered": [10, 8, 80, 255],
- "main_window_header_secondary_button_background_active": [255, 255, 255, 0],
- "main_window_header_secondary_button_background_hovered": [255, 255, 255, 255],
- "main_window_header_secondary_button_outline_active": [255, 255, 255, 255],
- "main_window_header_secondary_button_outline_hovered": [255, 255, 255, 255],
-
"account_widget_outline_active": [70, 66, 126, 255],
"machine_selector_bar": [31, 36, 39, 255],
@@ -174,14 +179,8 @@
"action_button_disabled": [245, 245, 245, 255],
"action_button_disabled_text": [127, 127, 127, 255],
"action_button_disabled_border": [245, 245, 245, 255],
-
- "print_button_ready": [50, 130, 255, 255],
- "print_button_ready_border": [50, 130, 255, 255],
- "print_button_ready_text": [255, 255, 255, 255],
- "print_button_ready_hovered": [30, 186, 245, 243],
- "print_button_ready_hovered_border": [30, 186, 245, 243],
- "print_button_ready_pressed": [30, 186, 245, 243],
- "print_button_ready_pressed_border": [30, 186, 245, 243],
+ "action_button_shadow": [64, 47, 205, 255],
+ "action_button_disabled_shadow": [228, 228, 228, 255],
"scrollbar_background": [255, 255, 255, 255],
"scrollbar_handle": [31, 36, 39, 255],