Merge branch 'master' into CURA-7509_plugin_versions_on_crash

This commit is contained in:
Kostas Karmas 2020-06-18 09:13:28 +02:00
commit 039823e68e
57 changed files with 10668 additions and 239 deletions

View File

@ -103,6 +103,11 @@ class Account(QObject):
self._authorization_service.accessTokenChanged.connect(self._onAccessTokenChanged)
self._authorization_service.loadAuthDataFromPreferences()
@pyqtProperty(int, notify=syncStateChanged)
def syncState(self):
return self._sync_state
def setSyncState(self, service_name: str, state: int) -> None:
""" Can be used to register sync services and update account sync states

View File

@ -1,22 +1,21 @@
from typing import Optional
from PyQt5.QtCore import QObject, pyqtSignal, QTimer, pyqtProperty
from PyQt5.QtNetwork import QNetworkReply
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from cura.UltimakerCloud import UltimakerCloudConstants
class ConnectionStatus(QObject):
"""Status info for some web services"""
"""Provides an estimation of whether internet is reachable
UPDATE_INTERVAL = 10.0 # seconds
ULTIMAKER_CLOUD_STATUS_URL = UltimakerCloudConstants.CuraCloudAPIRoot + "/connect/v1/"
Estimation is updated with every request through HttpRequestManager.
Acts as a proxy to HttpRequestManager.internetReachableChanged without
exposing the HttpRequestManager in its entirety.
"""
__instance = None # type: Optional[ConnectionStatus]
internetReachableChanged = pyqtSignal()
umCloudReachableChanged = pyqtSignal()
@classmethod
def getInstance(cls, *args, **kwargs) -> "ConnectionStatus":
@ -24,41 +23,19 @@ class ConnectionStatus(QObject):
cls.__instance = cls(*args, **kwargs)
return cls.__instance
def __init__(self, parent: Optional["QObject"] = None):
def __init__(self, parent: Optional["QObject"] = None) -> None:
super().__init__(parent)
self._http = HttpRequestManager.getInstance()
self._statuses = {
self.ULTIMAKER_CLOUD_STATUS_URL: True,
"http://example.com": True
}
manager = HttpRequestManager.getInstance()
self._is_internet_reachable = manager.isInternetReachable # type: bool
manager.internetReachableChanged.connect(self._onInternetReachableChanged)
# Create a timer for automatic updates
self._update_timer = QTimer()
self._update_timer.setInterval(int(self.UPDATE_INTERVAL * 1000))
# The timer is restarted automatically
self._update_timer.setSingleShot(False)
self._update_timer.timeout.connect(self._update)
self._update_timer.start()
@pyqtProperty(bool, notify=internetReachableChanged)
@pyqtProperty(bool, notify = internetReachableChanged)
def isInternetReachable(self) -> bool:
# Is any of the test urls reachable?
return any(self._statuses.values())
return self._is_internet_reachable
def _update(self):
for url in self._statuses.keys():
self._http.get(
url = url,
callback = self._statusCallback,
error_callback = self._statusCallback,
timeout = 5
)
def _statusCallback(self, reply: QNetworkReply, error: QNetworkReply.NetworkError = None):
url = reply.request().url().toString()
prev_statuses = self._statuses.copy()
self._statuses[url] = HttpRequestManager.replyIndicatesSuccess(reply, error)
if any(self._statuses.values()) != any(prev_statuses.values()):
def _onInternetReachableChanged(self, reachable: bool):
if reachable != self._is_internet_reachable:
self._is_internet_reachable = reachable
self.internetReachableChanged.emit()

View File

@ -207,6 +207,7 @@ class CuraApplication(QtApplication):
self._first_start_machine_actions_model = None
self._welcome_pages_model = WelcomePagesModel(self, parent = self)
self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self)
self._add_printer_pages_model_without_cancel = AddPrinterPagesModel(self, parent = self)
self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self)
self._text_manager = TextManager(parent = self)
@ -261,6 +262,10 @@ class CuraApplication(QtApplication):
def ultimakerCloudAccountRootUrl(self) -> str:
return UltimakerCloudConstants.CuraCloudAccountAPIRoot
@pyqtProperty(str, constant=True)
def ultimakerDigitalFactoryUrl(self) -> str:
return UltimakerCloudConstants.CuraDigitalFactoryURL
def addCommandLineOptions(self):
"""Adds command line options to the command line parser.
@ -647,7 +652,7 @@ class CuraApplication(QtApplication):
return self._global_container_stack
@override(Application)
def setGlobalContainerStack(self, stack: "GlobalStack") -> None:
def setGlobalContainerStack(self, stack: Optional["GlobalStack"]) -> None:
self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing Active Machine..."))
super().setGlobalContainerStack(stack)
@ -812,6 +817,7 @@ class CuraApplication(QtApplication):
self._output_device_manager.start()
self._welcome_pages_model.initialize()
self._add_printer_pages_model.initialize()
self._add_printer_pages_model_without_cancel.initialize(cancellable = False)
self._whats_new_pages_model.initialize()
# Detect in which mode to run and execute that mode
@ -849,6 +855,7 @@ class CuraApplication(QtApplication):
self.callLater(self._openFile, file_name)
initializationFinished = pyqtSignal()
showAddPrintersUncancellableDialog = pyqtSignal() # Used to show the add printers dialog with a greyed background
def runWithoutGUI(self):
"""Run Cura without GUI elements and interaction (server mode)."""
@ -939,6 +946,10 @@ class CuraApplication(QtApplication):
def getAddPrinterPagesModel(self, *args) -> "AddPrinterPagesModel":
return self._add_printer_pages_model
@pyqtSlot(result = QObject)
def getAddPrinterPagesModelWithoutCancel(self, *args) -> "AddPrinterPagesModel":
return self._add_printer_pages_model_without_cancel
@pyqtSlot(result = QObject)
def getWhatsNewPagesModel(self, *args) -> "WhatsNewPagesModel":
return self._whats_new_pages_model

View File

@ -154,7 +154,7 @@ class BaseMaterialsModel(ListModel):
# Update the available materials (ContainerNode) for the current active machine and extruder setup.
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if not global_stack.hasMaterials:
if not global_stack or not global_stack.hasMaterials:
return # There are no materials for this machine, so nothing to do.
extruder_list = global_stack.extruderList
if self._extruder_position > len(extruder_list):

View File

@ -7,6 +7,8 @@ from enum import IntEnum
from threading import Thread
from typing import Union
from UM.Logger import Logger
MYPY = False
if MYPY:
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
@ -38,8 +40,10 @@ class FirmwareUpdater(QObject):
return
self._setFirmwareUpdateState(FirmwareUpdateState.updating)
self._update_firmware_thread.start()
try:
self._update_firmware_thread.start()
except RuntimeError:
Logger.warning("Could not start the update thread, since it's still running!")
def _updateFirmware(self) -> None:
raise NotImplementedError("_updateFirmware needs to be implemented")

View File

@ -290,9 +290,15 @@ class MachineManager(QObject):
self.activeStackValueChanged.emit()
@pyqtSlot(str)
def setActiveMachine(self, stack_id: str) -> None:
def setActiveMachine(self, stack_id: Optional[str]) -> None:
self.blurSettings.emit() # Ensure no-one has focus.
if not stack_id:
self._application.setGlobalContainerStack(None)
self.globalContainerChanged.emit()
self._application.showAddPrintersUncancellableDialog.emit()
return
container_registry = CuraContainerRegistry.getInstance()
containers = container_registry.findContainerStacks(id = stack_id)
if not containers:
@ -721,6 +727,8 @@ class MachineManager(QObject):
other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id]
if other_machine_stacks:
self.setActiveMachine(other_machine_stacks[0]["id"])
else:
self.setActiveMachine(None)
metadatas = CuraContainerRegistry.getInstance().findContainerStacksMetadata(id = machine_id)
if not metadatas:

View File

@ -10,12 +10,11 @@ from .WelcomePagesModel import WelcomePagesModel
#
class AddPrinterPagesModel(WelcomePagesModel):
def initialize(self) -> None:
def initialize(self, cancellable: bool = True) -> None:
self._pages.append({"id": "add_network_or_local_printer",
"page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
"next_page_id": "machine_actions",
"next_page_button_text": self._catalog.i18nc("@action:button", "Add"),
"previous_page_button_text": self._catalog.i18nc("@action:button", "Cancel"),
})
self._pages.append({"id": "add_printer_by_ip",
"page_url": self._getBuiltinWelcomePagePath("AddPrinterByIpContent.qml"),
@ -30,6 +29,9 @@ class AddPrinterPagesModel(WelcomePagesModel):
"page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
"should_show_function": self.shouldShowMachineActions,
})
if cancellable:
self._pages[0]["previous_page_button_text"] = self._catalog.i18nc("@action:button", "Cancel")
self.setItems(self._pages)

View File

@ -7,6 +7,7 @@
DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str
DEFAULT_CLOUD_API_VERSION = "1" # type: str
DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str
DEFAULT_DIGITAL_FACTORY_URL = "https://digitalfactory.ultimaker.com" # type: str
# Container Metadata keys
META_UM_LINKED_TO_ACCOUNT = "um_linked_to_account"
@ -32,3 +33,10 @@ try:
CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT
except ImportError:
CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT
try:
from cura.CuraVersion import CuraDigitalFactoryURL # type: ignore
if CuraDigitalFactoryURL == "":
CuraDigitalFactoryURL = DEFAULT_DIGITAL_FACTORY_URL
except ImportError:
CuraDigitalFactoryURL = DEFAULT_DIGITAL_FACTORY_URL

View File

@ -368,15 +368,20 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
machine_name = self._getMachineNameFromSerializedStack(serialized)
self._machine_info.metadata_dict = self._getMetaDataDictFromSerializedStack(serialized)
# Check if the definition has been changed (this usually happens due to an upgrade)
id_list = self._getContainerIdListFromSerialized(serialized)
if id_list[7] != machine_definition_id:
machine_definition_id = id_list[7]
stacks = self._container_registry.findContainerStacks(name = machine_name, type = "machine")
self._is_same_machine_type = True
existing_global_stack = None
if stacks:
global_stack = stacks[0]
existing_global_stack = global_stack
containers_found_dict["machine"] = True
# Check if there are any changes at all in any of the container stacks.
id_list = self._getContainerIdListFromSerialized(serialized)
for index, container_id in enumerate(id_list):
# take into account the old empty container IDs
container_id = self._old_empty_profile_id_dict.get(container_id, container_id)
@ -661,6 +666,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
for definition_container_file in definition_container_files:
container_id = self._stripFileToId(definition_container_file)
definitions = self._container_registry.findDefinitionContainersMetadata(id = container_id)
if not definitions:
definition_container = DefinitionContainer(container_id)

View File

@ -56,7 +56,7 @@ class PauseAtHeight(Script):
"type": "enum",
"options": {"marlin": "Marlin (M0)", "griffin": "Griffin (M0, firmware retract)", "bq": "BQ (M25)", "reprap": "RepRap (M226)", "repetier": "Repetier (@pause)"},
"default_value": "marlin",
"value": "\\\"griffin\\\" if machine_gcode_flavor==\\\"Griffin\\\" else \\\"reprap\\\" if machine_gcode_flavor==\\\"RepRap (RepRap)\\\" else \\\"repetier\\\" if machine_gcode_flavor==\\\"Repetier\\\" else \\\"bq\\\" if \\\"BQ\\\" in machine_name else \\\"marlin\\\""
"value": "\\\"griffin\\\" if machine_gcode_flavor==\\\"Griffin\\\" else \\\"reprap\\\" if machine_gcode_flavor==\\\"RepRap (RepRap)\\\" else \\\"repetier\\\" if machine_gcode_flavor==\\\"Repetier\\\" else \\\"bq\\\" if \\\"BQ\\\" in machine_name or \\\"Flying Bear Ghost 4S\\\" in machine_name else \\\"marlin\\\""
},
"disarm_timeout":
{

View File

@ -4,6 +4,7 @@ import os
from typing import Dict, List, Optional, Set
from PyQt5.QtNetwork import QNetworkReply
from PyQt5.QtWidgets import QMessageBox
from UM import i18nCatalog
from UM.Logger import Logger # To log errors talking to the API.
@ -50,6 +51,7 @@ class CloudOutputDeviceManager:
self._account = CuraApplication.getInstance().getCuraAPI().account # type: Account
self._api = CloudApiClient(CuraApplication.getInstance(), on_error = lambda error: Logger.log("e", str(error)))
self._account.loginStateChanged.connect(self._onLoginStateChanged)
self._removed_printers_message = None # type: Optional[Message]
# Ensure we don't start twice.
self._running = False
@ -102,7 +104,7 @@ class CloudOutputDeviceManager:
self._api.getClusters(self._onGetRemoteClustersFinished, self._onGetRemoteClusterFailed)
def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
"""Callback for when the request for getting the clusters is finished."""
"""Callback for when the request for getting the clusters is successful and finished."""
self._um_cloud_printers = {m.getMetaDataEntry(self.META_CLUSTER_ID): m for m in
CuraApplication.getInstance().getContainerRegistry().findContainerStacks(
@ -120,6 +122,11 @@ class CloudOutputDeviceManager:
self._um_cloud_printers[device_id].setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, True)
self._onDevicesDiscovered(new_clusters)
# Hide the current removed_printers_message, if there is any
if self._removed_printers_message:
self._removed_printers_message.actionTriggered.disconnect(self._onRemovedPrintersMessageActionTriggered)
self._removed_printers_message.hide()
# Remove the CloudOutput device for offline printers
offline_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
for device_id in offline_device_keys:
@ -269,14 +276,13 @@ class CloudOutputDeviceManager:
return
# Generate message
removed_printers_message = Message(
self._removed_printers_message = Message(
title = self.I18N_CATALOG.i18ncp(
"info:status",
"Cloud connection is not available for a printer",
"Cloud connection is not available for some printers",
len(self.reported_device_ids)
),
lifetime = 0
)
)
device_names = "\n".join(["<li>{} ({})</li>".format(self._um_cloud_printers[device].name, self._um_cloud_printers[device].definition.name) for device in self.reported_device_ids])
message_text = self.I18N_CATALOG.i18ncp(
@ -291,13 +297,19 @@ class CloudOutputDeviceManager:
"<a href='https://mycloud.ultimaker.com/'>Ultimaker Digital Factory</a>.",
device_names
)
removed_printers_message.setText(message_text)
removed_printers_message.addAction("keep_printer_configurations_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Keep printer configurations"),
icon = "",
description = "Keep the configuration of the cloud printer(s) synced with Cura which are not linked to your account.",
button_align = Message.ActionButtonAlignment.ALIGN_RIGHT)
removed_printers_message.actionTriggered.connect(self._onRemovedPrintersMessageActionTriggered)
self._removed_printers_message.setText(message_text)
self._removed_printers_message.addAction("keep_printer_configurations_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Keep printer configurations"),
icon = "",
description = "Keep the configuration of the cloud printer(s) synced with Cura which are not linked to your account.",
button_align = Message.ActionButtonAlignment.ALIGN_RIGHT)
self._removed_printers_message.addAction("remove_printers_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Remove printers"),
icon = "",
description = "Remove the cloud printer(s) which are not linked to your account.",
button_style = Message.ActionButtonStyle.SECONDARY,
button_align = Message.ActionButtonAlignment.ALIGN_LEFT)
self._removed_printers_message.actionTriggered.connect(self._onRemovedPrintersMessageActionTriggered)
output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
@ -314,7 +326,7 @@ class CloudOutputDeviceManager:
# Update the printer's metadata to mark it as not linked to the account
device.setMetaDataEntry(META_UM_LINKED_TO_ACCOUNT, False)
removed_printers_message.show()
self._removed_printers_message.show()
def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice]
@ -402,7 +414,23 @@ class CloudOutputDeviceManager:
if container_cluster_id in self._remote_clusters.keys():
del self._remote_clusters[container_cluster_id]
@staticmethod
def _onRemovedPrintersMessageActionTriggered(removed_printers_message: Message, action: str) -> None:
def _onRemovedPrintersMessageActionTriggered(self, removed_printers_message: Message, action: str) -> None:
if action == "keep_printer_configurations_action":
removed_printers_message.hide()
elif action == "remove_printers_action":
machine_manager = CuraApplication.getInstance().getMachineManager()
remove_printers_ids = {self._um_cloud_printers[i].getId() for i in self.reported_device_ids}
all_ids = {m.getId() for m in CuraApplication.getInstance().getContainerRegistry().findContainerStacks(type = "machine")}
question_title = self.I18N_CATALOG.i18nc("@title:window", "Remove printers?")
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove {} printer(s) from Cura. This action cannot be undone. \nAre you sure you want to continue?".format(len(remove_printers_ids)))
if remove_printers_ids == all_ids:
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove all printers from Cura. This action cannot be undone. \nAre you sure you want to continue?")
result = QMessageBox.question(None, question_title, question_content)
if result == QMessageBox.No:
return
for machine_cloud_id in self.reported_device_ids:
machine_manager.setActiveMachine(self._um_cloud_printers[machine_cloud_id].getId())
machine_manager.removeMachine(self._um_cloud_printers[machine_cloud_id].getId())
removed_printers_message.hide()

View File

@ -2,10 +2,17 @@
# Cura is released under the terms of the LGPLv3 or higher.
import configparser
from typing import Tuple, List
from typing import Tuple, List, Dict
import io
from UM.VersionUpgrade import VersionUpgrade
# Renamed definition files
_RENAMED_DEFINITION_DICT = {
"dagoma_discoeasy200": "dagoma_discoeasy200_bicolor",
} # type: Dict[str, str]
class VersionUpgrade462to47(VersionUpgrade):
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
"""
@ -71,6 +78,10 @@ class VersionUpgrade462to47(VersionUpgrade):
ironing_inset = "=(" + ironing_inset + ")" + correction
parser["values"]["ironing_inset"] = ironing_inset
# Check renamed definitions
if "definition" in parser["general"] and parser["general"]["definition"] in _RENAMED_DEFINITION_DICT:
parser["general"]["definition"] = _RENAMED_DEFINITION_DICT[parser["general"]["definition"]]
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
@ -130,7 +141,9 @@ class VersionUpgrade462to47(VersionUpgrade):
script_str = script_str.replace("\\\\", r"\\\\").replace("\n", r"\\\n") # Escape newlines because configparser sees those as section delimiters.
new_scripts_entries.append(script_str)
parser["metadata"]["post_processing_scripts"] = "\n".join(new_scripts_entries)
# check renamed definition
if parser.has_option("containers", "7") and parser["containers"]["7"] in _RENAMED_DEFINITION_DICT:
parser["containers"]["7"] = _RENAMED_DEFINITION_DICT[parser["containers"]["7"]]
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]

View File

@ -465,7 +465,7 @@ class XmlMaterialProfile(InstanceContainer):
return "materials"
@classmethod
def getVersionFromSerialized(cls, serialized: str) -> Optional[int]:
def getVersionFromSerialized(cls, serialized: str) -> int:
data = ET.fromstring(serialized)
version = XmlMaterialProfile.Version

View File

@ -0,0 +1,70 @@
{
"version": 2,
"name": "Sovol-SV01",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Sovol",
"manufacturer": "Sovol 3D",
"file_formats": "text/x-gcode",
"has_variants": false,
"has_machine_quality": false,
"preferred_quality_type": "draft",
"machine_extruder_trains": {
"0": "SV01_extruder_0"
}
},
"overrides": {
"machine_name": { "default_value": "SV01" },
"machine_extruder_count": { "default_value": 1 },
"machine_width": { "default_value": 280 },
"machine_depth": { "default_value": 260 },
"machine_height": { "default_value": 300 },
"machine_max_feedrate_x": { "value": 500 },
"machine_max_feedrate_y": { "value": 500 },
"machine_max_feedrate_z": { "value": 10 },
"machine_max_feedrate_e": { "value": 50 },
"machine_max_acceleration_x": { "value": 500 },
"machine_max_acceleration_y": { "value": 500 },
"machine_max_acceleration_z": { "value": 100 },
"machine_max_acceleration_e": { "value": 5000 },
"machine_acceleration": { "value": 500 },
"machine_max_jerk_xy": { "value": 10 },
"machine_max_jerk_z": { "value": 0.4 },
"machine_max_jerk_e": { "value": 5 },
"machine_heated_bed": { "default_value": true },
"material_diameter": { "default_value": 1.75 },
"acceleration_print": { "value": 500 },
"acceleration_travel": { "value": 500 },
"acceleration_travel_layer_0": { "value": "acceleration_travel" },
"acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
"jerk_print": { "value": 8 },
"jerk_travel": { "value": "jerk_print" },
"jerk_travel_layer_0": { "value": "jerk_travel" },
"acceleration_enabled": { "value": false },
"jerk_enabled": { "value": false },
"speed_print": { "value": 50.0 } ,
"speed_infill": { "value": "speed_print" },
"skirt_brim_speed": { "value": "speed_layer_0" },
"line_width": { "value": "machine_nozzle_size" },
"optimize_wall_printing_order": { "value": "True" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
"material_final_print_temperature": { "value": "material_print_temperature" },
"material_flow": { "value": 100 },
"z_seam_type": { "value": "'back'" },
"z_seam_corner": { "value": "'z_seam_corner_weighted'" },
"infill_sparse_density": { "value": "20" },
"infill_pattern": { "value": "'lines'" },
"infill_before_walls": { "value": false },
"infill_overlap": { "value": 30.0 },
"skin_overlap": { "value": 10.0 },
"infill_wipe_dist": { "value": 0.0 },
"wall_0_wipe_dist": { "value": 0.0 },
"retraction_amount": { "default_value": 3},
"retraction_speed": { "default_value": 50},
"adhesion_type": { "value": "'skirt'" },
"machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" },
"machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X0 Y240 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }
}
}

View File

@ -0,0 +1,86 @@
{
"version": 2,
"name": "Sovol-SV02",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Sovol",
"manufacturer": "Sovol 3D",
"file_formats": "text/x-gcode",
"has_variants": false,
"has_machine_quality": false,
"preferred_quality_type": "draft",
"machine_extruder_trains": {
"0": "SV02_extruder_0",
"1": "SV02_extruder_1"
}
},
"overrides": {
"machine_name": { "default_value": "SV02" },
"machine_extruder_count": { "default_value": 2 },
"machine_heated_bed": { "default_value": true },
"machine_width": { "default_value": 300 },
"machine_depth": { "default_value": 250 },
"machine_height": { "default_value": 300 },
"machine_center_is_zero": { "default_value": false },
"retraction_amount": { "default_value": 5},
"retraction_speed": { "default_value": 50},
"gantry_height": { "value": "30" },
"speed_print": { "default_value": 50 },
"material_print_temperature": { "value": 195 },
"material_print_temperature_layer_0": { "value": "material_print_temperature" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
"material_final_print_temperature": { "value": 195 },
"machine_max_feedrate_x": { "value": 500 },
"machine_max_feedrate_y": { "value": 500 },
"machine_max_feedrate_z": { "value": 10 },
"machine_max_feedrate_e": { "value": 50 },
"machine_max_acceleration_x": { "value": 500 },
"machine_max_acceleration_y": { "value": 500 },
"machine_max_acceleration_z": { "value": 100 },
"machine_max_acceleration_e": { "value": 500 },
"machine_acceleration": { "value": 500 },
"machine_max_jerk_xy": { "value": 8 },
"machine_max_jerk_z": { "value": 0.4 },
"machine_max_jerk_e": { "value": 5 },
"machine_heated_bed": { "default_value": true },
"material_diameter": { "default_value": 1.75 },
"infill_overlap": { "default_value": 15 },
"acceleration_print": { "value": 500 },
"acceleration_travel": { "value": 500 },
"acceleration_travel_layer_0": { "value": "acceleration_travel" },
"jerk_print": { "value": 8 },
"jerk_travel": { "value": "jerk_print" },
"jerk_travel_layer_0": { "value": "jerk_travel" },
"acceleration_enabled": { "value": false },
"jerk_enabled": { "value": false },
"machine_max_jerk_xy": { "default_value": 5.0 },
"machine_max_jerk_z": { "default_value": 0.4 },
"machine_max_jerk_e": { "default_value": 5.0 },
"prime_tower_position_x": { "value": "240" },
"prime_tower_position_y": { "value": "190" },
"prime_tower_size": { "value": "30" },
"prime_tower_wipe_enabled": { "default_value": true },
"prime_tower_min_volume": { "value": "((resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height'))/2"},
"travel_retract_before_outer_wall": { "default_value": true },
"infill_sparse_density": { "value": "15" },
"infill_pattern": { "value": "'lines'" },
"infill_before_walls": { "value": false },
"infill_overlap": { "value": 30.0 },
"skin_overlap": { "value": 10.0 },
"infill_wipe_dist": { "value": 0.0 },
"wall_0_wipe_dist": { "value": 0.0 },
"adhesion_type": { "value": "'skirt'" },
"brim_replaces_support": { "value": false },
"skirt_gap": { "value": 2 },
"skirt_line_count": { "value": 3 },
"adhesion_extruder_nr": { "value": 1 },
"brim_width": { "value": 4 },
"coasting_enable": { "default_value": true },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": { "default_value": "G21 ;metric values\nG28 ;home all\nG90 ;absolute positioning\nM107 ;start with the fan off\nG1 F2400 Z15.0 ;raise the nozzle 15mm\nM109 S{material_print_temperature} ;Set Extruder Temperature and Wait\nM190 S{material_bed_temperature}; Wait for bed temperature to reach target temp\nT0 ;Switch to Extruder 1\nG1 F3000 X5 Y10 Z0.2 ;move to prime start position\nG92 E0 ;reset extrusion distance\nG1 F600 X160 E5 ;prime nozzle in a line\nG1 F5000 X180 ;quick wipe\nG92 E0 ;reset extrusion distance" },
"machine_end_gcode": { "default_value": "M104 S0 ;hotend off\nM140 S0 ;bed off\nG92 E0\nG1 F2000 E-100 ;retract filament 100mm\nG92 E0\nG1 F3000 X0 Y240 ;move bed for easy part removal\nM84 ;disable steppers" },
"top_bottom_thickness": { "default_value": 1 }
}
}

View File

@ -5702,7 +5702,7 @@
"minimum_value": "0",
"maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)",
"minimum_value_warning": "max(extruderValues('prime_tower_line_width')) * 2",
"maximum_value_warning": "20",
"maximum_value_warning": "42",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@ -6049,8 +6049,8 @@
},
"infill_mesh_order":
{
"label": "Infill Mesh Order",
"description": "Determines which infill mesh is inside the infill of another infill mesh. An infill mesh with a higher order will modify the infill of infill meshes with lower order and normal meshes.",
"label": "Mesh Processing Rank",
"description": "Determines the priority of this mesh when considering overlapping volumes. Areas where multiple meshes reside will be won by the lower rank mesh. An infill mesh with a higher order will modify the infill of infill meshes with lower order and normal meshes.",
"default_value": 0,
"value": "1 if infill_mesh else 0",
"minimum_value_warning": "1",

View File

@ -0,0 +1,31 @@
{
"version": 2,
"name": "TinyBoy E10/J10/L10/M10",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Fred Chan",
"manufacturer": "TinyBoy",
"file_formats": "text/x-gcode",
"has_materials": false,
"has_machine_quality": true,
"preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "tinyboy_extruder_0"
}
},
"overrides": {
"machine_name": { "default_value": "TinyBoy E10" },
"machine_width": { "default_value": 100 },
"machine_depth": { "default_value": 100 },
"machine_height": { "default_value": 105 },
"machine_start_gcode": {
"default_value": "G28 ;Home\nG1 Z15.0 F2000 ;Move the platform"
},
"machine_end_gcode": {
"default_value": "M104 S0\nM140 S0\nG92 E80\nG1 E-80 F2000\nG28 X0 Y0\nM84"
}
}
}

View File

@ -0,0 +1,31 @@
{
"version": 2,
"name": "TinyBoy E16/L16/M16",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Fred Chan",
"manufacturer": "TinyBoy",
"file_formats": "text/x-gcode",
"has_materials": false,
"has_machine_quality": true,
"preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "tinyboy_extruder_0"
}
},
"overrides": {
"machine_name": { "default_value": "TinyBoy E16" },
"machine_width": { "default_value": 100 },
"machine_depth": { "default_value": 100 },
"machine_height": { "default_value": 165 },
"machine_start_gcode": {
"default_value": "G28 ;Home\nG1 Z15.0 F2000 ;Move the platform"
},
"machine_end_gcode": {
"default_value": "M104 S0\nM140 S0\nG92 E80\nG1 E-80 F2000\nG28 X0 Y0\nM84"
}
}
}

View File

@ -0,0 +1,36 @@
{
"version": 2,
"name": "TinyBoy RA20",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Fred Chan",
"manufacturer": "TinyBoy",
"file_formats": "text/x-gcode",
"platform": "tinyboy_ra20.obj",
"platform_offset": [ 8, -73.3, -8 ],
"has_materials": false,
"has_machine_quality": true,
"preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "tinyboy_extruder_0"
}
},
"overrides": {
"machine_name": { "default_value": "TinyBoy RA20" },
"machine_width": { "default_value": 120 },
"machine_depth": { "default_value": 120 },
"machine_height": { "default_value": 205 },
"machine_heated_bed": { "default_value": true },
"machine_start_gcode": {
"default_value": "G28 ;Home\nG1 Z15.0 F2000 ;Move the platform"
},
"machine_end_gcode": {
"default_value": "M104 S0\nM140 S0\nG92 E80\nG1 E-80 F2000\nG28 X0 Y0\nM84"
}
}
}

View File

@ -55,7 +55,7 @@
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E6 ;extrude 6 mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 Y50 F9000\n;Put printing message on LCD screen\nM117 Printing..."
},
"machine_end_gcode": {
"value": "'M104 S0 ;extruder heater off' + ('\\nM140 S0 ;heated bed heater off' if machine_heated_bed else '') + '\\nG91 ;relative positioning\\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\\nM84 ;steppers off\\nG90 ;absolute positioning'"

View File

@ -0,0 +1,15 @@
{
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "SV01",
"position": "0"
},
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 }
}
}

View File

@ -0,0 +1,26 @@
{
"version": 2,
"name": "Left Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "SV02",
"position": "0"
},
"overrides": {
"extruder_nr": {
"default_value": 0,
"maximum_value": "1"
},
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
"machine_nozzle_size": { "default_value": 0.4 },
"machine_extruder_start_code": {
"default_value": "\nT0 ;switch to extruder 1\nG92 E0 ;reset extruder distance\nG1 F2000 E93 ;load filament\nG92 E0 ;reset extruder distance\nM104 S{material_print_temperature}"
},
"machine_extruder_end_code": {
"default_value": "\nG92 E0 ;reset extruder distance\nG1 F800 E-5 ;short retract\nG1 F2400 X250 Y220\nG1 F2000 E-93 ;long retract for filament removal\nG92 E0 ;reset extruder distance\nG90"
}
}
}

View File

@ -0,0 +1,26 @@
{
"version": 2,
"name": "Right Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "SV02",
"position": "1"
},
"overrides": {
"extruder_nr": {
"default_value": 1,
"maximum_value": "1"
},
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
"machine_nozzle_size": { "default_value": 0.4 },
"machine_extruder_start_code": {
"default_value": "\nT1 ;switch to extruder 2\nG92 E0 ;reset extruder distance\nG1 F2000 E93 ;load filament\nG92 E0 ;reset extruder distance\nM104 S{material_print_temperature}"
},
"machine_extruder_end_code": {
"default_value": "\nG92 E0 ;reset extruder distance\nG1 F800 E-5 ;short retract\nG1 F2400 X250 Y220\nG1 F2000 E-93 ;long retract for filament removal\nG92 E0 ;reset extruder distance\nG90"
}
}
}

View File

@ -0,0 +1,15 @@
{
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "tinyboy_e10",
"position": "0"
},
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.3 },
"material_diameter": { "default_value": 1.75 }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -7,19 +7,16 @@ import QtQuick.Controls 2.3
import UM 1.4 as UM
import Cura 1.1 as Cura
Column
Item
{
property var profile: null
property var loggedIn: false
property var profileImage: ""
padding: UM.Theme.getSize("wide_margin").height
spacing: UM.Theme.getSize("wide_margin").height
property var profile: Cura.API.account.userProfile
property bool loggedIn: Cura.API.account.isLoggedIn
property var profileImage: Cura.API.account.profileImageUrl
Loader
{
id: accountOperations
anchors.horizontalCenter: parent.horizontalCenter
anchors.centerIn: parent
sourceComponent: loggedIn ? userOperations : generalOperations
}

View File

@ -131,14 +131,9 @@ Item
opacity: opened ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
padding: 0
contentItem: AccountDetails
{
id: panel
profile: Cura.API.account.userProfile
loggedIn: Cura.API.account.isLoggedIn
profileImage: Cura.API.account.profileImageUrl
}
{}
background: UM.PointingRectangle
{

View File

@ -54,6 +54,6 @@ Item
visible: hasAvatar
source: UM.Theme.getIcon("circle_outline")
sourceSize: Qt.size(parent.width, parent.height)
color: UM.Theme.getColor("account_widget_ouline_active")
color: UM.Theme.getColor("account_widget_outline_active")
}
}

View File

@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column
{
spacing: UM.Theme.getSize("default_margin").width
padding: UM.Theme.getSize("default_margin").width
Image
{
id: machinesImage

View File

@ -4,15 +4,45 @@ import QtQuick.Controls 2.3
import UM 1.4 as UM
import Cura 1.1 as Cura
Row // sync state icon + message
Row // Sync state icon + message
{
property var syncState: Cura.API.account.syncState
id: syncRow
width: childrenRect.width
height: childrenRect.height
anchors.horizontalCenter: parent.horizontalCenter
spacing: UM.Theme.getSize("narrow_margin").height
states: [
State
{
name: "idle"
when: syncState == Cura.AccountSyncState.IDLE
PropertyChanges { target: icon; source: UM.Theme.getIcon("update")}
},
State
{
name: "syncing"
when: syncState == Cura.AccountSyncState.SYNCING
PropertyChanges { target: icon; source: UM.Theme.getIcon("update") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Checking...")}
},
State
{
name: "up_to_date"
when: syncState == Cura.AccountSyncState.SUCCESS
PropertyChanges { target: icon; source: UM.Theme.getIcon("checked") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Account synced")}
},
State
{
name: "error"
when: syncState == Cura.AccountSyncState.ERROR
PropertyChanges { target: icon; source: UM.Theme.getIcon("warning_light") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Something went wrong...")}
}
]
UM.RecolorImage
{
id: icon
@ -20,7 +50,7 @@ Row // sync state icon + message
height: width
source: Cura.API.account.manualSyncEnabled ? UM.Theme.getIcon("update") : UM.Theme.getIcon("checked")
color: palette.text
color: UM.Theme.getColor("account_sync_state_icon")
RotationAnimator
{
@ -30,7 +60,7 @@ Row // sync state icon + message
to: 360
duration: 1000
loops: Animation.Infinite
running: true
running: syncState == Cura.AccountSyncState.SYNCING
// reset rotation when stopped
onRunningChanged: {
@ -50,10 +80,13 @@ Row // sync state icon + message
Label
{
id: stateLabel
text: catalog.i18nc("@state", catalog.i18nc("@label", "You are in sync with your account"))
text: catalog.i18nc("@state", catalog.i18nc("@label", "Account synced"))
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
width: contentWidth + UM.Theme.getSize("default_margin").height
height: contentHeight
verticalAlignment: Text.AlignVCenter
visible: !Cura.API.account.manualSyncEnabled
}
@ -64,8 +97,10 @@ Row // sync state icon + message
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
height: contentHeight
width: contentWidth + UM.Theme.getSize("default_margin").height
visible: Cura.API.account.manualSyncEnabled
height: visible ? accountSyncButton.intrinsicHeight : 0
MouseArea
{
@ -77,33 +112,4 @@ Row // sync state icon + message
}
}
}
signal syncStateChanged(string newState)
onSyncStateChanged: {
if(newState == Cura.AccountSyncState.IDLE){
icon.source = UM.Theme.getIcon("update")
} else if(newState == Cura.AccountSyncState.SYNCING){
icon.source = UM.Theme.getIcon("update")
stateLabel.text = catalog.i18nc("@label", "Checking...")
} else if (newState == Cura.AccountSyncState.SUCCESS) {
icon.source = UM.Theme.getIcon("checked")
stateLabel.text = catalog.i18nc("@label", "You are in sync with your account")
} else if (newState == Cura.AccountSyncState.ERROR) {
icon.source = UM.Theme.getIcon("warning_light")
stateLabel.text = catalog.i18nc("@label", "Something went wrong...")
} else {
print("Error: unexpected sync state: " + newState)
}
if(newState == Cura.AccountSyncState.SYNCING){
updateAnimator.running = true
} else {
updateAnimator.running = false
}
}
Component.onCompleted: Cura.API.account.syncStateChanged.connect(syncStateChanged)
}
}

View File

@ -9,72 +9,119 @@ import Cura 1.1 as Cura
Column
{
width: Math.max(
Math.max(title.width, accountButton.width) + 2 * UM.Theme.getSize("default_margin").width,
syncRow.width
)
spacing: UM.Theme.getSize("narrow_margin").height
topPadding: UM.Theme.getSize("default_margin").height
bottomPadding: UM.Theme.getSize("default_margin").height
width: childrenRect.width
spacing: UM.Theme.getSize("default_margin").height
SystemPalette
Item
{
id: palette
id: accountInfo
width: childrenRect.width
height: childrenRect.height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
AvatarImage
{
id: avatar
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("main_window_header").height
height: UM.Theme.getSize("main_window_header").height
source: profile["profile_image_url"] ? profile["profile_image_url"] : ""
outlineColor: UM.Theme.getColor("main_background")
}
Rectangle
{
id: initialCircle
width: avatar.width
height: avatar.height
radius: width
anchors.verticalCenter: parent.verticalCenter
color: UM.Theme.getColor("action_button_disabled")
visible: !avatar.hasAvatar
Label
{
id: initialLabel
anchors.centerIn: parent
text: profile["username"].charAt(0).toUpperCase()
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
}
}
Column
{
anchors.left: avatar.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("narrow_margin").height
width: childrenRect.width
height: childrenRect.height
Label
{
id: username
renderType: Text.NativeRendering
text: profile.username
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
}
SyncState
{
id: syncRow
}
Label
{
id: lastSyncLabel
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a timestamp", "Last update: %1").arg(Cura.API.account.lastSyncDateTime)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
}
}
}
Label
Rectangle
{
id: title
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a username.", "Hi %1").arg(profile.username)
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
width: parent.width
color: UM.Theme.getColor("lining")
height: UM.Theme.getSize("default_lining").height
}
SyncState {
id: syncRow
}
Label
Cura.TertiaryButton
{
id: lastSyncLabel
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a timestamp", "Last update: %1").arg(Cura.API.account.lastSyncDateTime)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
}
Cura.SecondaryButton
{
id: accountButton
anchors.horizontalCenter: parent.horizontalCenter
id: cloudButton
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Ultimaker account")
text: catalog.i18nc("@button", "Ultimaker Digital Factory")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerDigitalFactoryUrl)
fixedWidthMode: false
}
Cura.TertiaryButton
{
id: accountButton
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Ultimaker Account")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl)
fixedWidthMode: false
}
Label
Rectangle
{
id: signOutButton
anchors.horizontalCenter: parent.horizontalCenter
text: catalog.i18nc("@button", "Sign out")
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
MouseArea
{
anchors.fill: parent
onClicked: Cura.API.account.logout()
hoverEnabled: true
onEntered: signOutButton.font.underline = true
onExited: signOutButton.font.underline = false
}
width: parent.width
color: UM.Theme.getColor("lining")
height: UM.Theme.getSize("default_lining").height
}
Cura.TertiaryButton
{
id: signOutButton
onClicked: Cura.API.account.logout()
text: catalog.i18nc("@button", "Sign Out")
}
}

View File

@ -33,6 +33,8 @@ Button
property alias shadowEnabled: shadow.visible
property alias busy: busyIndicator.visible
property bool underlineTextOnHover: false
property alias toolTipContentAlignment: tooltip.contentAlignment
// This property is used to indicate whether the button has a fixed width or the width would depend on the contents
@ -49,6 +51,14 @@ Button
height: UM.Theme.getSize("action_button").height
hoverEnabled: true
onHoveredChanged:
{
if(underlineTextOnHover)
{
buttonText.font.underline = hovered
}
}
contentItem: Row
{
spacing: UM.Theme.getSize("narrow_margin").width

View File

@ -84,6 +84,21 @@ UM.MainWindow
CuraApplication.purgeWindows()
}
Connections
{
// This connection is used when there is no ActiveMachine and the user is logged in
target: CuraApplication
onShowAddPrintersUncancellableDialog:
{
Cura.Actions.parent = backgroundItem
// Reuse the welcome dialog item to show "Add a printer" only.
welcomeDialogItem.model = CuraApplication.getAddPrinterPagesModelWithoutCancel()
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
}
Connections
{
target: CuraApplication
@ -117,6 +132,15 @@ UM.MainWindow
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
// Reuse the welcome dialog item to show the "Add printers" dialog. Triggered when there is no active
// machine and the user is logged in.
if (!Cura.MachineManager.activeMachine && Cura.API.account.isLoggedIn)
{
welcomeDialogItem.model = CuraApplication.getAddPrinterPagesModelWithoutCancel()
welcomeDialogItem.progressBarVisible = false
welcomeDialogItem.visible = true
}
}
}

View File

@ -14,8 +14,8 @@ UM.Dialog
id: base
title: catalog.i18nc("@title:window", "Discard or Keep changes")
width: UM.Theme.getSize("popup_dialog").width
height: UM.Theme.getSize("popup_dialog").height
minimumWidth: UM.Theme.getSize("popup_dialog").width
minimumHeight: UM.Theme.getSize("popup_dialog").height
property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged:
{
@ -80,6 +80,8 @@ UM.Dialog
property var extruder_name: userChangesModel.getItem(styleData.row).extruder
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
elide: Text.ElideRight
font: UM.Theme.getFont("system")
text:
{

View File

@ -143,7 +143,7 @@ UM.Dialog
{
width: parent.width
height: childrenRect.height
model: Cura.MachineManager.activeMachine.extruderList
model: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.extruderList : null
delegate: Column
{
height: childrenRect.height

View File

@ -77,6 +77,8 @@ UM.TooltipArea
anchors.left: fieldLabel.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
verticalAlignment: Text.AlignVCenter
padding: 0
leftPadding: UM.Theme.getSize("narrow_margin").width
width: numericTextFieldWithUnit.controlWidth
height: numericTextFieldWithUnit.controlHeight

View File

@ -33,7 +33,7 @@ Cura.ExpandablePopup
}
contentPadding: UM.Theme.getSize("default_lining").width
enabled: Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates; //Only let it drop down if there is any configuration that you could change.
enabled: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials || Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates : false; //Only let it drop down if there is any configuration that you could change.
headerItem: Item
{
@ -41,6 +41,7 @@ Cura.ExpandablePopup
RowLayout
{
anchors.fill: parent
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
Repeater
{
model: extrudersModel
@ -84,7 +85,7 @@ Cura.ExpandablePopup
{
id: variantLabel
visible: Cura.MachineManager.activeMachine.hasVariants
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
text: model.variant
elide: Text.ElideRight
@ -114,7 +115,7 @@ Cura.ExpandablePopup
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
visible: !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates)
visible: Cura.MachineManager.activeMachine ? !Cura.MachineManager.activeMachine.hasMaterials && (Cura.MachineManager.activeMachine.hasVariants || Cura.MachineManager.activeMachine.hasVariantBuildplates) : false
anchors
{

View File

@ -244,7 +244,7 @@ Item
Row
{
height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
visible: Cura.MachineManager.activeMachine.hasMaterials
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasMaterials : false
Label
{
@ -305,7 +305,7 @@ Item
Row
{
height: visible ? UM.Theme.getSize("print_setup_big_item").height : 0
visible: Cura.MachineManager.activeMachine.hasVariants
visible: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.hasVariants : false
Label
{

View File

@ -130,7 +130,11 @@ Item
target: extruderModel
onModelChanged:
{
supportExtruderCombobox.color = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
var maybeColor = supportExtruderCombobox.model.getItem(supportExtruderCombobox.currentIndex).color
if (maybeColor)
{
supportExtruderCombobox.color = maybeColor
}
}
}
onCurrentIndexChanged:

View File

@ -28,11 +28,11 @@ ListView
delegate: MachineSelectorButton
{
text: model.name
text: model.name ? model.name : ""
width: listView.width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
checked: Cura.MachineManager.activeMachine.id == model.id
checked: Cura.MachineManager.activeMachine ? Cura.MachineManager.activeMachine.id == model.id : false
onClicked:
{

View File

@ -0,0 +1,21 @@
// Copyright (c) 2020 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: "transparent"
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: "transparent"
underlineTextOnHover: true
}

View File

@ -96,6 +96,8 @@ Item
{
UM.Controller.setActiveTool(model.id);
}
base.state = (index < toolsModel.count/2) ? "anchorAtTop" : "anchorAtBottom";
}
}
}
@ -219,4 +221,40 @@ Item
visible: toolHint.text != ""
}
states: [
State {
name: "anchorAtTop"
AnchorChanges {
target: panelBorder
anchors.top: base.top
anchors.bottom: undefined
}
PropertyChanges {
target: panelBorder
anchors.topMargin: base.activeY
}
},
State {
name: "anchorAtBottom"
AnchorChanges {
target: panelBorder
anchors.top: undefined
anchors.bottom: base.top
}
PropertyChanges {
target: panelBorder
anchors.bottomMargin: {
if (panelBorder.height > (base.activeY + UM.Theme.getSize("button").height)) {
// panel is tall, align the top of the panel with the top of the first tool button
return -panelBorder.height
}
// align the bottom of the panel with the bottom of the selected tool button
return -(base.activeY + UM.Theme.getSize("button").height)
}
}
}
]
}

View File

@ -5,7 +5,7 @@ import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import Cura 1.0 as Cura
import Cura 1.1 as Cura
//
@ -29,8 +29,6 @@ Item
"Custom": -1
}
property int maxItemCountAtOnce: 10 // show at max 10 items at once, otherwise you need to scroll.
// User-editable printer name
property alias printerName: printerNameTextField.text
property alias isPrinterNameValid: printerNameTextField.acceptableInput
@ -54,12 +52,27 @@ Item
}
}
function getMachineName()
{
return machineList.model.getItem(machineList.currentIndex) != undefined ? machineList.model.getItem(machineList.currentIndex).name : "";
}
function getMachineMetaDataEntry(key)
{
var metadata = machineList.model.getItem(machineList.currentIndex) != undefined ? machineList.model.getItem(machineList.currentIndex).metadata : undefined;
if (metadata)
{
return metadata[key];
}
return undefined;
}
Component.onCompleted:
{
updateCurrentItemUponSectionChange()
}
Item
Row
{
id: localPrinterSelectionItem
anchors.left: parent.left
@ -68,19 +81,12 @@ Item
height: childrenRect.height
// ScrollView + ListView for selecting a local printer to add
ScrollView
Cura.ScrollView
{
id: scrollView
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: (maxItemCountAtOnce * UM.Theme.getSize("action_button").height) - UM.Theme.getSize("default_margin").height
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AsNeeded
clip: true
height: childrenHeight
width: Math.floor(parent.width * 0.4)
ListView
{
@ -183,52 +189,94 @@ Item
}
}
}
}
// Horizontal line
Rectangle
{
id: horizontalLine
anchors.top: localPrinterSelectionItem.bottom
anchors.left: parent.left
anchors.right: parent.right
height: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
}
// User-editable printer name row
Row
{
anchors.top: horizontalLine.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: UM.Theme.getSize("default_lining").height
anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
Label
// Vertical line
Rectangle
{
text: catalog.i18nc("@label", "Printer name")
anchors.verticalCenter: parent.verticalCenter
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
id: verticalLine
anchors.top: parent.top
height: childrenHeight - UM.Theme.getSize("default_lining").height
width: UM.Theme.getSize("default_lining").height
color: UM.Theme.getColor("lining")
}
Cura.TextField
// User-editable printer name row
Column
{
id: printerNameTextField
anchors.verticalCenter: parent.verticalCenter
width: (parent.width / 2) | 0
placeholderText: catalog.i18nc("@text", "Please give your printer a name")
maximumLength: 40
validator: RegExpValidator
width: Math.floor(parent.width * 0.6)
spacing: UM.Theme.getSize("default_margin").width
padding: UM.Theme.getSize("default_margin").width
Label
{
regExp: printerNameTextField.machineNameValidator.machineNameRegex
width: parent.width
wrapMode: Text.WordWrap
text: base.getMachineName()
color: UM.Theme.getColor("primary_button")
font: UM.Theme.getFont("huge")
elide: Text.ElideRight
}
Grid
{
width: parent.width
columns: 2
rowSpacing: UM.Theme.getSize("default_lining").height
columnSpacing: UM.Theme.getSize("default_margin").width
verticalItemAlignment: Grid.AlignVCenter
Label
{
text: catalog.i18nc("@label", "Manufacturer")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
Label
{
text: base.getMachineMetaDataEntry("manufacturer")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
Label
{
text: catalog.i18nc("@label", "Profile author")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
Label
{
text: base.getMachineMetaDataEntry("author")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
Label
{
text: catalog.i18nc("@label", "Printer name")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
Cura.TextField
{
id: printerNameTextField
placeholderText: catalog.i18nc("@text", "Please give your printer a name")
maximumLength: 40
validator: RegExpValidator
{
regExp: printerNameTextField.machineNameValidator.machineNameRegex
}
property var machineNameValidator: Cura.MachineNameValidator { }
}
}
property var machineNameValidator: Cura.MachineNameValidator { }
}
}
}

View File

@ -108,6 +108,12 @@ Item
AddLocalPrinterScrollView
{
id: localPrinterView
property int childrenHeight: backButton.y - addLocalPrinterDropDown.y - UM.Theme.getSize("expandable_component_content_header").height - UM.Theme.getSize("default_margin").height
onChildrenHeightChanged:
{
addLocalPrinterDropDown.children[1].height = childrenHeight
}
}
}
}

View File

@ -0,0 +1,46 @@
// Copyright (c) 2020 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.1 as UM
ScrollView
{
clip: true
// Setting this property to false hides the scrollbar both when the scrollbar is not needed (child height < height)
// and when the scrollbar is not actively being hovered or pressed
property bool scrollAlwaysVisible: true
ScrollBar.vertical: ScrollBar
{
hoverEnabled: true
policy: parent.scrollAlwaysVisible ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
contentItem: Rectangle
{
implicitWidth: UM.Theme.getSize("scrollbar").width
opacity: (parent.active || parent.parent.scrollAlwaysVisible) ? 1.0 : 0.0
radius: Math.round(width / 2)
color:
{
if (parent.pressed)
{
return UM.Theme.getColor("scrollbar_handle_down")
}
else if (parent.hovered)
{
return UM.Theme.getColor("scrollbar_handle_hover")
}
return UM.Theme.getColor("scrollbar_handle")
}
Behavior on color { ColorAnimation { duration: 100; } }
Behavior on opacity { NumberAnimation { duration: 100 } }
}
}
}

View File

@ -35,6 +35,7 @@ RadioButton 1.0 RadioButton.qml
Scrollable 1.0 Scrollable.qml
TabButton 1.0 TabButton.qml
TextField 1.0 TextField.qml
ScrollView 1.0 ScrollView.qml
# Cura/MachineSettings

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = Draft
definition = tinyboy_e10
[metadata]
setting_version = 15
type = quality
quality_type = draft
weight = 0
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.3
layer_height_0 = 0.3
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 60
speed_support = 60
speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = High
definition = tinyboy_e10
[metadata]
setting_version = 15
type = quality
quality_type = high
weight = 2
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.1
layer_height_0 = 0.1
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 50
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = Normal
definition = tinyboy_e10
[metadata]
setting_version = 15
type = quality
quality_type = normal
weight = 1
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.2
layer_height_0 = 0.2
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = Draft
definition = tinyboy_e16
[metadata]
setting_version = 15
type = quality
quality_type = draft
weight = 0
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.3
layer_height_0 = 0.3
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 60
speed_support = 60
speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = High
definition = tinyboy_e16
[metadata]
setting_version = 15
type = quality
quality_type = high
weight = 2
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.1
layer_height_0 = 0.1
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 50
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = Normal
definition = tinyboy_e16
[metadata]
setting_version = 15
type = quality
quality_type = normal
weight = 1
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.2
layer_height_0 = 0.2
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = Draft
definition = tinyboy_ra20
[metadata]
setting_version = 15
type = quality
quality_type = draft
weight = 0
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = none
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.3
layer_height_0 = 0.3
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 60
speed_support = 60
speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = High
definition = tinyboy_ra20
[metadata]
setting_version = 15
type = quality
quality_type = high
weight = 2
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = none
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.1
layer_height_0 = 0.1
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 50
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -0,0 +1,61 @@
[general]
version = 4
name = Normal
definition = tinyboy_ra20
[metadata]
setting_version = 15
type = quality
quality_type = normal
weight = 1
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = none
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.2
layer_height_0 = 0.2
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View File

@ -24,6 +24,8 @@
"main_window_header_button_text_inactive": [128, 128, 128, 255],
"account_sync_state_icon": [255, 255, 255, 204],
"machine_selector_bar": [39, 44, 48, 255],
"machine_selector_active": [39, 44, 48, 255],
"machine_selector_printer_icon": [204, 204, 204, 255],

View File

@ -183,6 +183,7 @@
"main_window_header_button_background_hovered": [117, 114, 159, 255],
"account_widget_outline_active": [70, 66, 126, 255],
"account_sync_state_icon": [25, 25, 25, 255],
"machine_selector_bar": [31, 36, 39, 255],
"machine_selector_active": [68, 72, 75, 255],