1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 09:09:47 +00: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:
OverloadedOrama 2020-05-01 20:47:10 +03:00
parent 62bbad7374
commit 5a54235604
32 changed files with 295 additions and 165 deletions

View file

@ -8,6 +8,7 @@
* [Communicating with developers](#communicating-with-developers)
**Please read the first section before reporting a bug!**
<br><br>
## Reporting bugs or proposing features
Please, open just one issue for each bug you'd like to report, or a feature you'd like to request. Don't open many issues for the same bug or feature request, and don't use the same issue to report more than one bugs, or to request more than one feature. It's best to open different issues for each bug/feature request.
@ -15,7 +16,7 @@ Please, open just one issue for each bug you'd like to report, or a feature you'
Also, make sure to search the [issue tracker](https://github.com/Orama-Interactive/Pixelorama/issues) before opening a new issue, in case an issue like that exists. If you're unsure, feel free to open an issue. If it's a duplicate, we'll handle it.
When reporting a bug, make sure to provide enough details, such as information about your Operating System (OS), Pixelorama version, Godot version (if you're using the source project) and clear steps to reproduce the issue. Feel free to include screenshots that might help, too.
<br><br>
## Contributing pull requests
If you want to add new features or fix bugs, please make sure that:
@ -37,12 +38,12 @@ Please create different pull requests for each feature you'd like to implement,
This [Git style guide](https://github.com/agis-/git-style-guide) has some good practices to have in mind.
Keep in mind, however, that not all PRs will be merged. Some may need discussion, or others may be downright closed.
<br><br>
## Contributing translations
Pixelorama uses [Crowdin](https://crowdin.com/project/pixelorama) to host the translations. In order to contribute, you need to login with your Crowdin account, select the language(s) you'd like to provide translations for, select `Translations.pot` and start translating!
If you need help with the context of some strings, or want to translate in a language that is not available, feel free to contact me (Overloaded). All languages are welcome to be translated!
<br><br>
## Communicating with developers
To communicate with developers (e.g. to discuss a feature you want to implement or a bug you want to fix), the following channels can be used:

View file

@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<br><br>
## [v0.7] - Unreleased
This update has been brought to you by the contributions of:
@ -65,7 +66,7 @@ sapient-cogbag, Kinwailo, Igor Santarek (jegor377), Dávid Gábor BODOR (dragonf
### Removed
- It's no longer possible for frames to have different amounts of layers. All frames have the same amount.
- The guides no longer work with undo/redo.
<br><br>
## [v0.6.2] - 17-02-2020
@ -103,7 +104,7 @@ sapient-cogbag, Kinwailo, Igor Santarek (jegor377), Dávid Gábor BODOR (dragonf
- Possibly fixed a rare crash where the cursor image was failing to load. It is now being loaded only once.
- Fixed ruler markings cutting off before they should - Thanks to YeldhamDev!
- Fixed bug where resizing the image on export and moving selection content were not working on Godot 3.2 - Issues #161 and #162
<br><br>
## [v0.6.1] - 13-01-2020
@ -134,7 +135,7 @@ sapient-cogbag, Kinwailo, Igor Santarek (jegor377), Dávid Gábor BODOR (dragonf
- The canvas updates automatically when onion skinning settings change.
- Fixed a rare crash with straight lines. It was possible that the variable `is_making_line` could be true, even if the line itself has been freed from memory.
- Fixed issue where undo/redo was not working properly for straight lines that went outside the canvas.
<br><br>
## [v0.6] - 06-01-2020

View file

@ -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)

View file

@ -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

View file

@ -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:

View file

@ -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()

View file

@ -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")

View file

@ -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]

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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]:

View file

@ -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

View file

@ -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()

View file

@ -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)

View file

@ -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()

View file

@ -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)

View file

@ -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

View file

@ -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]

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)