2019-08-18 09:28:38 +00:00
|
|
|
extends Node
|
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
|
2020-03-12 02:17:48 +00:00
|
|
|
enum Grid_Types {CARTESIAN, ISOMETRIC, ALL}
|
2020-02-14 16:26:03 +00:00
|
|
|
enum Pressure_Sensitivity {NONE, ALPHA, SIZE, ALPHA_AND_SIZE}
|
2020-02-10 22:06:24 +00:00
|
|
|
enum Brush_Types {PIXEL, CIRCLE, FILLED_CIRCLE, FILE, RANDOM_FILE, CUSTOM}
|
2020-05-31 13:04:33 +00:00
|
|
|
enum Direction {UP, DOWN, LEFT, RIGHT}
|
2020-05-31 15:03:44 +00:00
|
|
|
enum Mouse_Button {LEFT, RIGHT}
|
2020-05-31 13:04:33 +00:00
|
|
|
enum Tools {PENCIL, ERASER, BUCKET, LIGHTENDARKEN, RECTSELECT, COLORPICKER, ZOOM}
|
2020-06-01 00:36:07 +00:00
|
|
|
enum Theme_Types {DARK, BLUE, CARAMEL, LIGHT}
|
2020-05-31 21:44:53 +00:00
|
|
|
enum Fill_Area {SAME_COLOR_AREA, SAME_COLOR_PIXELS}
|
|
|
|
enum Fill_With {COLOR, PATTERN}
|
|
|
|
enum Lighten_Darken_Mode {LIGHTEN, DARKEN}
|
|
|
|
enum Zoom_Mode {ZOOM_IN, ZOOM_OUT}
|
2020-04-10 21:47:06 +00:00
|
|
|
|
2020-04-13 07:55:01 +00:00
|
|
|
# Stuff for arrowkey-based canvas movements nyaa ^.^
|
|
|
|
const low_speed_move_rate := 150.0
|
|
|
|
const medium_speed_move_rate := 750.0
|
|
|
|
const high_speed_move_rate := 3750.0
|
|
|
|
|
2020-05-31 13:04:33 +00:00
|
|
|
var root_directory := "."
|
|
|
|
var window_title := "" setget title_changed # Why doesn't Godot have get_window_title()?
|
|
|
|
var config_cache := ConfigFile.new()
|
|
|
|
var XDGDataPaths = preload("res://src/XDGDataPaths.gd")
|
|
|
|
var directory_module : Reference
|
2020-04-13 07:55:01 +00:00
|
|
|
|
|
|
|
# Indices are as in the Direction enum
|
2020-04-13 13:39:18 +00:00
|
|
|
# This is the total time the key for
|
2020-04-13 07:55:01 +00:00
|
|
|
# that direction has been pressed.
|
|
|
|
var key_move_press_time := [0.0, 0.0, 0.0, 0.0]
|
|
|
|
|
2019-12-18 16:12:44 +00:00
|
|
|
var loaded_locales : Array
|
2019-10-29 21:22:38 +00:00
|
|
|
var undo_redo : UndoRedo
|
2020-02-22 15:14:32 +00:00
|
|
|
var undos := 0 # The number of times we added undo properties
|
2020-05-01 16:40:36 +00:00
|
|
|
var project_has_changed := false # Checks if the user has made changes to the project
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# Canvas related stuff
|
2020-03-03 00:50:39 +00:00
|
|
|
var canvases := [] setget canvases_changed
|
2020-02-28 01:27:22 +00:00
|
|
|
var layers := [] setget layers_changed
|
2020-04-06 15:35:54 +00:00
|
|
|
var layers_changed_skip := false
|
2019-11-10 01:25:25 +00:00
|
|
|
var current_frame := 0 setget frame_changed
|
2020-02-29 22:57:47 +00:00
|
|
|
var current_layer := 0 setget layer_changed
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2019-08-18 09:28:38 +00:00
|
|
|
var can_draw := false
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2019-10-03 16:37:31 +00:00
|
|
|
var has_focus := false
|
2020-02-14 16:26:03 +00:00
|
|
|
var pressure_sensitivity_mode = Pressure_Sensitivity.NONE
|
2020-05-11 13:15:59 +00:00
|
|
|
var open_last_project := false
|
2020-02-07 01:27:11 +00:00
|
|
|
var smooth_zoom := true
|
2020-05-05 00:53:58 +00:00
|
|
|
var cursor_image = preload("res://assets/graphics/cursor_icons/cursor.png")
|
2019-12-10 17:56:16 +00:00
|
|
|
var left_cursor_tool_texture : ImageTexture
|
|
|
|
var right_cursor_tool_texture : ImageTexture
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2019-12-05 23:48:29 +00:00
|
|
|
var selected_pixels := []
|
|
|
|
var image_clipboard : Image
|
2020-04-02 00:29:14 +00:00
|
|
|
var animation_tags := [] setget animation_tags_changed # [Name, Color, From, To]
|
2020-04-11 17:10:07 +00:00
|
|
|
var play_only_tags := true
|
2020-02-11 22:38:35 +00:00
|
|
|
|
2020-06-01 00:36:07 +00:00
|
|
|
var theme_type : int = Theme_Types.DARK
|
2020-01-10 19:32:31 +00:00
|
|
|
var is_default_image := true
|
2020-01-10 22:29:29 +00:00
|
|
|
var default_image_width := 64
|
|
|
|
var default_image_height := 64
|
2020-01-10 19:24:07 +00:00
|
|
|
var default_fill_color := Color(0, 0, 0, 0)
|
2020-03-12 02:17:48 +00:00
|
|
|
var grid_type = Grid_Types.CARTESIAN
|
2019-12-07 17:34:54 +00:00
|
|
|
var grid_width := 1
|
|
|
|
var grid_height := 1
|
|
|
|
var grid_color := Color.black
|
2019-12-27 00:28:36 +00:00
|
|
|
var guide_color := Color.purple
|
2020-04-18 07:03:18 +00:00
|
|
|
var checker_size := 10
|
2020-05-03 00:42:44 +00:00
|
|
|
var checker_color_1 := Color(0.47, 0.47, 0.47, 1)
|
|
|
|
var checker_color_2 := Color(0.34, 0.35, 0.34, 1)
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-05-31 20:04:59 +00:00
|
|
|
var autosave_interval := 5.0
|
|
|
|
var enable_autosave := true
|
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# Tools & options
|
2020-05-31 21:44:53 +00:00
|
|
|
var current_tools := [Tools.PENCIL, Tools.ERASER]
|
2020-01-13 11:26:06 +00:00
|
|
|
var show_left_tool_icon := true
|
|
|
|
var show_right_tool_icon := true
|
2019-12-05 23:48:29 +00:00
|
|
|
var left_square_indicator_visible := true
|
|
|
|
var right_square_indicator_visible := false
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2020-05-31 21:44:53 +00:00
|
|
|
var fill_areas := [Fill_Area.SAME_COLOR_AREA, Fill_Area.SAME_COLOR_AREA]
|
|
|
|
var fill_with := [Fill_With.COLOR, Fill_With.COLOR]
|
|
|
|
var fill_pattern_offsets := [Vector2.ZERO, Vector2.ZERO]
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-05-31 21:44:53 +00:00
|
|
|
var ld_modes := [Lighten_Darken_Mode.LIGHTEN, Lighten_Darken_Mode.LIGHTEN]
|
|
|
|
var ld_amounts := [0.1, 0.1]
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2020-05-31 21:44:53 +00:00
|
|
|
var color_picker_for := [Mouse_Button.LEFT, Mouse_Button.RIGHT]
|
2020-04-24 23:09:34 +00:00
|
|
|
|
2020-05-31 21:44:53 +00:00
|
|
|
var zoom_modes := [Zoom_Mode.ZOOM_IN, Zoom_Mode.ZOOM_OUT]
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-05-31 21:44:53 +00:00
|
|
|
var horizontal_mirror := [false, false]
|
|
|
|
var vertical_mirror := [false, false]
|
|
|
|
var pixel_perfect := [false, false]
|
2020-04-27 15:09:54 +00:00
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# View menu options
|
2019-09-18 14:47:28 +00:00
|
|
|
var tile_mode := false
|
2019-09-09 22:57:46 +00:00
|
|
|
var draw_grid := false
|
2019-12-03 00:30:38 +00:00
|
|
|
var show_rulers := true
|
|
|
|
var show_guides := true
|
2020-02-15 01:30:40 +00:00
|
|
|
var show_animation_timeline := true
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# Onion skinning options
|
2020-03-26 18:56:30 +00:00
|
|
|
var onion_skinning := false
|
2020-05-01 17:47:10 +00:00
|
|
|
var onion_skinning_past_rate := 1.0
|
|
|
|
var onion_skinning_future_rate := 1.0
|
2019-12-05 23:48:29 +00:00
|
|
|
var onion_skinning_blue_red := false
|
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# Brushes
|
2020-05-31 21:44:53 +00:00
|
|
|
var brush_sizes := [1, 1]
|
|
|
|
var current_brush_types := [Brush_Types.PIXEL, Brush_Types.PIXEL]
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2020-05-31 15:40:47 +00:00
|
|
|
var brush_type_window_position : int = Mouse_Button.LEFT
|
2019-12-25 18:27:25 +00:00
|
|
|
var left_circle_points := []
|
|
|
|
var right_circle_points := []
|
2019-12-05 23:48:29 +00:00
|
|
|
|
|
|
|
var brushes_from_files := 0
|
|
|
|
var custom_brushes := []
|
2020-05-31 21:44:53 +00:00
|
|
|
var custom_brush_indexes := [-1, -1]
|
|
|
|
var custom_brush_images := [Image.new(), Image.new()]
|
|
|
|
var custom_brush_textures := [ImageTexture.new(), ImageTexture.new()]
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-04-24 21:42:02 +00:00
|
|
|
# Patterns
|
|
|
|
var patterns := []
|
2020-05-31 15:40:47 +00:00
|
|
|
var pattern_window_position : int = Mouse_Button.LEFT
|
2020-05-31 21:44:53 +00:00
|
|
|
var pattern_images := [Image.new(), Image.new()]
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# Palettes
|
2019-12-15 03:11:32 +00:00
|
|
|
var palettes := {}
|
|
|
|
|
2019-12-25 19:42:01 +00:00
|
|
|
# Nodes
|
2019-11-13 13:45:55 +00:00
|
|
|
var control : Node
|
2019-12-18 23:18:57 +00:00
|
|
|
var top_menu_container : Panel
|
2019-12-10 17:56:16 +00:00
|
|
|
var left_cursor : Sprite
|
|
|
|
var right_cursor : Sprite
|
2019-08-18 09:28:38 +00:00
|
|
|
var canvas : Canvas
|
2019-09-09 22:57:46 +00:00
|
|
|
var canvas_parent : Node
|
2019-11-19 21:23:43 +00:00
|
|
|
var main_viewport : ViewportContainer
|
2019-09-25 19:59:48 +00:00
|
|
|
var second_viewport : ViewportContainer
|
2019-09-09 22:57:46 +00:00
|
|
|
var camera : Camera2D
|
2019-09-25 19:59:48 +00:00
|
|
|
var camera2 : Camera2D
|
2019-12-05 14:49:27 +00:00
|
|
|
var camera_preview : Camera2D
|
2019-09-18 14:47:28 +00:00
|
|
|
var selection_rectangle : Polygon2D
|
2019-12-03 00:30:38 +00:00
|
|
|
var horizontal_ruler : BaseButton
|
2019-11-20 22:11:21 +00:00
|
|
|
var vertical_ruler : BaseButton
|
2020-04-20 16:12:22 +00:00
|
|
|
var transparent_checker : ColorRect
|
2019-09-14 19:55:33 +00:00
|
|
|
|
2019-08-18 09:28:38 +00:00
|
|
|
var file_menu : MenuButton
|
|
|
|
var edit_menu : MenuButton
|
2019-09-18 21:10:23 +00:00
|
|
|
var view_menu : MenuButton
|
2019-12-24 14:48:07 +00:00
|
|
|
var image_menu : MenuButton
|
2019-09-25 19:59:48 +00:00
|
|
|
var help_menu : MenuButton
|
2019-12-05 23:48:29 +00:00
|
|
|
var cursor_position_label : Label
|
|
|
|
var zoom_level_label : Label
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2019-12-28 16:35:53 +00:00
|
|
|
var import_sprites_dialog : FileDialog
|
2020-05-03 15:47:13 +00:00
|
|
|
var export_dialog : AcceptDialog
|
2020-05-28 00:41:28 +00:00
|
|
|
var preferences_dialog : AcceptDialog
|
2019-12-28 16:35:53 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var color_pickers := []
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-04-25 19:24:20 +00:00
|
|
|
var color_switch_button : BaseButton
|
2020-04-15 18:52:20 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var tool_options_containers := []
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var brush_type_containers := []
|
|
|
|
var brush_type_buttons := []
|
2019-12-05 23:48:29 +00:00
|
|
|
var brushes_popup : Popup
|
|
|
|
var file_brush_container : GridContainer
|
|
|
|
var project_brush_container : GridContainer
|
2020-04-24 21:42:02 +00:00
|
|
|
var patterns_popup : Popup
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var brush_size_edits := []
|
|
|
|
var brush_size_sliders := []
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var pixel_perfect_containers := []
|
2020-04-27 15:09:54 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var color_interpolation_containers := []
|
|
|
|
var interpolate_spinboxes := []
|
|
|
|
var interpolate_sliders := []
|
2019-09-25 19:59:48 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var fill_area_containers := []
|
|
|
|
var fill_pattern_containers := []
|
2019-12-03 22:14:14 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var ld_containers := []
|
|
|
|
var ld_amount_sliders := []
|
|
|
|
var ld_amount_spinboxes := []
|
2019-12-03 23:01:37 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var colorpicker_containers := []
|
2020-01-10 20:44:29 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var zoom_containers := []
|
2020-04-13 02:07:52 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
var mirror_containers := []
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-01-15 20:01:43 +00:00
|
|
|
var animation_timeline : Panel
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-01-15 20:01:43 +00:00
|
|
|
var animation_timer : Timer
|
2020-01-18 19:06:47 +00:00
|
|
|
var frame_ids : HBoxContainer
|
2020-05-23 21:22:06 +00:00
|
|
|
var current_frame_mark_label : Label
|
2020-04-03 12:34:16 +00:00
|
|
|
var onion_skinning_button : BaseButton
|
2019-11-19 21:23:43 +00:00
|
|
|
var loop_animation_button : BaseButton
|
|
|
|
var play_forward : BaseButton
|
|
|
|
var play_backwards : BaseButton
|
2020-01-18 22:56:30 +00:00
|
|
|
var layers_container : VBoxContainer
|
|
|
|
var frames_container : VBoxContainer
|
2020-04-02 00:29:14 +00:00
|
|
|
var tag_container : Control
|
2020-04-05 22:07:28 +00:00
|
|
|
var tag_dialog : AcceptDialog
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-05-03 15:17:12 +00:00
|
|
|
var remove_frame_button : BaseButton
|
|
|
|
|
2019-11-19 21:23:43 +00:00
|
|
|
var remove_layer_button : BaseButton
|
|
|
|
var move_up_layer_button : BaseButton
|
|
|
|
var move_down_layer_button : BaseButton
|
|
|
|
var merge_down_layer_button : BaseButton
|
2019-12-24 21:51:08 +00:00
|
|
|
var layer_opacity_slider : HSlider
|
2019-12-24 22:23:45 +00:00
|
|
|
var layer_opacity_spinbox : SpinBox
|
2019-09-25 19:59:48 +00:00
|
|
|
|
2020-04-25 19:24:20 +00:00
|
|
|
var add_palette_button : BaseButton
|
2019-12-15 03:11:32 +00:00
|
|
|
var edit_palette_button : BaseButton
|
2019-12-30 18:29:46 +00:00
|
|
|
var palette_option_button : OptionButton
|
2019-12-15 03:11:32 +00:00
|
|
|
var palette_container : GridContainer
|
2019-12-17 01:23:18 +00:00
|
|
|
var edit_palette_popup : WindowDialog
|
|
|
|
var new_palette_dialog : ConfirmationDialog
|
|
|
|
var new_palette_name_line_edit : LineEdit
|
2019-12-18 14:43:11 +00:00
|
|
|
var palette_import_file_dialog : FileDialog
|
2019-12-17 01:23:18 +00:00
|
|
|
|
|
|
|
var error_dialog : AcceptDialog
|
2019-12-15 03:11:32 +00:00
|
|
|
|
2020-05-03 21:04:00 +00:00
|
|
|
onready var current_version : String = ProjectSettings.get_setting("application/config/Version")
|
|
|
|
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2019-08-18 09:28:38 +00:00
|
|
|
func _ready() -> void:
|
2019-12-26 19:36:56 +00:00
|
|
|
randomize()
|
2020-02-09 23:23:33 +00:00
|
|
|
if OS.has_feature("standalone"):
|
|
|
|
root_directory = OS.get_executable_path().get_base_dir()
|
2019-12-20 14:36:23 +00:00
|
|
|
# Load settings from the config file
|
|
|
|
config_cache.load("user://cache.ini")
|
2020-04-12 22:40:26 +00:00
|
|
|
|
2020-04-11 06:58:58 +00:00
|
|
|
# The fact that root_dir is set earlier than this is important
|
|
|
|
# XDGDataDirs depends on it nyaa
|
|
|
|
directory_module = XDGDataPaths.new()
|
2019-12-20 14:36:23 +00:00
|
|
|
|
2019-10-29 21:22:38 +00:00
|
|
|
undo_redo = UndoRedo.new()
|
2019-12-05 23:48:29 +00:00
|
|
|
image_clipboard = Image.new()
|
2020-04-12 22:40:26 +00:00
|
|
|
|
2019-08-18 09:28:38 +00:00
|
|
|
var root = get_tree().get_root()
|
2019-11-13 13:45:55 +00:00
|
|
|
control = find_node_by_name(root, "Control")
|
2019-12-18 23:18:57 +00:00
|
|
|
top_menu_container = find_node_by_name(control, "TopMenuContainer")
|
2019-12-10 17:56:16 +00:00
|
|
|
left_cursor = find_node_by_name(root, "LeftCursor")
|
|
|
|
right_cursor = find_node_by_name(root, "RightCursor")
|
2019-08-18 09:28:38 +00:00
|
|
|
canvas = find_node_by_name(root, "Canvas")
|
2019-09-09 22:57:46 +00:00
|
|
|
canvases.append(canvas)
|
2019-12-10 17:56:16 +00:00
|
|
|
left_cursor_tool_texture = ImageTexture.new()
|
2020-05-05 00:53:58 +00:00
|
|
|
left_cursor_tool_texture.create_from_image(preload("res://assets/graphics/cursor_icons/pencil_cursor.png"))
|
2019-12-10 17:56:16 +00:00
|
|
|
right_cursor_tool_texture = ImageTexture.new()
|
2020-05-05 00:53:58 +00:00
|
|
|
right_cursor_tool_texture.create_from_image(preload("res://assets/graphics/cursor_icons/eraser_cursor.png"))
|
2019-08-18 09:28:38 +00:00
|
|
|
canvas_parent = canvas.get_parent()
|
2019-11-19 21:23:43 +00:00
|
|
|
main_viewport = find_node_by_name(root, "ViewportContainer")
|
2019-09-25 19:59:48 +00:00
|
|
|
second_viewport = find_node_by_name(root, "ViewportContainer2")
|
2019-09-09 22:57:46 +00:00
|
|
|
camera = find_node_by_name(canvas_parent, "Camera2D")
|
2019-11-19 21:23:43 +00:00
|
|
|
camera2 = find_node_by_name(root, "Camera2D2")
|
2019-12-05 14:49:27 +00:00
|
|
|
camera_preview = find_node_by_name(root, "CameraPreview")
|
2019-09-18 14:47:28 +00:00
|
|
|
selection_rectangle = find_node_by_name(root, "SelectionRectangle")
|
2019-12-03 00:30:38 +00:00
|
|
|
horizontal_ruler = find_node_by_name(root, "HorizontalRuler")
|
2019-11-20 22:11:21 +00:00
|
|
|
vertical_ruler = find_node_by_name(root, "VerticalRuler")
|
2020-04-20 16:12:22 +00:00
|
|
|
transparent_checker = find_node_by_name(root, "TransparentChecker")
|
2019-10-29 21:22:38 +00:00
|
|
|
|
2019-08-18 09:28:38 +00:00
|
|
|
file_menu = find_node_by_name(root, "FileMenu")
|
|
|
|
edit_menu = find_node_by_name(root, "EditMenu")
|
2019-09-18 21:10:23 +00:00
|
|
|
view_menu = find_node_by_name(root, "ViewMenu")
|
2019-12-24 14:48:07 +00:00
|
|
|
image_menu = find_node_by_name(root, "ImageMenu")
|
2019-09-25 19:59:48 +00:00
|
|
|
help_menu = find_node_by_name(root, "HelpMenu")
|
2019-12-05 23:48:29 +00:00
|
|
|
cursor_position_label = find_node_by_name(root, "CursorPosition")
|
|
|
|
zoom_level_label = find_node_by_name(root, "ZoomLevel")
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2019-12-28 16:35:53 +00:00
|
|
|
import_sprites_dialog = find_node_by_name(root, "ImportSprites")
|
2020-05-03 15:47:13 +00:00
|
|
|
export_dialog = find_node_by_name(root, "ExportDialog")
|
2020-05-28 00:41:28 +00:00
|
|
|
preferences_dialog = find_node_by_name(root, "PreferencesDialog")
|
2019-12-28 16:35:53 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
tool_options_containers.append(find_node_by_name(root, "LeftToolOptions"))
|
|
|
|
tool_options_containers.append(find_node_by_name(root, "RightToolOptions"))
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
color_pickers.append(find_node_by_name(root, "LeftColorPickerButton"))
|
|
|
|
color_pickers.append(find_node_by_name(root, "RightColorPickerButton"))
|
2020-04-15 18:52:20 +00:00
|
|
|
color_switch_button = find_node_by_name(root, "ColorSwitch")
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
brush_type_containers.append(find_node_by_name(tool_options_containers[0], "LeftBrushType"))
|
|
|
|
brush_type_containers.append(find_node_by_name(tool_options_containers[1], "RightBrushType"))
|
|
|
|
brush_type_buttons.append(find_node_by_name(brush_type_containers[0], "LeftBrushTypeButton"))
|
|
|
|
brush_type_buttons.append(find_node_by_name(brush_type_containers[1], "RightBrushTypeButton"))
|
2019-12-05 23:48:29 +00:00
|
|
|
brushes_popup = find_node_by_name(root, "BrushesPopup")
|
|
|
|
file_brush_container = find_node_by_name(brushes_popup, "FileBrushContainer")
|
|
|
|
project_brush_container = find_node_by_name(brushes_popup, "ProjectBrushContainer")
|
2020-04-24 21:42:02 +00:00
|
|
|
patterns_popup = find_node_by_name(root, "PatternsPopup")
|
2019-12-03 16:36:28 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
brush_size_edits.append(find_node_by_name(root, "LeftBrushSizeEdit"))
|
|
|
|
brush_size_sliders.append(find_node_by_name(root, "LeftBrushSizeSlider"))
|
|
|
|
brush_size_edits.append(find_node_by_name(root, "RightBrushSizeEdit"))
|
|
|
|
brush_size_sliders.append(find_node_by_name(root, "RightBrushSizeSlider"))
|
2020-03-27 01:40:23 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
pixel_perfect_containers.append(find_node_by_name(root, "LeftBrushPixelPerfectMode"))
|
|
|
|
pixel_perfect_containers.append(find_node_by_name(root, "RightBrushPixelPerfectMode"))
|
2020-04-27 15:09:54 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
color_interpolation_containers.append(find_node_by_name(root, "LeftColorInterpolation"))
|
|
|
|
color_interpolation_containers.append(find_node_by_name(root, "RightColorInterpolation"))
|
|
|
|
interpolate_spinboxes.append(find_node_by_name(root, "LeftInterpolateFactor"))
|
|
|
|
interpolate_sliders.append(find_node_by_name(root, "LeftInterpolateSlider"))
|
|
|
|
interpolate_spinboxes.append(find_node_by_name(root, "RightInterpolateFactor"))
|
|
|
|
interpolate_sliders.append(find_node_by_name(root, "RightInterpolateSlider"))
|
2020-03-27 01:40:23 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
fill_area_containers.append(find_node_by_name(root, "LeftFillArea"))
|
|
|
|
fill_pattern_containers.append(find_node_by_name(root, "LeftFillPattern"))
|
|
|
|
fill_area_containers.append(find_node_by_name(root, "RightFillArea"))
|
|
|
|
fill_pattern_containers.append(find_node_by_name(root, "RightFillPattern"))
|
2020-03-27 01:40:23 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
ld_containers.append(find_node_by_name(root, "LeftLDOptions"))
|
|
|
|
ld_amount_sliders.append(find_node_by_name(root, "LeftLDAmountSlider"))
|
|
|
|
ld_amount_spinboxes.append(find_node_by_name(root, "LeftLDAmountSpinbox"))
|
|
|
|
ld_containers.append(find_node_by_name(root, "RightLDOptions"))
|
|
|
|
ld_amount_sliders.append(find_node_by_name(root, "RightLDAmountSlider"))
|
|
|
|
ld_amount_spinboxes.append(find_node_by_name(root, "RightLDAmountSpinbox"))
|
2020-03-27 01:40:23 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
colorpicker_containers.append(find_node_by_name(root, "LeftColorPickerOptions"))
|
|
|
|
colorpicker_containers.append(find_node_by_name(root, "RightColorPickerOptions"))
|
2020-03-27 01:40:23 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
zoom_containers.append(find_node_by_name(root, "LeftZoomOptions"))
|
|
|
|
zoom_containers.append(find_node_by_name(root, "RightZoomOptions"))
|
2020-04-13 02:07:52 +00:00
|
|
|
|
2020-05-31 15:03:44 +00:00
|
|
|
mirror_containers.append(find_node_by_name(root, "LeftMirrorButtons"))
|
|
|
|
mirror_containers.append(find_node_by_name(root, "RightMirrorButtons"))
|
2019-10-29 21:22:38 +00:00
|
|
|
|
2020-01-15 20:01:43 +00:00
|
|
|
animation_timeline = find_node_by_name(root, "AnimationTimeline")
|
2019-12-05 23:48:29 +00:00
|
|
|
|
2020-01-18 22:56:30 +00:00
|
|
|
layers_container = find_node_by_name(animation_timeline, "LayersContainer")
|
|
|
|
frames_container = find_node_by_name(animation_timeline, "FramesContainer")
|
2020-01-15 20:01:43 +00:00
|
|
|
animation_timer = find_node_by_name(animation_timeline, "AnimationTimer")
|
2020-01-18 19:06:47 +00:00
|
|
|
frame_ids = find_node_by_name(animation_timeline, "FrameIDs")
|
2020-05-23 21:22:06 +00:00
|
|
|
current_frame_mark_label = find_node_by_name(control, "CurrentFrameMark")
|
2020-04-03 12:34:16 +00:00
|
|
|
onion_skinning_button = find_node_by_name(animation_timeline, "OnionSkinning")
|
2020-01-15 20:01:43 +00:00
|
|
|
loop_animation_button = find_node_by_name(animation_timeline, "LoopAnim")
|
|
|
|
play_forward = find_node_by_name(animation_timeline, "PlayForward")
|
|
|
|
play_backwards = find_node_by_name(animation_timeline, "PlayBackwards")
|
2020-04-02 00:29:14 +00:00
|
|
|
tag_container = find_node_by_name(animation_timeline, "TagContainer")
|
2020-04-05 21:51:46 +00:00
|
|
|
tag_dialog = find_node_by_name(animation_timeline, "FrameTagDialog")
|
2019-11-29 22:41:34 +00:00
|
|
|
|
2020-05-03 15:17:12 +00:00
|
|
|
remove_frame_button = find_node_by_name(animation_timeline, "DeleteFrame")
|
|
|
|
|
2020-01-18 19:06:47 +00:00
|
|
|
remove_layer_button = find_node_by_name(animation_timeline, "RemoveLayer")
|
|
|
|
move_up_layer_button = find_node_by_name(animation_timeline, "MoveUpLayer")
|
2020-03-26 01:24:25 +00:00
|
|
|
move_down_layer_button = find_node_by_name(animation_timeline, "MoveDownLayer")
|
2020-01-18 19:06:47 +00:00
|
|
|
merge_down_layer_button = find_node_by_name(animation_timeline, "MergeDownLayer")
|
|
|
|
|
|
|
|
layer_opacity_slider = find_node_by_name(animation_timeline, "OpacitySlider")
|
|
|
|
layer_opacity_spinbox = find_node_by_name(animation_timeline, "OpacitySpinBox")
|
2019-12-15 11:44:53 +00:00
|
|
|
|
2019-12-15 03:11:32 +00:00
|
|
|
add_palette_button = find_node_by_name(root, "AddPalette")
|
|
|
|
edit_palette_button = find_node_by_name(root, "EditPalette")
|
2019-12-30 18:29:46 +00:00
|
|
|
palette_option_button = find_node_by_name(root, "PaletteOptionButton")
|
2019-12-15 03:11:32 +00:00
|
|
|
palette_container = find_node_by_name(root, "PaletteContainer")
|
2019-12-17 01:23:18 +00:00
|
|
|
edit_palette_popup = find_node_by_name(root, "EditPalettePopup")
|
|
|
|
new_palette_dialog = find_node_by_name(root, "NewPaletteDialog")
|
|
|
|
new_palette_name_line_edit = find_node_by_name(new_palette_dialog, "NewPaletteNameLineEdit")
|
2019-12-18 14:43:11 +00:00
|
|
|
palette_import_file_dialog = find_node_by_name(root, "PaletteImportFileDialog")
|
2019-12-17 01:23:18 +00:00
|
|
|
|
|
|
|
error_dialog = find_node_by_name(root, "ErrorDialog")
|
2019-08-18 09:28:38 +00:00
|
|
|
|
2020-06-01 13:42:53 +00:00
|
|
|
layers.append(Layer.new())
|
2020-01-18 19:06:47 +00:00
|
|
|
|
2020-04-02 00:29:14 +00:00
|
|
|
|
2019-12-28 01:07:48 +00:00
|
|
|
# Thanks to https://godotengine.org/qa/17524/how-to-find-an-instanced-scene-by-its-name
|
2020-06-01 13:42:53 +00:00
|
|
|
func find_node_by_name(root : Node, node_name : String) -> Node:
|
2019-10-29 21:22:38 +00:00
|
|
|
if root.get_name() == node_name:
|
2019-08-18 09:28:38 +00:00
|
|
|
return root
|
|
|
|
for child in root.get_children():
|
|
|
|
if child.get_name() == node_name:
|
|
|
|
return child
|
|
|
|
var found = find_node_by_name(child, node_name)
|
2019-10-29 21:22:38 +00:00
|
|
|
if found:
|
2019-08-18 09:28:38 +00:00
|
|
|
return found
|
2019-09-09 22:57:46 +00:00
|
|
|
return null
|
|
|
|
|
2020-04-19 21:09:48 +00:00
|
|
|
|
2019-11-13 13:45:55 +00:00
|
|
|
func notification_label(text : String) -> void:
|
2020-05-01 22:19:01 +00:00
|
|
|
var notification : Label = load("res://src/UI/NotificationLabel.tscn").instance()
|
2019-12-08 01:12:34 +00:00
|
|
|
notification.text = tr(text)
|
2020-03-09 14:59:17 +00:00
|
|
|
notification.rect_position = Vector2(240, OS.window_size.y - animation_timeline.rect_size.y - 20)
|
2020-03-01 15:56:34 +00:00
|
|
|
notification.theme = control.theme
|
2019-11-13 13:45:55 +00:00
|
|
|
get_tree().get_root().add_child(notification)
|
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
|
|
|
func general_undo() -> void:
|
2019-10-31 23:41:02 +00:00
|
|
|
undos -= 1
|
2019-11-11 16:41:43 +00:00
|
|
|
var action_name := undo_redo.get_current_action_name()
|
2020-04-19 18:17:33 +00:00
|
|
|
notification_label("Undo: %s" % action_name)
|
|
|
|
|
|
|
|
|
|
|
|
func general_redo() -> void:
|
|
|
|
if undos < undo_redo.get_version(): # If we did undo and then redo
|
|
|
|
undos = undo_redo.get_version()
|
|
|
|
if control.redone:
|
|
|
|
var action_name := undo_redo.get_current_action_name()
|
|
|
|
notification_label("Redo: %s" % action_name)
|
|
|
|
|
|
|
|
|
|
|
|
func undo(_canvases : Array, layer_index : int = -1) -> void:
|
|
|
|
general_undo()
|
|
|
|
var action_name := undo_redo.get_current_action_name()
|
2020-04-22 16:01:33 +00:00
|
|
|
if action_name == "Draw" or action_name == "Rectangle Select" or action_name == "Scale" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel":
|
2019-11-10 01:25:25 +00:00
|
|
|
for c in _canvases:
|
2019-11-05 16:19:41 +00:00
|
|
|
if layer_index > -1:
|
|
|
|
c.update_texture(layer_index)
|
|
|
|
else:
|
|
|
|
for i in c.layers.size():
|
|
|
|
c.update_texture(i)
|
|
|
|
|
|
|
|
if action_name == "Scale":
|
|
|
|
c.camera_zoom()
|
2019-12-27 22:57:28 +00:00
|
|
|
|
2019-11-10 01:25:25 +00:00
|
|
|
if action_name == "Add Frame":
|
|
|
|
canvas_parent.remove_child(_canvases[0])
|
2019-12-28 01:07:48 +00:00
|
|
|
# This actually means that canvases.size is one, but it hasn't been updated yet
|
|
|
|
if canvases.size() == 2: # Stop animating
|
2019-11-23 22:52:17 +00:00
|
|
|
play_forward.pressed = false
|
|
|
|
play_backwards.pressed = false
|
|
|
|
animation_timer.stop()
|
2019-11-10 01:25:25 +00:00
|
|
|
elif action_name == "Remove Frame":
|
|
|
|
canvas_parent.add_child(_canvases[0])
|
|
|
|
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
|
|
|
elif action_name == "Change Frame Order":
|
2019-11-19 21:23:43 +00:00
|
|
|
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
2019-11-10 01:25:25 +00:00
|
|
|
|
2019-12-27 22:57:28 +00:00
|
|
|
canvas.update()
|
2020-05-01 16:40:36 +00:00
|
|
|
if !project_has_changed:
|
|
|
|
project_has_changed = true
|
2020-02-22 15:32:16 +00:00
|
|
|
self.window_title = window_title + "(*)"
|
2019-11-13 13:45:55 +00:00
|
|
|
|
2019-10-29 21:22:38 +00:00
|
|
|
|
2019-11-10 01:25:25 +00:00
|
|
|
func redo(_canvases : Array, layer_index : int = -1) -> void:
|
2020-04-19 18:17:33 +00:00
|
|
|
general_redo()
|
2019-11-11 16:41:43 +00:00
|
|
|
var action_name := undo_redo.get_current_action_name()
|
2020-04-22 16:01:33 +00:00
|
|
|
if action_name == "Draw" or action_name == "Rectangle Select" or action_name == "Scale" or action_name == "Merge Layer" or action_name == "Link Cel" or action_name == "Unlink Cel":
|
2019-11-10 01:25:25 +00:00
|
|
|
for c in _canvases:
|
2019-11-05 16:19:41 +00:00
|
|
|
if layer_index > -1:
|
|
|
|
c.update_texture(layer_index)
|
|
|
|
else:
|
|
|
|
for i in c.layers.size():
|
|
|
|
c.update_texture(i)
|
|
|
|
|
|
|
|
if action_name == "Scale":
|
|
|
|
c.camera_zoom()
|
2019-11-10 01:25:25 +00:00
|
|
|
|
|
|
|
if action_name == "Add Frame":
|
|
|
|
canvas_parent.add_child(_canvases[0])
|
|
|
|
elif action_name == "Remove Frame":
|
|
|
|
canvas_parent.remove_child(_canvases[0])
|
2019-12-28 01:07:48 +00:00
|
|
|
if canvases.size() == 1: # Stop animating
|
2019-11-23 22:52:17 +00:00
|
|
|
play_forward.pressed = false
|
|
|
|
play_backwards.pressed = false
|
|
|
|
animation_timer.stop()
|
2019-11-10 01:25:25 +00:00
|
|
|
elif action_name == "Change Frame Order":
|
2019-11-19 21:23:43 +00:00
|
|
|
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
2019-11-10 01:25:25 +00:00
|
|
|
|
2019-12-27 22:57:28 +00:00
|
|
|
canvas.update()
|
2020-05-01 16:40:36 +00:00
|
|
|
if !project_has_changed:
|
|
|
|
project_has_changed = true
|
2020-02-22 15:32:16 +00:00
|
|
|
self.window_title = window_title + "(*)"
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2019-10-29 21:22:38 +00:00
|
|
|
|
2020-02-22 15:21:52 +00:00
|
|
|
func title_changed(value : String) -> void:
|
|
|
|
window_title = value
|
|
|
|
OS.set_window_title(value)
|
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2020-03-03 00:50:39 +00:00
|
|
|
func canvases_changed(value : Array) -> void:
|
|
|
|
canvases = value
|
|
|
|
for container in frames_container.get_children():
|
|
|
|
for button in container.get_children():
|
2020-03-04 23:53:48 +00:00
|
|
|
container.remove_child(button)
|
2020-03-03 00:50:39 +00:00
|
|
|
button.queue_free()
|
|
|
|
frames_container.remove_child(container)
|
|
|
|
|
|
|
|
for frame_id in frame_ids.get_children():
|
2020-03-04 23:53:48 +00:00
|
|
|
frame_ids.remove_child(frame_id)
|
2020-03-03 00:50:39 +00:00
|
|
|
frame_id.queue_free()
|
|
|
|
|
|
|
|
for i in range(layers.size() - 1, -1, -1):
|
2020-06-01 13:42:53 +00:00
|
|
|
frames_container.add_child(layers[i].frame_container)
|
2020-03-03 00:50:39 +00:00
|
|
|
|
|
|
|
for j in range(canvases.size()):
|
|
|
|
var label := Label.new()
|
|
|
|
label.rect_min_size.x = 36
|
|
|
|
label.align = Label.ALIGN_CENTER
|
|
|
|
label.text = str(j + 1)
|
|
|
|
frame_ids.add_child(label)
|
|
|
|
|
|
|
|
for i in range(layers.size() - 1, -1, -1):
|
2020-05-01 22:19:01 +00:00
|
|
|
var cel_button = load("res://src/UI/Timeline/CelButton.tscn").instance()
|
2020-05-01 19:17:05 +00:00
|
|
|
cel_button.frame = j
|
|
|
|
cel_button.layer = i
|
|
|
|
cel_button.get_child(0).texture = Global.canvases[j].layers[i][1]
|
2020-03-03 00:50:39 +00:00
|
|
|
|
2020-06-01 13:42:53 +00:00
|
|
|
layers[i].frame_container.add_child(cel_button)
|
2020-03-03 00:50:39 +00:00
|
|
|
|
2020-04-19 17:39:08 +00:00
|
|
|
# This is useful in case tagged frames get deleted DURING the animation is playing
|
|
|
|
# otherwise, this code is useless in this context, since these values are being set
|
|
|
|
# when the play buttons get pressed, anyway
|
|
|
|
animation_timeline.first_frame = 0
|
|
|
|
animation_timeline.last_frame = canvases.size() - 1
|
|
|
|
if play_only_tags:
|
|
|
|
for tag in animation_tags:
|
|
|
|
if current_frame + 1 >= tag[2] && current_frame + 1 <= tag[3]:
|
|
|
|
animation_timeline.first_frame = tag[2] - 1
|
|
|
|
animation_timeline.last_frame = min(canvases.size() - 1, tag[3] - 1)
|
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2020-04-09 22:06:24 +00:00
|
|
|
func clear_canvases() -> void:
|
2020-04-11 21:08:45 +00:00
|
|
|
for child in canvas_parent.get_children():
|
2020-04-09 22:06:24 +00:00
|
|
|
if child is Canvas:
|
|
|
|
child.queue_free()
|
2020-04-11 21:08:45 +00:00
|
|
|
canvases.clear()
|
|
|
|
animation_tags.clear()
|
|
|
|
self.animation_tags = animation_tags # To execute animation_tags_changed()
|
2020-04-09 22:06:24 +00:00
|
|
|
|
2020-04-21 16:42:01 +00:00
|
|
|
# Stop playing the animation
|
|
|
|
play_backwards.pressed = false
|
|
|
|
play_forward.pressed = false
|
|
|
|
animation_timer.stop()
|
|
|
|
|
2020-05-03 21:04:00 +00:00
|
|
|
self.window_title = "(" + tr("untitled") + ") - Pixelorama " + Global.current_version
|
2020-04-25 19:24:20 +00:00
|
|
|
OpenSave.current_save_path = ""
|
|
|
|
control.get_node("ExportDialog").was_exported = false
|
|
|
|
control.file_menu.set_item_text(3, tr("Save..."))
|
|
|
|
control.file_menu.set_item_text(6, tr("Export..."))
|
2020-04-11 21:08:45 +00:00
|
|
|
undo_redo.clear_history(false)
|
2020-04-09 22:06:24 +00:00
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2020-02-28 01:27:22 +00:00
|
|
|
func layers_changed(value : Array) -> void:
|
|
|
|
layers = value
|
2020-04-06 15:35:54 +00:00
|
|
|
if layers_changed_skip:
|
|
|
|
layers_changed_skip = false
|
|
|
|
return
|
2020-02-28 01:27:22 +00:00
|
|
|
|
|
|
|
for container in layers_container.get_children():
|
|
|
|
container.queue_free()
|
|
|
|
|
|
|
|
for container in frames_container.get_children():
|
|
|
|
for button in container.get_children():
|
2020-03-04 23:53:48 +00:00
|
|
|
container.remove_child(button)
|
2020-02-28 01:27:22 +00:00
|
|
|
button.queue_free()
|
|
|
|
frames_container.remove_child(container)
|
|
|
|
|
|
|
|
for i in range(layers.size() - 1, -1, -1):
|
2020-05-01 22:19:01 +00:00
|
|
|
var layer_container = load("res://src/UI/Timeline/LayerButton.tscn").instance()
|
2020-02-28 01:27:22 +00:00
|
|
|
layer_container.i = i
|
2020-06-01 13:56:23 +00:00
|
|
|
if layers[i].name == tr("Layer") + " 0":
|
2020-06-01 13:42:53 +00:00
|
|
|
layers[i].name = tr("Layer") + " %s" % i
|
2020-02-28 23:23:45 +00:00
|
|
|
|
2020-02-28 01:27:22 +00:00
|
|
|
layers_container.add_child(layer_container)
|
2020-06-01 13:42:53 +00:00
|
|
|
layer_container.label.text = layers[i].name
|
|
|
|
layer_container.line_edit.text = layers[i].name
|
2020-02-28 01:27:22 +00:00
|
|
|
|
2020-06-01 13:42:53 +00:00
|
|
|
frames_container.add_child(layers[i].frame_container)
|
2020-02-28 01:27:22 +00:00
|
|
|
for j in range(canvases.size()):
|
2020-05-01 22:19:01 +00:00
|
|
|
var cel_button = load("res://src/UI/Timeline/CelButton.tscn").instance()
|
2020-05-01 19:17:05 +00:00
|
|
|
cel_button.frame = j
|
|
|
|
cel_button.layer = i
|
|
|
|
cel_button.get_child(0).texture = Global.canvases[j].layers[i][1]
|
2020-02-28 01:27:22 +00:00
|
|
|
|
2020-06-01 13:42:53 +00:00
|
|
|
layers[i].frame_container.add_child(cel_button)
|
2020-02-28 01:27:22 +00:00
|
|
|
|
2020-03-04 23:13:59 +00:00
|
|
|
var layer_button = layers_container.get_child(layers_container.get_child_count() - 1 - current_layer)
|
|
|
|
layer_button.pressed = true
|
2020-03-04 23:53:48 +00:00
|
|
|
self.current_frame = current_frame # Call frame_changed to update UI
|
2020-03-04 23:13:59 +00:00
|
|
|
|
2020-06-01 13:42:53 +00:00
|
|
|
if layers[current_layer].locked:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(remove_layer_button, true)
|
2020-03-09 23:42:50 +00:00
|
|
|
|
|
|
|
if layers.size() == 1:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(remove_layer_button, true)
|
|
|
|
disable_button(move_up_layer_button, true)
|
|
|
|
disable_button(move_down_layer_button, true)
|
|
|
|
disable_button(merge_down_layer_button, true)
|
2020-06-01 13:42:53 +00:00
|
|
|
elif !layers[current_layer].locked:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(remove_layer_button, false)
|
2020-02-28 01:27:22 +00:00
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2019-11-10 01:25:25 +00:00
|
|
|
func frame_changed(value : int) -> void:
|
|
|
|
current_frame = value
|
2020-05-23 21:22:06 +00:00
|
|
|
current_frame_mark_label.text = "%s/%s" % [str(current_frame + 1), canvases.size()]
|
2019-11-10 01:25:25 +00:00
|
|
|
|
2020-03-04 23:53:48 +00:00
|
|
|
var i := 0
|
|
|
|
for c in canvases: # De-select all the other canvases/frames
|
2019-09-09 22:57:46 +00:00
|
|
|
c.visible = false
|
2020-01-15 20:47:56 +00:00
|
|
|
c.is_making_line = false
|
|
|
|
c.line_2d.set_point_position(1, c.line_2d.points[0])
|
2019-12-24 02:37:17 +00:00
|
|
|
var text_color := Color.white
|
2020-06-01 00:36:07 +00:00
|
|
|
if theme_type == Theme_Types.CARAMEL || theme_type == Theme_Types.LIGHT:
|
2019-12-24 02:37:17 +00:00
|
|
|
text_color = Color.black
|
2020-03-04 23:53:48 +00:00
|
|
|
frame_ids.get_child(i).add_color_override("font_color", text_color)
|
|
|
|
for layer in layers:
|
2020-06-01 13:42:53 +00:00
|
|
|
if i < layer.frame_container.get_child_count():
|
|
|
|
layer.frame_container.get_child(i).pressed = false
|
2020-03-04 23:53:48 +00:00
|
|
|
i += 1
|
|
|
|
|
|
|
|
# Select the new canvas/frame
|
|
|
|
canvas = canvases[current_frame]
|
|
|
|
canvas.visible = true
|
2020-05-05 22:36:14 +00:00
|
|
|
frame_ids.get_child(current_frame).add_color_override("font_color", control.theme.get_color("Selected Color", "Label"))
|
2020-06-01 13:42:53 +00:00
|
|
|
if current_frame < layers[current_layer].frame_container.get_child_count():
|
|
|
|
layers[current_layer].frame_container.get_child(current_frame).pressed = true
|
2019-09-25 19:59:48 +00:00
|
|
|
|
2020-05-03 15:17:12 +00:00
|
|
|
if canvases.size() == 1:
|
|
|
|
disable_button(remove_frame_button, true)
|
2020-06-01 13:42:53 +00:00
|
|
|
elif !layers[current_layer].locked:
|
2020-05-03 15:17:12 +00:00
|
|
|
disable_button(remove_frame_button, false)
|
|
|
|
|
2020-04-21 01:29:39 +00:00
|
|
|
Global.transparent_checker._ready() # To update the rect size
|
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2020-02-29 22:57:47 +00:00
|
|
|
func layer_changed(value : int) -> void:
|
|
|
|
current_layer = value
|
|
|
|
layer_opacity_slider.value = canvas.layers[current_layer][2] * 100
|
|
|
|
layer_opacity_spinbox.value = canvas.layers[current_layer][2] * 100
|
2020-03-04 23:13:59 +00:00
|
|
|
|
|
|
|
for container in layers_container.get_children():
|
|
|
|
container.pressed = false
|
|
|
|
|
|
|
|
if current_layer < layers_container.get_child_count():
|
|
|
|
var layer_button = layers_container.get_child(layers_container.get_child_count() - 1 - current_layer)
|
|
|
|
layer_button.pressed = true
|
|
|
|
|
2020-02-29 22:57:47 +00:00
|
|
|
if current_layer < layers.size() - 1:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(move_up_layer_button, false)
|
2020-02-29 22:57:47 +00:00
|
|
|
else:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(move_up_layer_button, true)
|
2020-02-29 22:57:47 +00:00
|
|
|
|
|
|
|
if current_layer > 0:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(move_down_layer_button, false)
|
|
|
|
disable_button(merge_down_layer_button, false)
|
2020-02-29 22:57:47 +00:00
|
|
|
else:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(move_down_layer_button, true)
|
|
|
|
disable_button(merge_down_layer_button, true)
|
2020-02-29 22:57:47 +00:00
|
|
|
|
2020-03-09 23:42:50 +00:00
|
|
|
if current_layer < layers.size():
|
2020-06-01 13:42:53 +00:00
|
|
|
if layers[current_layer].locked:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(remove_layer_button, true)
|
2020-03-09 23:42:50 +00:00
|
|
|
else:
|
|
|
|
if layers.size() > 1:
|
2020-05-03 00:13:08 +00:00
|
|
|
disable_button(remove_layer_button, false)
|
2020-03-09 23:42:50 +00:00
|
|
|
|
2020-03-04 23:53:48 +00:00
|
|
|
yield(get_tree().create_timer(0.01), "timeout")
|
|
|
|
self.current_frame = current_frame # Call frame_changed to update UI
|
|
|
|
|
2020-04-02 00:29:14 +00:00
|
|
|
|
2020-05-08 15:37:45 +00:00
|
|
|
func dialog_open(open : bool) -> void:
|
|
|
|
if open:
|
|
|
|
can_draw = false
|
|
|
|
control.get_node("ModulateTween").interpolate_property(control, "modulate", control.modulate, Color(0.5, 0.5, 0.5), 0.1, Tween.TRANS_LINEAR, Tween.EASE_OUT)
|
|
|
|
else:
|
|
|
|
can_draw = true
|
|
|
|
control.get_node("ModulateTween").interpolate_property(control, "modulate", control.modulate, Color.white, 0.1, Tween.TRANS_LINEAR, Tween.EASE_OUT)
|
|
|
|
|
|
|
|
control.get_node("ModulateTween").start()
|
|
|
|
|
|
|
|
|
2020-05-03 00:13:08 +00:00
|
|
|
func disable_button(button : BaseButton, disable : bool) -> void:
|
|
|
|
button.disabled = disable
|
|
|
|
if disable:
|
|
|
|
button.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
|
|
|
else:
|
|
|
|
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
|
|
|
|
|
|
if button is Button:
|
|
|
|
var theme := theme_type
|
2020-06-01 00:36:07 +00:00
|
|
|
if theme == Theme_Types.CARAMEL:
|
|
|
|
theme = Theme_Types.DARK
|
2020-05-03 00:13:08 +00:00
|
|
|
for c in button.get_children():
|
|
|
|
if c is TextureRect:
|
|
|
|
var normal_file_name = c.texture.resource_path.get_file().trim_suffix(".png").replace("_disabled", "")
|
|
|
|
if disable:
|
2020-05-06 12:56:44 +00:00
|
|
|
change_button_texturerect(c, "%s_disabled.png" % normal_file_name)
|
2020-05-03 00:13:08 +00:00
|
|
|
else:
|
2020-05-06 12:56:44 +00:00
|
|
|
change_button_texturerect(c, "%s.png" % normal_file_name)
|
2020-05-03 00:13:08 +00:00
|
|
|
break
|
|
|
|
|
|
|
|
|
2020-05-06 12:19:53 +00:00
|
|
|
func change_button_texturerect(texture_button : TextureRect, new_file_name : String) -> void:
|
|
|
|
var file_name := texture_button.texture.resource_path.get_basename().get_file()
|
|
|
|
var directory_path := texture_button.texture.resource_path.get_basename().replace(file_name, "")
|
|
|
|
texture_button.texture = load(directory_path.plus_file(new_file_name))
|
|
|
|
|
|
|
|
|
2020-04-02 00:29:14 +00:00
|
|
|
func animation_tags_changed(value : Array) -> void:
|
|
|
|
animation_tags = value
|
2020-04-05 21:51:46 +00:00
|
|
|
for child in tag_container.get_children():
|
|
|
|
child.queue_free()
|
|
|
|
|
|
|
|
for tag in animation_tags:
|
2020-05-01 22:19:01 +00:00
|
|
|
var tag_c : Container = load("res://src/UI/Timeline/AnimationTag.tscn").instance()
|
2020-04-05 21:51:46 +00:00
|
|
|
tag_container.add_child(tag_c)
|
|
|
|
var tag_position := tag_container.get_child_count() - 1
|
|
|
|
tag_container.move_child(tag_c, tag_position)
|
|
|
|
tag_c.get_node("Label").text = tag[0]
|
|
|
|
tag_c.get_node("Label").modulate = tag[1]
|
|
|
|
tag_c.get_node("Line2D").default_color = tag[1]
|
|
|
|
|
|
|
|
tag_c.rect_position.x = (tag[2] - 1) * 39 + tag[2]
|
|
|
|
|
|
|
|
var size : int = tag[3] - tag[2]
|
|
|
|
tag_c.rect_min_size.x = (size + 1) * 39
|
|
|
|
tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0)
|
|
|
|
tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32)
|
2020-04-02 00:29:14 +00:00
|
|
|
|
2020-04-19 17:39:08 +00:00
|
|
|
# This is useful in case tags get modified DURING the animation is playing
|
|
|
|
# otherwise, this code is useless in this context, since these values are being set
|
|
|
|
# when the play buttons get pressed, anyway
|
|
|
|
animation_timeline.first_frame = 0
|
|
|
|
animation_timeline.last_frame = canvases.size() - 1
|
|
|
|
if play_only_tags:
|
|
|
|
for tag in animation_tags:
|
|
|
|
if current_frame + 1 >= tag[2] && current_frame + 1 <= tag[3]:
|
|
|
|
animation_timeline.first_frame = tag[2] - 1
|
|
|
|
animation_timeline.last_frame = min(canvases.size() - 1, tag[3] - 1)
|
|
|
|
|
2020-04-02 00:29:14 +00:00
|
|
|
|
2020-04-11 21:08:45 +00:00
|
|
|
func update_hint_tooltips() -> void:
|
|
|
|
var root = get_tree().get_root()
|
|
|
|
|
|
|
|
var rect_select : BaseButton = find_node_by_name(root, "RectSelect")
|
|
|
|
rect_select.hint_tooltip = tr("""Rectangular Selection
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button
|
|
|
|
|
|
|
|
Press %s to move the content""") % [InputMap.get_action_list("left_rectangle_select_tool")[0].as_text(), InputMap.get_action_list("right_rectangle_select_tool")[0].as_text(), "Shift"]
|
|
|
|
|
2020-04-13 02:07:52 +00:00
|
|
|
var zoom_tool : BaseButton = find_node_by_name(root, "Zoom")
|
|
|
|
zoom_tool.hint_tooltip = tr("""Zoom
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button""") % [InputMap.get_action_list("left_zoom_tool")[0].as_text(), InputMap.get_action_list("right_zoom_tool")[0].as_text()]
|
|
|
|
|
|
|
|
|
2020-04-11 21:08:45 +00:00
|
|
|
var color_picker : BaseButton = find_node_by_name(root, "ColorPicker")
|
|
|
|
color_picker.hint_tooltip = tr("""Color Picker
|
|
|
|
Select a color from a pixel of the sprite
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button""") % [InputMap.get_action_list("left_colorpicker_tool")[0].as_text(), InputMap.get_action_list("right_colorpicker_tool")[0].as_text()]
|
|
|
|
|
|
|
|
var pencil : BaseButton = find_node_by_name(root, "Pencil")
|
|
|
|
pencil.hint_tooltip = tr("""Pencil
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button
|
|
|
|
|
|
|
|
Hold %s to make a line""") % [InputMap.get_action_list("left_pencil_tool")[0].as_text(), InputMap.get_action_list("right_pencil_tool")[0].as_text(), "Shift"]
|
|
|
|
|
|
|
|
var eraser : BaseButton = find_node_by_name(root, "Eraser")
|
|
|
|
eraser.hint_tooltip = tr("""Eraser
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button
|
|
|
|
|
|
|
|
Hold %s to make a line""") % [InputMap.get_action_list("left_eraser_tool")[0].as_text(), InputMap.get_action_list("right_eraser_tool")[0].as_text(), "Shift"]
|
|
|
|
|
|
|
|
var bucket : BaseButton = find_node_by_name(root, "Bucket")
|
|
|
|
bucket.hint_tooltip = tr("""Bucket
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button""") % [InputMap.get_action_list("left_fill_tool")[0].as_text(), InputMap.get_action_list("right_fill_tool")[0].as_text()]
|
|
|
|
|
|
|
|
var ld : BaseButton = find_node_by_name(root, "LightenDarken")
|
|
|
|
ld.hint_tooltip = tr("""Lighten/Darken
|
|
|
|
|
|
|
|
%s for left mouse button
|
|
|
|
%s for right mouse button""") % [InputMap.get_action_list("left_lightdark_tool")[0].as_text(), InputMap.get_action_list("right_lightdark_tool")[0].as_text()]
|
|
|
|
|
2020-04-12 16:50:14 +00:00
|
|
|
var color_switch : BaseButton = find_node_by_name(root, "ColorSwitch")
|
|
|
|
color_switch.hint_tooltip = tr("""Switch left and right colors
|
2020-04-15 18:52:20 +00:00
|
|
|
(%s)""") % InputMap.get_action_list("switch_colors")[0].as_text()
|
2020-04-12 16:50:14 +00:00
|
|
|
|
|
|
|
var first_frame : BaseButton = find_node_by_name(root, "FirstFrame")
|
|
|
|
first_frame.hint_tooltip = tr("""Jump to the first frame
|
|
|
|
(%s)""") % "Ctrl+Home"
|
|
|
|
|
|
|
|
var previous_frame : BaseButton = find_node_by_name(root, "PreviousFrame")
|
|
|
|
previous_frame.hint_tooltip = tr("""Go to the previous frame
|
|
|
|
(%s)""") % "Ctrl+Left"
|
|
|
|
|
|
|
|
play_backwards.hint_tooltip = tr("""Play the animation backwards (from end to beginning)
|
|
|
|
(%s)""") % "F4"
|
|
|
|
|
|
|
|
play_forward.hint_tooltip = tr("""Play the animation forward (from beginning to end)
|
|
|
|
(%s)""") % "F5"
|
|
|
|
|
|
|
|
var next_frame : BaseButton = find_node_by_name(root, "NextFrame")
|
|
|
|
next_frame.hint_tooltip = tr("""Go to the next frame
|
|
|
|
(%s)""") % "Ctrl+Right"
|
|
|
|
|
|
|
|
var last_frame : BaseButton = find_node_by_name(root, "LastFrame")
|
|
|
|
last_frame.hint_tooltip = tr("""Jump to the last frame
|
|
|
|
(%s)""") % "Ctrl+End"
|
|
|
|
|
2020-04-11 21:08:45 +00:00
|
|
|
|
2020-02-10 22:06:24 +00:00
|
|
|
func create_brush_button(brush_img : Image, brush_type := Brush_Types.CUSTOM, hint_tooltip := "") -> void:
|
2019-11-20 12:41:02 +00:00
|
|
|
var brush_container
|
2020-05-01 22:19:01 +00:00
|
|
|
var brush_button = load("res://src/UI/BrushButton.tscn").instance()
|
Import brushes from folder
- A new type of custom brush has been added, brushes from files! Basically there's a "Brushes" folder where Pixelorama can get brushes from, and, unlike the previous brushes, these are for all projects and are not saved in .pxo files. These brushes get loaded on the _ready() method of Main.gd, and are ignored by Godot.
- There are now 2 containers for the two types of custom brushes. The main pixel brush is with the brushes from files.
- Fixed bug where, if you had selected a custom "project" brush and loaded a .pxo file, the brush would still be selected, causing potential problems
- Fixed bug where you could save a project brush that was completely transparent
- Fixed bug where, if you named a file, some shortcuts would be activated.
- export_presets.cfg is now ignored.
2019-11-11 02:20:09 +00:00
|
|
|
brush_button.brush_type = brush_type
|
2019-09-27 17:05:24 +00:00
|
|
|
brush_button.custom_brush_index = custom_brushes.size() - 1
|
2020-02-10 22:06:24 +00:00
|
|
|
if brush_type == Brush_Types.FILE || brush_type == Brush_Types.RANDOM_FILE:
|
2019-11-20 12:41:02 +00:00
|
|
|
brush_container = file_brush_container
|
Import brushes from folder
- A new type of custom brush has been added, brushes from files! Basically there's a "Brushes" folder where Pixelorama can get brushes from, and, unlike the previous brushes, these are for all projects and are not saved in .pxo files. These brushes get loaded on the _ready() method of Main.gd, and are ignored by Godot.
- There are now 2 containers for the two types of custom brushes. The main pixel brush is with the brushes from files.
- Fixed bug where, if you had selected a custom "project" brush and loaded a .pxo file, the brush would still be selected, causing potential problems
- Fixed bug where you could save a project brush that was completely transparent
- Fixed bug where, if you named a file, some shortcuts would be activated.
- export_presets.cfg is now ignored.
2019-11-11 02:20:09 +00:00
|
|
|
else:
|
2019-11-20 12:41:02 +00:00
|
|
|
brush_container = project_brush_container
|
2019-09-25 19:59:48 +00:00
|
|
|
var brush_tex := ImageTexture.new()
|
|
|
|
brush_tex.create_from_image(brush_img, 0)
|
|
|
|
brush_button.get_child(0).texture = brush_tex
|
2019-11-25 16:56:53 +00:00
|
|
|
brush_button.hint_tooltip = hint_tooltip
|
2020-04-24 21:42:02 +00:00
|
|
|
brush_button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
2020-02-10 22:06:24 +00:00
|
|
|
if brush_type == Brush_Types.RANDOM_FILE:
|
2019-12-26 19:36:56 +00:00
|
|
|
brush_button.random_brushes.append(brush_img)
|
2019-11-20 12:41:02 +00:00
|
|
|
brush_container.add_child(brush_button)
|
2019-10-02 18:58:19 +00:00
|
|
|
|
2020-04-24 21:42:02 +00:00
|
|
|
|
2019-10-02 18:58:19 +00:00
|
|
|
func remove_brush_buttons() -> void:
|
2020-05-31 15:40:47 +00:00
|
|
|
current_brush_types[0] = Brush_Types.PIXEL
|
|
|
|
current_brush_types[1] = Brush_Types.PIXEL
|
2019-11-20 12:41:02 +00:00
|
|
|
for child in project_brush_container.get_children():
|
2019-11-11 16:41:43 +00:00
|
|
|
child.queue_free()
|
|
|
|
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2019-11-29 22:41:34 +00:00
|
|
|
func undo_custom_brush(_brush_button : BaseButton = null) -> void:
|
2020-04-19 18:17:33 +00:00
|
|
|
general_undo()
|
2019-11-11 16:41:43 +00:00
|
|
|
var action_name := undo_redo.get_current_action_name()
|
|
|
|
if action_name == "Delete Custom Brush":
|
2019-11-20 12:41:02 +00:00
|
|
|
project_brush_container.add_child(_brush_button)
|
|
|
|
project_brush_container.move_child(_brush_button, _brush_button.custom_brush_index - brushes_from_files)
|
2019-11-11 16:41:43 +00:00
|
|
|
_brush_button.get_node("DeleteButton").visible = false
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2019-11-11 16:41:43 +00:00
|
|
|
|
2019-11-29 22:41:34 +00:00
|
|
|
func redo_custom_brush(_brush_button : BaseButton = null) -> void:
|
2020-04-19 18:17:33 +00:00
|
|
|
general_redo()
|
2019-11-11 16:41:43 +00:00
|
|
|
var action_name := undo_redo.get_current_action_name()
|
|
|
|
if action_name == "Delete Custom Brush":
|
2019-11-20 12:41:02 +00:00
|
|
|
project_brush_container.remove_child(_brush_button)
|
2020-04-19 18:17:33 +00:00
|
|
|
|
2019-10-02 18:58:19 +00:00
|
|
|
|
2020-05-31 15:40:47 +00:00
|
|
|
func update_custom_brush(mouse_button : int) -> void:
|
|
|
|
if current_brush_types[mouse_button] == Brush_Types.PIXEL:
|
2019-11-29 22:41:34 +00:00
|
|
|
var pixel := Image.new()
|
2020-05-05 00:53:58 +00:00
|
|
|
pixel = preload("res://assets/graphics/pixel_image.png")
|
2020-05-31 15:40:47 +00:00
|
|
|
brush_type_buttons[mouse_button].get_child(0).texture.create_from_image(pixel, 0)
|
|
|
|
elif current_brush_types[mouse_button] == Brush_Types.CIRCLE:
|
2019-12-25 18:27:25 +00:00
|
|
|
var pixel := Image.new()
|
2020-05-05 00:53:58 +00:00
|
|
|
pixel = preload("res://assets/graphics/circle_9x9.png")
|
2020-05-31 15:40:47 +00:00
|
|
|
brush_type_buttons[mouse_button].get_child(0).texture.create_from_image(pixel, 0)
|
2020-05-31 21:44:53 +00:00
|
|
|
left_circle_points = plot_circle(brush_sizes[0])
|
|
|
|
right_circle_points = plot_circle(brush_sizes[1])
|
2020-05-31 15:40:47 +00:00
|
|
|
elif current_brush_types[mouse_button] == Brush_Types.FILLED_CIRCLE:
|
2019-12-27 20:02:47 +00:00
|
|
|
var pixel := Image.new()
|
2020-05-05 00:53:58 +00:00
|
|
|
pixel = preload("res://assets/graphics/circle_filled_9x9.png")
|
2020-05-31 15:40:47 +00:00
|
|
|
brush_type_buttons[mouse_button].get_child(0).texture.create_from_image(pixel, 0)
|
2020-05-31 21:44:53 +00:00
|
|
|
left_circle_points = plot_circle(brush_sizes[0])
|
|
|
|
right_circle_points = plot_circle(brush_sizes[1])
|
2019-11-29 22:41:34 +00:00
|
|
|
else:
|
2019-09-27 17:39:16 +00:00
|
|
|
var custom_brush := Image.new()
|
2020-05-31 15:40:47 +00:00
|
|
|
custom_brush.copy_from(custom_brushes[custom_brush_indexes[mouse_button]])
|
2019-09-27 17:39:16 +00:00
|
|
|
var custom_brush_size = custom_brush.get_size()
|
2020-05-31 21:44:53 +00:00
|
|
|
custom_brush.resize(custom_brush_size.x * brush_sizes[mouse_button], custom_brush_size.y * brush_sizes[mouse_button], Image.INTERPOLATE_NEAREST)
|
2020-05-31 15:40:47 +00:00
|
|
|
custom_brush_images[mouse_button] = blend_image_with_color(custom_brush, color_pickers[mouse_button].color, interpolate_spinboxes[mouse_button].value / 100)
|
|
|
|
custom_brush_textures[mouse_button].create_from_image(custom_brush_images[mouse_button], 0)
|
2019-10-29 21:22:38 +00:00
|
|
|
|
2020-05-31 15:40:47 +00:00
|
|
|
brush_type_buttons[mouse_button].get_child(0).texture = custom_brush_textures[mouse_button]
|
2019-11-29 22:41:34 +00:00
|
|
|
|
2020-05-01 17:47:10 +00:00
|
|
|
|
2019-09-27 17:05:24 +00:00
|
|
|
func blend_image_with_color(image : Image, color : Color, interpolate_factor : float) -> Image:
|
|
|
|
var blended_image := Image.new()
|
|
|
|
blended_image.copy_from(image)
|
|
|
|
var size := image.get_size()
|
|
|
|
blended_image.lock()
|
|
|
|
for xx in size.x:
|
|
|
|
for yy in size.y:
|
2019-12-25 18:27:25 +00:00
|
|
|
if color.a > 0: # If it's the pencil
|
2019-09-27 17:05:24 +00:00
|
|
|
var current_color := blended_image.get_pixel(xx, yy)
|
|
|
|
if current_color.a > 0:
|
|
|
|
var new_color := current_color.linear_interpolate(color, interpolate_factor)
|
2019-12-26 22:04:58 +00:00
|
|
|
new_color.a = current_color.a
|
2019-09-27 17:05:24 +00:00
|
|
|
blended_image.set_pixel(xx, yy, new_color)
|
2019-12-25 18:27:25 +00:00
|
|
|
else: # If color is transparent - if it's the eraser
|
2019-09-27 17:05:24 +00:00
|
|
|
blended_image.set_pixel(xx, yy, Color(0, 0, 0, 0))
|
2019-10-25 14:38:38 +00:00
|
|
|
return blended_image
|
2019-12-12 22:19:28 +00:00
|
|
|
|
2020-05-01 17:47:10 +00:00
|
|
|
|
2019-12-25 18:27:25 +00:00
|
|
|
# Algorithm based on http://members.chello.at/easyfilter/bresenham.html
|
|
|
|
# This is not used for drawing, rather for finding the points required
|
|
|
|
# for the mouse cursor/position indicator
|
|
|
|
func plot_circle(r : int) -> Array:
|
|
|
|
var circle_points := []
|
|
|
|
var xm := 0
|
|
|
|
var ym := 0
|
|
|
|
var x := -r
|
|
|
|
var y := 0
|
|
|
|
var err := 2 - r * 2
|
|
|
|
while x < 0:
|
|
|
|
circle_points.append(Vector2(xm - x, ym + y))
|
|
|
|
circle_points.append(Vector2(xm - y, ym - x))
|
|
|
|
circle_points.append(Vector2(xm + x, ym - y))
|
|
|
|
circle_points.append(Vector2(xm + y, ym + x))
|
|
|
|
r = err
|
|
|
|
if r <= y:
|
|
|
|
y += 1
|
|
|
|
err += y * 2 + 1
|
|
|
|
if r > x || err > y:
|
|
|
|
x += 1
|
|
|
|
err += x * 2 + 1
|
|
|
|
return circle_points
|
|
|
|
|
2020-05-01 17:47:10 +00:00
|
|
|
|
2019-12-12 22:19:28 +00:00
|
|
|
func _exit_tree() -> void:
|
2019-12-18 16:12:44 +00:00
|
|
|
config_cache.set_value("window", "screen", OS.current_screen)
|
|
|
|
config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen)
|
|
|
|
config_cache.set_value("window", "position", OS.window_position)
|
|
|
|
config_cache.set_value("window", "size", OS.window_size)
|
|
|
|
config_cache.save("user://cache.ini")
|
|
|
|
|
2019-12-12 22:19:28 +00:00
|
|
|
# Thanks to qarmin from GitHub for pointing this out
|
2019-12-18 16:12:44 +00:00
|
|
|
undo_redo.free()
|