mirror of
https://github.com/tonytins/CozyPixelStudio.git
synced 2025-06-25 21:14:42 -04:00
Changes to scripts to follow GDScript style guide
Please read here for more info: https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/gdscript_styleguide.html This commit does not add/change any new/existing features.
This commit is contained in:
parent
62bbad7374
commit
5a54235604
32 changed files with 295 additions and 165 deletions
|
@ -9,6 +9,7 @@ var last_frame := Global.canvases.size() - 1
|
|||
onready var timeline_scroll : ScrollContainer = $AnimationContainer/TimelineContainer/TimelineScroll
|
||||
onready var tag_scroll_container : ScrollContainer = $AnimationContainer/TimelineContainer/OpacityAndTagContainer/TagScroll
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
timeline_scroll.get_h_scrollbar().connect("value_changed", self, "_h_scroll_changed")
|
||||
Global.animation_timer.wait_time = 1 / fps
|
||||
|
@ -175,11 +176,14 @@ func _on_FrameTagButton_pressed() -> void:
|
|||
func _on_OnionSkinning_pressed() -> void:
|
||||
Global.onion_skinning = !Global.onion_skinning
|
||||
Global.canvas.update()
|
||||
var theme_type := Global.theme_type
|
||||
if theme_type == "Gold":
|
||||
theme_type = "Light"
|
||||
var texture_button : TextureRect = Global.onion_skinning_button.get_child(0)
|
||||
if Global.onion_skinning:
|
||||
texture_button.texture = load("res://Assets/Graphics/%s Themes/Timeline/onion_skinning.png" % Global.theme_type)
|
||||
texture_button.texture = load("res://Assets/Graphics/%s Themes/Timeline/onion_skinning.png" % theme_type)
|
||||
else:
|
||||
texture_button.texture = load("res://Assets/Graphics/%s Themes/Timeline/onion_skinning_off.png" % Global.theme_type)
|
||||
texture_button.texture = load("res://Assets/Graphics/%s Themes/Timeline/onion_skinning_off.png" % theme_type)
|
||||
|
||||
|
||||
func _on_OnionSkinningSettings_pressed() -> void:
|
||||
|
@ -318,22 +322,26 @@ func _on_FirstFrame_pressed() -> void:
|
|||
Global.current_frame = 0
|
||||
|
||||
|
||||
func _on_FPSValue_value_changed(value) -> void:
|
||||
func _on_FPSValue_value_changed(value : float) -> void:
|
||||
fps = float(value)
|
||||
Global.animation_timer.wait_time = 1 / fps
|
||||
|
||||
func _on_PastOnionSkinning_value_changed(value) -> void:
|
||||
|
||||
func _on_PastOnionSkinning_value_changed(value : float) -> void:
|
||||
Global.onion_skinning_past_rate = int(value)
|
||||
Global.canvas.update()
|
||||
|
||||
func _on_FutureOnionSkinning_value_changed(value) -> void:
|
||||
|
||||
func _on_FutureOnionSkinning_value_changed(value : float) -> void:
|
||||
Global.onion_skinning_future_rate = int(value)
|
||||
Global.canvas.update()
|
||||
|
||||
func _on_BlueRedMode_toggled(button_pressed) -> void:
|
||||
|
||||
func _on_BlueRedMode_toggled(button_pressed : bool) -> void:
|
||||
Global.onion_skinning_blue_red = button_pressed
|
||||
Global.canvas.update()
|
||||
|
||||
|
||||
# Layer buttons
|
||||
|
||||
func add_layer(is_new := true) -> void:
|
||||
|
@ -376,6 +384,7 @@ func add_layer(is_new := true) -> void:
|
|||
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
|
||||
Global.undo_redo.commit_action()
|
||||
|
||||
|
||||
func _on_RemoveLayer_pressed() -> void:
|
||||
var new_layers : Array = Global.layers.duplicate()
|
||||
new_layers.remove(Global.current_layer)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
extends BaseButton
|
||||
|
||||
|
||||
signal brush_selected
|
||||
|
||||
export var brush_type = 0 # Global.Brush_Types.PIXEL
|
||||
export var custom_brush_index := -3
|
||||
# warning-ignore:unused_class_variable
|
||||
var random_brushes := []
|
||||
signal brush_selected
|
||||
|
||||
|
||||
func _on_BrushButton_pressed() -> void:
|
||||
# Delete the brush on middle mouse press
|
||||
|
@ -59,6 +61,7 @@ func _on_BrushButton_pressed() -> void:
|
|||
Global.update_right_custom_brush()
|
||||
emit_signal("brush_selected")
|
||||
|
||||
|
||||
func _on_DeleteButton_pressed() -> void:
|
||||
if brush_type == Global.Brush_Types.CUSTOM:
|
||||
if Global.custom_left_brush_index == custom_brush_index:
|
||||
|
@ -94,10 +97,12 @@ func _on_DeleteButton_pressed() -> void:
|
|||
Global.undo_redo.add_undo_method(Global, "undo_custom_brush", self)
|
||||
Global.undo_redo.commit_action()
|
||||
|
||||
|
||||
func _on_BrushButton_mouse_entered() -> void:
|
||||
if brush_type == Global.Brush_Types.CUSTOM:
|
||||
$DeleteButton.visible = true
|
||||
|
||||
|
||||
func _on_BrushButton_mouse_exited() -> void:
|
||||
if brush_type == Global.Brush_Types.CUSTOM:
|
||||
$DeleteButton.visible = false
|
||||
|
|
|
@ -32,6 +32,7 @@ func dir_move_zoom_multiplier(press_time : float) -> float:
|
|||
else:
|
||||
return 0.0
|
||||
|
||||
|
||||
func reset_dir_move_time(direction) -> void:
|
||||
Global.key_move_press_time[direction] = 0.0
|
||||
|
||||
|
@ -78,6 +79,7 @@ const directional_sign_multipliers := [
|
|||
Vector2(1.0, 0.0)
|
||||
]
|
||||
|
||||
|
||||
# Process an action event for a pressed direction
|
||||
# action
|
||||
func process_direction_action_pressed(event: InputEvent) -> void:
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
class_name Canvas
|
||||
extends Node2D
|
||||
|
||||
|
||||
const Drawer = preload("Drawers.gd").Drawer
|
||||
const SimpleDrawer = preload("Drawers.gd").SimpleDrawer
|
||||
const PixelPerfectDrawer = preload("Drawers.gd").PixelPerfectDrawer
|
||||
|
||||
var layers := []
|
||||
var current_layer_index := 0
|
||||
var location := Vector2.ZERO
|
||||
|
@ -27,10 +32,6 @@ var is_making_selection := "None"
|
|||
var line_2d : Line2D
|
||||
var pen_pressure := 1.0 # For tablet pressure sensitivity
|
||||
|
||||
const Drawer = preload("Drawers.gd").Drawer
|
||||
const SimpleDrawer = preload("Drawers.gd").SimpleDrawer
|
||||
const PixelPerfectDrawer = preload("Drawers.gd").PixelPerfectDrawer
|
||||
|
||||
var pixel_perfect_drawer := PixelPerfectDrawer.new()
|
||||
var pixel_perfect_drawer_h_mirror := PixelPerfectDrawer.new()
|
||||
var pixel_perfect_drawer_v_mirror := PixelPerfectDrawer.new()
|
||||
|
@ -82,6 +83,7 @@ func _ready() -> void:
|
|||
line_2d.add_point(previous_mouse_pos_for_lines)
|
||||
add_child(line_2d)
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
# Onion Skinning
|
||||
if Global.onion_skinning:
|
||||
|
@ -519,6 +521,7 @@ func _input(event : InputEvent) -> void:
|
|||
if sprite_changed_this_frame:
|
||||
update_texture(Global.current_layer)
|
||||
|
||||
|
||||
func camera_zoom() -> void:
|
||||
# Set camera zoom based on the sprite size
|
||||
var bigger_canvas_axis = max(size.x, size.y)
|
||||
|
@ -548,6 +551,7 @@ func camera_zoom() -> void:
|
|||
|
||||
Global.transparent_checker._ready() # To update the rect size
|
||||
|
||||
|
||||
func handle_undo(action : String) -> void:
|
||||
if !can_undo:
|
||||
return
|
||||
|
@ -575,6 +579,7 @@ func handle_undo(action : String) -> void:
|
|||
|
||||
can_undo = false
|
||||
|
||||
|
||||
func handle_redo(action : String) -> void:
|
||||
can_undo = true
|
||||
|
||||
|
@ -595,6 +600,7 @@ func handle_redo(action : String) -> void:
|
|||
Global.undo_redo.add_do_method(Global, "redo", canvases, layer_index)
|
||||
Global.undo_redo.commit_action()
|
||||
|
||||
|
||||
func update_texture(layer_index : int) -> void:
|
||||
layers[layer_index][1].create_from_image(layers[layer_index][0], 0)
|
||||
|
||||
|
@ -602,6 +608,7 @@ func update_texture(layer_index : int) -> void:
|
|||
frame_texture_rect = Global.find_node_by_name(Global.layers[layer_index][3].get_child(frame),"FrameTexture")
|
||||
frame_texture_rect.texture = layers[layer_index][1]
|
||||
|
||||
|
||||
func pencil_and_eraser(sprite : Image, mouse_pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
|
||||
if made_line:
|
||||
return
|
||||
|
@ -619,6 +626,7 @@ func pencil_and_eraser(sprite : Image, mouse_pos : Vector2, color : Color, curre
|
|||
elif point_in_rectangle(previous_mouse_pos, location, location + size):
|
||||
fill_gaps(sprite, mouse_pos, previous_mouse_pos, color, current_mouse_button, current_action)
|
||||
|
||||
|
||||
func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
|
||||
if Global.can_draw && Global.has_focus:
|
||||
var brush_size := 1
|
||||
|
@ -855,6 +863,7 @@ func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_butt
|
|||
if is_making_line:
|
||||
line_2d.set_point_position(0, previous_mouse_pos_for_lines)
|
||||
|
||||
|
||||
# Bresenham's Algorithm
|
||||
# Thanks to https://godotengine.org/qa/35276/tile-based-line-drawing-algorithm-efficiency
|
||||
func fill_gaps(sprite : Image, mouse_pos : Vector2, prev_mouse_pos : Vector2, color : Color, current_mouse_button : String, current_action := "None") -> void:
|
||||
|
@ -880,6 +889,7 @@ func fill_gaps(sprite : Image, mouse_pos : Vector2, prev_mouse_pos : Vector2, co
|
|||
err += dx
|
||||
y += sy
|
||||
|
||||
|
||||
# Thanks to https://en.wikipedia.org/wiki/Flood_fill
|
||||
func flood_fill(sprite : Image, pos : Vector2, target_color : Color, replace_color : Color) -> void:
|
||||
pos = pos.floor()
|
||||
|
@ -986,6 +996,7 @@ func plot_circle(sprite : Image, xm : int, ym : int, r : int, color : Color, fil
|
|||
var draw_pos := Vector2(i + xm, j + ym)
|
||||
draw_pixel_blended(sprite, draw_pos, color)
|
||||
|
||||
|
||||
func draw_pixel_blended(sprite : Image, pos : Vector2, color : Color) -> void:
|
||||
var saved_pixel_index := mouse_press_pixels.find(pos)
|
||||
if point_in_rectangle(pos, Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)) && (saved_pixel_index == -1 || pen_pressure > mouse_press_pressure_values[saved_pixel_index]):
|
||||
|
@ -999,6 +1010,7 @@ func draw_pixel_blended(sprite : Image, pos : Vector2, color : Color) -> void:
|
|||
mouse_press_pressure_values[saved_pixel_index] = pen_pressure
|
||||
sprite.set_pixelv(pos, color)
|
||||
|
||||
|
||||
func blend_colors(color_1 : Color, color_2 : Color) -> Color:
|
||||
var color := Color()
|
||||
color.a = color_1.a + color_2.a * (1 - color_1.a) # Blend alpha
|
||||
|
@ -1009,14 +1021,17 @@ func blend_colors(color_1 : Color, color_2 : Color) -> Color:
|
|||
color.b = (color_1.b * color_1.a + color_2.b * color_2.a * (1-color_1.a)) / color.a
|
||||
return color
|
||||
|
||||
|
||||
# Checks if a point is inside a rectangle
|
||||
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
|
||||
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
|
||||
|
||||
|
||||
# Returns the position in the middle of a rectangle
|
||||
func rectangle_center(rect_position : Vector2, rect_size : Vector2) -> Vector2:
|
||||
return (rect_position - rect_size / 2).floor()
|
||||
|
||||
|
||||
# Custom blend rect function, needed because Godot's issue #31124
|
||||
func blend_rect(bg : Image, brush : Image, src_rect : Rect2, dst : Vector2) -> void:
|
||||
var brush_size := brush.get_size()
|
||||
|
@ -1042,6 +1057,7 @@ func blend_rect(bg : Image, brush : Image, src_rect : Rect2, dst : Vector2) -> v
|
|||
bg.set_pixel(dst_x, dst_y, out_color)
|
||||
brush.unlock()
|
||||
|
||||
|
||||
func adjust_hsv(img: Image, id : int, delta : float) -> void:
|
||||
var layer : Image = img
|
||||
layer.lock()
|
||||
|
|
|
@ -12,6 +12,7 @@ onready var contributors : Tree = $AboutUI/Credits/Contributors/ContributorTree
|
|||
onready var donors : Tree = $AboutUI/Credits/Donors/DonorTree
|
||||
onready var translators : Tree = $AboutUI/Credits/Translators/TranslatorTree
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var contributor_root := contributors.create_item()
|
||||
contributors.create_item(contributor_root).set_text(0, " Hugo Locurcio (Calinou)")
|
||||
|
@ -37,6 +38,7 @@ func _ready() -> void:
|
|||
donors.create_item(donors_root).set_text(0, " pcmxms")
|
||||
donors.create_item(donors_root).set_text(0, " Mike King")
|
||||
|
||||
|
||||
func _on_AboutDialog_about_to_show() -> void:
|
||||
var current_version : String = ProjectSettings.get_setting("application/config/Version")
|
||||
window_title = tr("About Pixelorama") + " " + current_version
|
||||
|
@ -86,10 +88,12 @@ func _on_AboutDialog_about_to_show() -> void:
|
|||
translators.create_item(translators_root).set_text(0, " Agnis Aldiņš (NeZvers) - " + tr("Latvian"))
|
||||
translators.create_item(translators_root).set_text(0, " Teashrock - " + tr("Esperanto"))
|
||||
|
||||
|
||||
func _on_AboutDialog_popup_hide() -> void:
|
||||
groups.clear()
|
||||
developers.clear()
|
||||
|
||||
|
||||
func _on_Groups_item_selected() -> void:
|
||||
for child in credits.get_children():
|
||||
if child != groups:
|
||||
|
@ -109,8 +113,10 @@ func _on_Groups_item_selected() -> void:
|
|||
func _on_Website_pressed() -> void:
|
||||
OS.shell_open("https://www.orama-interactive.com/pixelorama")
|
||||
|
||||
|
||||
func _on_GitHub_pressed() -> void:
|
||||
OS.shell_open("https://github.com/Orama-Interactive/Pixelorama")
|
||||
|
||||
|
||||
func _on_Donate_pressed() -> void:
|
||||
OS.shell_open("https://www.patreon.com/OramaInteractive")
|
||||
|
|
|
@ -51,13 +51,15 @@ var TStrings ={
|
|||
Templates.SNES_PAL: "SNES (PAL)"
|
||||
}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
ratio_box.connect("pressed", self, "_on_RatioCheckBox_toggled", [ratio_box.pressed])
|
||||
templates_options.connect("item_selected", self, "_on_TemplatesOptions_item_selected")
|
||||
|
||||
_CreateOptionList()
|
||||
|
||||
func _CreateOptionList():
|
||||
|
||||
func _CreateOptionList() -> void:
|
||||
for i in Templates.values():
|
||||
if i > 0:
|
||||
if TStrings[i] != "":
|
||||
|
@ -65,6 +67,7 @@ func _CreateOptionList():
|
|||
else:
|
||||
templates_options.add_item("{width}x{height}".format({"width":TResolutions[i].x, "height":TResolutions[i].y}), i)
|
||||
|
||||
|
||||
func _on_CreateNewImage_confirmed() -> void:
|
||||
var width : int = width_value.value
|
||||
var height : int = height_value.value
|
||||
|
@ -89,6 +92,7 @@ func _on_CreateNewImage_confirmed() -> void:
|
|||
Global.canvas.layers[0][0].lock()
|
||||
Global.canvas.update_texture(0)
|
||||
|
||||
|
||||
func _on_CreateNewImage_about_to_show() -> void:
|
||||
width_value.value = Global.default_image_width
|
||||
height_value.value = Global.default_image_height
|
||||
|
@ -99,10 +103,10 @@ func _on_CreateNewImage_about_to_show() -> void:
|
|||
if spin_box.is_connected("value_changed", self, "_on_SizeValue_value_changed"):
|
||||
spin_box.disconnect("value_changed", self, "_on_SizeValue_value_changed")
|
||||
|
||||
|
||||
var aspect_ratio: float
|
||||
|
||||
# warning-ignore:unused_argument
|
||||
func _on_RatioCheckBox_toggled(button_pressed: bool) -> void:
|
||||
func _on_RatioCheckBox_toggled(_button_pressed: bool) -> void:
|
||||
aspect_ratio = width_value.value / height_value.value
|
||||
for spin_box in [width_value, height_value]:
|
||||
if spin_box.is_connected("value_changed", self, "_on_SizeValue_value_changed"):
|
||||
|
@ -110,12 +114,14 @@ func _on_RatioCheckBox_toggled(button_pressed: bool) -> void:
|
|||
else:
|
||||
spin_box.connect("value_changed", self, "_on_SizeValue_value_changed")
|
||||
|
||||
|
||||
func _on_SizeValue_value_changed(value: float) -> void:
|
||||
if width_value.value == value:
|
||||
height_value.value = width_value.value / aspect_ratio
|
||||
if height_value.value == value:
|
||||
width_value.value = height_value.value * aspect_ratio
|
||||
|
||||
|
||||
func _on_TemplatesOptions_item_selected(id: int) -> void:
|
||||
if id != Templates.TDefault:
|
||||
size_value = TResolutions[id]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
extends AcceptDialog
|
||||
|
||||
enum ExportTab { Frame = 0, Spritesheet = 1, Animation = 2 }
|
||||
var current_tab : int = ExportTab.Frame
|
||||
enum ExportTab { FRAME = 0, SPRITESHEET = 1, ANIMATION = 2 }
|
||||
var current_tab : int = ExportTab.FRAME
|
||||
|
||||
# All canvases and their layers processed/blended into images
|
||||
var processed_images = [] # Image[]
|
||||
|
@ -10,17 +10,17 @@ var processed_images = [] # Image[]
|
|||
var frame_number := 0
|
||||
|
||||
# Spritesheet options
|
||||
enum Orientation { Rows = 0, Columns = 1 }
|
||||
var orientation : int = Orientation.Rows
|
||||
enum Orientation { ROWS = 0, COLUMNS = 1 }
|
||||
var orientation : int = Orientation.ROWS
|
||||
# How many rows/columns before new line is added
|
||||
var lines_count := 1
|
||||
|
||||
# Animation options
|
||||
enum AnimationType { MultipleFiles = 0, Animated = 1 }
|
||||
var animation_type : int = AnimationType.MultipleFiles
|
||||
enum AnimationType { MULTIPLE_FILES = 0, ANIMATED = 1 }
|
||||
var animation_type : int = AnimationType.MULTIPLE_FILES
|
||||
var background_color : Color = Color.white
|
||||
enum AnimationDirection { Forward = 0, Backwards = 1, PingPong = 2 }
|
||||
var direction : int = AnimationDirection.Forward
|
||||
enum AnimationDirection { FORWARD = 0, BACKWARDS = 1, PING_PONG = 2 }
|
||||
var direction : int = AnimationDirection.FORWARD
|
||||
|
||||
# Options
|
||||
var resize := 100
|
||||
|
@ -57,6 +57,7 @@ var stop_export = false
|
|||
var animated_preview_current_frame := 0
|
||||
var animated_preview_frames = []
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$VBoxContainer/Tabs.add_tab("Frame")
|
||||
$VBoxContainer/Tabs.add_tab("Spritesheet")
|
||||
|
@ -70,16 +71,17 @@ func _ready() -> void:
|
|||
|
||||
# Disable GIF export for unsupported platforms
|
||||
if not $GifExporter.is_platform_supported():
|
||||
$VBoxContainer/AnimationOptions/AnimationType.selected = AnimationType.MultipleFiles
|
||||
$VBoxContainer/AnimationOptions/AnimationType.selected = AnimationType.MULTIPLE_FILES
|
||||
$VBoxContainer/AnimationOptions/AnimationType.disabled = true
|
||||
|
||||
|
||||
func show_tab() -> void:
|
||||
$VBoxContainer/FrameOptions.hide()
|
||||
$VBoxContainer/SpritesheetOptions.hide()
|
||||
$VBoxContainer/AnimationOptions.hide()
|
||||
|
||||
match current_tab:
|
||||
ExportTab.Frame:
|
||||
ExportTab.FRAME:
|
||||
file_format = FileFormat.PNG
|
||||
$VBoxContainer/File/FileFormat.selected = FileFormat.PNG
|
||||
$FrameTimer.stop()
|
||||
|
@ -89,12 +91,12 @@ func show_tab() -> void:
|
|||
$VBoxContainer/FrameOptions/FrameNumber/FrameNumber.value = frame_number
|
||||
process_frame()
|
||||
$VBoxContainer/FrameOptions.show()
|
||||
ExportTab.Spritesheet:
|
||||
ExportTab.SPRITESHEET:
|
||||
file_format = FileFormat.PNG
|
||||
$VBoxContainer/File/FileFormat.selected = FileFormat.PNG
|
||||
$FrameTimer.stop()
|
||||
if not was_exported:
|
||||
orientation = Orientation.Rows
|
||||
orientation = Orientation.ROWS
|
||||
lines_count = int(ceil(sqrt(Global.canvases.size())))
|
||||
$VBoxContainer/SpritesheetOptions/Orientation/Orientation.selected = orientation
|
||||
$VBoxContainer/SpritesheetOptions/Orientation/LinesCount.max_value = Global.canvases.size()
|
||||
|
@ -102,7 +104,7 @@ func show_tab() -> void:
|
|||
$VBoxContainer/SpritesheetOptions/Orientation/LinesCountLabel.text = "Columns:"
|
||||
process_spritesheet()
|
||||
$VBoxContainer/SpritesheetOptions.show()
|
||||
ExportTab.Animation:
|
||||
ExportTab.ANIMATION:
|
||||
set_file_format_selector()
|
||||
process_animation()
|
||||
$VBoxContainer/AnimationOptions/AnimationType.selected = animation_type
|
||||
|
@ -116,11 +118,11 @@ func show_tab() -> void:
|
|||
func external_export() -> void:
|
||||
restore_previous_export_settings()
|
||||
match current_tab:
|
||||
ExportTab.Frame:
|
||||
ExportTab.FRAME:
|
||||
process_frame()
|
||||
ExportTab.Spritesheet:
|
||||
ExportTab.SPRITESHEET:
|
||||
process_spritesheet()
|
||||
ExportTab.Animation:
|
||||
ExportTab.ANIMATION:
|
||||
process_animation()
|
||||
export_processed_images(true)
|
||||
|
||||
|
@ -136,8 +138,8 @@ func process_frame() -> void:
|
|||
|
||||
func process_spritesheet() -> void:
|
||||
# If rows mode selected calculate columns count and vice versa
|
||||
var spritesheet_columns = lines_count if orientation == Orientation.Rows else frames_divided_by_spritesheet_lines()
|
||||
var spritesheet_rows = lines_count if orientation == Orientation.Columns else frames_divided_by_spritesheet_lines()
|
||||
var spritesheet_columns = lines_count if orientation == Orientation.ROWS else frames_divided_by_spritesheet_lines()
|
||||
var spritesheet_rows = lines_count if orientation == Orientation.COLUMNS else frames_divided_by_spritesheet_lines()
|
||||
|
||||
var width = Global.canvas.size.x * spritesheet_columns
|
||||
var height = Global.canvas.size.y * spritesheet_rows
|
||||
|
@ -149,7 +151,7 @@ func process_spritesheet() -> void:
|
|||
var hh := 0
|
||||
var vv := 0
|
||||
for canvas in Global.canvases:
|
||||
if orientation == Orientation.Rows:
|
||||
if orientation == Orientation.ROWS:
|
||||
if vv < spritesheet_columns:
|
||||
origin.x = canvas.size.x * vv
|
||||
vv += 1
|
||||
|
@ -184,16 +186,16 @@ func process_animation() -> void:
|
|||
|
||||
func set_preview() -> void:
|
||||
remove_previews()
|
||||
if processed_images.size() == 1 and current_tab != ExportTab.Animation:
|
||||
if processed_images.size() == 1 and current_tab != ExportTab.ANIMATION:
|
||||
$VBoxContainer/PreviewScroll/Previews.columns = 1
|
||||
add_image_preview(processed_images[0])
|
||||
else:
|
||||
match animation_type:
|
||||
AnimationType.MultipleFiles:
|
||||
AnimationType.MULTIPLE_FILES:
|
||||
$VBoxContainer/PreviewScroll/Previews.columns = ceil(sqrt(processed_images.size()))
|
||||
for i in range(processed_images.size()):
|
||||
add_image_preview(processed_images[i], i + 1)
|
||||
AnimationType.Animated:
|
||||
AnimationType.ANIMATED:
|
||||
$VBoxContainer/PreviewScroll/Previews.columns = 1
|
||||
add_animated_preview()
|
||||
|
||||
|
@ -215,7 +217,7 @@ func add_image_preview(image: Image, canvas_number: int = -1) -> void:
|
|||
|
||||
|
||||
func add_animated_preview() -> void:
|
||||
animated_preview_current_frame = processed_images.size() - 1 if direction == AnimationDirection.Backwards else 0
|
||||
animated_preview_current_frame = processed_images.size() - 1 if direction == AnimationDirection.BACKWARDS else 0
|
||||
animated_preview_frames = []
|
||||
|
||||
for processed_image in processed_images:
|
||||
|
@ -278,7 +280,7 @@ func export_processed_images(ignore_overwrites : bool) -> void:
|
|||
var export_paths = []
|
||||
for i in range(processed_images.size()):
|
||||
stop_export = false
|
||||
var multiple_files := true if (current_tab == ExportTab.Animation && animation_type == AnimationType.MultipleFiles) else false
|
||||
var multiple_files := true if (current_tab == ExportTab.ANIMATION && animation_type == AnimationType.MULTIPLE_FILES) else false
|
||||
var export_path = create_export_path(multiple_files, i + 1)
|
||||
# If user want to create new directory for each animation tag then check if directories exist and create them if not
|
||||
if multiple_files and new_dir_for_each_frame_tag:
|
||||
|
@ -301,24 +303,24 @@ func export_processed_images(ignore_overwrites : bool) -> void:
|
|||
return
|
||||
export_paths.append(export_path)
|
||||
# Only get one export path if single file animated image is exported
|
||||
if current_tab == ExportTab.Animation && animation_type == AnimationType.Animated:
|
||||
if current_tab == ExportTab.ANIMATION && animation_type == AnimationType.ANIMATED:
|
||||
break
|
||||
|
||||
# Scale images that are to export
|
||||
scale_processed_images()
|
||||
|
||||
if current_tab == ExportTab.Animation && animation_type == AnimationType.Animated:
|
||||
if current_tab == ExportTab.ANIMATION && animation_type == AnimationType.ANIMATED:
|
||||
var frame_delay_in_ms = Global.animation_timer.wait_time * 100
|
||||
|
||||
$GifExporter.begin_export(export_paths[0], processed_images[0].get_width(), processed_images[0].get_height(), frame_delay_in_ms, 0)
|
||||
match direction:
|
||||
AnimationDirection.Forward:
|
||||
AnimationDirection.FORWARD:
|
||||
for i in range(processed_images.size()):
|
||||
$GifExporter.write_frame(processed_images[i], background_color, frame_delay_in_ms)
|
||||
AnimationDirection.Backwards:
|
||||
AnimationDirection.BACKWARDS:
|
||||
for i in range(processed_images.size() - 1, -1, -1):
|
||||
$GifExporter.write_frame(processed_images[i], background_color, frame_delay_in_ms)
|
||||
AnimationDirection.PingPong:
|
||||
AnimationDirection.PING_PONG:
|
||||
for i in range(0, processed_images.size()):
|
||||
$GifExporter.write_frame(processed_images[i], background_color, frame_delay_in_ms)
|
||||
for i in range(processed_images.size() - 2, 0, -1):
|
||||
|
@ -410,19 +412,20 @@ func file_format_string(format_enum : int) -> String:
|
|||
func set_file_format_selector() -> void:
|
||||
$VBoxContainer/AnimationOptions/MultipleAnimationsDirectories.visible = false
|
||||
match animation_type:
|
||||
AnimationType.MultipleFiles:
|
||||
AnimationType.MULTIPLE_FILES:
|
||||
file_format = FileFormat.PNG
|
||||
$VBoxContainer/File/FileFormat.selected = FileFormat.PNG
|
||||
$FrameTimer.stop()
|
||||
$VBoxContainer/AnimationOptions/AnimatedOptions.hide()
|
||||
$VBoxContainer/AnimationOptions/MultipleAnimationsDirectories.pressed = new_dir_for_each_frame_tag
|
||||
$VBoxContainer/AnimationOptions/MultipleAnimationsDirectories.visible = true
|
||||
AnimationType.Animated:
|
||||
AnimationType.ANIMATED:
|
||||
file_format = FileFormat.GIF
|
||||
$VBoxContainer/File/FileFormat.selected = FileFormat.GIF
|
||||
$FrameTimer.wait_time = Global.animation_timer.wait_time
|
||||
$VBoxContainer/AnimationOptions/AnimatedOptions.show()
|
||||
|
||||
|
||||
func store_export_settings() -> void:
|
||||
exported_tab = current_tab
|
||||
exported_frame_number = frame_number
|
||||
|
@ -437,6 +440,7 @@ func store_export_settings() -> void:
|
|||
exported_file_name = file_name
|
||||
exported_file_format = file_format
|
||||
|
||||
|
||||
# Fill the dialog with previous export settings
|
||||
func restore_previous_export_settings() -> void:
|
||||
current_tab = exported_tab
|
||||
|
@ -475,6 +479,7 @@ func _on_ExportDialog_about_to_show() -> void:
|
|||
file_exists_alert = tr("File %s already exists. Overwrite?") # Update translation
|
||||
#$VBoxContainer/Tabs.set_tab_title(0, "Frame")
|
||||
|
||||
|
||||
func _on_Tabs_tab_clicked(tab : int) -> void:
|
||||
current_tab = tab
|
||||
show_tab()
|
||||
|
@ -488,7 +493,7 @@ func _on_Frame_value_changed(value: float) -> void:
|
|||
|
||||
func _on_Orientation_item_selected(id : int) -> void:
|
||||
orientation = id
|
||||
if orientation == Orientation.Rows:
|
||||
if orientation == Orientation.ROWS:
|
||||
$VBoxContainer/SpritesheetOptions/Orientation/LinesCountLabel.text = "Columns:"
|
||||
else:
|
||||
$VBoxContainer/SpritesheetOptions/Orientation/LinesCountLabel.text = "Rows:"
|
||||
|
@ -516,13 +521,13 @@ func _on_BackgroundColor_color_changed(color : Color) -> void:
|
|||
func _on_Direction_item_selected(id : int) -> void:
|
||||
direction = id
|
||||
match id:
|
||||
AnimationDirection.Forward:
|
||||
AnimationDirection.FORWARD:
|
||||
animated_preview_current_frame = 0
|
||||
AnimationDirection.Backwards:
|
||||
AnimationDirection.BACKWARDS:
|
||||
animated_preview_current_frame = processed_images.size() - 1
|
||||
AnimationDirection.PingPong:
|
||||
AnimationDirection.PING_PONG:
|
||||
animated_preview_current_frame = 0
|
||||
pingpong_direction = AnimationDirection.Forward
|
||||
pingpong_direction = AnimationDirection.FORWARD
|
||||
|
||||
|
||||
func _on_Resize_value_changed(value : float) -> void:
|
||||
|
@ -579,39 +584,39 @@ func _on_FileExistsAlert_custom_action(action : String) -> void:
|
|||
$Popups/FileExistsAlert.hide()
|
||||
|
||||
|
||||
var pingpong_direction = AnimationDirection.Forward
|
||||
var pingpong_direction = AnimationDirection.FORWARD
|
||||
func _on_FrameTimer_timeout() -> void:
|
||||
$VBoxContainer/PreviewScroll/Previews/PreviewContainer/Preview.texture = animated_preview_frames[animated_preview_current_frame]
|
||||
|
||||
match direction:
|
||||
AnimationDirection.Forward:
|
||||
AnimationDirection.FORWARD:
|
||||
if animated_preview_current_frame == animated_preview_frames.size() - 1:
|
||||
animated_preview_current_frame = 0
|
||||
else:
|
||||
animated_preview_current_frame += 1
|
||||
|
||||
AnimationDirection.Backwards:
|
||||
AnimationDirection.BACKWARDS:
|
||||
if animated_preview_current_frame == 0:
|
||||
animated_preview_current_frame = processed_images.size() - 1
|
||||
else:
|
||||
animated_preview_current_frame -= 1
|
||||
|
||||
AnimationDirection.PingPong:
|
||||
AnimationDirection.PING_PONG:
|
||||
match pingpong_direction:
|
||||
AnimationDirection.Forward:
|
||||
AnimationDirection.FORWARD:
|
||||
if animated_preview_current_frame == animated_preview_frames.size() - 1:
|
||||
pingpong_direction = AnimationDirection.Backwards
|
||||
pingpong_direction = AnimationDirection.BACKWARDS
|
||||
animated_preview_current_frame -= 1
|
||||
if animated_preview_current_frame <= 0:
|
||||
animated_preview_current_frame = 0
|
||||
else:
|
||||
animated_preview_current_frame += 1
|
||||
AnimationDirection.Backwards:
|
||||
AnimationDirection.BACKWARDS:
|
||||
if animated_preview_current_frame == 0:
|
||||
animated_preview_current_frame += 1
|
||||
if animated_preview_current_frame >= animated_preview_frames.size() - 1:
|
||||
animated_preview_current_frame = 0
|
||||
pingpong_direction = AnimationDirection.Forward
|
||||
pingpong_direction = AnimationDirection.FORWARD
|
||||
else:
|
||||
animated_preview_current_frame -= 1
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
extends WindowDialog
|
||||
|
||||
var current_layer : Image
|
||||
var preview_image : Image
|
||||
var preview_texture : ImageTexture
|
||||
|
||||
onready var hue_slider = $MarginContainer/VBoxContainer/HBoxContainer/Sliders/Hue
|
||||
onready var sat_slider = $MarginContainer/VBoxContainer/HBoxContainer/Sliders/Saturation
|
||||
onready var val_slider = $MarginContainer/VBoxContainer/HBoxContainer/Sliders/Value
|
||||
|
@ -10,26 +14,26 @@ onready var val_spinbox = $MarginContainer/VBoxContainer/HBoxContainer/TextBoxes
|
|||
|
||||
onready var preview = $MarginContainer/VBoxContainer/TextureRect
|
||||
|
||||
var current_layer:Image
|
||||
var preview_image:Image
|
||||
var preview_texture:ImageTexture
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
current_layer = Image.new()
|
||||
preview_image = Image.new()
|
||||
preview_texture = ImageTexture.new()
|
||||
preview_texture.flags = 0
|
||||
|
||||
func _on_HSVDialog_about_to_show():
|
||||
|
||||
func _on_HSVDialog_about_to_show() -> void:
|
||||
current_layer = Global.canvas.layers[Global.current_layer][0]
|
||||
preview_image.copy_from(current_layer)
|
||||
update_preview()
|
||||
|
||||
func _on_Cancel_pressed():
|
||||
|
||||
func _on_Cancel_pressed() -> void:
|
||||
visible = false
|
||||
reset()
|
||||
|
||||
func _on_Apply_pressed():
|
||||
|
||||
func _on_Apply_pressed() -> void:
|
||||
Global.canvas.handle_undo("Draw")
|
||||
Global.canvas.adjust_hsv(current_layer,0,hue_slider.value)
|
||||
Global.canvas.adjust_hsv(current_layer,1,sat_slider.value)
|
||||
|
@ -39,6 +43,7 @@ func _on_Apply_pressed():
|
|||
reset()
|
||||
visible = false
|
||||
|
||||
|
||||
func reset() -> void:
|
||||
disconnect_signals()
|
||||
hue_slider.value = 0
|
||||
|
@ -49,6 +54,7 @@ func reset() -> void:
|
|||
val_spinbox.value = 0
|
||||
reconnect_signals()
|
||||
|
||||
|
||||
func update_preview() -> void:
|
||||
preview_image.copy_from(current_layer)
|
||||
Global.canvas.adjust_hsv(preview_image,0,hue_slider.value)
|
||||
|
@ -57,6 +63,7 @@ func update_preview() -> void:
|
|||
preview_texture.create_from_image(preview_image, 0)
|
||||
preview.texture = preview_texture
|
||||
|
||||
|
||||
func disconnect_signals() -> void:
|
||||
hue_slider.disconnect("value_changed",self,"_on_Hue_value_changed")
|
||||
sat_slider.disconnect("value_changed",self,"_on_Saturation_value_changed")
|
||||
|
@ -65,6 +72,7 @@ func disconnect_signals() -> void:
|
|||
sat_spinbox.disconnect("value_changed",self,"_on_Saturation_value_changed")
|
||||
val_spinbox.disconnect("value_changed",self,"_on_Value_value_changed")
|
||||
|
||||
|
||||
func reconnect_signals() -> void:
|
||||
hue_slider.connect("value_changed",self,"_on_Hue_value_changed")
|
||||
sat_slider.connect("value_changed",self,"_on_Saturation_value_changed")
|
||||
|
@ -73,24 +81,20 @@ func reconnect_signals() -> void:
|
|||
sat_spinbox.connect("value_changed",self,"_on_Saturation_value_changed")
|
||||
val_spinbox.connect("value_changed",self,"_on_Value_value_changed")
|
||||
|
||||
func _on_Hue_value_changed(value):
|
||||
|
||||
func _on_Hue_value_changed(value : float) -> void:
|
||||
hue_spinbox.value = value
|
||||
hue_slider.value = value
|
||||
update_preview()
|
||||
|
||||
func _on_Saturation_value_changed(value):
|
||||
|
||||
func _on_Saturation_value_changed(value : float) -> void:
|
||||
sat_spinbox.value = value
|
||||
sat_slider.value = value
|
||||
update_preview()
|
||||
|
||||
func _on_Value_value_changed(value):
|
||||
|
||||
func _on_Value_value_changed(value : float) -> void:
|
||||
val_spinbox.value = value
|
||||
val_slider.value = value
|
||||
update_preview()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,20 +15,25 @@ func _ready() -> void:
|
|||
remove_child(child)
|
||||
get_vbox().add_child(child)
|
||||
|
||||
|
||||
func _on_ImportAsNewFrame_pressed() -> void:
|
||||
new_frame = !new_frame
|
||||
|
||||
|
||||
func _on_ImportSpritesheet_pressed() -> void:
|
||||
import_spritesheet = !import_spritesheet
|
||||
var spritesheet_container = Global.find_node_by_name(self, "Spritesheet")
|
||||
spritesheet_container.visible = import_spritesheet
|
||||
|
||||
|
||||
func _on_HorizontalFrames_value_changed(value) -> void:
|
||||
spritesheet_horizontal = value
|
||||
|
||||
|
||||
func _on_VerticalFrames_value_changed(value) -> void:
|
||||
spritesheet_vertical = value
|
||||
|
||||
|
||||
func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
|
||||
Global.control.opensprite_file_selected = true
|
||||
if !new_frame: # If we're not adding a new frame, delete the previous
|
||||
|
|
|
@ -3,6 +3,7 @@ extends ConfirmationDialog
|
|||
func _ready() -> void:
|
||||
$OptionsContainer/OutlineColor.get_picker().presets_visible = false
|
||||
|
||||
|
||||
func _on_OutlineDialog_confirmed() -> void:
|
||||
var outline_color : Color = $OptionsContainer/OutlineColor.color
|
||||
var thickness : int = $OptionsContainer/ThickValue.value
|
||||
|
|
|
@ -37,6 +37,7 @@ var shortcut_already_assigned = false
|
|||
var old_input_event : InputEventKey
|
||||
var new_input_event : InputEventKey
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Disable input until the shortcut selector is displayed
|
||||
set_process_input(false)
|
||||
|
@ -536,7 +537,7 @@ func _on_ShortcutSelector_confirmed() -> void:
|
|||
$Popups/ShortcutSelector.hide()
|
||||
|
||||
|
||||
func _on_OpenLastProject_pressed():
|
||||
func _on_OpenLastProject_pressed() -> void:
|
||||
Global.open_last_project = !Global.open_last_project
|
||||
Global.config_cache.set_value("preferences", "open_last_project", Global.open_last_project)
|
||||
Global.config_cache.save("user://cache.ini")
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
extends ConfirmationDialog
|
||||
|
||||
|
||||
func _on_ScaleImage_confirmed() -> void:
|
||||
var width : int = $VBoxContainer/OptionsContainer/WidthValue.value
|
||||
var height : int = $VBoxContainer/OptionsContainer/HeightValue.value
|
||||
|
|
|
@ -7,6 +7,7 @@ onready var developed_by_label : Label = $"Contents/MarginContainer/Info/VBoxCon
|
|||
onready var platinum_placeholder_label : Label = $"Contents/MarginContainer/Info/Sponsors/PlatinumContainer/PlaceholderLabel"
|
||||
onready var gold_placeholder_label : Label = $"Contents/MarginContainer/Info/Sponsors/GoldContainer/PlaceholderLabel"
|
||||
|
||||
|
||||
func _on_SplashDialog_about_to_show() -> void:
|
||||
if Global.config_cache.has_section_key("preferences", "startup"):
|
||||
show_on_startup_button.pressed = !Global.config_cache.get_value("preferences", "startup")
|
||||
|
@ -26,40 +27,49 @@ func _on_SplashDialog_about_to_show() -> void:
|
|||
platinum_placeholder_label.add_font_override("font", preload("res://Assets/Fonts/Roboto-Bold.tres"))
|
||||
gold_placeholder_label.add_font_override("font", preload("res://Assets/Fonts/Roboto-Bold.tres"))
|
||||
|
||||
|
||||
func _on_ArtCredits_pressed() -> void:
|
||||
OS.shell_open("https://www.instagram.com/erevoid")
|
||||
|
||||
|
||||
func _on_ShowOnStartup_toggled(pressed : bool) -> void:
|
||||
if pressed:
|
||||
Global.config_cache.set_value("preferences", "startup", false)
|
||||
else:
|
||||
Global.config_cache.set_value("preferences", "startup", true)
|
||||
|
||||
|
||||
func _on_PatronButton_pressed() -> void:
|
||||
OS.shell_open("https://www.patreon.com/OramaInteractive")
|
||||
|
||||
|
||||
func _on_TakeThisSpot_pressed() -> void:
|
||||
OS.shell_open("https://www.patreon.com/OramaInteractive")
|
||||
|
||||
func _on_GithubButton_pressed():
|
||||
|
||||
func _on_GithubButton_pressed() -> void:
|
||||
OS.shell_open("https://github.com/Orama-Interactive/Pixelorama")
|
||||
|
||||
func _on_DiscordButton_pressed():
|
||||
|
||||
func _on_DiscordButton_pressed() -> void:
|
||||
OS.shell_open("https://discord.gg/GTMtr8s")
|
||||
|
||||
|
||||
func _on_NewBtn_pressed():
|
||||
func _on_NewBtn_pressed() -> void:
|
||||
Global.control.file_menu_id_pressed(0)
|
||||
visible = false
|
||||
|
||||
func _on_OpenBtn__pressed():
|
||||
|
||||
func _on_OpenBtn__pressed() -> void:
|
||||
Global.control.file_menu_id_pressed(1)
|
||||
visible = false
|
||||
|
||||
func _on_OpenLastBtn_pressed():
|
||||
|
||||
func _on_OpenLastBtn_pressed() -> void:
|
||||
Global.control.file_menu_id_pressed(2)
|
||||
visible = false
|
||||
|
||||
func _on_ImportBtn_pressed():
|
||||
|
||||
func _on_ImportBtn_pressed() -> void:
|
||||
Global.control.file_menu_id_pressed(5)
|
||||
visible = false
|
||||
|
|
|
@ -10,6 +10,7 @@ class SimpleDrawer extends Drawer:
|
|||
func reset() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func set_pixel(_sprite: Image, _pos: Vector2, _new_color: Color) -> void:
|
||||
_sprite.set_pixel(_pos.x, _pos.y, _new_color)
|
||||
|
||||
|
@ -19,9 +20,11 @@ class PixelPerfectDrawer extends Drawer:
|
|||
const corners = [Vector2(1, 1), Vector2(-1, -1), Vector2(-1, 1), Vector2(1, -1)]
|
||||
var last_pixels = [null, null]
|
||||
|
||||
|
||||
func reset():
|
||||
last_pixels = [null, null]
|
||||
|
||||
|
||||
func set_pixel(_sprite: Image, _pos: Vector2, _new_color: Color) -> void:
|
||||
last_pixels.push_back([_pos, _sprite.get_pixel(_pos.x, _pos.y)])
|
||||
_sprite.set_pixel(_pos.x, _pos.y, _new_color)
|
||||
|
|
|
@ -117,8 +117,8 @@ var show_animation_timeline := true
|
|||
|
||||
# Onion skinning options
|
||||
var onion_skinning := false
|
||||
var onion_skinning_past_rate := 1
|
||||
var onion_skinning_future_rate := 1
|
||||
var onion_skinning_past_rate := 1.0
|
||||
var onion_skinning_future_rate := 1.0
|
||||
var onion_skinning_blue_red := false
|
||||
|
||||
# Brushes
|
||||
|
@ -238,7 +238,6 @@ var onion_skinning_button : BaseButton
|
|||
var loop_animation_button : BaseButton
|
||||
var play_forward : BaseButton
|
||||
var play_backwards : BaseButton
|
||||
var timeline_seconds : Control
|
||||
var layers_container : VBoxContainer
|
||||
var frames_container : VBoxContainer
|
||||
var tag_container : Control
|
||||
|
@ -874,6 +873,7 @@ func update_left_custom_brush() -> void:
|
|||
|
||||
left_brush_type_button.get_child(0).texture = custom_left_brush_texture
|
||||
|
||||
|
||||
func update_right_custom_brush() -> void:
|
||||
if current_right_brush_type == Brush_Types.PIXEL:
|
||||
var pixel := Image.new()
|
||||
|
@ -899,6 +899,7 @@ func update_right_custom_brush() -> void:
|
|||
|
||||
right_brush_type_button.get_child(0).texture = custom_right_brush_texture
|
||||
|
||||
|
||||
func blend_image_with_color(image : Image, color : Color, interpolate_factor : float) -> Image:
|
||||
var blended_image := Image.new()
|
||||
blended_image.copy_from(image)
|
||||
|
@ -916,6 +917,7 @@ func blend_image_with_color(image : Image, color : Color, interpolate_factor : f
|
|||
blended_image.set_pixel(xx, yy, Color(0, 0, 0, 0))
|
||||
return blended_image
|
||||
|
||||
|
||||
# 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
|
||||
|
@ -940,6 +942,7 @@ func plot_circle(r : int) -> Array:
|
|||
err += x * 2 + 1
|
||||
return circle_points
|
||||
|
||||
|
||||
func scale3X(sprite : Image, tol : float = 50) -> Image:
|
||||
var scaled = Image.new()
|
||||
scaled.create(sprite.get_width()*3, sprite.get_height()*3, false, Image.FORMAT_RGBA8)
|
||||
|
@ -997,6 +1000,7 @@ func scale3X(sprite : Image, tol : float = 50) -> Image:
|
|||
sprite.unlock()
|
||||
return scaled
|
||||
|
||||
|
||||
func rotxel(sprite : Image, angle : float) -> void:
|
||||
|
||||
# If angle is simple, then nn rotation is the best
|
||||
|
@ -1108,11 +1112,13 @@ func rotxel(sprite : Image, angle : float) -> void:
|
|||
sprite.unlock()
|
||||
aux.unlock()
|
||||
|
||||
|
||||
func fake_rotsprite(sprite : Image, angle : float) -> void:
|
||||
sprite.copy_from(scale3X(sprite))
|
||||
nn_rotate(sprite,angle)
|
||||
sprite.resize(sprite.get_width()/3,sprite.get_height()/3,0)
|
||||
|
||||
|
||||
func nn_rotate(sprite : Image, angle : float) -> void:
|
||||
var aux : Image = Image.new()
|
||||
aux.copy_from(sprite)
|
||||
|
@ -1132,14 +1138,17 @@ func nn_rotate(sprite : Image, angle : float) -> void:
|
|||
sprite.unlock()
|
||||
aux.unlock()
|
||||
|
||||
|
||||
func similarColors(c1 : Color, c2 : Color, tol : float = 100) -> bool:
|
||||
var dist = colorDistance(c1, c2)
|
||||
return dist <= tol
|
||||
|
||||
|
||||
func colorDistance(c1 : Color, c2 : Color) -> float:
|
||||
return sqrt(pow((c1.r - c2.r)*255, 2) + pow((c1.g - c2.g)*255, 2)
|
||||
+ pow((c1.b - c2.b)*255, 2) + pow((c1.a - c2.a)*255, 2))
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
config_cache.set_value("window", "screen", OS.current_screen)
|
||||
config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
extends Node
|
||||
|
||||
|
||||
# Get hold of the brushes, including random brushes (subdirectories and % files
|
||||
# in them, non % files get loaded independently.) nyaaa
|
||||
# Returns a list of [
|
||||
|
@ -304,6 +305,7 @@ func import_gpl(path : String) -> Palette:
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func import_png_palette(path: String) -> Palette:
|
||||
var result: Palette = null
|
||||
|
||||
|
@ -332,4 +334,3 @@ func import_png_palette(path: String) -> Palette:
|
|||
result.name = path.substr(name_start, name_end - name_start)
|
||||
|
||||
return result
|
||||
pass
|
||||
|
|
|
@ -8,6 +8,7 @@ var linked_button : BaseButton
|
|||
var label : Label
|
||||
var line_edit : LineEdit
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
visibility_button = Global.find_node_by_name(self, "VisibilityButton")
|
||||
lock_button = Global.find_node_by_name(self, "LockButton")
|
||||
|
@ -36,10 +37,12 @@ func _ready() -> void:
|
|||
linked_button.texture_normal = load("res://Assets/Graphics/%s Themes/Layers/Unlinked_Layer.png" % Global.theme_type)
|
||||
linked_button.texture_hover = load("res://Assets/Graphics/%s Themes/Layers/Unlinked_Layer_Hover.png" % Global.theme_type)
|
||||
|
||||
|
||||
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.scancode != KEY_SPACE:
|
||||
save_layer_name(line_edit.text)
|
||||
|
||||
|
||||
func _on_LayerContainer_pressed() -> void:
|
||||
pressed = !pressed
|
||||
label.visible = false
|
||||
|
@ -47,9 +50,11 @@ func _on_LayerContainer_pressed() -> void:
|
|||
line_edit.editable = true
|
||||
line_edit.grab_focus()
|
||||
|
||||
|
||||
func _on_LineEdit_focus_exited() -> void:
|
||||
save_layer_name(line_edit.text)
|
||||
|
||||
|
||||
func save_layer_name(new_name : String) -> void:
|
||||
label.visible = true
|
||||
line_edit.visible = false
|
||||
|
@ -58,13 +63,16 @@ func save_layer_name(new_name : String) -> void:
|
|||
Global.layers_changed_skip = true
|
||||
Global.layers[i][0] = new_name
|
||||
|
||||
|
||||
func _on_VisibilityButton_pressed() -> void:
|
||||
Global.layers[i][1] = !Global.layers[i][1]
|
||||
Global.canvas.update()
|
||||
|
||||
|
||||
func _on_LockButton_pressed() -> void:
|
||||
Global.layers[i][2] = !Global.layers[i][2]
|
||||
|
||||
|
||||
func _on_LinkButton_pressed() -> void:
|
||||
Global.layers[i][4] = !Global.layers[i][4]
|
||||
if Global.layers[i][4] && !Global.layers[i][5]:
|
||||
|
|
|
@ -10,6 +10,7 @@ var is_quitting_on_save := false
|
|||
var previous_left_color := Color.black
|
||||
var previous_right_color := Color.white
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
get_tree().set_auto_accept_quit(false)
|
||||
|
@ -245,10 +246,12 @@ func _input(event : InputEvent) -> void:
|
|||
elif event.is_action_pressed(t[1]): # Shortcut for left button
|
||||
_on_Tool_pressed(t[0], false, true)
|
||||
|
||||
|
||||
func _notification(what : int) -> void:
|
||||
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: # Handle exit
|
||||
show_quit_dialog()
|
||||
|
||||
|
||||
func file_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: # New
|
||||
|
@ -299,6 +302,7 @@ func file_menu_id_pressed(id : int) -> void:
|
|||
8: # Quit
|
||||
show_quit_dialog()
|
||||
|
||||
|
||||
func edit_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: # Undo
|
||||
|
@ -319,6 +323,7 @@ func edit_menu_id_pressed(id : int) -> void:
|
|||
$PreferencesDialog.popup_centered(Vector2(400, 280))
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
func view_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: # Tile mode
|
||||
|
@ -346,6 +351,7 @@ func view_menu_id_pressed(id : int) -> void:
|
|||
|
||||
Global.canvas.update()
|
||||
|
||||
|
||||
func image_menu_id_pressed(id : int) -> void:
|
||||
if Global.layers[Global.current_layer][2]: # No changes if the layer is locked
|
||||
return
|
||||
|
@ -434,6 +440,7 @@ func image_menu_id_pressed(id : int) -> void:
|
|||
$HSVDialog.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
func help_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: # Splash Screen
|
||||
|
@ -447,6 +454,7 @@ func help_menu_id_pressed(id : int) -> void:
|
|||
$AboutDialog.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
func load_last_project() -> void:
|
||||
# Check if any project was saved or opened last time
|
||||
if Global.config_cache.has_section_key("preferences", "last_project_path"):
|
||||
|
@ -500,17 +508,23 @@ func _on_ImportSprites_popup_hide() -> void:
|
|||
if !opensprite_file_selected:
|
||||
Global.can_draw = true
|
||||
|
||||
|
||||
func _on_ViewportContainer_mouse_entered() -> void:
|
||||
Global.has_focus = true
|
||||
|
||||
|
||||
func _on_ViewportContainer_mouse_exited() -> void:
|
||||
Global.has_focus = false
|
||||
|
||||
|
||||
func _can_draw_true() -> void:
|
||||
Global.can_draw = true
|
||||
|
||||
|
||||
func _can_draw_false() -> void:
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_left := true) -> void:
|
||||
var current_action := tool_pressed.name
|
||||
if (mouse_press and Input.is_action_just_released("left_mouse")) or (!mouse_press and key_for_left):
|
||||
|
@ -603,10 +617,12 @@ func _on_LeftBrushTypeButton_pressed() -> void:
|
|||
Global.brushes_popup.popup(Rect2(Global.left_brush_type_button.rect_global_position, Vector2(226, 72)))
|
||||
Global.brush_type_window_position = "left"
|
||||
|
||||
|
||||
func _on_RightBrushTypeButton_pressed() -> void:
|
||||
Global.brushes_popup.popup(Rect2(Global.right_brush_type_button.rect_global_position, Vector2(226, 72)))
|
||||
Global.brush_type_window_position = "right"
|
||||
|
||||
|
||||
func _on_LeftBrushSizeEdit_value_changed(value) -> void:
|
||||
Global.left_brush_size_edit.value = value
|
||||
Global.left_brush_size_slider.value = value
|
||||
|
@ -614,6 +630,7 @@ func _on_LeftBrushSizeEdit_value_changed(value) -> void:
|
|||
Global.left_brush_size = new_size
|
||||
update_left_custom_brush()
|
||||
|
||||
|
||||
func _on_RightBrushSizeEdit_value_changed(value) -> void:
|
||||
Global.right_brush_size_edit.value = value
|
||||
Global.right_brush_size_slider.value = value
|
||||
|
@ -621,9 +638,11 @@ func _on_RightBrushSizeEdit_value_changed(value) -> void:
|
|||
Global.right_brush_size = new_size
|
||||
update_right_custom_brush()
|
||||
|
||||
|
||||
func _on_Brush_Selected() -> void:
|
||||
$BrushesPopup.hide()
|
||||
|
||||
|
||||
func _on_ColorSwitch_pressed() -> void:
|
||||
var temp: Color = Global.left_color_picker.color
|
||||
Global.left_color_picker.color = Global.right_color_picker.color
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
extends Label
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
|
||||
func _ready() -> void:
|
||||
var tween := $Tween
|
||||
tween.interpolate_property(self, "rect_position", rect_position, Vector2(rect_position.x, rect_position.y - 100), 1, Tween.TRANS_LINEAR, Tween.EASE_OUT)
|
||||
tween.interpolate_property(self, "modulate", modulate, Color(modulate.r, modulate.g, modulate.b, 0), 1, Tween.TRANS_LINEAR, Tween.EASE_OUT)
|
||||
tween.start()
|
||||
|
||||
|
||||
func _on_Timer_timeout() -> void:
|
||||
queue_free()
|
||||
|
|
|
@ -13,9 +13,11 @@ onready var palette_name_edit = $VBoxContainer/PaletteOptions/EditPaletteNameLin
|
|||
onready var left_color_button = $VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/LeftColor/NinePatchRect
|
||||
onready var right_color_button = $VBoxContainer/HBoxContainer/VBoxContainer/CenterContainer/HBoxContainer/RightColor/NinePatchRect
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$VBoxContainer/HBoxContainer/EditPaletteColorPicker.presets_visible = false
|
||||
|
||||
|
||||
func open(palette : String) -> void:
|
||||
current_palette = palette
|
||||
palette_name_edit.text = current_palette
|
||||
|
@ -28,6 +30,7 @@ func open(palette : String) -> void:
|
|||
left_color_button.modulate = Global.left_color_picker.color
|
||||
right_color_button.modulate = Global.right_color_picker.color
|
||||
|
||||
|
||||
func _display_palette() -> void:
|
||||
_clear_swatches()
|
||||
var index := 0
|
||||
|
@ -50,17 +53,20 @@ func _display_palette() -> void:
|
|||
if index > 0: # If there are colors, select the first
|
||||
on_swatch_select(palette_grid.get_child(0))
|
||||
|
||||
|
||||
func _clear_swatches() -> void:
|
||||
for child in palette_grid.get_children():
|
||||
if child is BaseButton:
|
||||
child.disconnect("on_drop_data", self, "on_move_swatch")
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func on_swatch_select(new_button) -> void:
|
||||
current_swatch = new_button.index
|
||||
color_name_edit.text = working_palette.get_color_name(current_swatch)
|
||||
color_picker.color = working_palette.get_color(current_swatch)
|
||||
|
||||
|
||||
func on_move_swatch(from : int, to : int) -> void:
|
||||
working_palette.move_color(from, to)
|
||||
palette_grid.move_child(palette_grid.get_child(from), to)
|
||||
|
@ -68,6 +74,7 @@ func on_move_swatch(from : int, to : int) -> void:
|
|||
|
||||
re_index_swatches()
|
||||
|
||||
|
||||
func _on_AddSwatchButton_pressed() -> void:
|
||||
var color : Color = color_picker.color
|
||||
var new_index : int = working_palette.colors.size()
|
||||
|
@ -87,6 +94,7 @@ func _on_AddSwatchButton_pressed() -> void:
|
|||
palette_grid.add_child(new_button)
|
||||
on_swatch_select(new_button)
|
||||
|
||||
|
||||
func _on_RemoveSwatchButton_pressed() -> void:
|
||||
if working_palette.colors.size() > 0:
|
||||
working_palette.remove_color(current_swatch)
|
||||
|
@ -99,6 +107,7 @@ func _on_RemoveSwatchButton_pressed() -> void:
|
|||
if current_swatch >= 0:
|
||||
on_swatch_select(palette_grid.get_child(current_swatch))
|
||||
|
||||
|
||||
func re_index_swatches() -> void:
|
||||
# Re-index swatches with new order
|
||||
var index := 0
|
||||
|
@ -106,6 +115,7 @@ func re_index_swatches() -> void:
|
|||
child.index = index
|
||||
index += 1
|
||||
|
||||
|
||||
# Rename a palette, copying to user directory if necessary.
|
||||
func rename_palette_file_with_priority_dirs(old_fname: String, new_fname: String) -> void:
|
||||
var user_write_directory: String = Global.directory_module.get_palette_write_path()
|
||||
|
@ -144,27 +154,33 @@ func _on_EditPaletteSaveButton_pressed() -> void:
|
|||
Global.palette_container.save_palette(current_palette, working_palette.name + ".json")
|
||||
self.hide()
|
||||
|
||||
|
||||
func _on_EditPaletteCancelButton_pressed() -> void:
|
||||
self.hide()
|
||||
|
||||
|
||||
func _on_EditPaletteColorNameLineEdit_text_changed(new_text : String) -> void:
|
||||
if current_swatch >= 0 && current_swatch < working_palette.colors.size():
|
||||
working_palette.set_color_name(current_swatch, new_text)
|
||||
_refresh_hint_tooltip(current_swatch)
|
||||
|
||||
|
||||
func _on_EditPaletteColorPicker_color_changed(color : Color) -> void:
|
||||
if current_swatch >= 0 && current_swatch < working_palette.colors.size():
|
||||
palette_grid.get_child(current_swatch).get_child(0).modulate = color
|
||||
working_palette.set_color(current_swatch, color)
|
||||
_refresh_hint_tooltip(current_swatch)
|
||||
|
||||
|
||||
func _refresh_hint_tooltip(_index : int) -> void:
|
||||
palette_grid.get_child(current_swatch).hint_tooltip = "#" + working_palette.get_color_data(current_swatch).to_upper() + " " + working_palette.get_color_name(current_swatch)
|
||||
|
||||
|
||||
func _on_LeftColor_pressed() -> void:
|
||||
color_picker.color = Global.left_color_picker.color
|
||||
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
||||
|
||||
|
||||
func _on_RightColor_pressed() -> void:
|
||||
color_picker.color = Global.right_color_picker.color
|
||||
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
||||
|
|
|
@ -1,35 +1,44 @@
|
|||
class_name Palette
|
||||
extends Reference
|
||||
|
||||
func get_class():
|
||||
return "Palette"
|
||||
func is_class(_name):
|
||||
return _name == "Palette" or .is_class(_name)
|
||||
|
||||
var name : String = "Custom_Palette"
|
||||
var colors : Array = []
|
||||
var comments : String = ""
|
||||
var editable : bool = true
|
||||
|
||||
|
||||
func get_class() -> String:
|
||||
return "Palette"
|
||||
|
||||
|
||||
func is_class(_name : String) -> bool:
|
||||
return _name == "Palette" or .is_class(_name)
|
||||
|
||||
|
||||
func insert_color(index : int, new_color : Color, _name : String = "no name") -> void:
|
||||
if index <= colors.size():
|
||||
var c := PaletteColor.new(new_color, _name)
|
||||
colors.insert(index, c)
|
||||
|
||||
|
||||
func add_color(new_color : Color, _name : String = "no name") -> void:
|
||||
var c := PaletteColor.new(new_color, _name)
|
||||
colors.push_back(c)
|
||||
|
||||
|
||||
func remove_color(index : int) -> void:
|
||||
if index < colors.size():
|
||||
colors.remove(index)
|
||||
|
||||
|
||||
func move_color(from : int, to : int) -> void:
|
||||
if from < colors.size() && to < colors.size():
|
||||
var c : PaletteColor = colors[from]
|
||||
remove_color(from)
|
||||
insert_color(to, c.color, c.name)
|
||||
|
||||
|
||||
func get_color(index : int) -> Color:
|
||||
var result := Color.black
|
||||
|
||||
|
@ -38,10 +47,12 @@ func get_color(index : int) -> Color:
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func set_color(index : int, new_color : Color) -> void:
|
||||
if index < colors.size():
|
||||
colors[index].color = new_color
|
||||
|
||||
|
||||
func get_color_data(index : int) -> String:
|
||||
var result := ""
|
||||
|
||||
|
@ -50,16 +61,19 @@ func get_color_data(index : int) -> String:
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func has_color(color: Color) -> bool:
|
||||
for palette_color in colors:
|
||||
if palette_color.color == color:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func set_color_data(index : int, new_color : String) -> void:
|
||||
if index < colors.size():
|
||||
colors[index].data = new_color
|
||||
|
||||
|
||||
func get_color_name(index : int) -> String:
|
||||
var result = ""
|
||||
|
||||
|
@ -68,16 +82,19 @@ func get_color_name(index : int) -> String:
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func set_color_name(index : int, new_name : String) -> void:
|
||||
if index < colors.size():
|
||||
colors[index].name = new_name
|
||||
|
||||
|
||||
func save_to_file(path : String) -> void:
|
||||
var file = File.new()
|
||||
file.open(path, File.WRITE)
|
||||
file.store_string(_serialize())
|
||||
file.close()
|
||||
|
||||
|
||||
func duplicate(): # -> Palette
|
||||
var copy = get_script().new() # : Palette
|
||||
copy.name = name
|
||||
|
@ -87,6 +104,7 @@ func duplicate(): # -> Palette
|
|||
copy.colors.push_back(color.duplicate())
|
||||
return copy
|
||||
|
||||
|
||||
func _serialize() -> String:
|
||||
var result = ""
|
||||
var serialize_data : Dictionary = {
|
||||
|
@ -102,6 +120,7 @@ func _serialize() -> String:
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func deserialize(input_string : String): # -> Palette
|
||||
var result = get_script().new()
|
||||
|
||||
|
@ -126,6 +145,7 @@ func deserialize(input_string : String): # -> Palette
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func load_from_file(path : String): # -> Palette
|
||||
var result = null # : Palette
|
||||
var file = File.new()
|
||||
|
|
|
@ -7,6 +7,7 @@ export var draggable := false
|
|||
|
||||
var drag_preview_texture = preload("res://Assets/Graphics/Palette/swatch_drag_preview.png")
|
||||
|
||||
|
||||
func get_drag_data(_position):
|
||||
var data = null
|
||||
if draggable:
|
||||
|
@ -17,8 +18,10 @@ func get_drag_data(_position):
|
|||
set_drag_preview(drag_icon)
|
||||
return data
|
||||
|
||||
func can_drop_data(_position, _data):
|
||||
|
||||
func can_drop_data(_position, _data) -> bool:
|
||||
return true
|
||||
|
||||
func drop_data(_position, data):
|
||||
|
||||
func drop_data(_position, data) -> void:
|
||||
emit_signal("on_drop_data", data.source_index, index)
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
class_name PaletteColor
|
||||
extends Reference
|
||||
|
||||
func get_class():
|
||||
return "PaletteColor"
|
||||
func is_class(_name):
|
||||
return _name == "PaletteColor" or .is_class(_name)
|
||||
|
||||
var color : Color = Color.black setget _set_color
|
||||
var data : String = "" setget _set_data
|
||||
var name : String = "no name"
|
||||
|
||||
func _init(new_color : Color = Color.black, new_name : String = "no name"):
|
||||
|
||||
func get_class() -> String:
|
||||
return "PaletteColor"
|
||||
|
||||
|
||||
func is_class(_name : String) -> bool:
|
||||
return _name == "PaletteColor" or .is_class(_name)
|
||||
|
||||
|
||||
func _init(new_color : Color = Color.black, new_name : String = "no name") -> void:
|
||||
self.color = new_color
|
||||
self.name = new_name
|
||||
|
||||
|
||||
func _set_color(new_value : Color) -> void:
|
||||
color = new_value
|
||||
data = color.to_html(true)
|
||||
|
||||
|
||||
func _set_data(new_value : String) -> void:
|
||||
data = new_value
|
||||
color = Color(data)
|
||||
|
||||
|
||||
func toDict() -> Dictionary:
|
||||
var result = {
|
||||
"data" : data,
|
||||
|
@ -29,6 +37,7 @@ func toDict() -> Dictionary:
|
|||
}
|
||||
return result
|
||||
|
||||
|
||||
func fromDict(input_dict : Dictionary): # -> PaletteColor
|
||||
var result = get_script().new()
|
||||
|
||||
|
@ -37,6 +46,7 @@ func fromDict(input_dict : Dictionary): # -> PaletteColor
|
|||
|
||||
return result
|
||||
|
||||
|
||||
func duplicate(): # -> PaletteColor
|
||||
var copy = get_script().new() # : PaletteColor
|
||||
copy.data = data
|
||||
|
|
|
@ -15,12 +15,14 @@ func _ready() -> void:
|
|||
var add_palette_menu : PopupMenu = Global.add_palette_button.get_child(0)
|
||||
add_palette_menu.connect("id_pressed", self, "add_palette_menu_id_pressed")
|
||||
|
||||
|
||||
func _clear_swatches() -> void:
|
||||
for child in get_children():
|
||||
if child is BaseButton:
|
||||
child.disconnect("pressed", self, "on_color_select")
|
||||
child.queue_free()
|
||||
|
||||
|
||||
func on_palette_select(palette_name : String) -> void:
|
||||
_clear_swatches()
|
||||
if Global.palettes.has(palette_name): # Palette exists in memory
|
||||
|
@ -28,6 +30,7 @@ func on_palette_select(palette_name : String) -> void:
|
|||
var palette : Palette = Global.palettes[palette_name]
|
||||
_display_palette(palette)
|
||||
|
||||
|
||||
func on_new_empty_palette() -> void:
|
||||
Global.new_palette_dialog.window_title = "Create a new empty palette?"
|
||||
Global.new_palette_name_line_edit.text = "Custom_Palette"
|
||||
|
@ -35,10 +38,12 @@ func on_new_empty_palette() -> void:
|
|||
Global.new_palette_dialog.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
func on_import_palette() -> void:
|
||||
Global.palette_import_file_dialog.popup_centered()
|
||||
Global.can_draw = false
|
||||
|
||||
|
||||
func on_palette_import_file_selected(path : String) -> void:
|
||||
var palette : Palette = null
|
||||
if path.to_lower().ends_with("json"):
|
||||
|
@ -64,9 +69,11 @@ func on_palette_import_file_selected(path : String) -> void:
|
|||
Global.error_dialog.set_text("Invalid Palette file!")
|
||||
Global.error_dialog.popup_centered()
|
||||
|
||||
|
||||
func _on_AddPalette_pressed() -> void:
|
||||
Global.add_palette_button.get_child(0).popup(Rect2(Global.add_palette_button.rect_global_position, Vector2.ONE))
|
||||
|
||||
|
||||
func on_new_palette_confirmed() -> void:
|
||||
var new_palette_name : String = Global.new_palette_name_line_edit.text
|
||||
var result : String = create_new_palette(new_palette_name, from_palette)
|
||||
|
@ -74,6 +81,7 @@ func on_new_palette_confirmed() -> void:
|
|||
Global.error_dialog.set_text(result)
|
||||
Global.error_dialog.popup_centered()
|
||||
|
||||
|
||||
func add_palette_menu_id_pressed(id : int) -> void:
|
||||
match id:
|
||||
0: # New Empty Palette
|
||||
|
@ -81,6 +89,7 @@ func add_palette_menu_id_pressed(id : int) -> void:
|
|||
1: # Import Palette
|
||||
Global.palette_container.on_import_palette()
|
||||
|
||||
|
||||
func create_new_palette(name : String, _from_palette : Palette) -> String: # Returns empty string, else error string
|
||||
var new_palette : Palette = Palette.new()
|
||||
|
||||
|
@ -109,6 +118,7 @@ func create_new_palette(name : String, _from_palette : Palette) -> String: # Ret
|
|||
on_palette_select(name)
|
||||
return ""
|
||||
|
||||
|
||||
func on_edit_palette() -> void:
|
||||
var palette : Palette = Global.palettes[current_palette]
|
||||
|
||||
|
@ -126,10 +136,12 @@ func on_edit_palette() -> void:
|
|||
from_palette = null
|
||||
Global.edit_palette_popup.open(current_palette)
|
||||
|
||||
|
||||
func _on_PaletteOptionButton_item_selected(ID : int) -> void:
|
||||
var palette_name = Global.palette_option_button.get_item_metadata(ID)
|
||||
on_palette_select(palette_name)
|
||||
|
||||
|
||||
func _display_palette(palette : Palette) -> void:
|
||||
var index := 0
|
||||
|
||||
|
@ -144,6 +156,7 @@ func _display_palette(palette : Palette) -> void:
|
|||
add_child(new_button)
|
||||
index += 1
|
||||
|
||||
|
||||
func on_color_select(index : int) -> void:
|
||||
var color : Color = Global.palettes[current_palette].get_color(index)
|
||||
|
||||
|
@ -154,6 +167,7 @@ func on_color_select(index : int) -> void:
|
|||
Global.right_color_picker.color = color
|
||||
Global.update_right_custom_brush()
|
||||
|
||||
|
||||
func _load_palettes() -> void:
|
||||
Global.directory_module.ensure_xdg_user_dirs_exist()
|
||||
var search_locations = Global.directory_module.get_palette_search_path_in_order()
|
||||
|
@ -179,6 +193,7 @@ func _load_palettes() -> void:
|
|||
if not "Default" in Global.palettes && Global.palettes.size() > 0:
|
||||
Global.palette_container._on_PaletteOptionButton_item_selected(0)
|
||||
|
||||
|
||||
# Get the palette files in a single directory.
|
||||
# if it does not exist, return []
|
||||
func get_palette_files(path : String ) -> Array:
|
||||
|
@ -201,6 +216,7 @@ func get_palette_files(path : String ) -> Array:
|
|||
dir.list_dir_end()
|
||||
return results
|
||||
|
||||
|
||||
# This returns an array of arrays, with priorities.
|
||||
# In particular, it takes an array of paths to look for
|
||||
# arrays in, in order of file and palette override priority
|
||||
|
@ -230,6 +246,7 @@ func get_palette_priority_file_map(looking_paths: Array) -> Array:
|
|||
final_list.append(to_add_files)
|
||||
return final_list
|
||||
|
||||
|
||||
# Locate the highest priority palette by the given relative filename
|
||||
# If none is found in the directories, then do nothing and return
|
||||
# null
|
||||
|
@ -243,6 +260,7 @@ func get_best_palette_file_location(looking_paths: Array, fname: String): # ->
|
|||
|
||||
return null
|
||||
|
||||
|
||||
func save_palette(palette_name : String, filename : String) -> void:
|
||||
Global.directory_module.ensure_xdg_user_dirs_exist()
|
||||
var palette = Global.palettes[palette_name]
|
||||
|
|
|
@ -9,6 +9,7 @@ var mouse_pos := Vector2.ZERO
|
|||
var previous_points := points
|
||||
var type = Types.HORIZONTAL
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
width = 0.1
|
||||
default_color = Global.guide_color
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
extends Control
|
||||
|
||||
const RULER_WIDTH := 16
|
||||
|
||||
var font := preload("res://Assets/Fonts/Roboto-Small.tres")
|
||||
var major_subdivision := 2
|
||||
var minor_subdivision := 3
|
||||
|
||||
var first : Vector2
|
||||
var last : Vector2
|
||||
|
||||
# Code taken and modified from Godot's source code
|
||||
func _draw() -> void:
|
||||
var color := Color.white
|
||||
if Global.theme_type == "Gold" || Global.theme_type == "Light":
|
||||
color = Color.black
|
||||
var transform := Transform2D()
|
||||
var ruler_transform := Transform2D()
|
||||
var major_subdivide := Transform2D()
|
||||
var minor_subdivide := Transform2D()
|
||||
var fps = Global.animation_timeline.fps
|
||||
var horizontal_scroll = get_parent().get_node("FrameAndButtonContainer").get_node("ScrollContainer").scroll_horizontal
|
||||
var starting_pos := Vector2(10, 10)
|
||||
transform.x = Vector2(fps, fps) / 2.52
|
||||
|
||||
transform.origin = starting_pos - Vector2(horizontal_scroll, horizontal_scroll)
|
||||
|
||||
var basic_rule := 100.0
|
||||
while(basic_rule * fps > 100):
|
||||
basic_rule /= 2.0
|
||||
while(basic_rule * fps < 100):
|
||||
basic_rule *= 2.0
|
||||
|
||||
ruler_transform = ruler_transform.scaled(Vector2(basic_rule, basic_rule))
|
||||
|
||||
major_subdivide = major_subdivide.scaled(Vector2(1.0 / major_subdivision, 1.0 / major_subdivision))
|
||||
minor_subdivide = minor_subdivide.scaled(Vector2(1.0 / minor_subdivision, 1.0 / minor_subdivision))
|
||||
|
||||
first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(starting_pos)
|
||||
last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(rect_size - starting_pos)
|
||||
|
||||
for i in range(ceil(first.x), last.x - 1):
|
||||
var position : Vector2 = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Vector2(i, 0))
|
||||
if i % (major_subdivision * minor_subdivision) == 0:
|
||||
draw_line(Vector2(position.x + RULER_WIDTH, 0), Vector2(position.x + RULER_WIDTH, RULER_WIDTH), color)
|
||||
var val = (ruler_transform * major_subdivide * minor_subdivide).xform(Vector2(i, 0)).x / 100
|
||||
val = stepify(val, 0.01)
|
||||
draw_string(font, Vector2(position.x + RULER_WIDTH + 2, font.get_height() - 6), "%ss" % str(val), color)
|
||||
else:
|
||||
if i % minor_subdivision == 0:
|
||||
draw_line(Vector2(position.x + RULER_WIDTH, RULER_WIDTH * 0.33), Vector2(position.x + RULER_WIDTH, RULER_WIDTH), color)
|
||||
else:
|
||||
draw_line(Vector2(position.x + RULER_WIDTH, RULER_WIDTH * 0.66), Vector2(position.x + RULER_WIDTH, RULER_WIDTH), color)
|
||||
|
||||
# warning-ignore:unused_argument
|
||||
func _on_ScrollContainer_gui_input(event) -> void:
|
||||
update()
|
|
@ -1,5 +1,6 @@
|
|||
extends Viewport
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
world_2d = Global.canvas.get_parent().world_2d
|
||||
|
|
|
@ -10,6 +10,7 @@ var orig_x := 0.0
|
|||
var orig_y := 0.0
|
||||
var orig_colors := []
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
img = Image.new()
|
||||
img.create(1, 1, false, Image.FORMAT_RGBA8)
|
||||
|
@ -17,8 +18,8 @@ func _ready() -> void:
|
|||
tex = ImageTexture.new()
|
||||
tex.create_from_image(img, 0)
|
||||
|
||||
# warning-ignore:unused_argument
|
||||
func _process(delta : float) -> void:
|
||||
|
||||
func _process(_delta : float) -> void:
|
||||
if Global.layers[Global.current_layer][2]:
|
||||
return
|
||||
var mouse_pos: Vector2 = get_local_mouse_position() - Global.canvas.location
|
||||
|
@ -138,9 +139,11 @@ func _process(delta : float) -> void:
|
|||
layer.set_pixel(xx, yy, Color(0, 0, 0, 0))
|
||||
Global.canvas.handle_redo("Draw")
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
if img.get_size() == polygon[2] - polygon[0]:
|
||||
draw_texture(tex, polygon[0], Color(1, 1, 1, 0.5))
|
||||
|
||||
|
||||
func point_in_rectangle(p : Vector2, coord1 : Vector2, coord2 : Vector2) -> bool:
|
||||
return p.x > coord1.x && p.y > coord1.y && p.x < coord2.x && p.y < coord2.y
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
extends ColorRect
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
rect_size = Global.canvas.size
|
||||
material.set_shader_param("size", Global.checker_size)
|
||||
material.set_shader_param("color1", Global.checker_color_1)
|
||||
|
|
|
@ -109,6 +109,7 @@ func get_palette_write_path() -> String:
|
|||
func get_brushes_write_path() -> String:
|
||||
return xdg_data_home.plus_file(brushes_data_subdirectory)
|
||||
|
||||
|
||||
# Get the path that we are ok to be writing patterns to:
|
||||
func get_patterns_write_path() -> String:
|
||||
return xdg_data_home.plus_file(patterns_data_subdirectory)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue