1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-08 11:29:47 +00:00
Pixelorama/src/UI/Timeline/LayerButton.gd

231 lines
7.8 KiB
GDScript

class_name LayerButton
extends HBoxContainer
const HIERARCHY_DEPTH_PIXEL_SHIFT := 16
var layer_index := 0:
set(value):
layer_index = value
if is_instance_valid(main_button):
main_button.layer_index = value
var button_pressed := false:
set(value):
button_pressed = value
main_button.button_pressed = value
get:
return main_button.button_pressed
@onready var properties: AcceptDialog = Global.control.find_child("LayerProperties")
@onready var main_button := %LayerMainButton as Button
@onready var expand_button := %ExpandButton as BaseButton
@onready var visibility_button := %VisibilityButton as BaseButton
@onready var lock_button := %LockButton as BaseButton
@onready var label := %LayerNameLabel as Label
@onready var line_edit := %LayerNameLineEdit as LineEdit
@onready var hierarchy_spacer := %HierarchySpacer as Control
@onready var linked_button := %LinkButton as BaseButton
@onready var clipping_mask_icon := %ClippingMask as TextureRect
@onready var popup_menu := $PopupMenu as PopupMenu
func _ready() -> void:
main_button.layer_index = layer_index
main_button.hierarchy_depth_pixel_shift = HIERARCHY_DEPTH_PIXEL_SHIFT
Global.cel_switched.connect(func(): z_index = 1 if button_pressed else 0)
var layer := Global.current_project.layers[layer_index]
layer.name_changed.connect(func(): label.text = layer.name)
layer.visibility_changed.connect(update_buttons)
if layer is PixelLayer:
linked_button.visible = true
elif layer is GroupLayer:
expand_button.visible = true
custom_minimum_size.y = Global.animation_timeline.cel_size
label.text = layer.name
line_edit.text = layer.name
for child in get_children():
if not child is Button:
continue
var texture := child.get_child(0)
if not texture is TextureRect:
continue
texture.modulate = Global.modulate_icon_color
# Visualize how deep into the hierarchy the layer is
var hierarchy_depth := layer.get_hierarchy_depth()
hierarchy_spacer.custom_minimum_size.x = hierarchy_depth * HIERARCHY_DEPTH_PIXEL_SHIFT
update_buttons()
func update_buttons() -> void:
var layer := Global.current_project.layers[layer_index]
if layer is GroupLayer:
if layer.expanded:
Global.change_button_texturerect(expand_button.get_child(0), "group_expanded.png")
else:
Global.change_button_texturerect(expand_button.get_child(0), "group_collapsed.png")
if layer.visible:
Global.change_button_texturerect(visibility_button.get_child(0), "layer_visible.png")
else:
Global.change_button_texturerect(visibility_button.get_child(0), "layer_invisible.png")
if layer.locked:
Global.change_button_texturerect(lock_button.get_child(0), "lock.png")
else:
Global.change_button_texturerect(lock_button.get_child(0), "unlock.png")
if linked_button:
if layer.new_cels_linked: # If new layers will be linked
Global.change_button_texturerect(linked_button.get_child(0), "linked_layer.png")
else:
Global.change_button_texturerect(linked_button.get_child(0), "unlinked_layer.png")
visibility_button.modulate.a = 1
lock_button.modulate.a = 1
popup_menu.set_item_checked(0, layer.clipping_mask)
clipping_mask_icon.visible = layer.clipping_mask
if is_instance_valid(layer.parent):
if not layer.parent.is_visible_in_hierarchy():
visibility_button.modulate.a = 0.33
if layer.parent.is_locked_in_hierarchy():
lock_button.modulate.a = 0.33
## When pressing a button, change the appearance of other layers (ie: expand or visible)
func _update_buttons_all_layers() -> void:
for layer_button: LayerButton in get_parent().get_children():
layer_button.update_buttons()
var layer := Global.current_project.layers[layer_button.layer_index]
var expanded := layer.is_expanded_in_hierarchy()
layer_button.visible = expanded
Global.cel_vbox.get_child(layer_button.get_index()).visible = expanded
func _input(event: InputEvent) -> void:
if (
(event.is_action_released(&"ui_accept") or event.is_action_released(&"ui_cancel"))
and line_edit.visible
and event.keycode != KEY_SPACE
):
_save_layer_name(line_edit.text)
func _on_main_button_gui_input(event: InputEvent) -> void:
var project := Global.current_project
if not event is InputEventMouseButton:
return
if event.button_index == MOUSE_BUTTON_LEFT:
Global.canvas.selection.transform_content_confirm()
var prev_curr_layer := project.current_layer
if Input.is_action_pressed(&"shift"):
var layer_diff_sign := signi(layer_index - prev_curr_layer)
if layer_diff_sign == 0:
layer_diff_sign = 1
for i in range(0, project.frames.size()):
for j in range(prev_curr_layer, layer_index + layer_diff_sign, layer_diff_sign):
var frame_layer := [i, j]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
project.change_cel(-1, layer_index)
elif Input.is_action_pressed(&"ctrl"):
for i in range(0, project.frames.size()):
var frame_layer := [i, layer_index]
if !project.selected_cels.has(frame_layer):
project.selected_cels.append(frame_layer)
project.change_cel(-1, layer_index)
else: # If the button is pressed without Shift or Control
_select_current_layer()
if event.double_click:
label.visible = false
line_edit.visible = true
line_edit.editable = true
line_edit.grab_focus()
elif event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
var layer := Global.current_project.layers[layer_index]
if not layer is GroupLayer:
popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ONE))
func _on_layer_name_line_edit_focus_exited() -> void:
_save_layer_name(line_edit.text)
func _save_layer_name(new_name: String) -> void:
label.visible = true
line_edit.visible = false
line_edit.editable = false
if layer_index < Global.current_project.layers.size():
Global.current_project.layers[layer_index].name = new_name
func _on_expand_button_pressed() -> void:
var layer := Global.current_project.layers[layer_index]
layer.expanded = !layer.expanded
_update_buttons_all_layers()
func _on_visibility_button_pressed() -> void:
Global.canvas.selection.transform_content_confirm()
var layer := Global.current_project.layers[layer_index]
layer.visible = !layer.visible
Global.canvas.update_all_layers = true
Global.canvas.queue_redraw()
if Global.select_layer_on_button_click:
_select_current_layer()
_update_buttons_all_layers()
func _on_lock_button_pressed() -> void:
Global.canvas.selection.transform_content_confirm()
var layer := Global.current_project.layers[layer_index]
layer.locked = !layer.locked
if Global.select_layer_on_button_click:
_select_current_layer()
_update_buttons_all_layers()
func _on_link_button_pressed() -> void:
Global.canvas.selection.transform_content_confirm()
var layer := Global.current_project.layers[layer_index]
if not layer is PixelLayer:
return
layer.new_cels_linked = !layer.new_cels_linked
update_buttons()
if Global.select_layer_on_button_click:
_select_current_layer()
func _select_current_layer() -> void:
Global.current_project.selected_cels.clear()
var frame_layer := [Global.current_project.current_frame, layer_index]
if !Global.current_project.selected_cels.has(frame_layer):
Global.current_project.selected_cels.append(frame_layer)
Global.current_project.change_cel(-1, layer_index)
func _on_popup_menu_id_pressed(id: int) -> void:
var layer := Global.current_project.layers[layer_index]
if id == 0:
properties.layer_indices = _get_layer_indices()
properties.popup_centered()
if id == 1:
layer.clipping_mask = not layer.clipping_mask
popup_menu.set_item_checked(0, layer.clipping_mask)
clipping_mask_icon.visible = layer.clipping_mask
Global.canvas.draw_layers()
func _get_layer_indices() -> Array:
var indices := []
for cel in Global.current_project.selected_cels:
var l: int = cel[1]
if not l in indices:
indices.append(l)
indices.sort()
if not layer_index in indices:
indices = [layer_index]
return indices