diff --git a/src/Autoload/Tools.gd b/src/Autoload/Tools.gd index a9eb19bae71..5146e4b0e7d 100644 --- a/src/Autoload/Tools.gd +++ b/src/Autoload/Tools.gd @@ -1,6 +1,8 @@ extends Node signal color_changed(color, button) +signal flip_rotate(flip_x, flip_y, rotate_90, rotate_180, rotate_270) +signal share_brush_config(_brush, _size, _flip_x, _flip_y, _rotate_90, _rotate_180, _rotate_270) enum Dynamics { NONE, PRESSURE, VELOCITY } diff --git a/src/Tools/BaseDraw.gd b/src/Tools/BaseDraw.gd index 6f862f2cc02..087bae9ba3e 100644 --- a/src/Tools/BaseDraw.gd +++ b/src/Tools/BaseDraw.gd @@ -3,6 +3,13 @@ extends BaseTool var _brush := Brushes.get_default_brush() var _brush_size := 1 var _brush_size_dynamics := 1 +var _brush_flip_x := false +var _brush_flip_y := false +var _brush_rotate_90 := false +var _brush_rotate_180 := false +var _brush_rotate_270 := false +var _i_shared_my_brush := false +var _brush_sharing_check := false var _cache_limit := 3 var _brush_interpolate := 0 var _brush_image := Image.new() @@ -37,6 +44,7 @@ func _ready() -> void: Global.global_tool_options.dynamics_changed.connect(_reset_dynamics) Tools.color_changed.connect(_on_Color_changed) Global.brushes_popup.brush_removed.connect(_on_Brush_removed) + Tools.share_brush_config.connect(_update_brush_config) func _on_BrushType_pressed() -> void: @@ -54,10 +62,15 @@ func _on_BrushType_pressed() -> void: if child is GridContainer: child.columns = columns Global.brushes_popup.popup(Rect2(pop_position, Vector2(size_x, size_y))) + Tools.flip_rotate.emit( + _brush_flip_x, _brush_flip_y, _brush_rotate_90, _brush_rotate_180, _brush_rotate_270 + ) func _on_Brush_selected(brush: Brushes.Brush) -> void: _brush = brush + if _brush_sharing_check == true: + _sharing_brush() update_brush() save_config() @@ -65,6 +78,8 @@ func _on_Brush_selected(brush: Brushes.Brush) -> void: func _on_BrushSize_value_changed(value: float) -> void: if _brush_size != int(value): _brush_size = int(value) + if _brush_sharing_check == true: + _sharing_brush() _brush_size_dynamics = _brush_size if Tools.dynamics_size != Tools.Dynamics.NONE: _brush_size_dynamics = Tools.brush_size_min @@ -122,9 +137,43 @@ func set_config(config: Dictionary) -> void: func update_config() -> void: $Brush/BrushSize.value = _brush_size $ColorInterpolation.value = _brush_interpolate + $Flip/FlipX.button_pressed = _brush_flip_x + $Flip/FlipY.button_pressed = _brush_flip_y + $Rotate/Rotate90.button_pressed = _brush_rotate_90 + $Rotate/Rotate180.button_pressed = _brush_rotate_180 + $Rotate/Rotate270.button_pressed = _brush_rotate_270 update_brush() +func _update_brush_config( + b_brush, b_size, b_flip_x, b_flip_y, b_rotate_90, b_rotate_180, b_rotate_270 +) -> void: + if _i_shared_my_brush == false: + _brush = b_brush + _brush_size = b_size + _brush_flip_x = b_flip_x + _brush_flip_y = b_flip_y + _brush_rotate_90 = b_rotate_90 + _brush_rotate_180 = b_rotate_180 + _brush_rotate_270 = b_rotate_270 + update_config() + else: + _i_shared_my_brush = false + + +func _sharing_brush() -> void: + _i_shared_my_brush = true + Tools.share_brush_config.emit( + _brush, + _brush_size, + _brush_flip_x, + _brush_flip_y, + _brush_rotate_90, + _brush_rotate_180, + _brush_rotate_270 + ) + + func update_brush() -> void: $Brush/BrushSize.suffix = "px" # Assume we are using default brushes match _brush.type: @@ -151,6 +200,7 @@ func update_brush() -> void: var random := randi() % _brush.random.size() _orignal_brush_image = _brush.random[random] _brush_image = _create_blended_brush_image(_orignal_brush_image) + update_brush_image_flip_and_rotate() _brush_texture = ImageTexture.create_from_image(_brush_image) update_mirror_brush() _stroke_dimensions = _brush_image.get_size() @@ -166,6 +216,7 @@ func update_random_image() -> void: var random := randi() % _brush.random.size() _brush_image = _create_blended_brush_image(_brush.random[random]) _orignal_brush_image = _brush_image + update_brush_image_flip_and_rotate() _brush_texture = ImageTexture.create_from_image(_brush_image) _indicator = _create_brush_indicator() update_mirror_brush() @@ -180,6 +231,19 @@ func update_mirror_brush() -> void: _mirror_brushes.xy.flip_y() +func update_brush_image_flip_and_rotate() -> void: + if _brush_flip_x == true: + _brush_image.flip_x() + if _brush_flip_y == true: + _brush_image.flip_y() + if _brush_rotate_90 == true: + _brush_image.rotate_90(CLOCKWISE) + if _brush_rotate_180 == true: + _brush_image.rotate_180() + if _brush_rotate_270 == true: + _brush_image.rotate_90(COUNTERCLOCKWISE) + + func update_mask(can_skip := true) -> void: if can_skip and Tools.dynamics_alpha == Tools.Dynamics.NONE: if _mask: @@ -241,6 +305,7 @@ func draw_end(pos: Vector2i) -> void: match _brush.type: Brushes.FILE, Brushes.RANDOM_FILE, Brushes.CUSTOM: _brush_image = _create_blended_brush_image(_orignal_brush_image) + update_brush_image_flip_and_rotate() _brush_texture = ImageTexture.create_from_image(_brush_image) update_mirror_brush() _stroke_dimensions = _brush_image.get_size() @@ -279,6 +344,7 @@ func _prepare_tool() -> void: Brushes.FILE, Brushes.RANDOM_FILE, Brushes.CUSTOM: # save _brush_image for safe keeping _brush_image = _create_blended_brush_image(_orignal_brush_image) + update_brush_image_flip_and_rotate() _brush_texture = ImageTexture.create_from_image(_brush_image) update_mirror_brush() _stroke_dimensions = _brush_image.get_size() @@ -707,3 +773,44 @@ func _pick_color(pos: Vector2i) -> void: else MOUSE_BUTTON_RIGHT ) Tools.assign_color(color, button, false) + + +func _on_flip_x_toggled(button_pressed: bool) -> void: + _brush_flip_x = button_pressed + if _brush_sharing_check == true: + _sharing_brush() + update_brush() + + +func _on_flip_y_toggled(button_pressed: bool) -> void: + _brush_flip_y = button_pressed + if _brush_sharing_check == true: + _sharing_brush() + update_brush() + + +func _on_rotate_90_toggled(button_pressed: bool) -> void: + _brush_rotate_90 = button_pressed + if _brush_sharing_check == true: + _sharing_brush() + update_brush() + + +func _on_rotate_180_toggled(button_pressed: bool) -> void: + _brush_rotate_180 = button_pressed + if _brush_sharing_check == true: + _sharing_brush() + update_brush() + + +func _on_rotate_270_toggled(button_pressed: bool) -> void: + _brush_rotate_270 = button_pressed + if _brush_sharing_check == true: + _sharing_brush() + update_brush() + + +func _on_share_brush_config_toggled(button_pressed: bool) -> void: + _brush_sharing_check = button_pressed + if _brush_sharing_check == true: + _sharing_brush() diff --git a/src/Tools/BaseDraw.tscn b/src/Tools/BaseDraw.tscn index b05261e5672..965e0bc89da 100644 --- a/src/Tools/BaseDraw.tscn +++ b/src/Tools/BaseDraw.tscn @@ -25,7 +25,33 @@ anti_aliasing = false [node name="ToolOptions" instance=ExtResource("2")] script = ExtResource("3") -[node name="Brush" type="HBoxContainer" parent="." index="2"] +[node name="Flip" type="HBoxContainer" parent="." index="2"] +layout_mode = 2 + +[node name="FlipX" type="CheckBox" parent="Flip" index="0"] +layout_mode = 2 +text = "Flip X" + +[node name="FlipY" type="CheckBox" parent="Flip" index="1"] +layout_mode = 2 +text = "Flip Y" + +[node name="Rotate" type="HBoxContainer" parent="." index="3"] +layout_mode = 2 + +[node name="Rotate90" type="CheckBox" parent="Rotate" index="0"] +layout_mode = 2 +text = "R 90" + +[node name="Rotate180" type="CheckBox" parent="Rotate" index="1"] +layout_mode = 2 +text = "R 180" + +[node name="Rotate270" type="CheckBox" parent="Rotate" index="2"] +layout_mode = 2 +text = "R 270" + +[node name="Brush" type="HBoxContainer" parent="." index="4"] layout_mode = 2 alignment = 1 @@ -59,12 +85,22 @@ suffix = "px" global_increment_action = "brush_size_increment" global_decrement_action = "brush_size_decrement" -[node name="ColorInterpolation" parent="." index="3" instance=ExtResource("1")] +[node name="ColorInterpolation" parent="." index="5" instance=ExtResource("1")] visible = false layout_mode = 2 tooltip_text = "0: Color from the brush itself, 100: the currently selected color" prefix = "Brush color from:" +[node name="ShareBrushConfig" type="CheckBox" parent="." index="6"] +layout_mode = 2 +text = "Share Brush Config" + +[connection signal="toggled" from="Flip/FlipX" to="." method="_on_flip_x_toggled"] +[connection signal="toggled" from="Flip/FlipY" to="." method="_on_flip_y_toggled"] +[connection signal="toggled" from="Rotate/Rotate90" to="." method="_on_rotate_90_toggled"] +[connection signal="toggled" from="Rotate/Rotate180" to="." method="_on_rotate_180_toggled"] +[connection signal="toggled" from="Rotate/Rotate270" to="." method="_on_rotate_270_toggled"] [connection signal="pressed" from="Brush/Type" to="." method="_on_BrushType_pressed"] [connection signal="value_changed" from="Brush/BrushSize" to="." method="_on_BrushSize_value_changed"] [connection signal="value_changed" from="ColorInterpolation" to="." method="_on_InterpolateFactor_value_changed"] +[connection signal="toggled" from="ShareBrushConfig" to="." method="_on_share_brush_config_toggled"] diff --git a/src/Tools/DesignTools/EllipseTool.tscn b/src/Tools/DesignTools/EllipseTool.tscn index 73e0366580c..66f07fc777f 100644 --- a/src/Tools/DesignTools/EllipseTool.tscn +++ b/src/Tools/DesignTools/EllipseTool.tscn @@ -5,3 +5,12 @@ [node name="ToolOptions" instance=ExtResource("1")] script = ExtResource("2") + +[node name="Flip" parent="." index="4"] +visible = false + +[node name="Rotate" parent="." index="5"] +visible = false + +[node name="ShareBrushConfig" parent="." index="8"] +visible = false diff --git a/src/Tools/DesignTools/LineTool.tscn b/src/Tools/DesignTools/LineTool.tscn index f10be6fbf74..96d64113a37 100644 --- a/src/Tools/DesignTools/LineTool.tscn +++ b/src/Tools/DesignTools/LineTool.tscn @@ -16,7 +16,16 @@ suffix = "px" global_increment_action = "brush_size_increment" global_decrement_action = "brush_size_decrement" -[node name="Brush" parent="." index="3"] +[node name="Flip" parent="." index="3"] +visible = false + +[node name="Rotate" parent="." index="4"] +visible = false + +[node name="Brush" parent="." index="5"] +visible = false + +[node name="ShareBrushConfig" parent="." index="7"] visible = false [connection signal="value_changed" from="ThicknessSlider" to="." method="_on_Thickness_value_changed"] diff --git a/src/Tools/DesignTools/Pencil.tscn b/src/Tools/DesignTools/Pencil.tscn index 40ae6992ceb..1d56b0df8ff 100644 --- a/src/Tools/DesignTools/Pencil.tscn +++ b/src/Tools/DesignTools/Pencil.tscn @@ -7,23 +7,23 @@ [node name="ToolOptions" instance=ExtResource("1")] script = ExtResource("3") -[node name="Overwrite" type="CheckBox" parent="." index="4"] +[node name="Overwrite" type="CheckBox" parent="." index="6"] layout_mode = 2 tooltip_text = "Overwrites color instead of blending it. This option is only relevant with colors that are not fully opaque" mouse_default_cursor_shape = 2 text = "Overwrite color" -[node name="FillInside" type="CheckBox" parent="." index="5"] +[node name="FillInside" type="CheckBox" parent="." index="7"] layout_mode = 2 mouse_default_cursor_shape = 2 text = "Fill inside" -[node name="SpacingMode" type="CheckBox" parent="." index="6"] +[node name="SpacingMode" type="CheckBox" parent="." index="8"] layout_mode = 2 mouse_default_cursor_shape = 2 text = "Spacing" -[node name="Spacing" parent="." index="7" instance=ExtResource("2")] +[node name="Spacing" parent="." index="9" instance=ExtResource("2")] visible = false layout_mode = 2 allow_greater = true diff --git a/src/Tools/DesignTools/RectangleTool.tscn b/src/Tools/DesignTools/RectangleTool.tscn index a2aa05834c1..be5af8f5fd0 100644 --- a/src/Tools/DesignTools/RectangleTool.tscn +++ b/src/Tools/DesignTools/RectangleTool.tscn @@ -5,3 +5,12 @@ [node name="ToolOptions" instance=ExtResource("1")] script = ExtResource("2") + +[node name="Flip" parent="." index="4"] +visible = false + +[node name="Rotate" parent="." index="5"] +visible = false + +[node name="ShareBrushConfig" parent="." index="8"] +visible = false diff --git a/src/UI/Buttons/BrushButton.gd b/src/UI/Buttons/BrushButton.gd index 951e4d41abd..49cfa6a1b25 100644 --- a/src/UI/Buttons/BrushButton.gd +++ b/src/UI/Buttons/BrushButton.gd @@ -3,6 +3,10 @@ extends BaseButton var brush = Global.brushes_popup.Brush.new() +func _ready() -> void: + Tools.flip_rotate.connect(_flip_rotate_updated) + + func _on_BrushButton_pressed() -> void: # Delete the brush on middle mouse press if Input.is_action_just_released("middle_mouse"): @@ -26,3 +30,18 @@ func _on_BrushButton_mouse_entered() -> void: func _on_BrushButton_mouse_exited() -> void: if brush.type == Global.brushes_popup.CUSTOM: $DeleteButton.visible = false + + +func _flip_rotate_updated( + flip_x: bool, flip_y: bool, rotate_90: bool, rotate_180: bool, rotate_270: bool +): + $BrushTexture.set_flip_h(flip_x) + $BrushTexture.set_flip_v(flip_y) + var brush_texture_rotation = 0 + if rotate_90 == true: + brush_texture_rotation += 90 + if rotate_180 == true: + brush_texture_rotation += 180 + if rotate_270 == true: + brush_texture_rotation += 270 + $BrushTexture.rotation_degrees = brush_texture_rotation diff --git a/src/UI/Buttons/BrushButton.tscn b/src/UI/Buttons/BrushButton.tscn index 4df757891b1..0b278e1be2f 100644 --- a/src/UI/Buttons/BrushButton.tscn +++ b/src/UI/Buttons/BrushButton.tscn @@ -19,6 +19,7 @@ offset_left = 2.0 offset_top = 2.0 offset_right = -2.0 offset_bottom = -2.0 +pivot_offset = Vector2(16, 16) expand_mode = 1 stretch_mode = 6