diff --git a/cura/Arranging/ShapeArray.py b/cura/Arranging/ShapeArray.py index 9232c9f22f..68be9a6478 100644 --- a/cura/Arranging/ShapeArray.py +++ b/cura/Arranging/ShapeArray.py @@ -29,8 +29,12 @@ class ShapeArray: offset_x = int(numpy.amin(flip_vertices[:, 1])) flip_vertices[:, 0] = numpy.add(flip_vertices[:, 0], -offset_y) flip_vertices[:, 1] = numpy.add(flip_vertices[:, 1], -offset_x) - shape = [int(numpy.amax(flip_vertices[:, 0])), int(numpy.amax(flip_vertices[:, 1]))] + shape = numpy.array([int(numpy.amax(flip_vertices[:, 0])), int(numpy.amax(flip_vertices[:, 1]))]) + shape[numpy.where(shape == 0)] = 1 arr = cls.arrayFromPolygon(shape, flip_vertices) + if not numpy.ndarray.any(arr): + # set at least 1 pixel + arr[0][0] = 1 return cls(arr, offset_x, offset_y) ## Instantiate an offset and hull ShapeArray from a scene node. diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 32e3867300..351843ae14 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -270,7 +270,7 @@ class ExtruderManager(QObject): return [] # Get the extruders of all printable meshes in the scene - meshes = [node for node in DepthFirstIterator(scene_root) if type(node) is SceneNode and node.isSelectable()] + meshes = [node for node in DepthFirstIterator(scene_root) if isinstance(node, SceneNode) and node.isSelectable()] for mesh in meshes: extruder_stack_id = mesh.callDecoration("getActiveExtruder") if not extruder_stack_id: diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 74dd515951..4491008997 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -204,17 +204,19 @@ class CuraEngineBackend(QObject, Backend): if self._process_layers_job: Logger.log("d", " ## Process layers job still busy, trying later") - self._invokeSlice() return + if not hasattr(self._scene, "gcode_list"): + self._scene.gcode_list = {} + # see if we really have to slice active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate build_plate_to_be_sliced = self._build_plates_to_be_sliced.pop(0) Logger.log("d", "Going to slice build plate [%s]!" % build_plate_to_be_sliced) num_objects = self._numObjects() if build_plate_to_be_sliced not in num_objects or num_objects[build_plate_to_be_sliced] == 0: + self._scene.gcode_list[build_plate_to_be_sliced] = [] Logger.log("d", "Build plate %s has 0 objects to be sliced, skipping", build_plate_to_be_sliced) - self._invokeSlice() return self._stored_layer_data = [] @@ -231,8 +233,6 @@ class CuraEngineBackend(QObject, Backend): self.processingProgress.emit(0.0) self.backendStateChange.emit(BackendState.NotStarted) - if not hasattr(self._scene, "gcode_list"): - self._scene.gcode_list = {} self._scene.gcode_list[build_plate_to_be_sliced] = [] #[] indexed by build plate number self._slicing = True self.slicingStarted.emit() diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index ea126bfd44..5bdb6d4cb0 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -111,7 +111,7 @@ Item { ScrollView { height: parent.height - width: UM.Theme.getSize("setting").width + width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width style: UM.Theme.styles.scrollview ListView diff --git a/plugins/SimulationView/layers3d_shadow.shader b/plugins/SimulationView/layers3d_shadow.shader index ad75fcf9d0..15136fcf3f 100644 --- a/plugins/SimulationView/layers3d_shadow.shader +++ b/plugins/SimulationView/layers3d_shadow.shader @@ -145,35 +145,42 @@ geometry41core = myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert)); myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz_head + g_vertex_offset_vert)); + //And reverse so that the line is also visible from the back side. + myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); + myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz + g_vertex_offset_vert)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head + g_vertex_offset_vert)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz + g_vertex_offset_vert)); EndPrimitive(); } else { // All normal lines are rendered as 3d tubes. - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert)); myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz)); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert)); - myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert)); + myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_vert)); myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); myEmitVertex(v_vertex[1], v_color[1], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position + g_vertex_offset_horz)); + myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert)); + myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_vert)); + myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); + myEmitVertex(v_vertex[1], v_color[1], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[1].gl_Position - g_vertex_offset_horz)); EndPrimitive(); // left side - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); + myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_vert)); myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head)); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); EndPrimitive(); - myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); + myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_vert, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_vert)); myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz_head, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz_head)); - myEmitVertex(v_vertex[0], v_color[0], g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position + g_vertex_offset_horz)); + myEmitVertex(v_vertex[0], v_color[0], -g_vertex_normal_horz, u_viewProjectionMatrix * (gl_in[0].gl_Position - g_vertex_offset_horz)); EndPrimitive(); diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 17f8b6826f..6eef6b1e9b 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1853,6 +1853,14 @@ "settable_per_mesh": true } } + }, + "infill_enable_travel_optimization": + { + "label": "Enable Travel Optimization", + "description": "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased.", + "type": "bool", + "default_value": false, + "settable_per_mesh": true } } }, @@ -3475,13 +3483,22 @@ "settable_per_mesh": true, "settable_per_extruder": false }, + "support_tree_enable": + { + "label": "Tree Support", + "description": "Generate a tree-like support with branches that support your print. This may reduce material usage and print time.", + "type": "bool", + "default_value": false, + "settable_per_mesh": true, + "settable_per_extruder": false + }, "support_extruder_nr": { "label": "Support Extruder", "description": "The extruder train to use for printing the support. This is used in multi-extrusion.", "type": "extruder", "default_value": "0", - "enabled": "support_enable and machine_extruder_count > 1", + "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false, "children": { @@ -3492,7 +3509,7 @@ "type": "extruder", "default_value": "0", "value": "support_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1", + "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3503,7 +3520,7 @@ "type": "extruder", "default_value": "0", "value": "support_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1", + "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3514,7 +3531,7 @@ "type": "extruder", "default_value": "0", "value": "support_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1", + "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false, "children": @@ -3526,7 +3543,7 @@ "type": "extruder", "default_value": "0", "value": "support_interface_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1", + "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3537,7 +3554,7 @@ "type": "extruder", "default_value": "0", "value": "support_interface_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1", + "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false } @@ -3557,7 +3574,7 @@ }, "default_value": "everywhere", "resolve": "'everywhere' if 'everywhere' in extruderValues('support_type') else 'buildplate'", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3572,7 +3589,7 @@ "maximum_value_warning": "80", "default_value": 50, "limit_to_extruder": "support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": true }, "support_pattern": @@ -3591,7 +3608,7 @@ "cross": "Cross" }, "default_value": "zigzag", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true @@ -3602,7 +3619,7 @@ "description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.", "type": "bool", "default_value": true, - "enabled": "support_enable and (support_pattern == 'zigzag')", + "enabled": "(support_enable or support_tree_enable) and support_pattern == 'zigzag'", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true @@ -3616,7 +3633,8 @@ "minimum_value": "0", "maximum_value_warning": "100", "default_value": 15, - "enabled": "support_enable", + "value": "15 if support_enable else 0", + "enabled": "support_enable or support_tree_enable", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true, @@ -3631,7 +3649,7 @@ "minimum_value": "0", "minimum_value_warning": "support_line_width", "default_value": 2.66, - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "value": "0 if support_infill_rate == 0 else (support_line_width * 100) / support_infill_rate * (2 if support_pattern == 'grid' else (3 if support_pattern == 'triangles' else 1))", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, @@ -3649,7 +3667,7 @@ "maximum_value_warning": "machine_nozzle_size", "default_value": 0.1, "limit_to_extruder": "support_interface_extruder_nr if support_interface_enable else support_infill_extruder_nr", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": true, "children": { @@ -3662,7 +3680,7 @@ "maximum_value_warning": "machine_nozzle_size", "default_value": 0.1, "type": "float", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "value": "extruderValue(support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr, 'support_z_distance')", "limit_to_extruder": "support_roof_extruder_nr if support_roof_enable else support_infill_extruder_nr", "settable_per_mesh": true @@ -3678,7 +3696,7 @@ "value": "extruderValue(support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr, 'support_z_distance') if support_type == 'everywhere' else 0", "limit_to_extruder": "support_bottom_extruder_nr if support_bottom_enable else support_infill_extruder_nr", "type": "float", - "enabled": "support_enable and resolveOrValue('support_type') == 'everywhere'", + "enabled": "(support_enable or support_tree_enable) and resolveOrValue('support_type') == 'everywhere'", "settable_per_mesh": true } } @@ -3693,7 +3711,7 @@ "maximum_value_warning": "1.5 * machine_nozzle_tip_outer_diameter", "default_value": 0.7, "limit_to_extruder": "support_infill_extruder_nr", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": true }, "support_xy_overrides_z": @@ -3788,10 +3806,114 @@ "maximum_value_warning": "0.75 * machine_nozzle_size", "maximum_value": "resolveOrValue('layer_height') * 8", "value": "resolveOrValue('layer_height')", - "enabled": "support_enable and support_infill_rate > 0", + "enabled": "(support_enable or support_tree_enable) and support_infill_rate > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, + "support_tree_angle": + { + "label": "Tree Support Branch Angle", + "description": "The angle of the branches. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "maximum_value": "90", + "maximum_value_warning": "60", + "default_value": 40, + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable", + "settable_per_mesh": false, + "settable_per_extruder": true + }, + "support_tree_branch_distance": + { + "label": "Tree Support Branch Distance", + "description": "How far apart the branches need to be when they touch the model. Making this distance small will cause the tree support to touch the model at more points, causing better overhang but making support harder to remove.", + "unit": "mm", + "type": "float", + "minimum_value": "0.001", + "default_value": 4, + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable", + "settable_per_mesh": true + }, + "support_tree_branch_diameter": + { + "label": "Tree Support Branch Diameter", + "description": "The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this.", + "unit": "mm", + "type": "float", + "minimum_value": "0.001", + "minimum_value_warning": "support_line_width * 2", + "default_value": 2, + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable", + "settable_per_mesh": false, + "settable_per_extruder": true + }, + "support_tree_branch_diameter_angle": + { + "label": "Tree Support Branch Diameter Angle", + "description": "The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length. A bit of an angle can increase stability of the tree support.", + "unit": "°", + "type": "float", + "minimum_value": "0", + "maximum_value": "89.9999", + "maximum_value_warning": "15", + "default_value": 5, + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable", + "settable_per_mesh": false, + "settable_per_extruder": true + }, + "support_tree_collision_resolution": + { + "label": "Tree Support Collision Resolution", + "description": "Resolution to compute collisions with to avoid hitting the model. Setting this lower will produce more accurate trees that fail less often, but increases slicing time dramatically.", + "unit": "mm", + "type": "float", + "minimum_value": "0.001", + "minimum_value_warning": "support_line_width / 4", + "maximum_value_warning": "support_line_width * 2", + "default_value": 0.4, + "value": "support_line_width / 2", + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable and support_tree_branch_diameter_angle > 0", + "settable_per_mesh": false, + "settable_per_extruder": true + }, + "support_tree_wall_thickness": + { + "label": "Tree Support Wall Thickness", + "description": "The thickness of the walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily.", + "unit": "mm", + "type": "float", + "minimum_value": "0", + "minimum_value_warning": "wall_line_width", + "default_value": 0.8, + "value": "support_line_width", + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable", + "settable_per_mesh": false, + "settable_per_extruder": true, + "children": + { + "support_tree_wall_count": + { + "label": "Tree Support Wall Line Count", + "description": "The number of walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily.", + "type": "int", + "minimum_value": "0", + "minimum_value_warning": "1", + "default_value": 1, + "value": "round(support_tree_wall_thickness / support_line_width)", + "limit_to_extruder": "support_infill_extruder_nr", + "enabled": "support_tree_enable", + "settable_per_mesh": false, + "settable_per_extruder": true + } + } + }, "gradual_support_infill_steps": { "label": "Gradual Support Infill Steps", @@ -3801,7 +3923,7 @@ "minimum_value": "0", "maximum_value_warning": "1 if (support_pattern == 'cross' or support_pattern == 'lines' or support_pattern == 'zigzag' or support_pattern == 'concentric' or support_pattern == 'concentric_3d') else 5", "maximum_value": "999999 if support_line_distance == 0 else (20 - math.log(support_line_distance) / math.log(2))", - "enabled": "support_enable and support_infill_rate > 0", + "enabled": "(support_enable or support_tree_enable) and support_infill_rate > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, @@ -3814,7 +3936,7 @@ "default_value": 1, "minimum_value": "0.0001", "minimum_value_warning": "3 * resolveOrValue('layer_height')", - "enabled": "support_enable and support_infill_rate > 0 and gradual_support_infill_steps > 0", + "enabled": "(support_enable or support_tree_enable) and support_infill_rate > 0 and gradual_support_infill_steps > 0", "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false }, @@ -3825,7 +3947,7 @@ "type": "bool", "default_value": false, "limit_to_extruder": "support_interface_extruder_nr", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": true, "children": { @@ -3837,7 +3959,7 @@ "default_value": false, "value": "extruderValue(support_roof_extruder_nr, 'support_interface_enable')", "limit_to_extruder": "support_roof_extruder_nr", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": true }, "support_bottom_enable": @@ -3848,7 +3970,7 @@ "default_value": false, "value": "extruderValue(support_bottom_extruder_nr, 'support_interface_enable')", "limit_to_extruder": "support_bottom_extruder_nr", - "enabled": "support_enable", + "enabled": "support_enable or support_tree_enable", "settable_per_mesh": true } } @@ -3864,7 +3986,7 @@ "minimum_value_warning": "0.2 + layer_height", "maximum_value_warning": "10", "limit_to_extruder": "support_interface_extruder_nr", - "enabled": "support_interface_enable and support_enable", + "enabled": "support_interface_enable and (support_enable or support_tree_enable)", "settable_per_mesh": true, "children": { @@ -3880,7 +4002,7 @@ "maximum_value_warning": "10", "value": "extruderValue(support_roof_extruder_nr, 'support_interface_height')", "limit_to_extruder": "support_roof_extruder_nr", - "enabled": "support_roof_enable and support_enable", + "enabled": "support_roof_enable and (support_enable or support_tree_enable)", "settable_per_mesh": true }, "support_bottom_height": @@ -3895,7 +4017,7 @@ "minimum_value_warning": "min(0.2 + layer_height, support_bottom_stair_step_height)", "maximum_value_warning": "10", "limit_to_extruder": "support_bottom_extruder_nr", - "enabled": "support_bottom_enable and support_enable", + "enabled": "support_bottom_enable and (support_enable or support_tree_enable)", "settable_per_mesh": true } } @@ -3922,7 +4044,7 @@ "minimum_value": "0", "maximum_value_warning": "100", "limit_to_extruder": "support_interface_extruder_nr", - "enabled": "support_interface_enable and support_enable", + "enabled": "support_interface_enable and (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": true, "children": @@ -3937,7 +4059,7 @@ "minimum_value": "0", "maximum_value": "100", "limit_to_extruder": "support_roof_extruder_nr", - "enabled": "support_roof_enable and support_enable", + "enabled": "support_roof_enable and (support_enable or support_tree_enable)", "value": "extruderValue(support_roof_extruder_nr, 'support_interface_density')", "settable_per_mesh": false, "settable_per_extruder": true, @@ -3954,7 +4076,7 @@ "minimum_value_warning": "support_roof_line_width - 0.0001", "value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == 'grid' else (3 if support_roof_pattern == 'triangles' else 1))", "limit_to_extruder": "support_roof_extruder_nr", - "enabled": "support_roof_enable and support_enable", + "enabled": "support_roof_enable and (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": true } @@ -3970,7 +4092,7 @@ "minimum_value": "0", "maximum_value": "100", "limit_to_extruder": "support_bottom_extruder_nr", - "enabled": "support_bottom_enable and support_enable", + "enabled": "support_bottom_enable and (support_enable or support_tree_enable)", "value": "extruderValue(support_bottom_extruder_nr, 'support_interface_density')", "settable_per_mesh": false, "settable_per_extruder": true, @@ -3987,7 +4109,7 @@ "minimum_value_warning": "support_bottom_line_width - 0.0001", "value": "0 if support_bottom_density == 0 else (support_bottom_line_width * 100) / support_bottom_density * (2 if support_bottom_pattern == 'grid' else (3 if support_bottom_pattern == 'triangles' else 1))", "limit_to_extruder": "support_bottom_extruder_nr", - "enabled": "support_bottom_enable and support_enable", + "enabled": "support_bottom_enable and (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": true } @@ -4011,7 +4133,7 @@ }, "default_value": "concentric", "limit_to_extruder": "support_interface_extruder_nr", - "enabled": "support_interface_enable and support_enable", + "enabled": "support_interface_enable and (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": true, "children": @@ -4033,7 +4155,7 @@ "default_value": "concentric", "value": "extruderValue(support_roof_extruder_nr, 'support_interface_pattern')", "limit_to_extruder": "support_roof_extruder_nr", - "enabled": "support_roof_enable and support_enable", + "enabled": "support_roof_enable and (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": true }, @@ -4054,7 +4176,7 @@ "default_value": "concentric", "value": "extruderValue(support_bottom_extruder_nr, 'support_interface_pattern')", "limit_to_extruder": "support_bottom_extruder_nr", - "enabled": "support_bottom_enable and support_enable", + "enabled": "support_bottom_enable and (support_enable or support_tree_enable)", "settable_per_mesh": false, "settable_per_extruder": true } diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml index 72bc42bfb0..afc80dd314 100644 --- a/resources/qml/Menus/ViewMenu.qml +++ b/resources/qml/Menus/ViewMenu.qml @@ -50,6 +50,7 @@ Menu { id: buildPlateMenu; title: catalog.i18nc("@action:inmenu menubar:view","&Build plate"); + visible: UM.Preferences.getValue("cura/use_multi_build_plate") Instantiator { model: Cura.BuildPlateModel diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml index 04afbe2fb0..a02ea2288d 100644 --- a/resources/qml/ObjectsList.qml +++ b/resources/qml/ObjectsList.qml @@ -231,7 +231,6 @@ Rectangle tooltip: ''; anchors { - //top: buildPlateSelection.bottom; topMargin: UM.Theme.getSize("default_margin").height; left: parent.left; leftMargin: UM.Theme.getSize("default_margin").height; diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml index 3ccf668699..cc7ca9354d 100644 --- a/resources/qml/Settings/SettingCategory.qml +++ b/resources/qml/Settings/SettingCategory.qml @@ -1,18 +1,58 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import UM 1.1 as UM import Cura 1.0 as Cura -Button { - id: base; - - style: UM.Theme.styles.sidebar_category; +Button +{ + id: base + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width + anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + background: Rectangle + { + implicitHeight: UM.Theme.getSize("section").height + color: { + if (base.color) { + return base.color; + } else if (!base.enabled) { + return UM.Theme.getColor("setting_category_disabled"); + } else if (base.hovered && base.checkable && base.checked) { + return UM.Theme.getColor("setting_category_active_hover"); + } else if (base.pressed || (base.checkable && base.checked)) { + return UM.Theme.getColor("setting_category_active"); + } else if (base.hovered) { + return UM.Theme.getColor("setting_category_hover"); + } else { + return UM.Theme.getColor("setting_category"); + } + } + Behavior on color { ColorAnimation { duration: 50; } } + Rectangle + { + height: UM.Theme.getSize("default_lining").height + width: parent.width + anchors.bottom: parent.bottom + color: { + if (!base.enabled) { + return UM.Theme.getColor("setting_category_disabled_border"); + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { + return UM.Theme.getColor("setting_category_active_hover_border"); + } else if (base.pressed || (base.checkable && base.checked)) { + return UM.Theme.getColor("setting_category_active_border"); + } else if (base.hovered || base.activeFocus) { + return UM.Theme.getColor("setting_category_hover_border"); + } else { + return UM.Theme.getColor("setting_category_border"); + } + } + } + } signal showTooltip(string text) signal hideTooltip() @@ -23,20 +63,102 @@ Button { property var focusItem: base - text: definition.label - iconSource: UM.Theme.getIcon(definition.icon) + //text: definition.label + + contentItem: Item { + anchors.fill: parent + anchors.left: parent.left + + Label { + anchors + { + left: parent.left + leftMargin: 2 * UM.Theme.getSize("default_margin").width + UM.Theme.getSize("section_icon").width + right: parent.right; + verticalCenter: parent.verticalCenter; + } + text: definition.label + font: UM.Theme.getFont("setting_category") + color: + { + if (!base.enabled) { + return UM.Theme.getColor("setting_category_disabled_text"); + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { + return UM.Theme.getColor("setting_category_active_hover_text"); + } else if (base.pressed || (base.checkable && base.checked)) { + return UM.Theme.getColor("setting_category_active_text"); + } else if (base.hovered || base.activeFocus) { + return UM.Theme.getColor("setting_category_hover_text"); + } else { + return UM.Theme.getColor("setting_category_text"); + } + } + fontSizeMode: Text.HorizontalFit + minimumPointSize: 8 + } + UM.RecolorImage + { + id: category_arrow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: UM.Theme.getSize("default_margin").width + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + sourceSize.height: width + color: + { + if (!base.enabled) { + return UM.Theme.getColor("setting_category_disabled_text"); + } else if ((base.hovered || base.activeFocus) && base.checkable && base.checked) { + return UM.Theme.getColor("setting_category_active_hover_text"); + } else if (base.pressed || (base.checkable && base.checked)) { + return UM.Theme.getColor("setting_category_active_text"); + } else if (base.hovered || base.activeFocus) { + return UM.Theme.getColor("setting_category_hover_text"); + } else { + return UM.Theme.getColor("setting_category_text"); + } + } + source: base.checked ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_left") + } + } + + UM.RecolorImage + { + id: icon + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("default_margin").width + color: + { + if (!base.enabled) { + return UM.Theme.getColor("setting_category_disabled_text"); + } else if((base.hovered || base.activeFocus) && base.checkable && base.checked) { + return UM.Theme.getColor("setting_category_active_hover_text"); + } else if(base.pressed || (base.checkable && base.checked)) { + return UM.Theme.getColor("setting_category_active_text"); + } else if(base.hovered || base.activeFocus) { + return UM.Theme.getColor("setting_category_hover_text"); + } else { + return UM.Theme.getColor("setting_category_text"); + } + } + source: UM.Theme.getIcon(definition.icon) + width: UM.Theme.getSize("section_icon").width; + height: UM.Theme.getSize("section_icon").height; + sourceSize.width: width + 15 * screenScaleFactor + sourceSize.height: width + 15 * screenScaleFactor + } checkable: true checked: definition.expanded onClicked: { - if(definition.expanded) - { + if (definition.expanded) { settingDefinitionsModel.collapse(definition.key); - } - else - { + } else { settingDefinitionsModel.expandAll(definition.key); } //Set focus so that tab navigation continues from this point on. @@ -70,13 +192,14 @@ Button { anchors { right: inheritButton.visible ? inheritButton.left : parent.right - rightMargin: inheritButton.visible? UM.Theme.getSize("default_margin").width / 2 : UM.Theme.getSize("setting_preferences_button_margin").width - verticalCenter: parent.verticalCenter; + // use 1.9 as the factor because there is a 0.1 difference between the settings and inheritance warning icons + rightMargin: inheritButton.visible ? UM.Theme.getSize("default_margin").width / 2 : category_arrow.width + UM.Theme.getSize("default_margin").width * 1.9 + verticalCenter: parent.verticalCenter } - color: UM.Theme.getColor("setting_control_button"); + color: UM.Theme.getColor("setting_control_button") hoverColor: UM.Theme.getColor("setting_control_button_hover") - iconSource: UM.Theme.getIcon("settings"); + iconSource: UM.Theme.getIcon("settings") onClicked: { Cura.Actions.configureSettingVisibility.trigger(definition) @@ -85,20 +208,20 @@ Button { UM.SimpleButton { - id: inheritButton; + id: inheritButton anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width + anchors.rightMargin: category_arrow.width + UM.Theme.getSize("default_margin").width * 2 visible: { - if(Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0) + if (Cura.SettingInheritanceManager.settingsWithInheritanceWarning.indexOf(definition.key) >= 0) { var children_with_override = Cura.SettingInheritanceManager.getChildrenKeysWithOverride(definition.key) - for(var i = 0; i < children_with_override.length; i++) + for (var i = 0; i < children_with_override.length; i++) { - if(!settingDefinitionsModel.getVisible(children_with_override[i])) + if (!settingDefinitionsModel.getVisible(children_with_override[i])) { return true } diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 9029249249..2aad6181d8 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -1,10 +1,9 @@ // Copyright (c) 2015 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 +import QtQuick 2.8 import QtQuick.Layouts 1.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls 2.1 import UM 1.2 as UM diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index f2ec5fda65..63d13ae514 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -1,9 +1,8 @@ // Copyright (c) 2015 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import UM 1.1 as UM @@ -17,95 +16,103 @@ SettingItem id: control model: definition.options - textRole: "value"; + textRole: "value" anchors.fill: parent MouseArea { - anchors.fill: parent; - acceptedButtons: Qt.NoButton; - onWheel: wheel.accepted = true; + anchors.fill: parent + acceptedButtons: Qt.NoButton + onWheel: wheel.accepted = true } - style: ComboBoxStyle + background: Rectangle { - background: Rectangle + color: { - color: - { - if(!enabled) - { - return UM.Theme.getColor("setting_control_disabled") - } - if(control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_highlight") - } - return UM.Theme.getColor("setting_control") + if (!enabled) { + return UM.Theme.getColor("setting_control_disabled") } - border.width: UM.Theme.getSize("default_lining").width - border.color: - { - if(!enabled) - { - return UM.Theme.getColor("setting_control_disabled_border") - } - if(control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_border_highlight") - } - return UM.Theme.getColor("setting_control_border") + + if (control.hovered || control.activeFocus) { + return UM.Theme.getColor("setting_control_highlight") } + + return UM.Theme.getColor("setting_control") } - label: Item + + border.width: UM.Theme.getSize("default_lining").width + border.color: { - Label - { - anchors.left: parent.left; - anchors.leftMargin: UM.Theme.getSize("default_lining").width - anchors.right: downArrow.left; - anchors.rightMargin: UM.Theme.getSize("default_lining").width; - anchors.verticalCenter: parent.verticalCenter; - - text: control.currentText; - font: UM.Theme.getFont("default"); - color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text"); - - elide: Text.ElideRight; - verticalAlignment: Text.AlignVCenter; + if (!enabled) { + return UM.Theme.getColor("setting_control_disabled_border") } - UM.RecolorImage - { - id: downArrow - anchors.right: parent.right; - anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2; - anchors.verticalCenter: parent.verticalCenter; - - source: UM.Theme.getIcon("arrow_bottom") - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor - - color: UM.Theme.getColor("setting_control_text"); - + if (control.hovered || control.activeFocus) { + return UM.Theme.getColor("setting_control_border_highlight") } + + return UM.Theme.getColor("setting_control_border") + } + } + + indicator: UM.RecolorImage + { + id: downArrow + x: control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 * screenScaleFactor + sourceSize.height: width + 5 * screenScaleFactor + + color: UM.Theme.getColor("setting_control_text") + } + + contentItem: Label + { + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.verticalCenter: parent.verticalCenter + anchors.right: downArrow.left + + text: control.currentText + font: UM.Theme.getFont("default") + color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text") + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + delegate: ItemDelegate + { + width: control.width + height: control.height + highlighted: control.highlightedIndex == index + + contentItem: Text + { + text: modelData.value + color: control.contentItem.color + font: UM.Theme.getFont("default") + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter } } onActivated: { - forceActiveFocus(); - propertyProvider.setPropertyValue("value", definition.options[index].key); + forceActiveFocus() + propertyProvider.setPropertyValue("value", definition.options[index].key) } onActiveFocusChanged: { if(activeFocus) { - base.focusReceived(); + base.focusReceived() } } @@ -113,6 +120,7 @@ SettingItem { base.setActiveFocusToNextSetting(true) } + Keys.onBacktabPressed: { base.setActiveFocusToNextSetting(false) @@ -126,16 +134,14 @@ SettingItem { // FIXME this needs to go away once 'resolve' is combined with 'value' in our data model. var value = undefined; - if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) - { + if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) { // We have a resolve function. Indicates that the setting is not settable per extruder and that // we have to choose between the resolved value (default) and the global value // (if user has explicitly set this). value = base.resolve; } - if (value == undefined) - { + if (value == undefined) { value = propertyProvider.properties.value; } diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml index ca99640f6d..b754c3fd74 100644 --- a/resources/qml/Settings/SettingExtruder.qml +++ b/resources/qml/Settings/SettingExtruder.qml @@ -1,9 +1,8 @@ // Copyright (c) 2016 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import UM 1.1 as UM import Cura 1.0 as Cura @@ -65,83 +64,101 @@ SettingItem value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : "" } - style: ComboBoxStyle + indicator: UM.RecolorImage { - background: Rectangle + id: downArrow + x: control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 * screenScaleFactor + sourceSize.height: width + 5 * screenScaleFactor + + color: UM.Theme.getColor("setting_control_text"); + } + + background: Rectangle + { + color: { - color: + if (!enabled) { - if(!enabled) - { - return UM.Theme.getColor("setting_control_disabled"); - } - if(control.hovered || base.activeFocus) - { - return UM.Theme.getColor("setting_control_highlight"); - } - return UM.Theme.getColor("setting_control"); + return UM.Theme.getColor("setting_control_disabled"); } - border.width: UM.Theme.getSize("default_lining").width - border.color: + if (control.hovered || base.activeFocus) { - if(!enabled) - { - return UM.Theme.getColor("setting_control_disabled_border") - } - if(control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_border_highlight") - } - return UM.Theme.getColor("setting_control_border") + return UM.Theme.getColor("setting_control_highlight"); } + return UM.Theme.getColor("setting_control"); } - label: Item + border.width: UM.Theme.getSize("default_lining").width + border.color: { - Label + if (!enabled) { - id: extruderText - anchors.verticalCenter: parent.verticalCenter - - text: control.currentText - font: UM.Theme.getFont("default") - color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") - - elide: Text.ElideLeft - verticalAlignment: Text.AlignVCenter + return UM.Theme.getColor("setting_control_disabled_border") } - Rectangle + if (control.hovered || control.activeFocus) { - id: swatch - height: UM.Theme.getSize("setting_control").height / 2 - width: height - - anchors - { - right: arrow.left - verticalCenter: parent.verticalCenter - margins: UM.Theme.getSize("default_margin").width / 4 - } - - border.width: UM.Theme.getSize("default_lining").width * 2 - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: width / 2 - - color: control.color + return UM.Theme.getColor("setting_control_border_highlight") } - UM.RecolorImage - { - id: arrow - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + return UM.Theme.getColor("setting_control_border") + } + } - source: UM.Theme.getIcon("arrow_bottom") - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor + contentItem: Item + { + Label + { + id: extruderText - color: UM.Theme.getColor("setting_control_text") - } + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.right: swatch.left + + text: control.currentText + font: UM.Theme.getFont("default") + color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") + + elide: Text.ElideLeft + verticalAlignment: Text.AlignVCenter + } + + Rectangle + { + id: swatch + height: UM.Theme.getSize("setting_control").height / 2 + width: height + + anchors.right: parent.right + anchors.rightMargin: downArrow.width + UM.Theme.getSize("setting_unit_margin").width + anchors.verticalCenter: parent.verticalCenter + anchors.margins: UM.Theme.getSize("default_margin").width / 4 + + border.width: UM.Theme.getSize("default_lining").width + border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") + radius: width / 2 + + color: control.color + } + } + + delegate: ItemDelegate + { + width: control.width + height: control.height + highlighted: control.highlightedIndex == index + + contentItem: Text + { + text: model.name + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter } } } diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 4a89090984..1b1f302846 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -1,10 +1,9 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 +import QtQuick 2.8 import QtQuick.Layouts 1.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls 2.1 import UM 1.1 as UM import Cura 1.0 as Cura diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml index 1c286fcd2d..3bb2a2f1e0 100644 --- a/resources/qml/Settings/SettingOptionalExtruder.qml +++ b/resources/qml/Settings/SettingOptionalExtruder.qml @@ -1,9 +1,8 @@ // Copyright (c) 2016 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import UM 1.1 as UM import Cura 1.0 as Cura @@ -84,83 +83,101 @@ SettingItem value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : "" } - style: ComboBoxStyle + indicator: UM.RecolorImage { - background: Rectangle + id: downArrow + x: control.width - width - control.rightPadding + y: control.topPadding + (control.availableHeight - height) / 2 + + source: UM.Theme.getIcon("arrow_bottom") + width: UM.Theme.getSize("standard_arrow").width + height: UM.Theme.getSize("standard_arrow").height + sourceSize.width: width + 5 * screenScaleFactor + sourceSize.height: width + 5 * screenScaleFactor + + color: UM.Theme.getColor("setting_control_text"); + } + + background: Rectangle + { + color: { - color: + if (!enabled) { - if(!enabled) - { - return UM.Theme.getColor("setting_control_disabled"); - } - if(control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_highlight"); - } - return UM.Theme.getColor("setting_control"); + return UM.Theme.getColor("setting_control_disabled"); } - border.width: UM.Theme.getSize("default_lining").width - border.color: + if (control.hovered || control.activeFocus) { - if(!enabled) - { - return UM.Theme.getColor("setting_control_disabled_border") - } - if(control.hovered || control.activeFocus) - { - return UM.Theme.getColor("setting_control_border_highlight") - } - return UM.Theme.getColor("setting_control_border") + return UM.Theme.getColor("setting_control_highlight"); } + return UM.Theme.getColor("setting_control"); } - label: Item + border.width: UM.Theme.getSize("default_lining").width + border.color: { - Label + if (!enabled) { - anchors.verticalCenter: parent.verticalCenter - width: parent.width - swatch.width - arrow.width; - - text: control.currentText - font: UM.Theme.getFont("default") - color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") - - elide: Text.ElideRight - verticalAlignment: Text.AlignVCenter + return UM.Theme.getColor("setting_control_disabled_border") } - Rectangle + if (control.hovered || control.activeFocus) { - id: swatch - height: UM.Theme.getSize("setting_control").height / 2 - width: height - - anchors - { - right: arrow.left; - verticalCenter: parent.verticalCenter - margins: UM.Theme.getSize("default_margin").width / 4 - } - - border.width: UM.Theme.getSize("default_lining").width * 2 - border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") - radius: width / 2 - - color: control.color + return UM.Theme.getColor("setting_control_border_highlight") } - UM.RecolorImage - { - id: arrow - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + return UM.Theme.getColor("setting_control_border") + } + } - source: UM.Theme.getIcon("arrow_bottom") - width: UM.Theme.getSize("standard_arrow").width - height: UM.Theme.getSize("standard_arrow").height - sourceSize.width: width + 5 * screenScaleFactor - sourceSize.height: width + 5 * screenScaleFactor + contentItem: Item + { + Label + { + id: extruderText - color: UM.Theme.getColor("setting_control_text") - } + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width + anchors.right: swatch.left + + text: control.currentText + font: UM.Theme.getFont("default") + color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text") + + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + } + + Rectangle + { + id: swatch + height: UM.Theme.getSize("setting_control").height / 2 + width: height + + anchors.right: parent.right + anchors.rightMargin: downArrow.width + UM.Theme.getSize("setting_unit_margin").width + anchors.verticalCenter: parent.verticalCenter + anchors.margins: UM.Theme.getSize("default_margin").width / 4 + + border.width: UM.Theme.getSize("default_lining").width + border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border") + radius: width / 2 + + color: control.color + } + } + + delegate: ItemDelegate + { + width: control.width + height: control.height + highlighted: control.highlightedIndex == index + + contentItem: Text + { + text: model.name + color: UM.Theme.getColor("setting_control_text") + font: UM.Theme.getFont("default") + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter } } } diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml index 8a51f2baff..181cb9cb77 100644 --- a/resources/qml/Settings/SettingTextField.qml +++ b/resources/qml/Settings/SettingTextField.qml @@ -1,8 +1,8 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.2 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import UM 1.1 as UM @@ -17,6 +17,7 @@ SettingItem { textHasChanged = false; textBeforeEdit = focusItem.text; + focusItem.selectAll(); } contents: Rectangle diff --git a/resources/qml/Settings/SettingUnknown.qml b/resources/qml/Settings/SettingUnknown.qml index f4dadf8d75..82d54f96b8 100644 --- a/resources/qml/Settings/SettingUnknown.qml +++ b/resources/qml/Settings/SettingUnknown.qml @@ -1,8 +1,8 @@ // Copyright (c) 2015 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.1 -import QtQuick.Controls 1.1 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import UM 1.2 as UM diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 5d39572647..6929614830 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -1,7 +1,7 @@ // Copyright (c) 2017 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 +import QtQuick 2.8 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index c18bc072a3..e1c0a07f89 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -1,10 +1,9 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick 2.8 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.0 as Cura @@ -12,9 +11,9 @@ import "Menus" Rectangle { - id: base; + id: base - property int currentModeIndex; + property int currentModeIndex property bool hideSettings: PrintInformation.preSliced property bool hideView: Cura.MachineManager.activeMachineName == "" @@ -78,7 +77,7 @@ Rectangle MouseArea { anchors.fill: parent - acceptedButtons: Qt.AllButtons; + acceptedButtons: Qt.AllButtons onWheel: { @@ -119,13 +118,14 @@ Rectangle UM.Preferences.setValue("cura/active_mode", currentModeIndex); if(modesListModel.count > base.currentModeIndex) { - sidebarContents.push({ "item": modesListModel.get(base.currentModeIndex).item, "replace": true }); + sidebarContents.replace(modesListModel.get(base.currentModeIndex).item, { "replace": true }) } } - Label { + Label + { id: settingsModeLabel - text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox","Print Setup disabled\nG-code files cannot be modified"); + text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified") anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.top: headerSeparator.bottom @@ -136,13 +136,18 @@ Rectangle visible: !monitoringPrint && !hideView } - Rectangle { + // Settings mode selection toggle + Rectangle + { id: settingsModeSelection color: "transparent" + width: Math.floor(parent.width * 0.55) height: UM.Theme.getSize("sidebar_header_mode_toggle").height + anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width + anchors.topMargin: UM.Theme.getSize("sidebar_margin").height anchors.top: { if (settingsModeLabel.contentWidth >= parent.width - width - UM.Theme.getSize("sidebar_margin").width * 2) @@ -154,66 +159,69 @@ Rectangle return headerSeparator.bottom; } } - anchors.topMargin: UM.Theme.getSize("sidebar_margin").height + visible: !monitoringPrint && !hideSettings && !hideView - Component{ + + Component + { id: wizardDelegate - Button { + + Button + { + id: control + height: settingsModeSelection.height + width: Math.floor(0.5 * parent.width) + anchors.left: parent.left anchors.leftMargin: model.index * Math.floor(settingsModeSelection.width / 2) anchors.verticalCenter: parent.verticalCenter - width: Math.floor(0.5 * parent.width) - text: model.text - exclusiveGroup: modeMenuGroup; - checkable: true; + + ButtonGroup.group: modeMenuGroup + + checkable: true checked: base.currentModeIndex == index onClicked: base.currentModeIndex = index - onHoveredChanged: { + onHoveredChanged: + { if (hovered) { tooltipDelayTimer.item = settingsModeSelection tooltipDelayTimer.text = model.tooltipText - tooltipDelayTimer.start(); + tooltipDelayTimer.start() } else { - tooltipDelayTimer.stop(); - base.hideTooltip(); + tooltipDelayTimer.stop() + base.hideTooltip() } } - style: ButtonStyle { - background: Rectangle { - border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width - border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : - control.hovered ? UM.Theme.getColor("action_button_hovered_border") : - UM.Theme.getColor("action_button_border") - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : - control.hovered ? UM.Theme.getColor("action_button_hovered") : - UM.Theme.getColor("action_button") - Behavior on color { ColorAnimation { duration: 50; } } - Label { - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: UM.Theme.getSize("default_lining").width * 2 - anchors.rightMargin: UM.Theme.getSize("default_lining").width * 2 - color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") : - control.hovered ? UM.Theme.getColor("action_button_hovered_text") : - UM.Theme.getColor("action_button_text") - font: UM.Theme.getFont("default") - text: control.text - horizontalAlignment: Text.AlignHCenter - elide: Text.ElideMiddle - } - } - label: Item { } + background: Rectangle + { + border.width: control.checked ? UM.Theme.getSize("default_lining").width * 2 : UM.Theme.getSize("default_lining").width + border.color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_border") : control.hovered ? UM.Theme.getColor("action_button_hovered_border"): UM.Theme.getColor("action_button_border") + + // for some reason, QtQuick decided to use the color of the background property as text color for the contentItem, so here it is + color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") + } + + contentItem: Text + { + text: model.text + font: UM.Theme.getFont("default") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight } } } - ExclusiveGroup { id: modeMenuGroup; } + + ButtonGroup + { + id: modeMenuGroup + } ListView { @@ -238,31 +246,21 @@ Rectangle anchors.right: base.right visible: !monitoringPrint && !hideSettings - delegate: StackViewDelegate - { - function transitionFinished(properties) - { - properties.exitItem.opacity = 1 + replaceEnter: Transition { + PropertyAnimation { + property: "opacity" + from: 0 + to:1 + duration: 100 } + } - pushTransition: StackViewTransition - { - PropertyAnimation - { - target: enterItem - property: "opacity" - from: 0 - to: 1 - duration: 100 - } - PropertyAnimation - { - target: exitItem - property: "opacity" - from: 1 - to: 0 - duration: 100 - } + replaceExit: Transition { + PropertyAnimation { + property: "opacity" + from: 1 + to:0 + duration: 100 } } } @@ -559,19 +557,19 @@ Rectangle SidebarTooltip { - id: tooltip; + id: tooltip } // Setting mode: Recommended or Custom ListModel { - id: modesListModel; + id: modesListModel } SidebarSimple { - id: sidebarSimple; - visible: false; + id: sidebarSimple + visible: false onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() @@ -579,8 +577,8 @@ Rectangle SidebarAdvanced { - id: sidebarAdvanced; - visible: false; + id: sidebarAdvanced + visible: false onShowTooltip: base.showTooltip(item, location, text) onHideTooltip: base.hideTooltip() @@ -598,7 +596,7 @@ Rectangle tooltipText: catalog.i18nc("@tooltip", "Custom Print Setup

Print with finegrained control over every last bit of the slicing process."), item: sidebarAdvanced }) - sidebarContents.push({ "item": modesListModel.get(base.currentModeIndex).item, "immediate": true }); + sidebarContents.replace(modesListModel.get(base.currentModeIndex).item, { "immediate": true }) var index = Math.floor(UM.Preferences.getValue("cura/active_mode")) if(index) diff --git a/resources/qml/SidebarAdvanced.qml b/resources/qml/SidebarAdvanced.qml index 95f218639b..f214e425b1 100644 --- a/resources/qml/SidebarAdvanced.qml +++ b/resources/qml/SidebarAdvanced.qml @@ -1,9 +1,8 @@ // Copyright (c) 2015 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.0 - -import QtQuick.Controls 1.2 +import QtQuick 2.8 +import QtQuick.Controls 2.1 import "Settings" diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml index 7aca25160a..ac124c8911 100644 --- a/resources/qml/SidebarSimple.qml +++ b/resources/qml/SidebarSimple.qml @@ -1,17 +1,17 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.2 -import QtQuick.Controls 1.1 -import QtQuick.Controls.Styles 1.1 -import QtQuick.Layouts 1.1 +import QtQuick 2.8 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.3 import UM 1.2 as UM import Cura 1.2 as Cura Item { - id: base; + id: base signal showTooltip(Item item, point location, string text); signal hideTooltip(); @@ -70,6 +70,18 @@ Item onActiveVariantChanged: qualityModel.update() } + Connections { + target: base + onVisibleChanged: + { + // update needs to be called when the widgets are visible, otherwise the step width calculation + // will fail because the width of an invisible item is 0. + if (visible) { + qualityModel.update(); + } + } + } + ListModel { id: qualityModel @@ -103,7 +115,7 @@ Item if (Cura.SimpleModeSettingsManager.isProfileUserCreated) { qualityModel.qualitySliderActiveIndex = -1 } else { - qualityModel.qualitySliderActiveIndex = i + qualityModel.qualitySliderActiveIndex = i } qualityModel.existingQualityProfile = 1 @@ -183,11 +195,10 @@ Item text: { var result = "" - if(Cura.MachineManager.activeMachine != null){ + if (Cura.MachineManager.activeMachine != null) { + result = Cura.ProfilesModel.getItem(index).layer_height_without_unit - var result = Cura.ProfilesModel.getItem(index).layer_height_without_unit - - if(result == undefined) + if (result == undefined) result = "" } return result diff --git a/tests/TestArrange.py b/tests/TestArrange.py index 737305f638..4f6bb64118 100755 --- a/tests/TestArrange.py +++ b/tests/TestArrange.py @@ -118,6 +118,13 @@ def test_arrayFromPolygon2(): assert numpy.any(array) +## Polygon -> array +def test_fromPolygon(): + vertices = numpy.array([[0, 0.5], [0, 0], [0.5, 0]]) + array = ShapeArray.fromPolygon(vertices, scale=0.5) + assert numpy.any(array.arr) + + ## Line definition -> array with true/false def test_check(): base_array = numpy.zeros([5, 5], dtype=float)