mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-19 17:49:47 +00:00
9a85de74b5
* Initial work of a color picker that is always visible * Make the new color picker fully functional * Minor UI fixes * Change the UI a bit so the color picker buttons look like they used to To save horizontal space * Add sliders as a separate panel and rename some file names * Move the left/right color buttons next to the hex text edit * Add color picker sliders to the same panel as the rest of the color picker, as an expandable/collapsible area * Change default layout * Some minor UI improvements * Remove guides from ColorPicker.tscn * Reduce the lines of code that calculate the average color * Make Pixelorama remember if the color picker is expanded and its color mode * Update tallscreen.tres * Update tallscreen.tres * Pixelorama now also remembers the last used picker shape * Add some extra comments in the code * Fix typo * Add some translation strings
558 lines
18 KiB
GDScript
558 lines
18 KiB
GDScript
extends Node
|
||
|
||
signal color_changed(color, button)
|
||
|
||
enum Dynamics { NONE, PRESSURE, VELOCITY }
|
||
|
||
var picking_color_for := MOUSE_BUTTON_LEFT
|
||
var horizontal_mirror := false
|
||
var vertical_mirror := false
|
||
var pixel_perfect := false
|
||
|
||
# Dynamics
|
||
var stabilizer_enabled := false
|
||
var stabilizer_value := 16
|
||
var dynamics_alpha: int = Dynamics.NONE
|
||
var dynamics_size: int = Dynamics.NONE
|
||
var pen_pressure := 1.0
|
||
var pen_pressure_min := 0.2
|
||
var pen_pressure_max := 0.8
|
||
var pressure_buf := [0, 0] # past pressure value buffer
|
||
var mouse_velocity := 1.0
|
||
var mouse_velocity_min_thres := 0.2
|
||
var mouse_velocity_max_thres := 0.8
|
||
var mouse_velocity_max := 1000.0
|
||
var alpha_min := 0.1
|
||
var alpha_max := 1.0
|
||
var brush_size_min := 1
|
||
var brush_size_max := 4
|
||
|
||
var tools := {
|
||
"RectSelect":
|
||
Tool.new(
|
||
"RectSelect",
|
||
"Rectangular Selection",
|
||
"rectangle_select",
|
||
"res://src/Tools/SelectionTools/RectSelect.tscn"
|
||
),
|
||
"EllipseSelect":
|
||
Tool.new(
|
||
"EllipseSelect",
|
||
"Elliptical Selection",
|
||
"ellipse_select",
|
||
"res://src/Tools/SelectionTools/EllipseSelect.tscn"
|
||
),
|
||
"PolygonSelect":
|
||
Tool.new(
|
||
"PolygonSelect",
|
||
"Polygonal Selection",
|
||
"polygon_select",
|
||
"res://src/Tools/SelectionTools/PolygonSelect.tscn",
|
||
[],
|
||
"Double-click to connect the last point to the starting point"
|
||
),
|
||
"ColorSelect":
|
||
Tool.new(
|
||
"ColorSelect",
|
||
"Select By Color",
|
||
"color_select",
|
||
"res://src/Tools/SelectionTools/ColorSelect.tscn"
|
||
),
|
||
"MagicWand":
|
||
Tool.new(
|
||
"MagicWand", "Magic Wand", "magic_wand", "res://src/Tools/SelectionTools/MagicWand.tscn"
|
||
),
|
||
"Lasso":
|
||
Tool.new(
|
||
"Lasso", "Lasso / Free Select Tool", "lasso", "res://src/Tools/SelectionTools/Lasso.tscn"
|
||
),
|
||
"PaintSelect":
|
||
Tool.new(
|
||
"PaintSelect",
|
||
"Select by Drawing",
|
||
"paint_selection",
|
||
"res://src/Tools/SelectionTools/PaintSelect.tscn"
|
||
),
|
||
"Move":
|
||
Tool.new("Move", "Move", "move", "res://src/Tools/Move.tscn", [Global.LayerTypes.PIXEL]),
|
||
"Zoom": Tool.new("Zoom", "Zoom", "zoom", "res://src/Tools/Zoom.tscn"),
|
||
"Pan": Tool.new("Pan", "Pan", "pan", "res://src/Tools/Pan.tscn"),
|
||
"ColorPicker":
|
||
Tool.new(
|
||
"ColorPicker",
|
||
"Color Picker",
|
||
"colorpicker",
|
||
"res://src/Tools/ColorPicker.tscn",
|
||
[],
|
||
"Select a color from a pixel of the sprite"
|
||
),
|
||
"Crop":
|
||
Tool.new("Crop", "Crop", "crop", "res://src/Tools/CropTool.tscn", [], "Resize the canvas"),
|
||
"Pencil":
|
||
Tool.new(
|
||
"Pencil",
|
||
"Pencil",
|
||
"pencil",
|
||
"res://src/Tools/Pencil.tscn",
|
||
[Global.LayerTypes.PIXEL],
|
||
"Hold %s to make a line",
|
||
["draw_create_line"]
|
||
),
|
||
"Eraser":
|
||
Tool.new(
|
||
"Eraser",
|
||
"Eraser",
|
||
"eraser",
|
||
"res://src/Tools/Eraser.tscn",
|
||
[Global.LayerTypes.PIXEL],
|
||
"Hold %s to make a line",
|
||
["draw_create_line"]
|
||
),
|
||
"Bucket":
|
||
Tool.new("Bucket", "Bucket", "fill", "res://src/Tools/Bucket.tscn", [Global.LayerTypes.PIXEL]),
|
||
"Shading":
|
||
Tool.new(
|
||
"Shading",
|
||
"Shading Tool",
|
||
"shading",
|
||
"res://src/Tools/Shading.tscn",
|
||
[Global.LayerTypes.PIXEL]
|
||
),
|
||
"LineTool":
|
||
(
|
||
Tool
|
||
. new(
|
||
"LineTool",
|
||
"Line Tool",
|
||
"linetool",
|
||
"res://src/Tools/LineTool.tscn",
|
||
[Global.LayerTypes.PIXEL],
|
||
"""Hold %s to snap the angle of the line
|
||
Hold %s to center the shape on the click origin
|
||
Hold %s to displace the shape's origin""",
|
||
["shape_perfect", "shape_center", "shape_displace"]
|
||
)
|
||
),
|
||
"RectangleTool":
|
||
(
|
||
Tool
|
||
. new(
|
||
"RectangleTool",
|
||
"Rectangle Tool",
|
||
"rectangletool",
|
||
"res://src/Tools/RectangleTool.tscn",
|
||
[Global.LayerTypes.PIXEL],
|
||
"""Hold %s to create a 1:1 shape
|
||
Hold %s to center the shape on the click origin
|
||
Hold %s to displace the shape's origin""",
|
||
["shape_perfect", "shape_center", "shape_displace"]
|
||
)
|
||
),
|
||
"EllipseTool":
|
||
(
|
||
Tool
|
||
. new(
|
||
"EllipseTool",
|
||
"Ellipse Tool",
|
||
"ellipsetool",
|
||
"res://src/Tools/EllipseTool.tscn",
|
||
[Global.LayerTypes.PIXEL],
|
||
"""Hold %s to create a 1:1 shape
|
||
Hold %s to center the shape on the click origin
|
||
Hold %s to displace the shape's origin""",
|
||
["shape_perfect", "shape_center", "shape_displace"]
|
||
)
|
||
),
|
||
"3DShapeEdit":
|
||
Tool.new(
|
||
"3DShapeEdit",
|
||
"3D Shape Edit",
|
||
"3dshapeedit",
|
||
"res://src/Tools/3DShapeEdit.tscn",
|
||
[Global.LayerTypes.THREE_D]
|
||
),
|
||
}
|
||
|
||
var _tool_button_scene := preload("res://src/Tools/ToolButton.tscn")
|
||
var _slots := {}
|
||
var _panels := {}
|
||
var _curr_layer_type := Global.LayerTypes.PIXEL
|
||
var _left_tools_per_layer_type := {
|
||
Global.LayerTypes.PIXEL: "Pencil",
|
||
Global.LayerTypes.THREE_D: "3DShapeEdit",
|
||
}
|
||
var _right_tools_per_layer_type := {
|
||
Global.LayerTypes.PIXEL: "Eraser",
|
||
Global.LayerTypes.THREE_D: "Pan",
|
||
}
|
||
var _tool_buttons: Node
|
||
var _active_button := -1
|
||
var _last_position := Vector2i(Vector2.INF)
|
||
|
||
|
||
class Tool:
|
||
var name := ""
|
||
var display_name := ""
|
||
var scene_path: String
|
||
var scene: PackedScene
|
||
var icon: Texture2D
|
||
var cursor_icon: Texture2D
|
||
var shortcut := ""
|
||
var extra_hint := ""
|
||
var extra_shortcuts: PackedStringArray = []
|
||
var layer_types: PackedInt32Array = []
|
||
var button_node: BaseButton
|
||
|
||
func _init(
|
||
_name: String,
|
||
_display_name: String,
|
||
_shortcut: String,
|
||
_scene_path: String,
|
||
_layer_types: PackedInt32Array = [],
|
||
_extra_hint := "",
|
||
_extra_shortucts: PackedStringArray = []
|
||
) -> void:
|
||
name = _name
|
||
display_name = _display_name
|
||
shortcut = _shortcut
|
||
scene_path = _scene_path
|
||
layer_types = _layer_types
|
||
extra_hint = _extra_hint
|
||
extra_shortcuts = _extra_shortucts
|
||
icon = load("res://assets/graphics/tools/%s.png" % name.to_lower())
|
||
cursor_icon = load("res://assets/graphics/tools/cursors/%s.png" % name.to_lower())
|
||
|
||
func instantiate_scene() -> Node:
|
||
if not is_instance_valid(scene):
|
||
scene = load(scene_path)
|
||
return scene.instantiate()
|
||
|
||
func generate_hint_tooltip() -> String:
|
||
var hint := display_name
|
||
var shortcuts := []
|
||
var left_text := ""
|
||
var right_text := ""
|
||
if InputMap.has_action("left_" + shortcut + "_tool"):
|
||
var left_list := InputMap.action_get_events("left_" + shortcut + "_tool")
|
||
if left_list.size() > 0:
|
||
var left_shortcut: String = left_list[0].as_text()
|
||
shortcuts.append(left_shortcut)
|
||
left_text = "\n%s for left mouse button"
|
||
if InputMap.has_action("right_" + shortcut + "_tool"):
|
||
var right_list := InputMap.action_get_events("right_" + shortcut + "_tool")
|
||
if right_list.size() > 0:
|
||
var right_shortcut: String = right_list[0].as_text()
|
||
shortcuts.append(right_shortcut)
|
||
right_text = "\n%s for right mouse button"
|
||
|
||
if !shortcuts.is_empty():
|
||
hint += "\n" + left_text + right_text
|
||
|
||
if !extra_hint.is_empty():
|
||
hint += "\n\n" + extra_hint
|
||
|
||
var extra_shortcuts_mapped := []
|
||
for action in extra_shortcuts:
|
||
var key_string := "None"
|
||
var events := InputMap.action_get_events(action)
|
||
if events.size() > 0:
|
||
key_string = events[0].as_text()
|
||
extra_shortcuts_mapped.append(key_string)
|
||
|
||
shortcuts.append_array(extra_shortcuts_mapped)
|
||
|
||
if shortcuts.is_empty():
|
||
hint = tr(hint)
|
||
else:
|
||
hint = tr(hint) % shortcuts
|
||
return hint
|
||
|
||
|
||
class Slot:
|
||
var name: String
|
||
var kname: String
|
||
var tool_node: Node = null
|
||
var button: int
|
||
var color: Color
|
||
|
||
func _init(slot_name: String) -> void:
|
||
name = slot_name
|
||
kname = name.replace(" ", "_").to_lower()
|
||
|
||
|
||
func _ready() -> void:
|
||
Global.cel_changed.connect(_cel_changed)
|
||
_tool_buttons = Global.control.find_child("ToolButtons")
|
||
for t in tools:
|
||
add_tool_button(tools[t])
|
||
var tool_shortcut: String = tools[t].shortcut
|
||
var left_tool_shortcut := "left_%s_tool" % tool_shortcut
|
||
var right_tool_shortcut := "right_%s_tool" % tool_shortcut
|
||
Keychain.actions[left_tool_shortcut] = Keychain.InputAction.new("", "Left")
|
||
Keychain.actions[right_tool_shortcut] = Keychain.InputAction.new("", "Right")
|
||
|
||
_slots[MOUSE_BUTTON_LEFT] = Slot.new("Left tool")
|
||
_slots[MOUSE_BUTTON_RIGHT] = Slot.new("Right tool")
|
||
_panels[MOUSE_BUTTON_LEFT] = Global.control.find_child("LeftPanelContainer", true, false)
|
||
_panels[MOUSE_BUTTON_RIGHT] = Global.control.find_child("RightPanelContainer", true, false)
|
||
|
||
var default_left_tool: String = _left_tools_per_layer_type[0]
|
||
var default_right_tool: String = _right_tools_per_layer_type[0]
|
||
var tool_name: String = Global.config_cache.get_value(
|
||
_slots[MOUSE_BUTTON_LEFT].kname, "tool", default_left_tool
|
||
)
|
||
if not tool_name in tools or not _is_tool_available(Global.LayerTypes.PIXEL, tools[tool_name]):
|
||
tool_name = default_left_tool
|
||
set_tool(tool_name, MOUSE_BUTTON_LEFT)
|
||
tool_name = Global.config_cache.get_value(
|
||
_slots[MOUSE_BUTTON_RIGHT].kname, "tool", default_right_tool
|
||
)
|
||
if not tool_name in tools or not _is_tool_available(Global.LayerTypes.PIXEL, tools[tool_name]):
|
||
tool_name = default_right_tool
|
||
set_tool(tool_name, MOUSE_BUTTON_RIGHT)
|
||
update_tool_buttons()
|
||
|
||
horizontal_mirror = Global.config_cache.get_value("preferences", "horizontal_mirror", false)
|
||
vertical_mirror = Global.config_cache.get_value("preferences", "vertical_mirror", false)
|
||
pixel_perfect = Global.config_cache.get_value("preferences", "pixel_perfect", false)
|
||
|
||
# Yield is necessary for the color picker nodes to update their color values
|
||
await get_tree().process_frame
|
||
var color_value: Color = Global.config_cache.get_value(
|
||
_slots[MOUSE_BUTTON_LEFT].kname, "color", Color.BLACK
|
||
)
|
||
assign_color(color_value, MOUSE_BUTTON_LEFT, false)
|
||
color_value = Global.config_cache.get_value(
|
||
_slots[MOUSE_BUTTON_RIGHT].kname, "color", Color.WHITE
|
||
)
|
||
assign_color(color_value, MOUSE_BUTTON_RIGHT, false)
|
||
update_tool_cursors()
|
||
var layer: BaseLayer = Global.current_project.layers[Global.current_project.current_layer]
|
||
var layer_type := layer.get_layer_type()
|
||
_show_relevant_tools(layer_type)
|
||
|
||
|
||
func add_tool_button(t: Tool) -> void:
|
||
var tool_button: BaseButton = _tool_button_scene.instantiate()
|
||
tool_button.name = t.name
|
||
tool_button.get_node("BackgroundLeft").modulate = Global.left_tool_color
|
||
tool_button.get_node("BackgroundRight").modulate = Global.right_tool_color
|
||
tool_button.get_node("ToolIcon").texture = t.icon
|
||
tool_button.tooltip_text = t.generate_hint_tooltip()
|
||
t.button_node = tool_button
|
||
_tool_buttons.add_child(tool_button)
|
||
tool_button.pressed.connect(_tool_buttons._on_Tool_pressed.bind(tool_button))
|
||
|
||
|
||
func remove_tool(t: Tool) -> void:
|
||
t.button_node.queue_free()
|
||
tools.erase(t.name)
|
||
|
||
|
||
func set_tool(tool_name: String, button: int) -> void:
|
||
var slot: Slot = _slots[button]
|
||
var panel: Node = _panels[button]
|
||
var node: Node = tools[tool_name].instantiate_scene()
|
||
if button == MOUSE_BUTTON_LEFT: # As guides are only moved with left mouse
|
||
if tool_name == "Pan": # tool you want to give more access at guides
|
||
Global.move_guides_on_canvas = true
|
||
else:
|
||
Global.move_guides_on_canvas = false
|
||
node.name = tool_name
|
||
node.tool_slot = slot
|
||
slot.tool_node = node
|
||
slot.button = button
|
||
panel.add_child(slot.tool_node)
|
||
|
||
if _curr_layer_type == Global.LayerTypes.GROUP:
|
||
return
|
||
if button == MOUSE_BUTTON_LEFT:
|
||
_left_tools_per_layer_type[_curr_layer_type] = tool_name
|
||
elif button == MOUSE_BUTTON_RIGHT:
|
||
_right_tools_per_layer_type[_curr_layer_type] = tool_name
|
||
|
||
|
||
func assign_tool(tool_name: String, button: int) -> void:
|
||
var slot: Slot = _slots[button]
|
||
var panel: Node = _panels[button]
|
||
|
||
if slot.tool_node != null:
|
||
if slot.tool_node.name == tool_name:
|
||
return
|
||
panel.remove_child(slot.tool_node)
|
||
slot.tool_node.queue_free()
|
||
|
||
set_tool(tool_name, button)
|
||
update_tool_buttons()
|
||
update_tool_cursors()
|
||
Global.config_cache.set_value(slot.kname, "tool", tool_name)
|
||
|
||
|
||
func default_color() -> void:
|
||
assign_color(Color.BLACK, MOUSE_BUTTON_LEFT)
|
||
assign_color(Color.WHITE, MOUSE_BUTTON_RIGHT)
|
||
|
||
|
||
func swap_color() -> void:
|
||
var left = _slots[MOUSE_BUTTON_LEFT].color
|
||
var right = _slots[MOUSE_BUTTON_RIGHT].color
|
||
assign_color(right, MOUSE_BUTTON_LEFT, false)
|
||
assign_color(left, MOUSE_BUTTON_RIGHT, false)
|
||
|
||
|
||
func assign_color(color: Color, button: int, change_alpha := true) -> void:
|
||
var c: Color = _slots[button].color
|
||
# This was requested by Issue #54 on GitHub
|
||
if color.a == 0 and change_alpha:
|
||
if color.r != c.r or color.g != c.g or color.b != c.b:
|
||
color.a = 1
|
||
_slots[button].color = color
|
||
Global.config_cache.set_value(_slots[button].kname, "color", color)
|
||
color_changed.emit(color, button)
|
||
# If current palette has that color then select that color
|
||
Global.palette_panel.palette_grid.find_and_select_color(button, color)
|
||
|
||
|
||
func get_assigned_color(button: int) -> Color:
|
||
return _slots[button].color
|
||
|
||
|
||
func set_button_size(button_size: int) -> void:
|
||
var size := Vector2(24, 24) if button_size == Global.ButtonSize.SMALL else Vector2(32, 32)
|
||
for t in _tool_buttons.get_children():
|
||
t.custom_minimum_size = size
|
||
|
||
|
||
func update_tool_buttons() -> void:
|
||
for child in _tool_buttons.get_children():
|
||
var left_background: NinePatchRect = child.get_node("BackgroundLeft")
|
||
var right_background: NinePatchRect = child.get_node("BackgroundRight")
|
||
left_background.visible = _slots[MOUSE_BUTTON_LEFT].tool_node.name == child.name
|
||
right_background.visible = _slots[MOUSE_BUTTON_RIGHT].tool_node.name == child.name
|
||
|
||
|
||
func update_hint_tooltips() -> void:
|
||
await get_tree().process_frame
|
||
for tool_name in tools:
|
||
var t: Tool = tools[tool_name]
|
||
t.button_node.tooltip_text = t.generate_hint_tooltip()
|
||
|
||
|
||
func update_tool_cursors() -> void:
|
||
var left_tool: Tool = tools[_slots[MOUSE_BUTTON_LEFT].tool_node.name]
|
||
Global.control.left_cursor.texture = left_tool.cursor_icon
|
||
var right_tool: Tool = tools[_slots[MOUSE_BUTTON_RIGHT].tool_node.name]
|
||
Global.control.right_cursor.texture = right_tool.cursor_icon
|
||
|
||
|
||
func draw_indicator() -> void:
|
||
if Global.right_square_indicator_visible:
|
||
_slots[MOUSE_BUTTON_RIGHT].tool_node.draw_indicator(false)
|
||
if Global.left_square_indicator_visible:
|
||
_slots[MOUSE_BUTTON_LEFT].tool_node.draw_indicator(true)
|
||
|
||
|
||
func draw_preview() -> void:
|
||
_slots[MOUSE_BUTTON_LEFT].tool_node.draw_preview()
|
||
_slots[MOUSE_BUTTON_RIGHT].tool_node.draw_preview()
|
||
|
||
|
||
func handle_draw(position: Vector2i, event: InputEvent) -> void:
|
||
if not Global.can_draw:
|
||
return
|
||
|
||
var draw_pos := position
|
||
if Global.mirror_view:
|
||
draw_pos.x = Global.current_project.size.x - position.x - 1
|
||
|
||
if event.is_action_pressed("activate_left_tool") and _active_button == -1:
|
||
_active_button = MOUSE_BUTTON_LEFT
|
||
_slots[_active_button].tool_node.draw_start(draw_pos)
|
||
elif event.is_action_released("activate_left_tool") and _active_button == MOUSE_BUTTON_LEFT:
|
||
_slots[_active_button].tool_node.draw_end(draw_pos)
|
||
_active_button = -1
|
||
elif event.is_action_pressed("activate_right_tool") and _active_button == -1:
|
||
_active_button = MOUSE_BUTTON_RIGHT
|
||
_slots[_active_button].tool_node.draw_start(draw_pos)
|
||
elif event.is_action_released("activate_right_tool") and _active_button == MOUSE_BUTTON_RIGHT:
|
||
_slots[_active_button].tool_node.draw_end(draw_pos)
|
||
_active_button = -1
|
||
|
||
if event is InputEventMouseMotion:
|
||
pen_pressure = event.pressure
|
||
# Workaround https://github.com/godotengine/godot/issues/53033#issuecomment-930409407
|
||
# If a pressure value of 1 is encountered, "correct" the value by
|
||
# extrapolating from the delta of the past two values. This will
|
||
# correct the jumping to 1 error while also allowing values that
|
||
# are "supposed" to be 1.
|
||
if pen_pressure == 1 && pressure_buf[0] != 0:
|
||
pen_pressure = minf(1, pressure_buf[0] + pressure_buf[0] - pressure_buf[1])
|
||
pressure_buf.pop_back()
|
||
pressure_buf.push_front(pen_pressure)
|
||
pen_pressure = remap(pen_pressure, pen_pressure_min, pen_pressure_max, 0.0, 1.0)
|
||
pen_pressure = clampf(pen_pressure, 0.0, 1.0)
|
||
|
||
mouse_velocity = event.velocity.length() / mouse_velocity_max
|
||
mouse_velocity = remap(
|
||
mouse_velocity, mouse_velocity_min_thres, mouse_velocity_max_thres, 0.0, 1.0
|
||
)
|
||
mouse_velocity = clampf(mouse_velocity, 0.0, 1.0)
|
||
if dynamics_alpha != Dynamics.PRESSURE and dynamics_size != Dynamics.PRESSURE:
|
||
pen_pressure = 1.0
|
||
if dynamics_alpha != Dynamics.VELOCITY and dynamics_size != Dynamics.VELOCITY:
|
||
mouse_velocity = 1.0
|
||
if not position == _last_position:
|
||
_last_position = position
|
||
_slots[MOUSE_BUTTON_LEFT].tool_node.cursor_move(position)
|
||
_slots[MOUSE_BUTTON_RIGHT].tool_node.cursor_move(position)
|
||
if _active_button != -1:
|
||
_slots[_active_button].tool_node.draw_move(draw_pos)
|
||
|
||
var project := Global.current_project
|
||
var text := "[%s×%s]" % [project.size.x, project.size.y]
|
||
if Global.has_focus:
|
||
text += " %s, %s" % [position.x, position.y]
|
||
if not _slots[MOUSE_BUTTON_LEFT].tool_node.cursor_text.is_empty():
|
||
text += " %s" % _slots[MOUSE_BUTTON_LEFT].tool_node.cursor_text
|
||
if not _slots[MOUSE_BUTTON_RIGHT].tool_node.cursor_text.is_empty():
|
||
text += " %s" % _slots[MOUSE_BUTTON_RIGHT].tool_node.cursor_text
|
||
Global.cursor_position_label.text = text
|
||
|
||
|
||
func get_alpha_dynamic(strength := 1.0) -> float:
|
||
if dynamics_alpha == Dynamics.PRESSURE:
|
||
strength *= lerpf(alpha_min, alpha_max, pen_pressure)
|
||
elif dynamics_alpha == Dynamics.VELOCITY:
|
||
strength *= lerpf(alpha_min, alpha_max, mouse_velocity)
|
||
return strength
|
||
|
||
|
||
func _cel_changed() -> void:
|
||
var layer: BaseLayer = Global.current_project.layers[Global.current_project.current_layer]
|
||
var layer_type := layer.get_layer_type()
|
||
# Do not make any changes when its the same type of layer, or a group layer
|
||
if layer_type == _curr_layer_type or layer_type == Global.LayerTypes.GROUP:
|
||
return
|
||
_show_relevant_tools(layer_type)
|
||
|
||
|
||
func _show_relevant_tools(layer_type: Global.LayerTypes) -> void:
|
||
# Hide tools that are not available in the current layer type
|
||
for button in _tool_buttons.get_children():
|
||
var tool_name: String = button.name
|
||
var t: Tool = tools[tool_name]
|
||
var hide_tool := _is_tool_available(layer_type, t)
|
||
button.visible = hide_tool
|
||
|
||
# Assign new tools if the layer type has changed
|
||
_curr_layer_type = layer_type
|
||
var new_tool_name: String = _left_tools_per_layer_type[layer_type]
|
||
assign_tool(new_tool_name, MOUSE_BUTTON_LEFT)
|
||
|
||
new_tool_name = _right_tools_per_layer_type[layer_type]
|
||
assign_tool(new_tool_name, MOUSE_BUTTON_RIGHT)
|
||
|
||
|
||
func _is_tool_available(layer_type: int, t: Tool) -> bool:
|
||
return t.layer_types.is_empty() or layer_type in t.layer_types
|