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:
parent
62bbad7374
commit
5a54235604
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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…
Reference in a new issue