diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 1691361629..707a5df2a7 100644 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -34,16 +34,18 @@ PRIME_CLEARANCE = 6.5 ## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas. class BuildVolume(SceneNode): - VolumeOutlineColor = Color(12, 169, 227, 255) - XAxisColor = Color(255, 0, 0, 255) - YAxisColor = Color(0, 0, 255, 255) - ZAxisColor = Color(0, 255, 0, 255) - raftThicknessChanged = Signal() def __init__(self, parent = None): super().__init__(parent) + self._volume_outline_color = None + self._x_axis_color = None + self._y_axis_color = None + self._z_axis_color = None + self._disallowed_area_color = None + self._error_area_color = None + self._width = 0 self._height = 0 self._depth = 0 @@ -75,6 +77,9 @@ class BuildVolume(SceneNode): Application.getInstance().globalContainerStackChanged.connect(self._onStackChanged) self._onStackChanged() + self._engine_ready = False + Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated) + self._has_errors = False Application.getInstance().getController().getScene().sceneChanged.connect(self._onSceneChanged) @@ -99,6 +104,7 @@ class BuildVolume(SceneNode): # but it does not update the disallowed areas after material change Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged) + def _onSceneChanged(self, source): if self._global_container_stack: self._change_timer.start() @@ -158,6 +164,9 @@ class BuildVolume(SceneNode): if not self._shader: self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader")) self._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader")) + theme = Application.getInstance().getTheme() + self._grid_shader.setUniformValue("u_gridColor0", Color(*theme.getColor("buildplate").getRgb())) + self._grid_shader.setUniformValue("u_gridColor1", Color(*theme.getColor("buildplate_alt").getRgb())) renderer.queueNode(self, mode = RenderBatch.RenderMode.Lines) renderer.queueNode(self, mesh = self._origin_mesh) @@ -176,6 +185,18 @@ class BuildVolume(SceneNode): if not self._width or not self._height or not self._depth: return + if not Application.getInstance()._engine: + return + + if not self._volume_outline_color: + theme = Application.getInstance().getTheme() + self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb()) + self._x_axis_color = Color(*theme.getColor("x_axis").getRgb()) + self._y_axis_color = Color(*theme.getColor("y_axis").getRgb()) + self._z_axis_color = Color(*theme.getColor("z_axis").getRgb()) + self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb()) + self._error_area_color = Color(*theme.getColor("error_area").getRgb()) + min_w = -self._width / 2 max_w = self._width / 2 min_h = 0.0 @@ -188,20 +209,20 @@ class BuildVolume(SceneNode): if self._shape != "elliptic": # Outline 'cube' of the build volume mb = MeshBuilder() - mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) + mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self._volume_outline_color) + mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self._volume_outline_color) + mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self._volume_outline_color) + mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self._volume_outline_color) - mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) + mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self._volume_outline_color) + mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self._volume_outline_color) + mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color) + mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color) - mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) - mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) + mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self._volume_outline_color) + mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self._volume_outline_color) + mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self._volume_outline_color) + mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color) self.setMeshData(mb.build()) @@ -228,8 +249,8 @@ class BuildVolume(SceneNode): aspect = self._depth / self._width scale_matrix.compose(scale = Vector(1, 1, aspect)) mb = MeshBuilder() - mb.addArc(max_w, Vector.Unit_Y, center = (0, min_h - z_fight_distance, 0), color = self.VolumeOutlineColor) - mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self.VolumeOutlineColor) + mb.addArc(max_w, Vector.Unit_Y, center = (0, min_h - z_fight_distance, 0), color = self._volume_outline_color) + mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self._volume_outline_color) self.setMeshData(mb.build().getTransformed(scale_matrix)) # Build plate grid mesh @@ -260,21 +281,21 @@ class BuildVolume(SceneNode): height = self._origin_line_width, depth = self._origin_line_width, center = origin + Vector(self._origin_line_length / 2, 0, 0), - color = self.XAxisColor + color = self._x_axis_color ) mb.addCube( width = self._origin_line_width, height = self._origin_line_length, depth = self._origin_line_width, center = origin + Vector(0, self._origin_line_length / 2, 0), - color = self.YAxisColor + color = self._y_axis_color ) mb.addCube( width = self._origin_line_width, height = self._origin_line_width, depth = self._origin_line_length, center = origin - Vector(0, 0, self._origin_line_length / 2), - color = self.ZAxisColor + color = self._z_axis_color ) self._origin_mesh = mb.build() @@ -282,7 +303,7 @@ class BuildVolume(SceneNode): disallowed_area_size = 0 if self._disallowed_areas: mb = MeshBuilder() - color = Color(0.0, 0.0, 0.0, 0.15) + color = self._disallowed_area_color for polygon in self._disallowed_areas: points = polygon.getPoints() if len(points) == 0: @@ -311,7 +332,7 @@ class BuildVolume(SceneNode): if self._error_areas: mb = MeshBuilder() for error_area in self._error_areas: - color = Color(1.0, 0.0, 0.0, 0.5) + color = self._error_area_color points = error_area.getPoints() first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, self._clamp(points[0][1], min_d, max_d)) @@ -398,7 +419,12 @@ class BuildVolume(SceneNode): self._updateDisallowedAreas() self._updateRaftThickness() - self.rebuild() + if self._engine_ready: + self.rebuild() + + def _onEngineCreated(self): + self._engine_ready = True + self.rebuild() def _onSettingPropertyChanged(self, setting_key, property_name): if property_name != "value": diff --git a/cura/ConvexHullNode.py b/cura/ConvexHullNode.py index 8e5acf9518..7282b0ffb2 100644 --- a/cura/ConvexHullNode.py +++ b/cura/ConvexHullNode.py @@ -1,6 +1,7 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. +from UM.Application import Application from UM.Scene.SceneNode import SceneNode from UM.Resources import Resources from UM.Math.Color import Color @@ -23,7 +24,7 @@ class ConvexHullNode(SceneNode): self._original_parent = parent # Color of the drawn convex hull - self._color = Color(0.4, 0.4, 0.4, 1.0) + self._color = None # The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting. self._mesh_height = 0.1 @@ -72,7 +73,7 @@ class ConvexHullNode(SceneNode): return True def _onNodeDecoratorsChanged(self, node): - self._color = Color(35, 35, 35, 0.5) + self._color = Color(*Application.getInstance().getTheme().getColor("convex_hull").getRgb()) convex_hull_head = self._node.callDecoration("getConvexHullHead") if convex_hull_head: diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0e626b82f0..6288c2d211 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -319,6 +319,11 @@ class CuraApplication(QtApplication): showPrintMonitor = pyqtSignal(bool, arguments = ["show"]) + def setViewLegendItems(self, items): + self.viewLegendItemsChanged.emit(items) + + viewLegendItemsChanged = pyqtSignal("QVariantList", arguments = ["items"]) + ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. # # Note that the AutoSave plugin also calls this method. diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index cb00bd0c60..70b17cff75 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -1,4 +1,5 @@ from UM.Math.Color import Color +from UM.Application import Application import numpy @@ -37,7 +38,7 @@ class LayerPolygon: # Buffering the colors shouldn't be necessary as it is not # re-used and can save alot of memory usage. - self._color_map = self.__color_map * [1, 1, 1, self._extruder] # The alpha component is used to store the extruder nr + self._color_map = LayerPolygon.getColorMap() * [1, 1, 1, self._extruder] # The alpha component is used to store the extruder nr self._colors = self._color_map[self._types] # When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType @@ -172,17 +173,25 @@ class LayerPolygon: return normals - # Should be generated in better way, not hardcoded. - __color_map = numpy.array([ - [1.0, 1.0, 1.0, 1.0], # NoneType - [1.0, 0.0, 0.0, 1.0], # Inset0Type - [0.0, 1.0, 0.0, 1.0], # InsetXType - [1.0, 1.0, 0.0, 1.0], # SkinType - [0.0, 1.0, 1.0, 1.0], # SupportType - [0.0, 1.0, 1.0, 1.0], # SkirtType - [1.0, 0.75, 0.0, 1.0], # InfillType - [0.0, 1.0, 1.0, 1.0], # SupportInfillType - [0.0, 0.0, 1.0, 1.0], # MoveCombingType - [0.5, 0.5, 1.0, 1.0], # MoveRetractionType - [0.25, 0.75, 1.0, 1.0] # SupportInterfaceType - ]) \ No newline at end of file + __color_map = None + + ## Gets the instance of the VersionUpgradeManager, or creates one. + @classmethod + def getColorMap(cls): + if cls.__color_map is None: + theme = Application.getInstance().getTheme() + cls.__color_map = numpy.array([ + theme.getColor("layerview_none").getRgbF(), # NoneType + theme.getColor("layerview_inset_0").getRgbF(), # Inset0Type + theme.getColor("layerview_inset_x").getRgbF(), # InsetXType + theme.getColor("layerview_skin").getRgbF(), # SkinType + theme.getColor("layerview_support").getRgbF(), # SupportType + theme.getColor("layerview_skirt").getRgbF(), # SkirtType + theme.getColor("layerview_infill").getRgbF(), # InfillType + theme.getColor("layerview_support_infill").getRgbF(), # SupportInfillType + theme.getColor("layerview_move_combing").getRgbF(), # MoveCombingType + theme.getColor("layerview_move_retraction").getRgbF(), # MoveRetractionType + theme.getColor("layerview_support_interface").getRgbF() # SupportInterfaceType + ]) + + return cls.__color_map diff --git a/plugins/LayerView/LayerView.py b/plugins/LayerView/LayerView.py index 0bae9c891c..df0c92f87e 100644 --- a/plugins/LayerView/LayerView.py +++ b/plugins/LayerView/LayerView.py @@ -60,6 +60,8 @@ class LayerView(View): self._proxy = LayerViewProxy.LayerViewProxy() self._controller.getScene().getRoot().childrenChanged.connect(self._onSceneChanged) + self._legend_items = None + Preferences.getInstance().addPreference("view/top_layer_count", 5) Preferences.getInstance().addPreference("view/only_show_top_layers", False) Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) @@ -110,7 +112,7 @@ class LayerView(View): if not self._ghost_shader: self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) - self._ghost_shader.setUniformValue("u_color", Color(32, 32, 32, 96)) + self._ghost_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_ghost").getRgb())) for node in DepthFirstIterator(scene.getRoot()): # We do not want to render ConvexHullNode as it conflicts with the bottom layers. @@ -194,6 +196,9 @@ class LayerView(View): if not self._layerview_composite_shader: self._layerview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layerview_composite.shader")) + theme = Application.getInstance().getTheme() + self._layerview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) + self._layerview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") @@ -203,6 +208,8 @@ class LayerView(View): self._old_composite_shader = self._composite_pass.getCompositeShader() self._composite_pass.setCompositeShader(self._layerview_composite_shader) + Application.getInstance().setViewLegendItems(self._getLegendItems()) + elif event.type == Event.ViewDeactivateEvent: self._wireprint_warning_message.hide() Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged) @@ -212,6 +219,8 @@ class LayerView(View): self._composite_pass.setLayerBindings(self._old_layer_bindings) self._composite_pass.setCompositeShader(self._old_composite_shader) + Application.getInstance().setViewLegendItems([]) + def _onGlobalStackChanged(self): if self._global_container_stack: self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) @@ -261,6 +270,24 @@ class LayerView(View): self._startUpdateTopLayers() + def _getLegendItems(self): + if self._legend_items is None: + theme = Application.getInstance().getTheme() + self._legend_items = [ + {"color": theme.getColor("layerview_inset_0").name(), "title": catalog.i18nc("@label:layerview polygon type", "Outer Wall")}, # Inset0Type + {"color": theme.getColor("layerview_inset_x").name(), "title": catalog.i18nc("@label:layerview polygon type", "Inner Wall")}, # InsetXType + {"color": theme.getColor("layerview_skin").name(), "title": catalog.i18nc("@label:layerview polygon type", "Top / Bottom")}, # SkinType + {"color": theme.getColor("layerview_infill").name(), "title": catalog.i18nc("@label:layerview polygon type", "Infill")}, # InfillType + {"color": theme.getColor("layerview_support").name(), "title": catalog.i18nc("@label:layerview polygon type", "Support Skin")}, # SupportType + {"color": theme.getColor("layerview_support_infill").name(), "title": catalog.i18nc("@label:layerview polygon type", "Support Infill")}, # SupportInfillType + {"color": theme.getColor("layerview_support_interface").name(), "title": catalog.i18nc("@label:layerview polygon type", "Support Interface")}, # SupportInterfaceType + {"color": theme.getColor("layerview_skirt").name(), "title": catalog.i18nc("@label:layerview polygon type", "Build Plate Adhesion")}, # SkirtType + {"color": theme.getColor("layerview_move_combing").name(), "title": catalog.i18nc("@label:layerview polygon type", "Travel Move")}, # MoveCombingType + {"color": theme.getColor("layerview_move_retraction").name(), "title": catalog.i18nc("@label:layerview polygon type", "Retraction Move")}, # MoveRetractionType + #{"color": theme.getColor("layerview_none").name(), "title": catalog.i18nc("@label:layerview polygon type", "Unknown")} # NoneType + ] + return self._legend_items + class _CreateTopLayersJob(Job): def __init__(self, scene, layer_number, solid_layers): diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 8277813c92..893c4ed180 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -38,8 +38,9 @@ class SolidView(View): if not self._disabled_shader: self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader")) - self._disabled_shader.setUniformValue("u_diffuseColor1", [0.48, 0.48, 0.48, 1.0]) - self._disabled_shader.setUniformValue("u_diffuseColor2", [0.68, 0.68, 0.68, 1.0]) + theme = Application.getInstance().getTheme() + self._disabled_shader.setUniformValue("u_diffuseColor1", theme.getColor("model_unslicable").getRgbF()) + self._disabled_shader.setUniformValue("u_diffuseColor2", theme.getColor("model_unslicable_alt").getRgbF()) self._disabled_shader.setUniformValue("u_width", 50.0) multi_extrusion = False diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index 9913ee786f..931ecb1975 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -3,6 +3,8 @@ import os.path +from UM.Application import Application +from UM.Math.Color import Color from UM.PluginRegistry import PluginRegistry from UM.Event import Event from UM.View.View import View @@ -31,7 +33,7 @@ class XRayView(View): if not self._xray_shader: self._xray_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader")) - self._xray_shader.setUniformValue("u_color", [0.1, 0.1, 0.2, 1.0]) + self._xray_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("xray").getRgb())) for node in BreadthFirstIterator(scene.getRoot()): if not node.render(renderer): @@ -58,6 +60,10 @@ class XRayView(View): if not self._xray_composite_shader: self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader")) + theme = Application.getInstance().getTheme() + self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) + self._xray_composite_shader.setUniformValue("u_error_color", Color(*theme.getColor("xray_error").getRgb())) + self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader index f6e67c1d0f..e7a38950bf 100644 --- a/plugins/XRayView/xray_composite.shader +++ b/plugins/XRayView/xray_composite.shader @@ -22,6 +22,7 @@ fragment = uniform float u_outline_strength; uniform vec4 u_outline_color; uniform vec4 u_error_color; + uniform vec4 u_background_color; const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0); @@ -37,7 +38,7 @@ fragment = kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; - vec4 result = vec4(0.965, 0.965, 0.965, 1.0); + vec4 result = u_background_color; vec4 layer0 = texture2D(u_layer0, v_uvs); result = layer0 * layer0.a + result * (1.0 - layer0.a); @@ -70,6 +71,7 @@ fragment = u_layer0 = 0 u_layer1 = 1 u_layer2 = 2 +u_background_color = [0.965, 0.965, 0.965, 1.0] u_outline_strength = 1.0 u_outline_color = [0.05, 0.66, 0.89, 1.0] u_error_color = [1.0, 0.0, 0.0, 1.0] diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 1383338144..264bec6d9a 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -306,6 +306,18 @@ UM.MainWindow } } + Legend + { + id: legend + anchors + { + top: parent.top + topMargin: UM.Theme.getSize("default_margin").height + right: sidebar.left + rightMargin: UM.Theme.getSize("default_margin").width + } + } + JobSpecs { id: jobSpecs diff --git a/resources/qml/Legend.qml b/resources/qml/Legend.qml new file mode 100644 index 0000000000..353747ef67 --- /dev/null +++ b/resources/qml/Legend.qml @@ -0,0 +1,66 @@ +// Copyright (c) 2015 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. + +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Layouts 1.1 + +import UM 1.1 as UM +import Cura 1.0 as Cura + +Rectangle { + id: base + + UM.I18nCatalog { id: catalog; name:"cura"} + + width: childrenRect.width + height: childrenRect.height + color: "transparent" + + Connections + { + target: Printer + onViewLegendItemsChanged: + { + legendItemRepeater.model = items + } + } + + Column + { + Repeater + { + id: legendItemRepeater + + Item { + anchors.right: parent.right + height: childrenRect.height + width: childrenRect.width + + Rectangle { + id: swatch + + anchors.right: parent.right + anchors.verticalCenter: label.verticalCenter + height: UM.Theme.getSize("setting_control").height / 2 + width: height + + color: modelData.color + border.width: UM.Theme.getSize("default_lining").width + border.color: UM.Theme.getColor("text_subtext") + } + Label { + id: label + + text: modelData.title + font: UM.Theme.getFont("small") + color: UM.Theme.getColor("text_subtext") + + anchors.right: swatch.left + anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2 + } + } + } + } +} diff --git a/resources/themes/cura/theme.json b/resources/themes/cura/theme.json index d5a95a7104..31caeeabd4 100644 --- a/resources/themes/cura/theme.json +++ b/resources/themes/cura/theme.json @@ -192,7 +192,44 @@ "status_ready": [0, 205, 0, 255], "status_busy": [12, 169, 227, 255], "status_paused": [255, 140, 0, 255], - "status_stopped": [236, 82, 80, 255] + "status_stopped": [236, 82, 80, 255], + + "disabled_axis": [127, 127, 127, 255], + "x_axis": [255, 0, 0, 255], + "y_axis": [0, 0, 255, 255], + "z_axis": [0, 255, 0, 255], + "all_axis": [255, 255, 255, 255], + + "viewport_background": [245, 245, 245, 255], + "volume_outline": [12, 169, 227, 255], + "buildplate": [244, 244, 244, 255], + "buildplate_alt": [204, 204, 204, 255], + + "convex_hull": [35, 35, 35, 127], + "disallowed_area": [0, 0, 0, 40], + "error_area": [255, 0, 0, 127], + + "model_default": [255, 201, 36, 255], + "model_overhang": [255, 0, 0, 255], + "model_unslicable": [122, 122, 122, 255], + "model_unslicable_alt": [172, 172, 127, 255], + "model_selection_outline": [12, 169, 227, 255], + + "xray": [26, 26, 62, 255], + "xray_error": [255, 0, 0, 255], + + "layerview_ghost": [32, 32, 32, 96], + "layerview_none": [255, 255, 255, 255], + "layerview_inset_0": [255, 0, 0, 255], + "layerview_inset_x": [0, 255, 0, 255], + "layerview_skin": [255, 255, 0, 255], + "layerview_support": [0, 255, 255, 255], + "layerview_skirt": [0, 255, 255, 255], + "layerview_infill": [255, 192, 0, 255], + "layerview_support_infill": [0, 255, 255, 255], + "layerview_move_combing": [0, 0, 255, 255], + "layerview_move_retraction": [128, 128, 255, 255], + "layerview_support_interface": [64, 192, 255, 255] }, "sizes": {