This commit is contained in:
Tim Kuipers 2015-08-24 12:05:49 +02:00
commit 7f15505f01
48 changed files with 783 additions and 314 deletions

View file

@ -39,7 +39,8 @@ Please checkout [cura-build](https://github.com/Ultimaker/cura-build)
Third party plugins
-------------
[Print time calculator](https://github.com/nallath/PrintCostCalculator)
* [Print time calculator](https://github.com/nallath/PrintCostCalculator)
* [Post processing plugin](https://github.com/nallath/PostProcessingPlugin)
Making profiles for other printers
----------------------------------

View file

@ -79,11 +79,13 @@ class CuraApplication(QtApplication):
self._platform_activity = False
self.activeMachineChanged.connect(self._onActiveMachineChanged)
self.getController().getScene().sceneChanged.connect(self.updatePlatformActivity)
Preferences.getInstance().addPreference("cura/active_machine", "")
Preferences.getInstance().addPreference("cura/active_mode", "simple")
Preferences.getInstance().addPreference("cura/recent_files", "")
Preferences.getInstance().addPreference("cura/categories_expanded", "")
Preferences.getInstance().addPreference("view/center_on_select", True)
JobQueue.getInstance().jobFinished.connect(self._onJobFinished)
@ -115,6 +117,11 @@ class CuraApplication(QtApplication):
def run(self):
self._i18n_catalog = i18nCatalog("cura");
i18nCatalog.setTagReplacements({
"filename": "font color=\"black\"",
"message": "font color=UM.Theme.colors.message_text;",
})
self.showSplashMessage(self._i18n_catalog.i18nc("Splash screen message", "Setting up scene..."))
controller = self.getController()
@ -196,10 +203,10 @@ class CuraApplication(QtApplication):
self._previous_active_tool = None
else:
self.getController().setActiveTool("TranslateTool")
self._camera_animation.setStart(self.getController().getTool("CameraTool").getOrigin())
self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
self._camera_animation.start()
if Preferences.getInstance().getValue("view/center_on_select"):
self._camera_animation.setStart(self.getController().getTool("CameraTool").getOrigin())
self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
self._camera_animation.start()
else:
if self.getController().getActiveTool():
self._previous_active_tool = self.getController().getActiveTool().getPluginId()
@ -214,24 +221,15 @@ class CuraApplication(QtApplication):
def getPlatformActivity(self):
return self._platform_activity
@pyqtSlot(bool)
def setPlatformActivity(self, activity):
##Sets the _platform_activity variable on true or false depending on whether there is a mesh on the platform
if activity == True:
self._platform_activity = activity
elif activity == False:
nodes = []
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if type(node) is not SceneNode or not node.getMeshData():
continue
nodes.append(node)
i = 0
for node in nodes:
if not node.getMeshData():
continue
i += 1
if i <= 1: ## i == 0 when the meshes are removed using the deleteAll function; i == 1 when the last remaining mesh is removed using the deleteObject function
self._platform_activity = activity
def updatePlatformActivity(self, node = None):
count = 0
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if type(node) is not SceneNode or not node.getMeshData():
continue
count += 1
self._platform_activity = True if count > 0 else False
self.activityChanged.emit()
## Remove an object from the scene
@ -252,8 +250,7 @@ class CuraApplication(QtApplication):
group_node = group_node.getParent()
op = RemoveSceneNodeOperation(group_node)
op.push()
self.setPlatformActivity(False)
## Create a number of copies of existing object.
@pyqtSlot("quint64", int)
def multiplyObject(self, object_id, count):
@ -300,8 +297,7 @@ class CuraApplication(QtApplication):
op.addOperation(RemoveSceneNodeOperation(node))
op.push()
self.setPlatformActivity(False)
## Reset all translation on nodes with mesh data.
@pyqtSlot()
def resetAllTranslation(self):

View file

@ -12,6 +12,8 @@ from UM.Math.Vector import Vector
from UM.Math.AxisAlignedBox import AxisAlignedBox
from UM.Application import Application
from UM.Scene.Selection import Selection
from UM.Preferences import Preferences
from cura.ConvexHullDecorator import ConvexHullDecorator
from . import PlatformPhysicsOperation
@ -37,6 +39,8 @@ class PlatformPhysics:
self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self._onChangeTimerFinished)
Preferences.getInstance().addPreference("physics/automatic_push_free", True)
def _onSceneChanged(self, source):
self._change_timer.start()
@ -82,7 +86,7 @@ class PlatformPhysics:
elif Selection.isSelected(node):
pass
else:
elif Preferences.getInstance().getValue("physics/automatic_push_free"):
# Check for collisions between convex hulls
for other_node in BreadthFirstIterator(root):
# Ignore root, ourselves and anything that is not a normal SceneNode.

View file

@ -15,16 +15,21 @@ import os
import struct
import math
from os import listdir
import untangle
import zipfile
import xml.etree.ElementTree as ET
## Base implementation for reading 3MF files. Has no support for textures. Only loads meshes!
class ThreeMFReader(MeshReader):
def __init__(self):
super(ThreeMFReader, self).__init__()
self._supported_extension = ".3mf"
self._namespaces = {
"3mf": "http://schemas.microsoft.com/3dmanufacturing/core/2015/02",
"cura": "http://software.ultimaker.com/xml/cura/3mf/2015/10"
}
def read(self, file_name):
result = None
extension = os.path.splitext(file_name)[1]
@ -33,32 +38,39 @@ class ThreeMFReader(MeshReader):
# The base object of 3mf is a zipped archive.
archive = zipfile.ZipFile(file_name, 'r')
try:
# The model is always stored in this place.
root = untangle.parse(archive.read("3D/3dmodel.model").decode("utf-8"))
for object in root.model.resources.object: # There can be multiple objects, try to load all of them.
root = ET.parse(archive.open("3D/3dmodel.model"))
# There can be multiple objects, try to load all of them.
objects = root.findall("./3mf:resources/3mf:object", self._namespaces)
for object in objects:
mesh = MeshData()
node = SceneNode()
vertex_list = []
for vertex in object.mesh.vertices.vertex:
vertex_list.append([vertex['x'],vertex['y'],vertex['z']])
#for vertex in object.mesh.vertices.vertex:
for vertex in object.findall(".//3mf:vertex", self._namespaces):
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
triangles = object.findall(".//3mf:triangle", self._namespaces)
mesh.reserveFaceCount(len(triangles))
mesh.reserveFaceCount(len(object.mesh.triangles.triangle))
for triangle in object.mesh.triangles.triangle:
v1 = int(triangle["v1"])
v2 = int(triangle["v2"])
v3 = int(triangle["v3"])
#for triangle in object.mesh.triangles.triangle:
for triangle in triangles:
v1 = int(triangle.get("v1"))
v2 = int(triangle.get("v2"))
v3 = int(triangle.get("v3"))
mesh.addFace(vertex_list[v1][0],vertex_list[v1][1],vertex_list[v1][2],vertex_list[v2][0],vertex_list[v2][1],vertex_list[v2][2],vertex_list[v3][0],vertex_list[v3][1],vertex_list[v3][2])
#TODO: We currently do not check for normals and simply recalculate them.
mesh.calculateNormals()
node.setMeshData(mesh)
node.setSelectable(True)
# Magical python comprehension; looks for the matching transformation
transformation = next((x for x in root.model.build.item if x["objectid"] == object["id"]), None)
if transformation["transform"]:
splitted_transformation = transformation["transform"].split()
transformation = root.findall("./3mf:build/3mf:item[@objectid='{0}']".format(object.get("id")), self._namespaces)
if transformation:
transformation = transformation[0]
if transformation.get("transform"):
splitted_transformation = transformation.get("transform").split()
## Transformation is saved as:
## M00 M01 M02 0.0
## M10 M11 M12 0.0
@ -99,10 +111,10 @@ class ThreeMFReader(MeshReader):
rotation = Quaternion.fromAngleAxis(-0.5 * math.pi, Vector(1,0,0))
node.rotate(rotation)
result.addChild(node)
# If there is more then one object, group them.
#If there is more then one object, group them.
try:
if len(root.model.resources.object) > 1:
if len(objects) > 1:
group_decorator = GroupDecorator()
result.addDecorator(group_decorator)
except:

View file

@ -130,6 +130,7 @@ class CuraEngineBackend(Backend):
if not getattr(node, "_outside_buildarea", False):
temp_list.append(node)
if len(temp_list) == 0:
self.processingProgress.emit(0.0)
return
object_groups.append(temp_list)
#for node in DepthFirstIterator(self._scene.getRoot()):
@ -241,6 +242,10 @@ class CuraEngineBackend(Backend):
self._socket.registerMessageType(6, Cura_pb2.SettingList)
self._socket.registerMessageType(7, Cura_pb2.GCodePrefix)
## Manually triggers a reslice
def forceSlice(self):
self._change_timer.start()
def _onChanged(self):
if not self._settings:
return

View file

@ -28,7 +28,8 @@ class LayerData(MeshData):
self._layers[layer].polygons.append(p)
def getLayer(self, layer):
return self._layers[layer]
if layer in self._layers:
return self._layers[layer]
def getLayers(self):
return self._layers

View file

@ -17,8 +17,8 @@ class RemovableDriveOutputDevice(OutputDevice):
super().__init__(device_id)
self.setName(device_name)
self.setShortDescription(catalog.i18nc("", "Save to Removable Drive"))
self.setDescription(catalog.i18nc("", "Save to Removable Drive {0}").format(device_name))
self.setShortDescription(catalog.i18nc("@action:button", "Save to Removable Drive"))
self.setDescription(catalog.i18nc("@info:tooltip", "Save to Removable Drive {0}").format(device_name))
self.setIconName("save_sd")
self.setPriority(1)
@ -49,7 +49,7 @@ class RemovableDriveOutputDevice(OutputDevice):
job.progress.connect(self._onProgress)
job.finished.connect(self._onFinished)
message = Message(catalog.i18nc("", "Saving to Removable Drive {0}").format(self.getName()), 0, False, -1)
message = Message(catalog.i18nc("@info:status", "Saving to Removable Drive <filename>{0}</filename>").format(self.getName()), 0, False, -1)
message.show()
job._message = message

View file

@ -22,7 +22,7 @@ UM.Dialog
Column
{
anchors.fill: parent;
Text
{
anchors {

View file

@ -44,6 +44,9 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
self._connect_thread = threading.Thread(target = self._connect)
self._connect_thread.daemon = True
self._end_stop_thread = threading.Thread(target = self._pollEndStop)
self._end_stop_thread.deamon = True
# Printer is connected
self._is_connected = False
@ -52,7 +55,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
# The baud checking is done by sending a number of m105 commands to the printer and waiting for a readable
# response. If the baudrate is correct, this should make sense, else we get giberish.
self._required_responses_auto_baud = 10
self._required_responses_auto_baud = 3
self._progress = 0
@ -60,8 +63,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
self._listen_thread.daemon = True
self._update_firmware_thread = threading.Thread(target= self._updateFirmware)
self._update_firmware_thread.demon = True
self._update_firmware_thread.deamon = True
self._heatup_wait_start_time = time.time()
## Queue for commands that need to be send. Used when command is sent when a print is active.
@ -97,6 +100,14 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
# Current Z stage location
self._current_z = 0
self._x_min_endstop_pressed = False
self._y_min_endstop_pressed = False
self._z_min_endstop_pressed = False
self._x_max_endstop_pressed = False
self._y_max_endstop_pressed = False
self._z_max_endstop_pressed = False
# In order to keep the connection alive we request the temperature every so often from a different extruder.
# This index is the extruder we requested data from the last time.
self._temperature_requested_extruder_index = 0
@ -112,6 +123,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
extruderTemperatureChanged = pyqtSignal()
bedTemperatureChanged = pyqtSignal()
endstopStateChanged = pyqtSignal(str ,bool, arguments = ["key","state"])
@pyqtProperty(float, notify = progressChanged)
def progress(self):
return self._progress
@ -209,6 +222,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
self.setProgress(100, 100)
self.firmwareUpdateComplete.emit()
## Upload new firmware to machine
# \param filename full path of firmware file to be uploaded
def updateFirmware(self, file_name):
@ -216,6 +231,20 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
self._firmware_file_name = file_name
self._update_firmware_thread.start()
@pyqtSlot()
def startPollEndstop(self):
self._poll_endstop = True
self._end_stop_thread.start()
@pyqtSlot()
def stopPollEndstop(self):
self._poll_endstop = False
def _pollEndStop(self):
while self._is_connected and self._poll_endstop:
self.sendCommand("M119")
time.sleep(0.5)
## Private connect function run by thread. Can be started by calling connect.
def _connect(self):
Logger.log("d", "Attempting to connect to %s", self._serial_port)
@ -255,9 +284,9 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
if line is None:
self.setIsConnected(False) # Something went wrong with reading, could be that close was called.
return
if b"T:" in line:
self._serial.timeout = 0.5
self._sendCommand("M105")
sucesfull_responses += 1
if sucesfull_responses >= self._required_responses_auto_baud:
self._serial.timeout = 2 #Reset serial timeout
@ -265,6 +294,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
Logger.log("i", "Established printer connection on port %s" % self._serial_port)
return
self._sendCommand("M105") # Send M105 as long as we are listening, otherwise we end up in an undefined state
Logger.log("e", "Baud rate detection for %s failed", self._serial_port)
self.close() # Unable to connect, wrap up.
self.setIsConnected(False)
@ -297,6 +328,9 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
except Exception as e:
pass # This should work, but it does fail sometimes for some reason
self._connect_thread = threading.Thread(target=self._connect)
self._connect_thread.daemon = True
if self._serial is not None:
self.setIsConnected(False)
try:
@ -305,11 +339,30 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
pass
self._serial.close()
self._listen_thread = threading.Thread(target=self._listen)
self._listen_thread.daemon = True
self._serial = None
def isConnected(self):
return self._is_connected
@pyqtSlot(int)
def heatupNozzle(self, temperature):
self._sendCommand("M104 S%s" % temperature)
@pyqtSlot(int)
def heatupBed(self, temperature):
self._sendCommand("M140 S%s" % temperature)
@pyqtSlot("long", "long","long")
def moveHead(self, x, y, z):
print("Moving head" , x , " ", y , " " , z)
self._sendCommand("G0 X%s Y%s Z%s"%(x,y,z))
@pyqtSlot()
def homeHead(self):
self._sendCommand("G28")
## Directly send the command, withouth checking connection state (eg; printing).
# \param cmd string with g-code
def _sendCommand(self, cmd):
@ -402,6 +455,20 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
def requestWrite(self, node):
self.showControlInterface()
def _setEndstopState(self, endstop_key, value):
if endstop_key == b'x_min':
if self._x_min_endstop_pressed != value:
self.endstopStateChanged.emit('x_min', value)
self._x_min_endstop_pressed = value
elif endstop_key == b'y_min':
if self._y_min_endstop_pressed != value:
self.endstopStateChanged.emit('y_min', value)
self._y_min_endstop_pressed = value
elif endstop_key == b'z_min':
if self._z_min_endstop_pressed != value:
self.endstopStateChanged.emit('z_min', value)
self._z_min_endstop_pressed = value
## Listen thread function.
def _listen(self):
Logger.log("i", "Printer connection listen thread started for %s" % self._serial_port)
@ -413,6 +480,14 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
if line is None:
break # None is only returned when something went wrong. Stop listening
if time.time() > temperature_request_timeout:
if self._extruder_count > 0:
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._extruder_count
self.sendCommand("M105 T%d" % (self._temperature_requested_extruder_index))
else:
self.sendCommand("M105")
temperature_request_timeout = time.time() + 5
if line.startswith(b"Error:"):
# Oh YEAH, consistency.
# Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
@ -437,16 +512,11 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
except Exception as e:
pass
#TODO: temperature changed callback
elif b"_min" in line or b"_max" in line:
tag, value = line.split(b':', 1)
self._setEndstopState(tag,(b'H' in value or b'TRIGGERED' in value))
if self._is_printing:
if time.time() > temperature_request_timeout: # When printing, request temperature every 5 seconds.
if self._extruder_count > 0:
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._extruder_count
self.sendCommand("M105 T%d" % (self._temperature_requested_extruder_index))
else:
self.sendCommand("M105")
temperature_request_timeout = time.time() + 5
if line == b"" and time.time() > ok_timeout:
line = b"ok" # Force a timeout (basicly, send next command)
@ -540,3 +610,10 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
def _getBaudrateList(self):
ret = [250000, 230400, 115200, 57600, 38400, 19200, 9600]
return ret
def _onFirmwareUpdateComplete(self):
self._update_firmware_thread.join()
self._update_firmware_thread = threading.Thread(target= self._updateFirmware)
self._update_firmware_thread.deamon = True
self.connect()

View file

@ -10,6 +10,7 @@ from UM.Resources import Resources
from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
from UM.Qt.ListModel import ListModel
import threading
import platform
@ -35,6 +36,7 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
Extension.__init__(self)
self._serial_port_list = []
self._printer_connections = {}
self._printer_connections_model = None
self._update_thread = threading.Thread(target = self._updateThread)
self._update_thread.setDaemon(True)
@ -49,6 +51,7 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
self.addConnectionSignal.connect(self.addConnection) #Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
addConnectionSignal = Signal()
printerConnectionStateChanged = pyqtSignal()
def start(self):
self._check_updates = True
@ -84,15 +87,31 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
self.spawnFirmwareInterface("")
for printer_connection in self._printer_connections:
try:
printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))
self._printer_connections[printer_connection].updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))
except FileNotFoundError:
continue
@pyqtSlot(str, result = bool)
def updateFirmwareBySerial(self, serial_port):
printer_connection = self.getConnectionByPort(serial_port)
if printer_connection is not None:
self.spawnFirmwareInterface(printer_connection.getSerialPort())
printer_connection.updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))
if serial_port in self._printer_connections:
self.spawnFirmwareInterface(self._printer_connections[serial_port].getSerialPort())
try:
self._printer_connections[serial_port].updateFirmware(Resources.getPath(Resources.FirmwareLocation, self._getDefaultFirmwareName()))
except FileNotFoundError:
self._firmware_view.close()
Logger.log("e", "Could not find firmware required for this machine")
return False
return True
return False
## Return the singleton instance of the USBPrinterManager
@classmethod
def getInstance(cls, engine = None, script_engine = None):
# Note: Explicit use of class name to prevent issues with inheritance.
if USBPrinterManager._instance is None:
USBPrinterManager._instance = cls()
return USBPrinterManager._instance
def _getDefaultFirmwareName(self):
machine_type = Application.getInstance().getActiveMachine().getTypeID()
@ -140,6 +159,17 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
self.getOutputDeviceManager().addOutputDevice(self._printer_connections[serial_port])
else:
self.getOutputDeviceManager().removeOutputDevice(serial_port)
self.printerConnectionStateChanged.emit()
@pyqtProperty(QObject , notify = printerConnectionStateChanged)
def connectedPrinterList(self):
self._printer_connections_model = ListModel()
self._printer_connections_model.addRoleName(Qt.UserRole + 1,"name")
self._printer_connections_model.addRoleName(Qt.UserRole + 2, "printer")
for connection in self._printer_connections:
if self._printer_connections[connection].isConnected():
self._printer_connections_model.appendItem({"name":connection, "printer": self._printer_connections[connection]})
return self._printer_connections_model
## Create a list of serial ports on the system.
# \param only_list_usb If true, only usb ports are listed
@ -163,4 +193,6 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
base_list = filter(lambda s: "Bluetooth" not in s, base_list) # Filter because mac sometimes puts them in the list
else:
base_list = base_list + glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*") + glob.glob("/dev/cu.*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob("/dev/serial/by-id/*")
return list(base_list)
return list(base_list)
_instance = None

View file

@ -2,7 +2,7 @@
# Cura is released under the terms of the AGPLv3 or higher.
from . import USBPrinterManager
from PyQt5.QtQml import qmlRegisterType, qmlRegisterSingletonType
from UM.i18n import i18nCatalog
i18n_catalog = i18nCatalog("cura")
@ -19,4 +19,5 @@ def getMetaData():
}
def register(app):
return {"extension":USBPrinterManager.USBPrinterManager(),"output_device": USBPrinterManager.USBPrinterManager() }
qmlRegisterSingletonType(USBPrinterManager.USBPrinterManager, "UM", 1, 0, "USBPrinterManager", USBPrinterManager.USBPrinterManager.getInstance)
return {"extension":USBPrinterManager.USBPrinterManager.getInstance(),"output_device": USBPrinterManager.USBPrinterManager.getInstance() }

View file

@ -40,10 +40,18 @@ Item {
property alias reportBug: reportBugAction;
property alias about: aboutAction;
property alias toggleFullScreen: toggleFullScreenAction;
Action
{
id:toggleFullScreenAction
shortcut: StandardKey.FullScreen;
}
Action {
id: undoAction;
//: Undo action
text: qsTr("&Undo");
text: qsTr("Undo");
iconName: "edit-undo";
shortcut: StandardKey.Undo;
}
@ -51,7 +59,7 @@ Item {
Action {
id: redoAction;
//: Redo action
text: qsTr("&Redo");
text: qsTr("Redo");
iconName: "edit-redo";
shortcut: StandardKey.Redo;
}
@ -59,7 +67,7 @@ Item {
Action {
id: quitAction;
//: Quit action
text: qsTr("&Quit");
text: qsTr("Quit");
iconName: "application-exit";
shortcut: StandardKey.Quit;
}
@ -67,20 +75,20 @@ Item {
Action {
id: preferencesAction;
//: Preferences action
text: qsTr("&Preferences...");
text: qsTr("Preferences...");
iconName: "configure";
}
Action {
id: addMachineAction;
//: Add Printer action
text: qsTr("&Add Printer...");
text: qsTr("Add Printer...");
}
Action {
id: settingsAction;
//: Configure Printers action
text: qsTr("&Configure Printers");
text: qsTr("Configure Printers");
iconName: "configure";
}
@ -102,7 +110,7 @@ Item {
Action {
id: aboutAction;
//: About action
text: qsTr("&About...");
text: qsTr("About...");
iconName: "help-about";
}
@ -190,7 +198,7 @@ Item {
Action {
id: openAction;
//: Open file action
text: qsTr("&Open...");
text: qsTr("Load file");
iconName: "document-open";
shortcut: StandardKey.Open;
}
@ -198,7 +206,7 @@ Item {
Action {
id: saveAction;
//: Save file action
text: qsTr("&Save...");
text: qsTr("Save...");
iconName: "document-save";
shortcut: StandardKey.Save;
}

View file

@ -12,7 +12,6 @@ import UM 1.1 as UM
UM.MainWindow {
id: base
visible: true
//: Cura application window title
title: qsTr("Cura");
@ -212,10 +211,8 @@ UM.MainWindow {
UM.MessageStack {
anchors {
left: toolbar.right;
leftMargin: UM.Theme.sizes.window_margin.width;
right: sidebar.left;
rightMargin: UM.Theme.sizes.window_margin.width;
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: -(UM.Theme.sizes.logo.width/ 2)
top: parent.verticalCenter;
bottom: parent.bottom;
}
@ -242,17 +239,15 @@ UM.MainWindow {
Button {
id: openFileButton;
iconSource: UM.Theme.icons.open;
style: UM.Backend.progress < 0 ? UM.Theme.styles.open_file_button : UM.Theme.styles.tool_button;
//style: UM.Backend.progress < 0 ? UM.Theme.styles.open_file_button : UM.Theme.styles.tool_button;
style: UM.Theme.styles.open_file_button
tooltip: '';
anchors {
top: parent.top;
topMargin: UM.Theme.sizes.window_margin.height;
topMargin: UM.Theme.sizes.loadfile_margin.height
left: parent.left;
leftMargin: UM.Theme.sizes.window_margin.width;
leftMargin: UM.Theme.sizes.loadfile_margin.width
}
action: actions.open;
}
@ -349,8 +344,15 @@ UM.MainWindow {
id: preferences
Component.onCompleted: {
//; Remove & re-add the general page as we want to use our own instead of uranium standard.
removePage(0);
insertPage(0, qsTr("General") , "" , Qt.resolvedUrl("./GeneralPage.qml"));
//: View preferences page title
insertPage(1, qsTr("View"), "view-preview", Qt.resolvedUrl("./ViewPage.qml"));
//Force refresh
setPage(0)
}
}
@ -423,6 +425,8 @@ UM.MainWindow {
reportBug.onTriggered: CuraActions.openBugReportPage();
showEngineLog.onTriggered: engineLog.visible = true;
about.onTriggered: aboutDialog.visible = true;
toggleFullScreen.onTriggered: base.toggleFullscreen()
}
Menu {
@ -481,7 +485,6 @@ UM.MainWindow {
onAccepted:
{
UM.MeshFileHandler.readLocalFile(fileUrl)
Printer.setPlatformActivity(true)
}
}

View file

@ -0,0 +1,130 @@
// Copyright (c) 2015 Ultimaker B.V.
// Uranium is released under the terms of the AGPLv3 or higher.
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.1
import UM 1.0 as UM
UM.PreferencesPage
{
//: General configuration page title
title: qsTr("General");
function reset()
{
UM.Preferences.resetPreference("general/language")
UM.Preferences.resetPreference("physics/automatic_push_free")
}
GridLayout
{
columns: 2;
//: Language selection label
Label
{
id: languageLabel
text: qsTr("Language")
}
ComboBox
{
id: languageComboBox
model: ListModel
{
id: languageList
//: English language combo box option
ListElement { text: QT_TR_NOOP("English"); code: "en" }
//: German language combo box option
ListElement { text: QT_TR_NOOP("German"); code: "de" }
//: French language combo box option
// ListElement { text: QT_TR_NOOP("French"); code: "fr" }
//: Spanish language combo box option
ListElement { text: QT_TR_NOOP("Spanish"); code: "es" }
//: Italian language combo box option
// ListElement { text: QT_TR_NOOP("Italian"); code: "it" }
//: Finnish language combo box option
ListElement { text: QT_TR_NOOP("Finnish"); code: "fi" }
//: Russian language combo box option
ListElement { text: QT_TR_NOOP("Russian"); code: "ru" }
}
currentIndex:
{
var code = UM.Preferences.getValue("general/language");
for(var i = 0; i < languageList.count; ++i)
{
if(model.get(i).code == code)
{
return i
}
}
}
onActivated: UM.Preferences.setValue("general/language", model.get(index).code)
anchors.left: languageLabel.right
anchors.top: languageLabel.top
anchors.leftMargin: 20
Component.onCompleted:
{
// Because ListModel is stupid and does not allow using qsTr() for values.
for(var i = 0; i < languageList.count; ++i)
{
languageList.setProperty(i, "text", qsTr(languageList.get(i).text));
}
// Glorious hack time. ComboBox does not update the text properly after changing the
// model. So change the indices around to force it to update.
currentIndex += 1;
currentIndex -= 1;
}
}
Label
{
id: languageCaption;
Layout.columnSpan: 2
//: Language change warning
text: qsTr("You will need to restart the application for language changes to have effect.")
wrapMode: Text.WordWrap
font.italic: true
}
CheckBox
{
id: pushFreeCheckbox
checked: UM.Preferences.getValue("physics/automatic_push_free")
onCheckedChanged: UM.Preferences.setValue("physics/automatic_push_free", checked)
}
Button
{
id: pushFreeText //is a button so the user doesn't have te click inconvenientley precise to enable or disable the checkbox
//: Display Overhang preference checkbox
text: qsTr("Automatic push free");
onClicked: pushFreeCheckbox.checked = !pushFreeCheckbox.checked
//: Display Overhang preference tooltip
tooltip: "Are objects on the platform automatically moved so they no longer intersect"
style: ButtonStyle
{
background: Rectangle
{
border.width: 0
color: "transparent"
}
label: Text
{
renderType: Text.NativeRendering
horizontalAlignment: Text.AlignLeft
text: control.text
}
}
}
Item { Layout.fillHeight: true; Layout.columnSpan: 2 }
}
}

View file

@ -19,7 +19,7 @@ Item {
anchors.bottom: parent.bottom;
anchors.left: parent.left;
spacing: 1
spacing: UM.Theme.sizes.default_lining.width
Repeater {
id: repeat
@ -67,6 +67,8 @@ Item {
Behavior on opacity { NumberAnimation { duration: 100 } }
color: UM.Theme.colors.tool_panel_background;
border.width: UM.Theme.sizes.default_lining.width
border.color: UM.Theme.colors.button_lining
Loader {
id: panel

View file

@ -8,7 +8,8 @@ import QtQuick.Controls.Styles 1.1
import UM 1.0 as UM
UM.PreferencesPage {
UM.PreferencesPage
{
id: preferencesPage
//: View configuration page title
@ -17,22 +18,26 @@ UM.PreferencesPage {
function reset()
{
UM.Preferences.resetPreference("view/show_overhang");
UM.Preferences.resetPreferences("view/center_on_select");
}
GridLayout {
GridLayout
{
columns: 2;
CheckBox {
id: viewCheckbox
CheckBox
{
id: overhangCheckbox
checked: UM.Preferences.getValue("view/show_overhang")
onCheckedChanged: UM.Preferences.setValue("view/show_overhang", checked)
}
Button {
Button
{
id: viewText //is a button so the user doesn't have te click inconvenientley precise to enable or disable the checkbox
//: Display Overhang preference checkbox
text: qsTr("Display Overhang");
onClicked: viewCheckbox.checked = !viewCheckbox.checked
onClicked: overhangCheckbox.checked = !overhangCheckbox.checked
//: Display Overhang preference tooltip
tooltip: "Highlight unsupported areas of the model in red. Without support these areas will nog print properly."
@ -49,6 +54,39 @@ UM.PreferencesPage {
}
}
}
CheckBox
{
id: centerCheckbox
checked: UM.Preferences.getValue("view/center_on_select")
onCheckedChanged: UM.Preferences.setValue("view/center_on_select", checked)
}
Button
{
id: centerText //is a button so the user doesn't have te click inconvenientley precise to enable or disable the checkbox
//: Display Overhang preference checkbox
text: qsTr("Center camera when item is selected");
onClicked: centerCheckbox.checked = !centerCheckbox.checked
//: Display Overhang preference tooltip
tooltip: "Moves the camera so the object is in the center of the view when an object is selected"
style: ButtonStyle
{
background: Rectangle
{
border.width: 0
color: "transparent"
}
label: Text
{
renderType: Text.NativeRendering
horizontalAlignment: Text.AlignLeft
text: control.text
}
}
}
Item { Layout.fillHeight: true; Layout.columnSpan: 2 }
}
}

View file

@ -252,6 +252,10 @@ ColumnLayout
UM.Models.availableMachinesModel.createMachine(machineList.currentIndex, machineName.text)
var pages = UM.Models.availableMachinesModel.getItem(machineList.currentIndex).pages
var old_page_count = elementRoot.getPageCount()
for(var i = 0; i < UM.Models.count; i++)
{
print(UM.Models.getItem(i))
}
// Delete old pages (if any)
for (var i = old_page_count - 1; i > 0; i--)
{

View file

@ -8,62 +8,47 @@ import QtQuick.Window 2.1
import UM 1.0 as UM
ColumnLayout {
Column
{
id: wizardPage
property string title
property int pageWidth
property int pageHeight
SystemPalette{id: palette}
//signal openFile(string fileName)
//signal closeWizard()
width: wizardPage.pageWidth
height: wizardPage.pageHeight
Connections {
target: elementRoot
onResize: {
wizardPage.width = pageWidth
wizardPage.height = pageHeight
}
property int leveling_state: 0
property bool three_point_leveling: true
property int platform_width: UM.Models.settingsModel.getMachineSetting("machine_width")
property int platform_height: UM.Models.settingsModel.getMachineSetting("machine_depth")
anchors.fill: parent;
property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
Component.onCompleted: printer_connection.homeHead()
Label
{
text: ""
//Component.onCompleted:console.log(UM.Models.settingsModel.getMachineSetting("machine_width"))
}
Label {
text: parent.title
font.pointSize: 18;
}
Label {
//: Add Printer wizard page description
text: qsTr("Please select the type of printer:");
}
ScrollView {
Layout.fillWidth: true;
ListView {
id: machineList;
model: UM.Models.availableMachinesModel
delegate: RadioButton {
exclusiveGroup: printerGroup;
text: model.name;
onClicked: {
ListView.view.currentIndex = index;
}
Button
{
text: "Move to next position"
onClicked:
{
if(wizardPage.leveling_state == 0)
{
printer_connection.moveHead(platform_width /2 , platform_height,0)
}
if(wizardPage.leveling_state == 1)
{
printer_connection.moveHead(platform_width , 0,0)
}
if(wizardPage.leveling_state == 2)
{
printer_connection.moveHead(0, 0 ,0)
}
wizardPage.leveling_state++
}
}
Label {
//: Add Printer wizard field label
text: qsTr("Printer Name:");
function threePointLeveling(width, height)
{
}
TextField { id: machineName; Layout.fillWidth: true; text: machineList.model.getItem(machineList.currentIndex).name }
Item { Layout.fillWidth: true; Layout.fillHeight: true; }
ExclusiveGroup { id: printerGroup; }
}

View file

@ -13,6 +13,16 @@ Column
id: wizardPage
property string title
anchors.fill: parent;
property bool x_min_pressed: false
property bool y_min_pressed: false
property bool z_min_pressed: false
property bool heater_works: false
property int extruder_target_temp: 0
property int bed_target_temp: 0
property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
Component.onCompleted: printer_connection.startPollEndstop()
Component.onDestruction: printer_connection.stopPollEndstop()
Label
{
@ -23,44 +33,144 @@ Column
Label
{
//: Add Printer wizard page description
text: qsTr("Please select the type of printer:");
text: qsTr("It's a good idea to do a few sanity checks on your Ultimaker. \n You can skip these if you know your machine is functional");
}
ScrollView
Row
{
height: parent.height - 50
width: parent.width
ListView
Label
{
id: machineList;
model: UM.Models.availableMachinesModel
delegate: RadioButton
{
exclusiveGroup: printerGroup;
text: model.name;
onClicked:
{
ListView.view.currentIndex = index;
}
}
text: qsTr("Connection: ")
}
Label
{
text: UM.USBPrinterManager.connectedPrinterList.count ? "Done":"Incomplete"
}
}
Row
{
Label
{
text: qsTr("Min endstop X: ")
}
Label
{
text: x_min_pressed ? qsTr("Works") : qsTr("Not checked")
}
}
Row
{
Label
{
text: qsTr("Min endstop Y: ")
}
Label
{
text: y_min_pressed ? qsTr("Works") : qsTr("Not checked")
}
}
Label
Row
{
//: Add Printer wizard field label
text: qsTr("Printer Name:");
Label
{
text: qsTr("Min endstop Z: ")
}
Label
{
text: z_min_pressed ? qsTr("Works") : qsTr("Not checked")
}
}
TextField
Row
{
id: machineName; Layout.fillWidth: true; text: machineList.model.getItem(machineList.currentIndex).name
Label
{
text: qsTr("Nozzle temperature check: ")
}
Label
{
text: printer_connection.extruderTemperature
}
Button
{
text: "Start heating"
onClicked:
{
heater_status_label.text = qsTr("Checking")
printer_connection.heatupNozzle(190)
wizardPage.extruder_target_temp = 190
}
}
Label
{
id: heater_status_label
text: qsTr("Not checked")
}
}
Item
Row
{
Layout.fillWidth: true;
Layout.fillHeight: true;
Label
{
text: qsTr("bed temperature check: ")
}
Label
{
text: printer_connection.bedTemperature
}
Button
{
text: "Start heating"
onClicked:
{
bed_status_label.text = qsTr("Checking")
printer_connection.printer.heatupBed(60)
wizardPage.bed_target_temp = 60
}
}
Label
{
id: bed_status_label
text: qsTr("Not checked")
}
}
Connections
{
target: printer_connection
onEndstopStateChanged:
{
if(key == "x_min")
{
x_min_pressed = true
}
if(key == "y_min")
{
y_min_pressed = true
}
if(key == "z_min")
{
z_min_pressed = true
}
}
onExtruderTemperatureChanged:
{
if(printer_connection.extruderTemperature > wizardPage.extruder_target_temp - 10 && printer_connection.extruderTemperature < wizardPage.extruder_target_temp + 10)
{
heater_status_label.text = qsTr("Works")
printer_connection.heatupNozzle(0)
}
}
onBedTemperatureChanged:
{
if(printer_connection.bedTemperature > wizardPage.bed_target_temp - 5 && printer_connection.bedTemperature < wizardPage.bed_target_temp + 5)
{
bed_status_label.text = qsTr("Works")
printer_connection.heatupBed(0)
}
}
}
ExclusiveGroup

View file

@ -13,19 +13,12 @@ Column
id: wizardPage
property string title
anchors.fill: parent;
Label
{
text: parent.title
font.pointSize: 18;
}
Label
{
//: Add Printer wizard page description
text: qsTr("Please select the type of printer:");
}
ScrollView
{
height: parent.height - 50
@ -33,14 +26,26 @@ Column
ListView
{
id: machineList;
model: UM.Models.availableMachinesModel
delegate: RadioButton
model: UM.USBPrinterManager.connectedPrinterList
delegate:Row
{
exclusiveGroup: printerGroup;
text: model.name;
onClicked:
id: derp
Text
{
ListView.view.currentIndex = index;
id: text_area
text: model.name
}
Button
{
text: "Update";
onClicked:
{
if(!UM.USBPrinterManager.updateFirmwareBySerial(text_area.text))
{
status_text.text = "ERROR"
}
}
}
}
}
@ -48,15 +53,10 @@ Column
Label
{
//: Add Printer wizard field label
text: qsTr("Printer Name:");
id: status_text
text: ""
}
TextField
{
id: machineName; Layout.fillWidth: true; text: machineList.model.getItem(machineList.currentIndex).name
}
Item
{
@ -64,8 +64,5 @@ Column
Layout.fillHeight: true;
}
ExclusiveGroup
{
id: printerGroup;
}
}

View file

@ -28,21 +28,6 @@
"machine_center_is_zero": {
"default": false
},
"machine_head_shape_min_x": {
"default": 40
},
"machine_head_shape_min_y": {
"default": 10
},
"machine_head_shape_max_x": {
"default": 60
},
"machine_head_shape_max_y": {
"default": 30
},
"machine_nozzle_gantry_distance": {
"default": 55
},
"machine_extruder_count": {
"default": 1
},
@ -67,20 +52,20 @@
"machine_head_polygon": {
"default": [
[
-10,
10
-1,
1
],
[
10,
10
-1,
-1
],
[
10,
-10
1,
-1
],
[
-10,
-10
1,
1
]
]
},

View file

@ -38,14 +38,30 @@
"machine_height": { "default": 205 },
"machine_heated_bed": { "default": true },
"machine_head_with_fans_polygon":
{
"default": [
[
-40,
30
],
[
-40,
-10
],
[
60,
-10
],
[
60,
30
]
]
},
"machine_center_is_zero": { "default": false },
"machine_nozzle_size": { "default": 0.4 },
"machine_head_shape_min_x": { "default": 40 },
"machine_head_shape_min_y": { "default": 10 },
"machine_head_shape_max_x": { "default": 60 },
"machine_head_shape_max_y": { "default": 30 },
"machine_nozzle_gantry_distance": { "default": 55 },
"gantry_height": { "default": 55 },
"machine_use_extruder_offset_to_offset_coords": { "default": true },
"machine_gcode_flavor": { "default": "UltiGCode" },
"machine_disallowed_areas": { "default": [

View file

@ -41,11 +41,28 @@
"machine_depth": { "default": 205 },
"machine_center_is_zero": { "default": false },
"machine_nozzle_size": { "default": 0.4 },
"machine_head_shape_min_x": { "default": 75 },
"machine_head_shape_min_y": { "default": 18 },
"machine_head_shape_max_x": { "default": 18 },
"machine_head_shape_max_y": { "default": 35 },
"machine_nozzle_gantry_distance": { "default": 55 },
"machine_head_with_fans_polygon":
{
"default": [
[
-75,
35
],
[
-75,
-18
],
[
18,
35
],
[
18,
-18
]
]
},
"gantry_height": { "default": 55 },
"machine_use_extruder_offset_to_offset_coords": { "default": true },
"machine_gcode_flavor": { "default": "RepRap (Marlin/Sprinter)" },

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -35,54 +35,26 @@ QtObject {
}
}
property Component open_file_button: Component {
property Component open_file_button: Component {
ButtonStyle {
background: Item {
implicitWidth: UM.Theme.sizes.button.width;
implicitHeight: UM.Theme.sizes.button.height;
background: Item{
implicitWidth: UM.Theme.sizes.loadfile_button.width
implicitHeight: UM.Theme.sizes.loadfile_button.height
Rectangle {
anchors.bottom: parent.verticalCenter;
width: parent.width;
height: control.hovered ? parent.height / 2 + label.height : 0;
Behavior on height { NumberAnimation { duration: 100; } }
opacity: control.hovered ? 1.0 : 0.0;
Behavior on opacity { NumberAnimation { duration: 100; } }
Label {
id: label;
anchors.horizontalCenter: parent.horizontalCenter;
text: control.text.replace("&", "");
font: UM.Theme.fonts.button_tooltip;
color: UM.Theme.colors.button_tooltip_text;
}
}
UM.AngledCornerRectangle {
anchors.fill: parent;
color: {
if(control.hovered) {
return UM.Theme.colors.button_active_hover;
} else {
return UM.Theme.colors.button_active;
}
}
width: parent.width
height: parent.height
color: control.hovered ? UM.Theme.colors.load_save_button_hover : UM.Theme.colors.load_save_button
Behavior on color { ColorAnimation { duration: 50; } }
cornerSize: UM.Theme.sizes.default_margin.width;
}
Label {
anchors.centerIn: parent
text: control.text
color: UM.Theme.colors.load_save_button_text
font: UM.Theme.fonts.default
}
}
label: Item {
Image {
anchors.centerIn: parent;
source: control.iconSource;
width: UM.Theme.sizes.button_icon.width;
height: UM.Theme.sizes.button_icon.height;
sourceSize: UM.Theme.sizes.button_icon;
}
label: Label{
visible: false
}
}
}
@ -90,7 +62,6 @@ QtObject {
property Component tool_button: Component {
ButtonStyle {
background: Item {
///////////TODO CHANGE SIZES!!
implicitWidth: UM.Theme.sizes.button.width;
implicitHeight: UM.Theme.sizes.button.height;
@ -99,7 +70,6 @@ QtObject {
anchors.top: parent.verticalCenter;
width: parent.width;
///////////TODO CHANGE LABELHEIGHT!!
height: control.hovered ? parent.height / 2 + label.height : 0;
Behavior on height { NumberAnimation { duration: 100; } }
@ -109,7 +79,7 @@ QtObject {
Label {
id: label
anchors.bottom: parent.bottom
text: control.text.replace("&", "");
text: control.text
font: UM.Theme.fonts.button_tooltip;
color: UM.Theme.colors.button_tooltip_text;
}
@ -138,13 +108,14 @@ QtObject {
Behavior on color { ColorAnimation { duration: 50; } }
Label {
id: tool_button_arrow
anchors.right: parent.right;
anchors.rightMargin: UM.Theme.sizes.default_margin.width / 2;
anchors.rightMargin: (UM.Theme.sizes.button.width - UM.Theme.sizes.button_icon.width - tool_button_arrow.width) / 2
anchors.verticalCenter: parent.verticalCenter;
text: "▼";
font: UM.Theme.fonts.small;
visible: control.menu != null;
color: "white";
color: UM.Theme.colors.button_text
}
}
}
@ -162,34 +133,98 @@ QtObject {
}
}
}
property Component tool_button_panel: Component {
ButtonStyle {
background: Item {
implicitWidth: UM.Theme.sizes.button.width;
implicitHeight: UM.Theme.sizes.button.height;
Rectangle {
id: tool_button_background
anchors.top: parent.verticalCenter;
width: parent.width;
height: control.hovered ? parent.height / 2 + label.height : 0;
Behavior on height { NumberAnimation { duration: 100; } }
opacity: control.hovered ? 1.0 : 0.0;
Behavior on opacity { NumberAnimation { duration: 100; } }
Label {
id: label
anchors.bottom: parent.bottom
text: control.text
width: UM.Theme.sizes.button.width;
wrapMode: Text.WordWrap
font: UM.Theme.fonts.button_tooltip;
color: UM.Theme.colors.button_tooltip_text;
}
}
Rectangle {
id: buttonFace;
anchors.fill: parent;
property bool down: control.pressed || (control.checkable && control.checked);
color: {
if(!control.enabled) {
return UM.Theme.colors.button_disabled;
} else if(control.checkable && control.checked && control.hovered) {
return UM.Theme.colors.button_active_hover;
} else if(control.pressed || (control.checkable && control.checked)) {
return UM.Theme.colors.button_active;
} else if(control.hovered) {
return UM.Theme.colors.button_hover;
} else {
return UM.Theme.colors.button;
}
}
Behavior on color { ColorAnimation { duration: 50; } }
}
}
label: Item {
Image {
anchors.centerIn: parent;
source: control.iconSource;
width: UM.Theme.sizes.button_icon.width;
height: UM.Theme.sizes.button_icon.height;
sourceSize: UM.Theme.sizes.button_icon;
}
}
}
}
property Component progressbar: Component{
ProgressBarStyle {
background: UM.AngledCornerRectangle {
cornerSize: UM.Theme.sizes.progressbar_control.height
implicitWidth: UM.Theme.sizes.progressbar.width
background:Rectangle {
implicitWidth: UM.Theme.sizes.message.width - (UM.Theme.sizes.default_margin.width * 2)
implicitHeight: UM.Theme.sizes.progressbar.height
x: UM.Theme.sizes.default_margin.width
color: UM.Theme.colors.progressbar_background
}
progress: UM.AngledCornerRectangle {
cornerSize: UM.Theme.sizes.progressbar_control.height
progress: Rectangle {
color: control.indeterminate ? "transparent" : UM.Theme.colors.progressbar_control
UM.AngledCornerRectangle {
cornerSize: UM.Theme.sizes.progressbar_control.height
Rectangle{
color: UM.Theme.colors.progressbar_control
width: UM.Theme.sizes.progressbar_control.width
height: UM.Theme.sizes.progressbar_control.height
x: UM.Theme.sizes.default_margin.width
visible: control.indeterminate
SequentialAnimation on x {
id: xAnim
property int animEndPoint: UM.Theme.sizes.progressbar.width - UM.Theme.sizes.progressbar_control.width
property int animEndPoint: UM.Theme.sizes.message.width - UM.Theme.sizes.default_margin.width - UM.Theme.sizes.progressbar_control.width
running: control.indeterminate
loops: Animation.Infinite
NumberAnimation { from: 0; to: xAnim.animEndPoint; duration: 2000;}
NumberAnimation { from: xAnim.animEndPoint; to: 0; duration: 2000;}
NumberAnimation { from: UM.Theme.sizes.default_margin.width; to: xAnim.animEndPoint; duration: 2000;}
NumberAnimation { from: xAnim.animEndPoint; to: UM.Theme.sizes.default_margin.width; duration: 2000;}
}
}
}

View file

@ -3,52 +3,52 @@
"large": {
"size": 1.5,
"bold": true,
"family": "Roboto"
"family": "ProximaNova"
},
"default": {
"size": 1,
"family": "Roboto"
"family": "ProximaNova"
},
"default_allcaps": {
"size": 1,
"capitalize": true,
"family": "Roboto"
"family": "ProximaNova"
},
"small": {
"size": 0.75,
"family": "Roboto"
"family": "ProximaNova"
},
"tiny": {
"size": 0.5,
"family": "Roboto"
"family": "ProximaNova"
},
"caption": {
"size": 0.75,
"italic": true,
"family": "Roboto"
"family": "ProximaNova"
},
"sidebar_header": {
"size": 0.75,
"capitalize": true,
"family": "Roboto"
"family": "ProximaNova"
},
"sidebar_save_to": {
"size": 1.0,
"family": "Roboto"
"family": "ProximaNova"
},
"timeslider_time": {
"size": 1.0,
"bold": true,
"family": "Roboto"
"family": "ProximaNova"
},
"button_tooltip": {
"size": 0.75,
"capitalize": true,
"family": "Roboto"
"family": "ProximaNova"
},
"setting_category": {
"size": 1.5,
"family": "Roboto"
"family": "ProximaNova"
}
},
@ -66,15 +66,20 @@
"text_hover": [35, 35, 35, 255],
"text_pressed": [12, 169, 227, 255],
"button": [160, 163, 171, 255],
"button_hover": [140, 144, 154, 255],
"button": [139, 143, 153, 255],
"button_hover": [116, 120, 127, 255],
"button_active": [12, 169, 227, 255],
"button_active_hover": [34, 150, 199, 255],
"button_lining": [140, 144, 154, 255],
"button_active_hover": [77, 184, 226, 255],
"button_lining": [208, 210, 211, 255],
"button_text": [255, 255, 255, 255],
"button_disabled": [245, 245, 245, 255],
"button_tooltip_text": [35, 35, 35, 255],
"load_save_button": [0, 0, 0, 255],
"load_save_button_text": [255, 255, 255, 255],
"load_save_button_hover": [43, 45, 46, 255],
"load_save_button_active": [43, 45, 46, 255],
"scrollbar_background": [245, 245, 245, 255],
"scrollbar_handle": [205, 202, 201, 255],
"scrollbar_handle_hover": [174, 174, 174, 255],
@ -98,7 +103,7 @@
"setting_validation_warning": [255, 186, 15, 255],
"setting_validation_ok": [255, 255, 255, 255],
"progressbar_background": [245, 245, 245, 255],
"progressbar_background": [208, 210, 211, 255],
"progressbar_control": [12, 169, 227, 255],
"slider_groove": [245, 245, 245, 255],
@ -126,8 +131,8 @@
"save_button_printtime_text": [12, 169, 227, 255],
"save_button_background": [249, 249, 249, 255],
"message": [160, 163, 171, 255],
"message_text": [35, 35, 35, 255],
"message_background": [255, 255, 255, 255],
"message_text": [12, 169, 227, 255],
"tool_panel_background": [255, 255, 255, 255]
},
@ -135,11 +140,15 @@
"sizes": {
"window_margin": [2.0, 2.0],
"default_margin": [1.0, 1.0],
"default_lining": [0.1, 0.1],
"panel": [22.0, 10.0],
"logo": [9.5, 2.0],
"toolbar_button": [2.0, 2.0],
"toolbar_spacing": [1.0, 1.0],
"loadfile_button": [11.0, 2.4],
"loadfile_margin": [0.8, 0.4],
"section": [22.0, 3.0],
"section_icon": [2.14, 2.14],
"section_text_margin": [0.33, 0.33],
@ -153,11 +162,11 @@
"standard_list_lineheight": [1.5, 1.5],
"standard_list_input": [20.0, 25.0],
"button": [4.25, 4.25],
"button_icon": [2.9, 2.9],
"button": [3.2, 3.2],
"button_icon": [2.5, 2.5],
"progressbar": [26.0, 0.5],
"progressbar_control": [8.0, 0.5],
"progressbar": [26.0, 0.8],
"progressbar_control": [8.0, 0.8],
"progressbar_padding": [0.0, 1.0],
"scrollbar": [0.5, 0.5],
@ -184,6 +193,7 @@
"wizard_progress": [10.0, 0.0],
"message": [30.0, 5.0],
"message_close": [1.25, 1.25]
"message_close": [1.25, 1.25],
"message_button": [6.0, 1.8]
}
}