From 81d4812b924f18773435cd672e47a3f3922e0004 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Tue, 26 Nov 2024 00:17:07 +0200 Subject: [PATCH] Preview tiles when using tools and draw tiles mode is enabled. --- src/Tools/BaseDraw.gd | 77 +++++++++++++++++------------- src/Tools/BaseShapeDrawer.gd | 2 +- src/Tools/BaseTool.gd | 52 +++++++++++--------- src/Tools/DesignTools/CurveTool.gd | 2 +- src/Tools/DesignTools/Eraser.gd | 2 +- src/Tools/DesignTools/LineTool.gd | 2 +- src/Tools/DesignTools/Pencil.gd | 2 +- src/Tools/DesignTools/Shading.gd | 2 +- src/UI/TilesPanel.gd | 18 +++++-- 9 files changed, 96 insertions(+), 63 deletions(-) diff --git a/src/Tools/BaseDraw.gd b/src/Tools/BaseDraw.gd index bb9da1a22..90c0ae9e1 100644 --- a/src/Tools/BaseDraw.gd +++ b/src/Tools/BaseDraw.gd @@ -1,3 +1,4 @@ +class_name BaseDrawTool extends BaseTool const IMAGE_BRUSHES := [Brushes.FILE, Brushes.RANDOM_FILE, Brushes.CUSTOM] @@ -42,6 +43,7 @@ var _circle_tool_shortcut: Array[Vector2i] func _ready() -> void: super._ready() + Global.cel_switched.connect(update_brush) Global.global_tool_options.dynamics_panel.dynamics_changed.connect(_reset_dynamics) Tools.color_changed.connect(_on_Color_changed) Global.brushes_popup.brush_removed.connect(_on_Brush_removed) @@ -160,34 +162,40 @@ func update_config() -> void: func update_brush() -> void: $Brush/BrushSize.suffix = "px" # Assume we are using default brushes - match _brush.type: - Brushes.PIXEL: - _brush_texture = ImageTexture.create_from_image( - load("res://assets/graphics/pixel_image.png") - ) - _stroke_dimensions = Vector2.ONE * _brush_size - Brushes.CIRCLE: - _brush_texture = ImageTexture.create_from_image( - load("res://assets/graphics/circle_9x9.png") - ) - _stroke_dimensions = Vector2.ONE * _brush_size - Brushes.FILLED_CIRCLE: - _brush_texture = ImageTexture.create_from_image( - load("res://assets/graphics/circle_filled_9x9.png") - ) - _stroke_dimensions = Vector2.ONE * _brush_size - Brushes.FILE, Brushes.RANDOM_FILE, Brushes.CUSTOM: - $Brush/BrushSize.suffix = "00 %" # Use a different size convention on images - if _brush.random.size() <= 1: - _orignal_brush_image = _brush.image - else: - 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() + if is_placing_tiles(): + var tileset := (Global.current_project.get_current_cel() as CelTileMap).tileset + var tile_index := clampi(TileSetPanel.selected_tile_index, 0, tileset.tiles.size() - 1) + _brush_image.copy_from(tileset.tiles[tile_index].image) + _brush_texture = ImageTexture.create_from_image(_brush_image) + else: + match _brush.type: + Brushes.PIXEL: + _brush_texture = ImageTexture.create_from_image( + load("res://assets/graphics/pixel_image.png") + ) + _stroke_dimensions = Vector2.ONE * _brush_size + Brushes.CIRCLE: + _brush_texture = ImageTexture.create_from_image( + load("res://assets/graphics/circle_9x9.png") + ) + _stroke_dimensions = Vector2.ONE * _brush_size + Brushes.FILLED_CIRCLE: + _brush_texture = ImageTexture.create_from_image( + load("res://assets/graphics/circle_filled_9x9.png") + ) + _stroke_dimensions = Vector2.ONE * _brush_size + Brushes.FILE, Brushes.RANDOM_FILE, Brushes.CUSTOM: + $Brush/BrushSize.suffix = "00 %" # Use a different size convention on images + if _brush.random.size() <= 1: + _orignal_brush_image = _brush.image + else: + 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() _circle_tool_shortcut = [] _indicator = _create_brush_indicator() _polylines = _create_polylines(_indicator) @@ -491,7 +499,12 @@ func remove_unselected_parts_of_brush(brush: Image, dst: Vector2i) -> Image: func draw_indicator(left: bool) -> void: var color := Global.left_tool_color if left else Global.right_tool_color - draw_indicator_at(snap_position(_cursor), Vector2i.ZERO, color) + var snapped_position := snap_position(_cursor) + if is_placing_tiles(): + var tileset := (Global.current_project.get_current_cel() as CelTileMap).tileset + var grid_size := tileset.tile_size + snapped_position = _snap_to_grid_center(snapped_position, grid_size, -1) + draw_indicator_at(snapped_position, Vector2i.ZERO, color) if ( Global.current_project.has_selection and Global.current_project.tiles.mode == Tiles.MODE.NONE @@ -500,7 +513,7 @@ func draw_indicator(left: bool) -> void: var nearest_pos := Global.current_project.selection_map.get_nearest_position(pos) if nearest_pos != Vector2i.ZERO: var offset := nearest_pos - draw_indicator_at(snap_position(_cursor), offset, Color.GREEN) + draw_indicator_at(snapped_position, offset, Color.GREEN) return if Global.current_project.tiles.mode and Global.current_project.tiles.has_point(_cursor): @@ -508,12 +521,12 @@ func draw_indicator(left: bool) -> void: var nearest_tile := Global.current_project.tiles.get_nearest_tile(pos) if nearest_tile.position != Vector2i.ZERO: var offset := nearest_tile.position - draw_indicator_at(snap_position(_cursor), offset, Color.GREEN) + draw_indicator_at(snapped_position, offset, Color.GREEN) func draw_indicator_at(pos: Vector2i, offset: Vector2i, color: Color) -> void: var canvas: Node2D = Global.canvas.indicators - if _brush.type in IMAGE_BRUSHES and not _draw_line: + if _brush.type in IMAGE_BRUSHES and not _draw_line or is_placing_tiles(): pos -= _brush_image.get_size() / 2 pos -= offset canvas.draw_texture(_brush_texture, pos) diff --git a/src/Tools/BaseShapeDrawer.gd b/src/Tools/BaseShapeDrawer.gd index 8789fccd2..0e7550092 100644 --- a/src/Tools/BaseShapeDrawer.gd +++ b/src/Tools/BaseShapeDrawer.gd @@ -1,4 +1,4 @@ -extends "res://src/Tools/BaseDraw.gd" +extends BaseDrawTool var _start := Vector2i.ZERO var _offset := Vector2i.ZERO diff --git a/src/Tools/BaseTool.gd b/src/Tools/BaseTool.gd index b93e5832f..2ab088871 100644 --- a/src/Tools/BaseTool.gd +++ b/src/Tools/BaseTool.gd @@ -80,6 +80,8 @@ func draw_end(_pos: Vector2i) -> void: func is_placing_tiles() -> bool: + if Global.current_project.frames.size() == 0 or Global.current_project.layers.size() == 0: + return false return Global.current_project.get_current_cel() is CelTileMap and TileSetPanel.placing_tiles @@ -167,28 +169,7 @@ func snap_position(pos: Vector2) -> Vector2: pos = grid_point.floor() if Global.snap_to_rectangular_grid_center: - var grid_center := ( - pos.snapped(Global.grids[0].grid_size) + Vector2(Global.grids[0].grid_size / 2) - ) - grid_center += Vector2(Global.grids[0].grid_offset) - # keeping grid_center as is would have been fine but this adds extra accuracy as to - # which snap point (from the list below) is closest to mouse and occupy THAT point - # t_l is for "top left" and so on - var t_l := grid_center + Vector2(-Global.grids[0].grid_size.x, -Global.grids[0].grid_size.y) - var t_c := grid_center + Vector2(0, -Global.grids[0].grid_size.y) - var t_r := grid_center + Vector2(Global.grids[0].grid_size.x, -Global.grids[0].grid_size.y) - var m_l := grid_center + Vector2(-Global.grids[0].grid_size.x, 0) - var m_c := grid_center - var m_r := grid_center + Vector2(Global.grids[0].grid_size.x, 0) - var b_l := grid_center + Vector2(-Global.grids[0].grid_size.x, Global.grids[0].grid_size.y) - var b_c := grid_center + Vector2(0, Global.grids[0].grid_size.y) - var b_r := grid_center + Vector2(Global.grids[0].grid_size) - var vec_arr := [t_l, t_c, t_r, m_l, m_c, m_r, b_l, b_c, b_r] - for vec in vec_arr: - if vec.distance_to(pos) < grid_center.distance_to(pos): - grid_center = vec - if grid_center.distance_to(pos) <= snapping_distance: - pos = grid_center.floor() + pos = _snap_to_grid_center(pos, Global.grids[0].grid_size, snapping_distance) var snap_to := Vector2.INF if Global.snap_to_guides: @@ -301,6 +282,33 @@ func _get_closest_point_to_segment( return closest_point +func _snap_to_grid_center(pos: Vector2, grid_size: Vector2i, snapping_distance: float) -> Vector2: + var grid_center := pos.snapped(grid_size) + Vector2(grid_size / 2) + grid_center += Vector2(Global.grids[0].grid_offset) + # keeping grid_center as is would have been fine but this adds extra accuracy as to + # which snap point (from the list below) is closest to mouse and occupy THAT point + # t_l is for "top left" and so on + var t_l := grid_center + Vector2(-grid_size.x, -grid_size.y) + var t_c := grid_center + Vector2(0, -grid_size.y) + var t_r := grid_center + Vector2(grid_size.x, -grid_size.y) + var m_l := grid_center + Vector2(-grid_size.x, 0) + var m_c := grid_center + var m_r := grid_center + Vector2(grid_size.x, 0) + var b_l := grid_center + Vector2(-grid_size.x, grid_size.y) + var b_c := grid_center + Vector2(0, grid_size.y) + var b_r := grid_center + Vector2(grid_size) + var vec_arr := [t_l, t_c, t_r, m_l, m_c, m_r, b_l, b_c, b_r] + for vec in vec_arr: + if vec.distance_to(pos) < grid_center.distance_to(pos): + grid_center = vec + if snapping_distance < 0: + pos = grid_center.floor() + else: + if grid_center.distance_to(pos) <= snapping_distance: + pos = grid_center.floor() + return pos + + func _snap_to_guide( snap_to: Vector2, pos: Vector2, distance: float, s1: Vector2, s2: Vector2 ) -> Vector2: diff --git a/src/Tools/DesignTools/CurveTool.gd b/src/Tools/DesignTools/CurveTool.gd index c326d5b43..fc690b584 100644 --- a/src/Tools/DesignTools/CurveTool.gd +++ b/src/Tools/DesignTools/CurveTool.gd @@ -1,4 +1,4 @@ -extends "res://src/Tools/BaseDraw.gd" +extends BaseDrawTool var _curve := Curve2D.new() ## The [Curve2D] responsible for the shape of the curve being drawn. var _drawing := false ## Set to true when a curve is being drawn. diff --git a/src/Tools/DesignTools/Eraser.gd b/src/Tools/DesignTools/Eraser.gd index 556993b6a..a2ea9b501 100644 --- a/src/Tools/DesignTools/Eraser.gd +++ b/src/Tools/DesignTools/Eraser.gd @@ -1,4 +1,4 @@ -extends "res://src/Tools/BaseDraw.gd" +extends BaseDrawTool var _last_position := Vector2.INF var _clear_image: Image diff --git a/src/Tools/DesignTools/LineTool.gd b/src/Tools/DesignTools/LineTool.gd index 7c97d0511..f856cd6ac 100644 --- a/src/Tools/DesignTools/LineTool.gd +++ b/src/Tools/DesignTools/LineTool.gd @@ -1,4 +1,4 @@ -extends "res://src/Tools/BaseDraw.gd" +extends BaseDrawTool var _original_pos := Vector2i.ZERO var _start := Vector2i.ZERO diff --git a/src/Tools/DesignTools/Pencil.gd b/src/Tools/DesignTools/Pencil.gd index 3a47716a1..825645b51 100644 --- a/src/Tools/DesignTools/Pencil.gd +++ b/src/Tools/DesignTools/Pencil.gd @@ -1,4 +1,4 @@ -extends "res://src/Tools/BaseDraw.gd" +extends BaseDrawTool var _prev_mode := false var _last_position := Vector2i(Vector2.INF) diff --git a/src/Tools/DesignTools/Shading.gd b/src/Tools/DesignTools/Shading.gd index 74faea35a..2413158ed 100644 --- a/src/Tools/DesignTools/Shading.gd +++ b/src/Tools/DesignTools/Shading.gd @@ -1,4 +1,4 @@ -extends "res://src/Tools/BaseDraw.gd" +extends BaseDrawTool enum ShadingMode { SIMPLE, HUE_SHIFTING, COLOR_REPLACE } enum LightenDarken { LIGHTEN, DARKEN } diff --git a/src/UI/TilesPanel.gd b/src/UI/TilesPanel.gd index e25ab7375..bbf909eb4 100644 --- a/src/UI/TilesPanel.gd +++ b/src/UI/TilesPanel.gd @@ -7,9 +7,15 @@ const TRANSPARENT_CHECKER := preload("res://src/UI/Nodes/TransparentChecker.tscn const MIN_BUTTON_SIZE := 36 const MAX_BUTTON_SIZE := 144 -static var placing_tiles := false +static var placing_tiles := false: + set(value): + placing_tiles = value + _call_update_brushes() static var tile_editing_mode := TileEditingMode.AUTO -static var selected_tile_index := 0 +static var selected_tile_index := 0: + set(value): + selected_tile_index = value + _call_update_brushes() var current_tileset: TileSetCustom var button_size := 36: set(value): @@ -29,7 +35,7 @@ var button_size := 36: func _ready() -> void: Tools.selected_tile_index_changed.connect(select_tile) Global.cel_switched.connect(_on_cel_switched) - Global.project_switched.connect(_on_cel_switched) + #Global.project_switched.connect(_on_cel_switched) func _gui_input(event: InputEvent) -> void: @@ -111,6 +117,12 @@ func select_tile(tile_index: int) -> void: tile_button_container.get_child(tile_index).button_pressed = true +static func _call_update_brushes() -> void: + for slot in Tools._slots.values(): + if slot.tool_node is BaseDrawTool: + slot.tool_node.update_brush() + + func _on_tile_button_toggled(toggled_on: bool, index: int) -> void: if toggled_on: selected_tile_index = index