mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-18 17:19:50 +00:00
Bring refactoring changes to master (#253)
* Refactoring image_menu_id_pressed method in Main.gd (#243) * Refactoring image_menu_id_pressed method in Main.gd I've moved the code from each "match" case into a seperate method to make it more readable. Co-authored-by: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> * Refactoring Main.gd. Mostly cutting big methods into smaller ones. (#244) * Refactoring Main.gd. Mostly cutting big methods into smaller one. - Reduced size of _ready method in Main.gd - Moved code from certain parts of old _ready method into seperate methods - Fixed the translation bug related to CurrentFrame node in TopMenuContainer scene. The CurrentFrame node wasn't updating the language when I was changing language. I've also changed the translation file for this. - Fixed Global.palette_option_button.selected related warning. Because of some unknown reasons, git didn't push completed line there. - Moved code from file_menu_id_pressed and view_menu_id_pressed method in Main.gd to separate methods to make it more readable. * Removed window_title changes from Main.tscn Co-authored-by: OverloadedOrama <35376950+OverloadedOrama@users.noreply.github.com> * Fixed TextureRect images of the circle brushes in BrushesPopup They all had the pixel brush image in their TextureRect * Split code from PreferencesDialog.gd to HandleLanguages.gd Also moved PreferencesDialog script & scene to src/Preferences. More Preferences code splitting will follow. * Split theme related code from PreferencesDialog into HandleThemes.gd * Moved shortcuts code from PreferencesDialog * Created DrawingAlgos.gd and moved a lot of drawing code there Moved code from Global.gd and Canvas.gd to DrawingAlgos.gd. Will also move the fill_gaps and draw_brush methods of Canvas.gd next. Maybe even refactor the inside of them a bit to make them easier to read. * Connected "files_dropped" signal to a method This lets the user drag and drop files into Pixelorama, while it runs, to open them. This doesn't work properly and will crash when it can't open the files. It will get merged into master soon. * Renamed handle_running_pixelorama_with_arguments() to handle_loading_files() handle_loading_files() is also used for _on_files_dropped() * Moved draw_brush() and fill_gaps() from Canvas.gd to DrawingAlgos.gd draw_brush() is currently very ugly and probably needs inside refactoring * Removed coord clamping from fill_gaps() This should make line making behave as expected when the mouse is outside of canvas boundaries * Drawing is no longer limited by the canvas boundaries his means that, if you have a brush largen than 1px, you can draw on the edges of the canvas. All pixels that are being drawn outside of the canvas will still have no effect. * Use enums instead of strings for tools This could be a slight increase in performance * Fixed line making with Shift and don't let color picker pick colors outside of canvas * Changed Global node variables to arrays for left/right Instead of having 2 variables for left & right nodes, use an array instead. This will help with better looking code, automation and less repetitive code, as seen in ToolButtons.gd. Move related refactoring will follow. * More Global left/right variables became Arrays Global.update_left_custom_brush() and its right counterpart have also now become Global.update_custom_brush(mouse_button : int) * Use Global.Mouse_Button instead of strings for comparison This should be a slight increase in performance * Refactoring perferences dialog (#251) * Added ItemList to themes * Language and theme checkboxes are now radio buttons * Even more Global left/right variables became arrays ColorAndToolOptions has now the same code for left and right tool options, with more similar refactoring coming soon to places like Canvas and DrawingAlgos * Refactored Canvas.gd * Refactored DrawingAlgos.draw_brush(), made draw_pixel() method This also fixes alpha blending and lighting/darkening issues when drawing pixels with mirroring. * Remove draw_pixel(), use draw_pixel_blended() instead * Ignore warnings I don't know what else to do about them, they seem trivial anyway * Use enum instead of strings for Global.theme_type Another potential small performance boost when changing themes. * Use a new Layer class to handle layer information This replaces the old Global.layers nested array mess, and makes the code easier to read and to understand. * Fixed linked cel crash and layer naming * Created a new Cel class, to handle cel information Like the Layer class, it is used in place of Canvas.layers nested array mess. It hasn't been tested thoroughly yet, so there may be crashes. * Fixed issue where if you moved a frame to the start (move left), it was invisible * Added AnimationTag class Replaces nested Global.animation_tags arrays. Also replaced array.duplicate(true) with looping through the array and creating a new class for each array element, because duplicate(true) does not create new classes, unfortunately, which was causing issues with undo/redo. Co-authored-by: Igor Santarek <jegor377@gmail.com> Co-authored-by: Kinwailo <lokinwai@gmail.com>
This commit is contained in:
parent
7a8ae9428b
commit
881e53dadc
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -7,10 +7,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
## [v0.7.1] - Unreleased
|
## [v0.7.1] - Unreleased
|
||||||
This update has been brought to you by the contributions of:
|
This update has been brought to you by the contributions of:
|
||||||
|
|
||||||
Igor Santarek (jegor377)
|
Igor Santarek (jegor377), rob-a-bolton
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Ability to remove the current palette
|
- Ability to remove the current palette.
|
||||||
|
- You can now drag & drop files into the program while it's running to open them.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Drawing is no longer limited by the canvas boundaries. This means that, if you have a brush largen than 1px, you can draw on the edges of the canvas. All pixels that are being drawn outside of the canvas will still have no effect.
|
||||||
|
- Language and theme checkboxes are now radio buttons.
|
||||||
|
- The Blue theme has more similar margins and seperations with the rest of the themes.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed failed imports of gpl palettes by adding support for the newer variant of gpl files. ([#250](https://github.com/Orama-Interactive/Pixelorama/pull/250))
|
||||||
|
- Fixed alpha blending and lighting/darkening issues when drawing pixels with mirroring.
|
||||||
|
- Fixed issue where if you moved a frame to the start (move left), it was invisible.
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
## [v0.7] - 2020-05-16
|
## [v0.7] - 2020-05-16
|
||||||
|
|
|
@ -732,9 +732,6 @@ msgstr ""
|
||||||
msgid "Current frame:"
|
msgid "Current frame:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Current frame: 1/1"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Jump to the first frame\n"
|
msgid "Jump to the first frame\n"
|
||||||
"(%s)"
|
"(%s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -152,6 +152,18 @@ border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
expand_margin_top = 2.0
|
expand_margin_top = 2.0
|
||||||
expand_margin_bottom = 2.0
|
expand_margin_bottom = 2.0
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id=27]
|
||||||
|
bg_color = Color( 0.588235, 0.568627, 0.470588, 1 )
|
||||||
|
border_width_left = 4
|
||||||
|
border_width_top = 4
|
||||||
|
border_width_right = 4
|
||||||
|
border_width_bottom = 4
|
||||||
|
border_color = Color( 0.588235, 0.568627, 0.470588, 1 )
|
||||||
|
corner_radius_top_left = 4
|
||||||
|
corner_radius_top_right = 4
|
||||||
|
corner_radius_bottom_right = 4
|
||||||
|
corner_radius_bottom_left = 4
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=17]
|
[sub_resource type="StyleBoxFlat" id=17]
|
||||||
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
||||||
border_width_left = 1
|
border_width_left = 1
|
||||||
|
@ -245,18 +257,6 @@ corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
anti_aliasing = false
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=27]
|
|
||||||
bg_color = Color( 0.588235, 0.568627, 0.470588, 1 )
|
|
||||||
border_width_left = 4
|
|
||||||
border_width_top = 4
|
|
||||||
border_width_right = 4
|
|
||||||
border_width_bottom = 4
|
|
||||||
border_color = Color( 0.588235, 0.568627, 0.470588, 1 )
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=28]
|
[sub_resource type="StyleBoxFlat" id=28]
|
||||||
bg_color = Color( 0.445313, 0.432846, 0.370514, 1 )
|
bg_color = Color( 0.445313, 0.432846, 0.370514, 1 )
|
||||||
border_width_left = 5
|
border_width_left = 5
|
||||||
|
@ -367,6 +367,20 @@ HSplitContainer/constants/autohide = 1
|
||||||
HSplitContainer/constants/separation = 6
|
HSplitContainer/constants/separation = 6
|
||||||
HSplitContainer/icons/grabber = ExtResource( 4 )
|
HSplitContainer/icons/grabber = ExtResource( 4 )
|
||||||
HSplitContainer/styles/bg = null
|
HSplitContainer/styles/bg = null
|
||||||
|
ItemList/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
|
ItemList/colors/font_color_selected = Color( 0.278431, 0.278431, 0.278431, 1 )
|
||||||
|
ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 )
|
||||||
|
ItemList/constants/hseparation = 4
|
||||||
|
ItemList/constants/icon_margin = 4
|
||||||
|
ItemList/constants/line_separation = 2
|
||||||
|
ItemList/constants/vseparation = 4
|
||||||
|
ItemList/fonts/font = null
|
||||||
|
ItemList/styles/bg = SubResource( 27 )
|
||||||
|
ItemList/styles/bg_focus = null
|
||||||
|
ItemList/styles/cursor = null
|
||||||
|
ItemList/styles/cursor_unfocused = null
|
||||||
|
ItemList/styles/selected = null
|
||||||
|
ItemList/styles/selected_focus = null
|
||||||
"Label/colors/Selected Color" = Color( 0.235294, 0.364706, 0.458824, 1 )
|
"Label/colors/Selected Color" = Color( 0.235294, 0.364706, 0.458824, 1 )
|
||||||
Label/colors/font_color = Color( 0, 0, 0, 1 )
|
Label/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
||||||
|
@ -512,7 +526,7 @@ Tree/colors/cursor_color = Color( 0, 0, 0, 1 )
|
||||||
Tree/colors/custom_button_font_highlight = Color( 0.941176, 0.941176, 0.941176, 1 )
|
Tree/colors/custom_button_font_highlight = Color( 0.941176, 0.941176, 0.941176, 1 )
|
||||||
Tree/colors/drop_position_color = Color( 1, 0.3, 0.2, 1 )
|
Tree/colors/drop_position_color = Color( 1, 0.3, 0.2, 1 )
|
||||||
Tree/colors/font_color = Color( 0, 0, 0, 1 )
|
Tree/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
Tree/colors/font_color_selected = Color( 0, 0, 0, 1 )
|
Tree/colors/font_color_selected = Color( 0.443137, 0.443137, 0.443137, 1 )
|
||||||
Tree/colors/guide_color = Color( 0, 0, 0, 0.1 )
|
Tree/colors/guide_color = Color( 0, 0, 0, 0.1 )
|
||||||
Tree/colors/relationship_line_color = Color( 0.27451, 0.27451, 0.27451, 1 )
|
Tree/colors/relationship_line_color = Color( 0.27451, 0.27451, 0.27451, 1 )
|
||||||
Tree/colors/selection_color = Color( 0.1, 0.1, 1, 0.8 )
|
Tree/colors/selection_color = Color( 0.1, 0.1, 1, 0.8 )
|
||||||
|
|
|
@ -172,6 +172,18 @@ border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
[sub_resource type="StyleBoxFlat" id=19]
|
[sub_resource type="StyleBoxFlat" id=19]
|
||||||
bg_color = Color( 0.133333, 0.133333, 0.133333, 1 )
|
bg_color = Color( 0.133333, 0.133333, 0.133333, 1 )
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id=32]
|
||||||
|
bg_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
|
border_width_left = 4
|
||||||
|
border_width_top = 4
|
||||||
|
border_width_right = 4
|
||||||
|
border_width_bottom = 4
|
||||||
|
border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
|
corner_radius_top_left = 4
|
||||||
|
corner_radius_top_right = 4
|
||||||
|
corner_radius_bottom_right = 4
|
||||||
|
corner_radius_bottom_left = 4
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=20]
|
[sub_resource type="StyleBoxFlat" id=20]
|
||||||
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
||||||
border_width_left = 1
|
border_width_left = 1
|
||||||
|
@ -286,18 +298,6 @@ corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
anti_aliasing = false
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=32]
|
|
||||||
bg_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
|
||||||
border_width_left = 4
|
|
||||||
border_width_top = 4
|
|
||||||
border_width_right = 4
|
|
||||||
border_width_bottom = 4
|
|
||||||
border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=33]
|
[sub_resource type="StyleBoxFlat" id=33]
|
||||||
border_width_left = 2
|
border_width_left = 2
|
||||||
border_width_right = 2
|
border_width_right = 2
|
||||||
|
@ -419,6 +419,20 @@ HSplitContainer/constants/autohide = 1
|
||||||
HSplitContainer/constants/separation = 6
|
HSplitContainer/constants/separation = 6
|
||||||
HSplitContainer/icons/grabber = ExtResource( 4 )
|
HSplitContainer/icons/grabber = ExtResource( 4 )
|
||||||
HSplitContainer/styles/bg = SubResource( 19 )
|
HSplitContainer/styles/bg = SubResource( 19 )
|
||||||
|
ItemList/colors/font_color = Color( 0.690196, 0.690196, 0.690196, 1 )
|
||||||
|
ItemList/colors/font_color_selected = Color( 1, 1, 1, 1 )
|
||||||
|
ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 )
|
||||||
|
ItemList/constants/hseparation = 4
|
||||||
|
ItemList/constants/icon_margin = 4
|
||||||
|
ItemList/constants/line_separation = 2
|
||||||
|
ItemList/constants/vseparation = 4
|
||||||
|
ItemList/fonts/font = null
|
||||||
|
ItemList/styles/bg = SubResource( 32 )
|
||||||
|
ItemList/styles/bg_focus = null
|
||||||
|
ItemList/styles/cursor = null
|
||||||
|
ItemList/styles/cursor_unfocused = null
|
||||||
|
ItemList/styles/selected = null
|
||||||
|
ItemList/styles/selected_focus = null
|
||||||
"Label/colors/Selected Color" = Color( 0.235294, 0.364706, 0.458824, 1 )
|
"Label/colors/Selected Color" = Color( 0.235294, 0.364706, 0.458824, 1 )
|
||||||
Label/colors/font_color = Color( 1, 1, 1, 1 )
|
Label/colors/font_color = Color( 1, 1, 1, 1 )
|
||||||
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
||||||
|
|
|
@ -165,6 +165,18 @@ border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
expand_margin_top = 2.0
|
expand_margin_top = 2.0
|
||||||
expand_margin_bottom = 2.0
|
expand_margin_bottom = 2.0
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id=28]
|
||||||
|
bg_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
|
border_width_left = 4
|
||||||
|
border_width_top = 4
|
||||||
|
border_width_right = 4
|
||||||
|
border_width_bottom = 4
|
||||||
|
border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
|
corner_radius_top_left = 4
|
||||||
|
corner_radius_top_right = 4
|
||||||
|
corner_radius_bottom_right = 4
|
||||||
|
corner_radius_bottom_left = 4
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=18]
|
[sub_resource type="StyleBoxFlat" id=18]
|
||||||
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
||||||
border_width_left = 1
|
border_width_left = 1
|
||||||
|
@ -258,18 +270,6 @@ corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
anti_aliasing = false
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=28]
|
|
||||||
bg_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
|
||||||
border_width_left = 4
|
|
||||||
border_width_top = 4
|
|
||||||
border_width_right = 4
|
|
||||||
border_width_bottom = 4
|
|
||||||
border_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=29]
|
[sub_resource type="StyleBoxFlat" id=29]
|
||||||
bg_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
bg_color = Color( 0.321569, 0.321569, 0.321569, 1 )
|
||||||
border_width_left = 2
|
border_width_left = 2
|
||||||
|
@ -370,6 +370,20 @@ HSplitContainer/constants/autohide = 1
|
||||||
HSplitContainer/constants/separation = 6
|
HSplitContainer/constants/separation = 6
|
||||||
HSplitContainer/icons/grabber = ExtResource( 6 )
|
HSplitContainer/icons/grabber = ExtResource( 6 )
|
||||||
HSplitContainer/styles/bg = null
|
HSplitContainer/styles/bg = null
|
||||||
|
ItemList/colors/font_color = Color( 0.690196, 0.690196, 0.690196, 1 )
|
||||||
|
ItemList/colors/font_color_selected = Color( 1, 1, 1, 1 )
|
||||||
|
ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 )
|
||||||
|
ItemList/constants/hseparation = 4
|
||||||
|
ItemList/constants/icon_margin = 4
|
||||||
|
ItemList/constants/line_separation = 2
|
||||||
|
ItemList/constants/vseparation = 4
|
||||||
|
ItemList/fonts/font = null
|
||||||
|
ItemList/styles/bg = SubResource( 28 )
|
||||||
|
ItemList/styles/bg_focus = null
|
||||||
|
ItemList/styles/cursor = null
|
||||||
|
ItemList/styles/cursor_unfocused = null
|
||||||
|
ItemList/styles/selected = null
|
||||||
|
ItemList/styles/selected_focus = null
|
||||||
"Label/colors/Selected Color" = Color( 0.235294, 0.364706, 0.458824, 1 )
|
"Label/colors/Selected Color" = Color( 0.235294, 0.364706, 0.458824, 1 )
|
||||||
Label/colors/font_color = Color( 1, 1, 1, 1 )
|
Label/colors/font_color = Color( 1, 1, 1, 1 )
|
||||||
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
||||||
|
|
|
@ -176,6 +176,18 @@ expand_margin_top = 2.0
|
||||||
expand_margin_bottom = 2.0
|
expand_margin_bottom = 2.0
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=19]
|
[sub_resource type="StyleBoxFlat" id=19]
|
||||||
|
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
|
border_width_left = 4
|
||||||
|
border_width_top = 4
|
||||||
|
border_width_right = 4
|
||||||
|
border_width_bottom = 4
|
||||||
|
border_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
|
corner_radius_top_left = 4
|
||||||
|
corner_radius_top_right = 4
|
||||||
|
corner_radius_bottom_right = 4
|
||||||
|
corner_radius_bottom_left = 4
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id=20]
|
||||||
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
bg_color = Color( 0.109804, 0.0862745, 0.0862745, 0 )
|
||||||
border_width_left = 1
|
border_width_left = 1
|
||||||
border_width_top = 1
|
border_width_top = 1
|
||||||
|
@ -188,10 +200,10 @@ corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
anti_aliasing = false
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=20]
|
[sub_resource type="StyleBoxFlat" id=21]
|
||||||
bg_color = Color( 0.772549, 0.772549, 0.772549, 1 )
|
bg_color = Color( 0.772549, 0.772549, 0.772549, 1 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=21]
|
[sub_resource type="StyleBoxFlat" id=22]
|
||||||
content_margin_left = 4.5
|
content_margin_left = 4.5
|
||||||
content_margin_right = 4.5
|
content_margin_right = 4.5
|
||||||
content_margin_top = 3.0
|
content_margin_top = 3.0
|
||||||
|
@ -202,7 +214,7 @@ corner_radius_top_right = 5
|
||||||
corner_radius_bottom_right = 5
|
corner_radius_bottom_right = 5
|
||||||
corner_radius_bottom_left = 5
|
corner_radius_bottom_left = 5
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=22]
|
[sub_resource type="StyleBoxFlat" id=23]
|
||||||
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
border_width_left = 6
|
border_width_left = 6
|
||||||
border_width_top = 10
|
border_width_top = 10
|
||||||
|
@ -215,10 +227,10 @@ corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
anti_aliasing = false
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=23]
|
[sub_resource type="StyleBoxFlat" id=24]
|
||||||
bg_color = Color( 0.764706, 0.764706, 0.764706, 1 )
|
bg_color = Color( 0.764706, 0.764706, 0.764706, 1 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=24]
|
[sub_resource type="StyleBoxFlat" id=25]
|
||||||
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
border_width_left = 5
|
border_width_left = 5
|
||||||
border_width_top = 10
|
border_width_top = 10
|
||||||
|
@ -231,7 +243,7 @@ corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
anti_aliasing = false
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=25]
|
[sub_resource type="StyleBoxFlat" id=26]
|
||||||
bg_color = Color( 0.352941, 0.352941, 0.352941, 1 )
|
bg_color = Color( 0.352941, 0.352941, 0.352941, 1 )
|
||||||
border_width_left = 10
|
border_width_left = 10
|
||||||
border_width_top = 6
|
border_width_top = 6
|
||||||
|
@ -239,7 +251,7 @@ border_width_right = 10
|
||||||
border_width_bottom = 8
|
border_width_bottom = 8
|
||||||
border_color = Color( 0.352941, 0.352941, 0.352941, 1 )
|
border_color = Color( 0.352941, 0.352941, 0.352941, 1 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=26]
|
[sub_resource type="StyleBoxFlat" id=27]
|
||||||
bg_color = Color( 0.239216, 0.239216, 0.239216, 1 )
|
bg_color = Color( 0.239216, 0.239216, 0.239216, 1 )
|
||||||
border_width_left = 10
|
border_width_left = 10
|
||||||
border_width_top = 6
|
border_width_top = 6
|
||||||
|
@ -247,7 +259,7 @@ border_width_right = 10
|
||||||
border_width_bottom = 8
|
border_width_bottom = 8
|
||||||
border_color = Color( 0.239216, 0.239216, 0.239216, 1 )
|
border_color = Color( 0.239216, 0.239216, 0.239216, 1 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=27]
|
[sub_resource type="StyleBoxFlat" id=28]
|
||||||
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
border_width_left = 10
|
border_width_left = 10
|
||||||
border_width_top = 6
|
border_width_top = 6
|
||||||
|
@ -255,19 +267,6 @@ border_width_right = 10
|
||||||
border_width_bottom = 8
|
border_width_bottom = 8
|
||||||
border_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
border_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=28]
|
|
||||||
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
|
||||||
border_width_left = 4
|
|
||||||
border_width_top = 4
|
|
||||||
border_width_right = 4
|
|
||||||
border_width_bottom = 4
|
|
||||||
border_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
|
||||||
corner_radius_top_left = 4
|
|
||||||
corner_radius_top_right = 4
|
|
||||||
corner_radius_bottom_right = 4
|
|
||||||
corner_radius_bottom_left = 4
|
|
||||||
anti_aliasing = false
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=29]
|
[sub_resource type="StyleBoxFlat" id=29]
|
||||||
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
bg_color = Color( 0.627451, 0.627451, 0.627451, 1 )
|
||||||
border_width_left = 4
|
border_width_left = 4
|
||||||
|
@ -279,6 +278,7 @@ corner_radius_top_left = 4
|
||||||
corner_radius_top_right = 4
|
corner_radius_top_right = 4
|
||||||
corner_radius_bottom_right = 4
|
corner_radius_bottom_right = 4
|
||||||
corner_radius_bottom_left = 4
|
corner_radius_bottom_left = 4
|
||||||
|
anti_aliasing = false
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=30]
|
[sub_resource type="StyleBoxFlat" id=30]
|
||||||
bg_color = Color( 0.529412, 0.529412, 0.529412, 1 )
|
bg_color = Color( 0.529412, 0.529412, 0.529412, 1 )
|
||||||
|
@ -390,6 +390,20 @@ HSplitContainer/constants/autohide = 1
|
||||||
HSplitContainer/constants/separation = 6
|
HSplitContainer/constants/separation = 6
|
||||||
HSplitContainer/icons/grabber = ExtResource( 1 )
|
HSplitContainer/icons/grabber = ExtResource( 1 )
|
||||||
HSplitContainer/styles/bg = null
|
HSplitContainer/styles/bg = null
|
||||||
|
ItemList/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
|
ItemList/colors/font_color_selected = Color( 0.278431, 0.278431, 0.278431, 1 )
|
||||||
|
ItemList/colors/guide_color = Color( 0, 0, 0, 0.1 )
|
||||||
|
ItemList/constants/hseparation = 4
|
||||||
|
ItemList/constants/icon_margin = 4
|
||||||
|
ItemList/constants/line_separation = 2
|
||||||
|
ItemList/constants/vseparation = 4
|
||||||
|
ItemList/fonts/font = null
|
||||||
|
ItemList/styles/bg = SubResource( 19 )
|
||||||
|
ItemList/styles/bg_focus = null
|
||||||
|
ItemList/styles/cursor = null
|
||||||
|
ItemList/styles/cursor_unfocused = null
|
||||||
|
ItemList/styles/selected = null
|
||||||
|
ItemList/styles/selected_focus = null
|
||||||
"Label/colors/Selected Color" = Color( 0.545098, 0.619608, 0.788235, 1 )
|
"Label/colors/Selected Color" = Color( 0.545098, 0.619608, 0.788235, 1 )
|
||||||
Label/colors/font_color = Color( 0, 0, 0, 1 )
|
Label/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
Label/colors/font_color_shadow = Color( 0, 0, 0, 0 )
|
||||||
|
@ -410,7 +424,7 @@ LineEdit/constants/minimum_spaces = 12
|
||||||
LineEdit/fonts/font = null
|
LineEdit/fonts/font = null
|
||||||
LineEdit/icons/clear = null
|
LineEdit/icons/clear = null
|
||||||
LineEdit/styles/focus = null
|
LineEdit/styles/focus = null
|
||||||
LineEdit/styles/normal = SubResource( 19 )
|
LineEdit/styles/normal = SubResource( 20 )
|
||||||
LineEdit/styles/read_only = null
|
LineEdit/styles/read_only = null
|
||||||
MenuButton/colors/font_color = Color( 0, 0, 0, 1 )
|
MenuButton/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
MenuButton/colors/font_color_disabled = Color( 1, 1, 1, 0.3 )
|
MenuButton/colors/font_color_disabled = Color( 1, 1, 1, 0.3 )
|
||||||
|
@ -436,10 +450,10 @@ OptionButton/styles/focus = null
|
||||||
OptionButton/styles/hover = null
|
OptionButton/styles/hover = null
|
||||||
OptionButton/styles/normal = null
|
OptionButton/styles/normal = null
|
||||||
OptionButton/styles/pressed = null
|
OptionButton/styles/pressed = null
|
||||||
Panel/styles/panel = SubResource( 20 )
|
Panel/styles/panel = SubResource( 21 )
|
||||||
Panel/styles/panelf = null
|
Panel/styles/panelf = null
|
||||||
Panel/styles/panelnc = null
|
Panel/styles/panelnc = null
|
||||||
PanelContainer/styles/panel = SubResource( 21 )
|
PanelContainer/styles/panel = SubResource( 22 )
|
||||||
PopupMenu/colors/font_color = Color( 0, 0, 0, 1 )
|
PopupMenu/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
PopupMenu/colors/font_color_accel = Color( 0.164706, 0.164706, 0.164706, 0.8 )
|
PopupMenu/colors/font_color_accel = Color( 0.164706, 0.164706, 0.164706, 0.8 )
|
||||||
PopupMenu/colors/font_color_disabled = Color( 0.4, 0.4, 0.4, 0.8 )
|
PopupMenu/colors/font_color_disabled = Color( 0.4, 0.4, 0.4, 0.8 )
|
||||||
|
@ -455,10 +469,10 @@ PopupMenu/icons/unchecked = null
|
||||||
PopupMenu/styles/hover = null
|
PopupMenu/styles/hover = null
|
||||||
PopupMenu/styles/labeled_separator_left = null
|
PopupMenu/styles/labeled_separator_left = null
|
||||||
PopupMenu/styles/labeled_separator_right = null
|
PopupMenu/styles/labeled_separator_right = null
|
||||||
PopupMenu/styles/panel = SubResource( 22 )
|
PopupMenu/styles/panel = SubResource( 23 )
|
||||||
PopupMenu/styles/panel_disabled = null
|
PopupMenu/styles/panel_disabled = null
|
||||||
PopupMenu/styles/separator = null
|
PopupMenu/styles/separator = null
|
||||||
PopupPanel/styles/panel = SubResource( 23 )
|
PopupPanel/styles/panel = SubResource( 24 )
|
||||||
SpinBox/icons/updown = ExtResource( 6 )
|
SpinBox/icons/updown = ExtResource( 6 )
|
||||||
TabContainer/colors/font_color_bg = Color( 0, 0, 0, 1 )
|
TabContainer/colors/font_color_bg = Color( 0, 0, 0, 1 )
|
||||||
TabContainer/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
|
TabContainer/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
|
||||||
|
@ -475,10 +489,10 @@ TabContainer/icons/increment = null
|
||||||
TabContainer/icons/increment_highlight = null
|
TabContainer/icons/increment_highlight = null
|
||||||
TabContainer/icons/menu = null
|
TabContainer/icons/menu = null
|
||||||
TabContainer/icons/menu_highlight = null
|
TabContainer/icons/menu_highlight = null
|
||||||
TabContainer/styles/panel = SubResource( 24 )
|
TabContainer/styles/panel = SubResource( 25 )
|
||||||
TabContainer/styles/tab_bg = SubResource( 25 )
|
TabContainer/styles/tab_bg = SubResource( 26 )
|
||||||
TabContainer/styles/tab_disabled = SubResource( 26 )
|
TabContainer/styles/tab_disabled = SubResource( 27 )
|
||||||
TabContainer/styles/tab_fg = SubResource( 27 )
|
TabContainer/styles/tab_fg = SubResource( 28 )
|
||||||
Tabs/colors/font_color_bg = Color( 0.69, 0.69, 0.69, 1 )
|
Tabs/colors/font_color_bg = Color( 0.69, 0.69, 0.69, 1 )
|
||||||
Tabs/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
|
Tabs/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
|
||||||
Tabs/colors/font_color_fg = Color( 0.94, 0.94, 0.94, 1 )
|
Tabs/colors/font_color_fg = Color( 0.94, 0.94, 0.94, 1 )
|
||||||
|
@ -494,10 +508,10 @@ Tabs/icons/increment = null
|
||||||
Tabs/icons/increment_highlight = null
|
Tabs/icons/increment_highlight = null
|
||||||
Tabs/styles/button = null
|
Tabs/styles/button = null
|
||||||
Tabs/styles/button_pressed = null
|
Tabs/styles/button_pressed = null
|
||||||
Tabs/styles/panel = SubResource( 24 )
|
Tabs/styles/panel = SubResource( 25 )
|
||||||
Tabs/styles/tab_bg = SubResource( 25 )
|
Tabs/styles/tab_bg = SubResource( 26 )
|
||||||
Tabs/styles/tab_disabled = SubResource( 26 )
|
Tabs/styles/tab_disabled = SubResource( 27 )
|
||||||
Tabs/styles/tab_fg = SubResource( 27 )
|
Tabs/styles/tab_fg = SubResource( 28 )
|
||||||
TextEdit/colors/background_color = Color( 0, 0, 0, 0 )
|
TextEdit/colors/background_color = Color( 0, 0, 0, 0 )
|
||||||
TextEdit/colors/brace_mismatch_color = Color( 1, 0.2, 0.2, 1 )
|
TextEdit/colors/brace_mismatch_color = Color( 1, 0.2, 0.2, 1 )
|
||||||
TextEdit/colors/breakpoint_color = Color( 0.8, 0.8, 0.4, 0.2 )
|
TextEdit/colors/breakpoint_color = Color( 0.8, 0.8, 0.4, 0.2 )
|
||||||
|
@ -529,7 +543,7 @@ TextEdit/fonts/font = null
|
||||||
TextEdit/icons/tab = null
|
TextEdit/icons/tab = null
|
||||||
TextEdit/styles/completion = null
|
TextEdit/styles/completion = null
|
||||||
TextEdit/styles/focus = null
|
TextEdit/styles/focus = null
|
||||||
TextEdit/styles/normal = SubResource( 28 )
|
TextEdit/styles/normal = SubResource( 29 )
|
||||||
TextEdit/styles/read_only = null
|
TextEdit/styles/read_only = null
|
||||||
ToolButton/colors/font_color = Color( 0, 0, 0, 1 )
|
ToolButton/colors/font_color = Color( 0, 0, 0, 1 )
|
||||||
ToolButton/colors/font_color_disabled = Color( 0.9, 0.95, 1, 0.3 )
|
ToolButton/colors/font_color_disabled = Color( 0.9, 0.95, 1, 0.3 )
|
||||||
|
@ -568,7 +582,7 @@ Tree/icons/checked = null
|
||||||
Tree/icons/select_arrow = null
|
Tree/icons/select_arrow = null
|
||||||
Tree/icons/unchecked = null
|
Tree/icons/unchecked = null
|
||||||
Tree/icons/updown = null
|
Tree/icons/updown = null
|
||||||
Tree/styles/bg = SubResource( 29 )
|
Tree/styles/bg = SubResource( 19 )
|
||||||
Tree/styles/bg_focus = null
|
Tree/styles/bg_focus = null
|
||||||
Tree/styles/button_pressed = null
|
Tree/styles/button_pressed = null
|
||||||
Tree/styles/cursor = null
|
Tree/styles/cursor = null
|
||||||
|
|
|
@ -9,16 +9,31 @@
|
||||||
config_version=4
|
config_version=4
|
||||||
|
|
||||||
_global_script_classes=[ {
|
_global_script_classes=[ {
|
||||||
|
"base": "Reference",
|
||||||
|
"class": "AnimationTag",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Classes/AnimationTag.gd"
|
||||||
|
}, {
|
||||||
"base": "Node2D",
|
"base": "Node2D",
|
||||||
"class": "Canvas",
|
"class": "Canvas",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Canvas.gd"
|
"path": "res://src/Canvas.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "Reference",
|
||||||
|
"class": "Cel",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Classes/Cel.gd"
|
||||||
|
}, {
|
||||||
"base": "Line2D",
|
"base": "Line2D",
|
||||||
"class": "Guide",
|
"class": "Guide",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/UI/Rulers/Guides.gd"
|
"path": "res://src/UI/Rulers/Guides.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "Reference",
|
||||||
|
"class": "Layer",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Classes/Layer.gd"
|
||||||
|
}, {
|
||||||
"base": "Button",
|
"base": "Button",
|
||||||
"class": "LayerButton",
|
"class": "LayerButton",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
|
@ -35,8 +50,11 @@ _global_script_classes=[ {
|
||||||
"path": "res://src/Palette/PaletteColor.gd"
|
"path": "res://src/Palette/PaletteColor.gd"
|
||||||
} ]
|
} ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
"AnimationTag": "",
|
||||||
"Canvas": "",
|
"Canvas": "",
|
||||||
|
"Cel": "",
|
||||||
"Guide": "",
|
"Guide": "",
|
||||||
|
"Layer": "",
|
||||||
"LayerButton": "",
|
"LayerButton": "",
|
||||||
"Palette": "",
|
"Palette": "",
|
||||||
"PaletteColor": ""
|
"PaletteColor": ""
|
||||||
|
@ -60,6 +78,7 @@ config/Version="v0.7"
|
||||||
Global="*res://src/Autoload/Global.gd"
|
Global="*res://src/Autoload/Global.gd"
|
||||||
Import="*res://src/Autoload/Import.gd"
|
Import="*res://src/Autoload/Import.gd"
|
||||||
OpenSave="*res://src/Autoload/OpenSave.gd"
|
OpenSave="*res://src/Autoload/OpenSave.gd"
|
||||||
|
DrawingAlgos="*res://src/Autoload/DrawingAlgos.gd"
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
|
|
646
src/Autoload/DrawingAlgos.gd
Normal file
646
src/Autoload/DrawingAlgos.gd
Normal file
|
@ -0,0 +1,646 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
const Drawer = preload("res://src/Classes/Drawers.gd").Drawer
|
||||||
|
const SimpleDrawer = preload("res://src/Classes/Drawers.gd").SimpleDrawer
|
||||||
|
const PixelPerfectDrawer = preload("res://src/Classes/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()
|
||||||
|
var pixel_perfect_drawer_hv_mirror := PixelPerfectDrawer.new()
|
||||||
|
var simple_drawer := SimpleDrawer.new()
|
||||||
|
|
||||||
|
var mouse_press_pixels := [] # Cleared after mouse release
|
||||||
|
var mouse_press_pressure_values := [] # Cleared after mouse release
|
||||||
|
|
||||||
|
|
||||||
|
func draw_pixel_blended(sprite : Image, pos : Vector2, color : Color, pen_pressure : float, current_mouse_button := -1, current_action := -1, drawer : Drawer = simple_drawer) -> void:
|
||||||
|
var west_limit = Global.canvas.west_limit
|
||||||
|
var east_limit = Global.canvas.east_limit
|
||||||
|
var north_limit = Global.canvas.north_limit
|
||||||
|
var south_limit = Global.canvas.south_limit
|
||||||
|
if !point_in_rectangle(pos, Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)):
|
||||||
|
return
|
||||||
|
|
||||||
|
var pos_floored := pos.floor()
|
||||||
|
var current_pixel_color = sprite.get_pixelv(pos)
|
||||||
|
var saved_pixel_index := mouse_press_pixels.find(pos_floored)
|
||||||
|
if current_action == Global.Tools.PENCIL && color.a < 1:
|
||||||
|
color = blend_colors(color, current_pixel_color)
|
||||||
|
|
||||||
|
if current_pixel_color != color && (saved_pixel_index == -1 || pen_pressure > mouse_press_pressure_values[saved_pixel_index]):
|
||||||
|
if current_action == Global.Tools.LIGHTENDARKEN:
|
||||||
|
var ld : int = Global.ld_modes[current_mouse_button]
|
||||||
|
var ld_amount : float = Global.ld_amounts[current_mouse_button]
|
||||||
|
if ld == Global.Lighten_Darken_Mode.LIGHTEN:
|
||||||
|
color = current_pixel_color.lightened(ld_amount)
|
||||||
|
else:
|
||||||
|
color = current_pixel_color.darkened(ld_amount)
|
||||||
|
|
||||||
|
if saved_pixel_index == -1:
|
||||||
|
mouse_press_pixels.append(pos_floored)
|
||||||
|
mouse_press_pressure_values.append(pen_pressure)
|
||||||
|
else:
|
||||||
|
mouse_press_pressure_values[saved_pixel_index] = pen_pressure
|
||||||
|
drawer.set_pixel(sprite, pos, color)
|
||||||
|
|
||||||
|
|
||||||
|
func draw_brush(sprite : Image, pos : Vector2, color : Color, current_mouse_button : int, pen_pressure : float, current_action := -1) -> void:
|
||||||
|
if Global.can_draw && Global.has_focus:
|
||||||
|
var west_limit = Global.canvas.west_limit
|
||||||
|
var east_limit = Global.canvas.east_limit
|
||||||
|
var north_limit = Global.canvas.north_limit
|
||||||
|
var south_limit = Global.canvas.south_limit
|
||||||
|
|
||||||
|
if Global.pressure_sensitivity_mode == Global.Pressure_Sensitivity.ALPHA:
|
||||||
|
if current_action == Global.Tools.PENCIL:
|
||||||
|
color.a *= pen_pressure
|
||||||
|
elif current_action == Global.Tools.ERASER: # This is not working
|
||||||
|
color.a *= (1.0 - pen_pressure)
|
||||||
|
|
||||||
|
var brush_size : int = Global.brush_sizes[current_mouse_button]
|
||||||
|
var brush_type : int = Global.current_brush_types[current_mouse_button]
|
||||||
|
|
||||||
|
var horizontal_mirror : bool = Global.horizontal_mirror[current_mouse_button]
|
||||||
|
var vertical_mirror : bool = Global.vertical_mirror[current_mouse_button]
|
||||||
|
|
||||||
|
if brush_type == Global.Brush_Types.PIXEL || current_action == Global.Tools.LIGHTENDARKEN:
|
||||||
|
var start_pos_x = pos.x - (brush_size >> 1)
|
||||||
|
var start_pos_y = pos.y - (brush_size >> 1)
|
||||||
|
var end_pos_x = start_pos_x + brush_size
|
||||||
|
var end_pos_y = start_pos_y + brush_size
|
||||||
|
|
||||||
|
for cur_pos_x in range(start_pos_x, end_pos_x):
|
||||||
|
for cur_pos_y in range(start_pos_y, end_pos_y):
|
||||||
|
var pixel_perfect : bool = Global.pixel_perfect[current_mouse_button]
|
||||||
|
# warning-ignore:incompatible_ternary
|
||||||
|
var drawer : Drawer = pixel_perfect_drawer if pixel_perfect else simple_drawer
|
||||||
|
draw_pixel_blended(sprite, Vector2(cur_pos_x, cur_pos_y), color, pen_pressure, current_mouse_button, current_action, drawer)
|
||||||
|
|
||||||
|
# Handle mirroring
|
||||||
|
var mirror_x = east_limit + west_limit - cur_pos_x - 1
|
||||||
|
var mirror_y = south_limit + north_limit - cur_pos_y - 1
|
||||||
|
if horizontal_mirror:
|
||||||
|
# warning-ignore:incompatible_ternary
|
||||||
|
var drawer_h_mirror : Drawer = pixel_perfect_drawer_h_mirror if pixel_perfect else simple_drawer
|
||||||
|
draw_pixel_blended(sprite, Vector2(mirror_x, cur_pos_y), color, pen_pressure, current_mouse_button, current_action, drawer_h_mirror)
|
||||||
|
if vertical_mirror:
|
||||||
|
# warning-ignore:incompatible_ternary
|
||||||
|
var drawer_v_mirror : Drawer = pixel_perfect_drawer_v_mirror if pixel_perfect else simple_drawer
|
||||||
|
draw_pixel_blended(sprite, Vector2(cur_pos_x, mirror_y), color, pen_pressure, current_mouse_button, current_action, drawer_v_mirror)
|
||||||
|
if horizontal_mirror && vertical_mirror:
|
||||||
|
# warning-ignore:incompatible_ternary
|
||||||
|
var drawer_hv_mirror : Drawer = pixel_perfect_drawer_hv_mirror if pixel_perfect else simple_drawer
|
||||||
|
draw_pixel_blended(sprite, Vector2(mirror_x, mirror_y), color, pen_pressure, current_mouse_button, current_action, drawer_hv_mirror)
|
||||||
|
|
||||||
|
Global.canvas.sprite_changed_this_frame = true
|
||||||
|
|
||||||
|
elif brush_type == Global.Brush_Types.CIRCLE || brush_type == Global.Brush_Types.FILLED_CIRCLE:
|
||||||
|
plot_circle(sprite, pos.x, pos.y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
|
||||||
|
|
||||||
|
# Handle mirroring
|
||||||
|
var mirror_x = east_limit + west_limit - pos.x
|
||||||
|
var mirror_y = south_limit + north_limit - pos.y
|
||||||
|
if horizontal_mirror:
|
||||||
|
plot_circle(sprite, mirror_x, pos.y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
|
||||||
|
if vertical_mirror:
|
||||||
|
plot_circle(sprite, pos.x, mirror_y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
|
||||||
|
if horizontal_mirror && vertical_mirror:
|
||||||
|
plot_circle(sprite, mirror_x, mirror_y, brush_size, color, brush_type == Global.Brush_Types.FILLED_CIRCLE)
|
||||||
|
|
||||||
|
Global.canvas.sprite_changed_this_frame = true
|
||||||
|
|
||||||
|
else:
|
||||||
|
var brush_index : int = Global.custom_brush_indexes[current_mouse_button]
|
||||||
|
var custom_brush_image : Image
|
||||||
|
if brush_type != Global.Brush_Types.RANDOM_FILE:
|
||||||
|
custom_brush_image = Global.custom_brush_images[current_mouse_button]
|
||||||
|
else: # Handle random brush
|
||||||
|
var brush_button = Global.file_brush_container.get_child(brush_index + 3)
|
||||||
|
var random_index = randi() % brush_button.random_brushes.size()
|
||||||
|
custom_brush_image = Image.new()
|
||||||
|
custom_brush_image.copy_from(brush_button.random_brushes[random_index])
|
||||||
|
var custom_brush_size = custom_brush_image.get_size()
|
||||||
|
custom_brush_image.resize(custom_brush_size.x * brush_size, custom_brush_size.y * brush_size, Image.INTERPOLATE_NEAREST)
|
||||||
|
custom_brush_image = Global.blend_image_with_color(custom_brush_image, color, Global.interpolate_spinboxes[current_mouse_button].value / 100)
|
||||||
|
custom_brush_image.lock()
|
||||||
|
|
||||||
|
var custom_brush_size := custom_brush_image.get_size() - Vector2.ONE
|
||||||
|
pos = pos.floor()
|
||||||
|
var dst := rectangle_center(pos, custom_brush_size)
|
||||||
|
var src_rect := Rect2(Vector2.ZERO, custom_brush_size + Vector2.ONE)
|
||||||
|
# Rectangle with the same size as the brush, but at cursor's position
|
||||||
|
var pos_rect := Rect2(dst, custom_brush_size + Vector2.ONE)
|
||||||
|
|
||||||
|
# The selection rectangle
|
||||||
|
# If there's no rectangle, the whole canvas is considered a selection
|
||||||
|
var selection_rect := Rect2()
|
||||||
|
selection_rect.position = Vector2(west_limit, north_limit)
|
||||||
|
selection_rect.end = Vector2(east_limit, south_limit)
|
||||||
|
# Intersection of the position rectangle and selection
|
||||||
|
var pos_rect_clipped := pos_rect.clip(selection_rect)
|
||||||
|
# If the size is 0, that means that the brush wasn't positioned inside the selection
|
||||||
|
if pos_rect_clipped.size == Vector2.ZERO:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Re-position src_rect and dst based on the clipped position
|
||||||
|
var pos_difference := (pos_rect.position - pos_rect_clipped.position).abs()
|
||||||
|
# Obviously, if pos_rect and pos_rect_clipped are the same, pos_difference is Vector2.ZERO
|
||||||
|
src_rect.position = pos_difference
|
||||||
|
dst += pos_difference
|
||||||
|
src_rect.end -= pos_rect.end - pos_rect_clipped.end
|
||||||
|
# If the selection rectangle is smaller than the brush, ...
|
||||||
|
# ... make sure pixels aren't being drawn outside the selection by adjusting src_rect's size
|
||||||
|
src_rect.size.x = min(src_rect.size.x, selection_rect.size.x)
|
||||||
|
src_rect.size.y = min(src_rect.size.y, selection_rect.size.y)
|
||||||
|
|
||||||
|
# Handle mirroring
|
||||||
|
var mirror_x = east_limit + west_limit - pos.x - (pos.x - dst.x)
|
||||||
|
var mirror_y = south_limit + north_limit - pos.y - (pos.y - dst.y)
|
||||||
|
if int(pos_rect_clipped.size.x) % 2 != 0:
|
||||||
|
mirror_x -= 1
|
||||||
|
if int(pos_rect_clipped.size.y) % 2 != 0:
|
||||||
|
mirror_y -= 1
|
||||||
|
# Use custom blend function cause of godot's issue #31124
|
||||||
|
if color.a > 0: # If it's the pencil
|
||||||
|
blend_rect(sprite, custom_brush_image, src_rect, dst)
|
||||||
|
if horizontal_mirror:
|
||||||
|
blend_rect(sprite, custom_brush_image, src_rect, Vector2(mirror_x, dst.y))
|
||||||
|
if vertical_mirror:
|
||||||
|
blend_rect(sprite, custom_brush_image, src_rect, Vector2(dst.x, mirror_y))
|
||||||
|
if horizontal_mirror && vertical_mirror:
|
||||||
|
blend_rect(sprite, custom_brush_image, src_rect, Vector2(mirror_x, mirror_y))
|
||||||
|
|
||||||
|
else: # if it's transparent - if it's the eraser
|
||||||
|
var custom_brush := Image.new()
|
||||||
|
custom_brush.copy_from(Global.custom_brushes[brush_index])
|
||||||
|
custom_brush_size = custom_brush.get_size()
|
||||||
|
custom_brush.resize(custom_brush_size.x * brush_size, custom_brush_size.y * brush_size, Image.INTERPOLATE_NEAREST)
|
||||||
|
var custom_brush_blended = Global.blend_image_with_color(custom_brush, color, 1)
|
||||||
|
|
||||||
|
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, dst)
|
||||||
|
if horizontal_mirror:
|
||||||
|
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(mirror_x, dst.y))
|
||||||
|
if vertical_mirror:
|
||||||
|
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(dst.x, mirror_y))
|
||||||
|
if horizontal_mirror && vertical_mirror:
|
||||||
|
sprite.blit_rect_mask(custom_brush_blended, custom_brush, src_rect, Vector2(mirror_x, mirror_y))
|
||||||
|
|
||||||
|
sprite.lock()
|
||||||
|
Global.canvas.sprite_changed_this_frame = true
|
||||||
|
|
||||||
|
Global.canvas.previous_mouse_pos_for_lines = pos.floor() + Vector2(0.5, 0.5)
|
||||||
|
Global.canvas.previous_mouse_pos_for_lines.x = clamp(Global.canvas.previous_mouse_pos_for_lines.x, Global.canvas.location.x, Global.canvas.location.x + Global.canvas.size.x)
|
||||||
|
Global.canvas.previous_mouse_pos_for_lines.y = clamp(Global.canvas.previous_mouse_pos_for_lines.y, Global.canvas.location.y, Global.canvas.location.y + Global.canvas.size.y)
|
||||||
|
if Global.canvas.is_making_line:
|
||||||
|
Global.canvas.line_2d.set_point_position(0, Global.canvas.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, end_pos : Vector2, start_pos : Vector2, color : Color, current_mouse_button : int, pen_pressure : float, current_action := -1) -> void:
|
||||||
|
var previous_mouse_pos_floored = start_pos.floor()
|
||||||
|
var mouse_pos_floored = end_pos.floor()
|
||||||
|
var dx := int(abs(mouse_pos_floored.x - previous_mouse_pos_floored.x))
|
||||||
|
var dy := int(-abs(mouse_pos_floored.y - previous_mouse_pos_floored.y))
|
||||||
|
var err := dx + dy
|
||||||
|
var e2 := err << 1 # err * 2
|
||||||
|
var sx = 1 if previous_mouse_pos_floored.x < mouse_pos_floored.x else -1
|
||||||
|
var sy = 1 if previous_mouse_pos_floored.y < mouse_pos_floored.y else -1
|
||||||
|
var x = previous_mouse_pos_floored.x
|
||||||
|
var y = previous_mouse_pos_floored.y
|
||||||
|
while !(x == mouse_pos_floored.x && y == mouse_pos_floored.y):
|
||||||
|
draw_brush(sprite, Vector2(x, y), color, current_mouse_button, pen_pressure, current_action)
|
||||||
|
e2 = err << 1
|
||||||
|
if e2 >= dy:
|
||||||
|
err += dy
|
||||||
|
x += sx
|
||||||
|
if e2 <= dx:
|
||||||
|
err += dx
|
||||||
|
y += sy
|
||||||
|
|
||||||
|
|
||||||
|
# Algorithm based on http://members.chello.at/easyfilter/bresenham.html
|
||||||
|
func plot_circle(sprite : Image, xm : int, ym : int, r : int, color : Color, fill := false) -> void:
|
||||||
|
var radius := r # Used later for filling
|
||||||
|
var x := -r
|
||||||
|
var y := 0
|
||||||
|
var err := 2 - r * 2 # II. Quadrant
|
||||||
|
while x < 0:
|
||||||
|
var quadrant_1 := Vector2(xm - x, ym + y)
|
||||||
|
var quadrant_2 := Vector2(xm - y, ym - x)
|
||||||
|
var quadrant_3 := Vector2(xm + x, ym - y)
|
||||||
|
var quadrant_4 := Vector2(xm + y, ym + x)
|
||||||
|
draw_pixel_blended(sprite, quadrant_1, color, Global.canvas.pen_pressure)
|
||||||
|
draw_pixel_blended(sprite, quadrant_2, color, Global.canvas.pen_pressure)
|
||||||
|
draw_pixel_blended(sprite, quadrant_3, color, Global.canvas.pen_pressure)
|
||||||
|
draw_pixel_blended(sprite, quadrant_4, color, Global.canvas.pen_pressure)
|
||||||
|
|
||||||
|
r = err
|
||||||
|
if r <= y:
|
||||||
|
y += 1
|
||||||
|
err += y * 2 + 1
|
||||||
|
if r > x || err > y:
|
||||||
|
x += 1
|
||||||
|
err += x * 2 + 1
|
||||||
|
|
||||||
|
if fill:
|
||||||
|
for j in range (-radius, radius + 1):
|
||||||
|
for i in range (-radius, radius + 1):
|
||||||
|
if i * i + j * j <= radius * radius:
|
||||||
|
var draw_pos := Vector2(i + xm, j + ym)
|
||||||
|
draw_pixel_blended(sprite, draw_pos, color, Global.canvas.pen_pressure)
|
||||||
|
|
||||||
|
|
||||||
|
# Thanks to https://en.wikipedia.org/wiki/Flood_fill
|
||||||
|
func flood_fill(sprite : Image, pos : Vector2, target_color : Color, replace_color : Color) -> void:
|
||||||
|
var west_limit = Global.canvas.west_limit
|
||||||
|
var east_limit = Global.canvas.east_limit
|
||||||
|
var north_limit = Global.canvas.north_limit
|
||||||
|
var south_limit = Global.canvas.south_limit
|
||||||
|
pos = pos.floor()
|
||||||
|
var pixel = sprite.get_pixelv(pos)
|
||||||
|
if target_color == replace_color:
|
||||||
|
return
|
||||||
|
elif pixel != target_color:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
|
||||||
|
if !point_in_rectangle(pos, Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)):
|
||||||
|
return
|
||||||
|
|
||||||
|
var q = [pos]
|
||||||
|
for n in q:
|
||||||
|
# If the difference in colors is very small, break the loop (thanks @azagaya on GitHub!)
|
||||||
|
if target_color == replace_color:
|
||||||
|
break
|
||||||
|
var west : Vector2 = n
|
||||||
|
var east : Vector2 = n
|
||||||
|
while west.x >= west_limit && sprite.get_pixelv(west) == target_color:
|
||||||
|
west += Vector2.LEFT
|
||||||
|
while east.x < east_limit && sprite.get_pixelv(east) == target_color:
|
||||||
|
east += Vector2.RIGHT
|
||||||
|
for px in range(west.x + 1, east.x):
|
||||||
|
var p := Vector2(px, n.y)
|
||||||
|
# Draw
|
||||||
|
sprite.set_pixelv(p, replace_color)
|
||||||
|
replace_color = sprite.get_pixelv(p)
|
||||||
|
var north := p + Vector2.UP
|
||||||
|
var south := p + Vector2.DOWN
|
||||||
|
if north.y >= north_limit && sprite.get_pixelv(north) == target_color:
|
||||||
|
q.append(north)
|
||||||
|
if south.y < south_limit && sprite.get_pixelv(south) == target_color:
|
||||||
|
q.append(south)
|
||||||
|
|
||||||
|
Global.canvas.sprite_changed_this_frame = true
|
||||||
|
|
||||||
|
|
||||||
|
func pattern_fill(sprite : Image, pos : Vector2, pattern : Image, target_color : Color, var offset : Vector2) -> void:
|
||||||
|
var west_limit = Global.canvas.west_limit
|
||||||
|
var east_limit = Global.canvas.east_limit
|
||||||
|
var north_limit = Global.canvas.north_limit
|
||||||
|
var south_limit = Global.canvas.south_limit
|
||||||
|
pos = pos.floor()
|
||||||
|
if !point_in_rectangle(pos, Vector2(west_limit - 1, north_limit - 1), Vector2(east_limit, south_limit)):
|
||||||
|
return
|
||||||
|
|
||||||
|
pattern.lock()
|
||||||
|
var pattern_size := pattern.get_size()
|
||||||
|
var q = [pos]
|
||||||
|
|
||||||
|
for n in q:
|
||||||
|
var west : Vector2 = n
|
||||||
|
var east : Vector2 = n
|
||||||
|
while west.x >= west_limit && sprite.get_pixelv(west) == target_color:
|
||||||
|
west += Vector2.LEFT
|
||||||
|
while east.x < east_limit && sprite.get_pixelv(east) == target_color:
|
||||||
|
east += Vector2.RIGHT
|
||||||
|
|
||||||
|
for px in range(west.x + 1, east.x):
|
||||||
|
var p := Vector2(px, n.y)
|
||||||
|
var xx : int = int(px + offset.x) % int(pattern_size.x)
|
||||||
|
var yy : int = int(n.y + offset.y) % int(pattern_size.y)
|
||||||
|
var pattern_color : Color = pattern.get_pixel(xx, yy)
|
||||||
|
if pattern_color == target_color:
|
||||||
|
continue
|
||||||
|
sprite.set_pixelv(p, pattern_color)
|
||||||
|
|
||||||
|
var north := p + Vector2.UP
|
||||||
|
var south := p + Vector2.DOWN
|
||||||
|
if north.y >= north_limit && sprite.get_pixelv(north) == target_color:
|
||||||
|
q.append(north)
|
||||||
|
if south.y < south_limit && sprite.get_pixelv(south) == target_color:
|
||||||
|
q.append(south)
|
||||||
|
|
||||||
|
pattern.unlock()
|
||||||
|
Global.canvas.sprite_changed_this_frame = true
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
if color.a != 0:
|
||||||
|
# Blend colors
|
||||||
|
color.r = (color_1.r * color_1.a + color_2.r * color_2.a * (1-color_1.a)) / color.a
|
||||||
|
color.g = (color_1.g * color_1.a + color_2.g * color_2.a * (1-color_1.a)) / color.a
|
||||||
|
color.b = (color_1.b * color_1.a + color_2.b * color_2.a * (1-color_1.a)) / color.a
|
||||||
|
return color
|
||||||
|
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
var clipped_src_rect := Rect2(Vector2.ZERO, brush_size).clip(src_rect)
|
||||||
|
if clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0:
|
||||||
|
return
|
||||||
|
var src_underscan := Vector2(min(0, src_rect.position.x), min(0, src_rect.position.y))
|
||||||
|
var dest_rect := Rect2(0, 0, bg.get_width(), bg.get_height()).clip(Rect2(dst - src_underscan, clipped_src_rect.size))
|
||||||
|
|
||||||
|
for x in range(0, dest_rect.size.x):
|
||||||
|
for y in range(0, dest_rect.size.y):
|
||||||
|
var src_x := clipped_src_rect.position.x + x;
|
||||||
|
var src_y := clipped_src_rect.position.y + y;
|
||||||
|
|
||||||
|
var dst_x := dest_rect.position.x + x;
|
||||||
|
var dst_y := dest_rect.position.y + y;
|
||||||
|
|
||||||
|
brush.lock()
|
||||||
|
var brush_color := brush.get_pixel(src_x, src_y)
|
||||||
|
var bg_color := bg.get_pixel(dst_x, dst_y)
|
||||||
|
var out_color := blend_colors(brush_color, bg_color)
|
||||||
|
if out_color.a != 0:
|
||||||
|
bg.set_pixel(dst_x, dst_y, out_color)
|
||||||
|
brush.unlock()
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
scaled.lock()
|
||||||
|
sprite.lock()
|
||||||
|
var a : Color
|
||||||
|
var b : Color
|
||||||
|
var c : Color
|
||||||
|
var d : Color
|
||||||
|
var e : Color
|
||||||
|
var f : Color
|
||||||
|
var g : Color
|
||||||
|
var h : Color
|
||||||
|
var i : Color
|
||||||
|
|
||||||
|
for x in range(1,sprite.get_width()-1):
|
||||||
|
for y in range(1,sprite.get_height()-1):
|
||||||
|
var xs : float = 3*x
|
||||||
|
var ys : float = 3*y
|
||||||
|
|
||||||
|
a = sprite.get_pixel(x-1,y-1)
|
||||||
|
b = sprite.get_pixel(x,y-1)
|
||||||
|
c = sprite.get_pixel(x+1,y-1)
|
||||||
|
d = sprite.get_pixel(x-1,y)
|
||||||
|
e = sprite.get_pixel(x,y)
|
||||||
|
f = sprite.get_pixel(x+1,y)
|
||||||
|
g = sprite.get_pixel(x-1,y+1)
|
||||||
|
h = sprite.get_pixel(x,y+1)
|
||||||
|
i = sprite.get_pixel(x+1,y+1)
|
||||||
|
|
||||||
|
var db : bool = similarColors(d, b, tol)
|
||||||
|
var dh : bool = similarColors(d, h, tol)
|
||||||
|
var bf : bool = similarColors(f, b, tol)
|
||||||
|
var ec : bool = similarColors(e, c, tol)
|
||||||
|
var ea : bool = similarColors(e, a, tol)
|
||||||
|
var fh : bool = similarColors(f, h, tol)
|
||||||
|
var eg : bool = similarColors(e, g, tol)
|
||||||
|
var ei : bool = similarColors(e, i, tol)
|
||||||
|
|
||||||
|
scaled.set_pixel(xs-1, ys-1, d if (db and !dh and !bf) else e )
|
||||||
|
scaled.set_pixel(xs, ys-1, b if (db and !dh and !bf and !ec) or
|
||||||
|
(bf and !db and !fh and !ea) else e)
|
||||||
|
scaled.set_pixel(xs+1, ys-1, f if (bf and !db and !fh) else e)
|
||||||
|
scaled.set_pixel(xs-1, ys, d if (dh and !fh and !db and !ea) or
|
||||||
|
(db and !dh and !bf and !eg) else e)
|
||||||
|
scaled.set_pixel(xs, ys, e);
|
||||||
|
scaled.set_pixel(xs+1, ys, f if (bf and !db and !fh and !ei) or
|
||||||
|
(fh and !bf and !dh and !ec) else e)
|
||||||
|
scaled.set_pixel(xs-1, ys+1, d if (dh and !fh and !db) else e)
|
||||||
|
scaled.set_pixel(xs, ys+1, h if (fh and !bf and !dh and !eg) or
|
||||||
|
(dh and !fh and !db and !ei) else e)
|
||||||
|
scaled.set_pixel(xs+1, ys+1, f if (fh and !bf and !dh) else e)
|
||||||
|
|
||||||
|
scaled.unlock()
|
||||||
|
sprite.unlock()
|
||||||
|
return scaled
|
||||||
|
|
||||||
|
|
||||||
|
func rotxel(sprite : Image, angle : float) -> void:
|
||||||
|
# If angle is simple, then nn rotation is the best
|
||||||
|
|
||||||
|
if angle == 0 || angle == PI/2 || angle == PI || angle == 2*PI:
|
||||||
|
nn_rotate(sprite, angle)
|
||||||
|
return
|
||||||
|
|
||||||
|
var aux : Image = Image.new()
|
||||||
|
aux.copy_from(sprite)
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
var center : Vector2 = Vector2(sprite.get_width() / 2, sprite.get_height() / 2)
|
||||||
|
var ox : int
|
||||||
|
var oy : int
|
||||||
|
var p : Color
|
||||||
|
aux.lock()
|
||||||
|
sprite.lock()
|
||||||
|
for x in range(sprite.get_width()):
|
||||||
|
for y in range(sprite.get_height()):
|
||||||
|
var dx = 3*(x - center.x)
|
||||||
|
var dy = 3*(y - center.y)
|
||||||
|
var found_pixel : bool = false
|
||||||
|
for k in range(9):
|
||||||
|
var i = -1 + k % 3
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
var j = -1 + int(k / 3)
|
||||||
|
var dir = atan2(dy + j, dx + i)
|
||||||
|
var mag = sqrt(pow(dx + i, 2) + pow(dy + j, 2))
|
||||||
|
dir -= angle
|
||||||
|
ox = round(center.x*3 + 1 + mag*cos(dir))
|
||||||
|
oy = round(center.y*3 + 1 + mag*sin(dir))
|
||||||
|
|
||||||
|
if (sprite.get_width() % 2 != 0):
|
||||||
|
ox += 1
|
||||||
|
oy += 1
|
||||||
|
|
||||||
|
if (ox >= 0 && ox < sprite.get_width()*3
|
||||||
|
&& oy >= 0 && oy < sprite.get_height()*3):
|
||||||
|
found_pixel = true
|
||||||
|
break
|
||||||
|
|
||||||
|
if !found_pixel:
|
||||||
|
sprite.set_pixel(x, y, Color(0,0,0,0))
|
||||||
|
continue
|
||||||
|
|
||||||
|
var fil : int = oy % 3
|
||||||
|
var col : int = ox % 3
|
||||||
|
var index : int = col + 3*fil
|
||||||
|
|
||||||
|
ox = round((ox - 1)/3.0);
|
||||||
|
oy = round((oy - 1)/3.0);
|
||||||
|
var a : Color
|
||||||
|
var b : Color
|
||||||
|
var c : Color
|
||||||
|
var d : Color
|
||||||
|
var e : Color
|
||||||
|
var f : Color
|
||||||
|
var g : Color
|
||||||
|
var h : Color
|
||||||
|
var i : Color
|
||||||
|
if (ox == 0 || ox == sprite.get_width() - 1 ||
|
||||||
|
oy == 0 || oy == sprite.get_height() - 1):
|
||||||
|
p = aux.get_pixel(ox, oy)
|
||||||
|
else:
|
||||||
|
a = aux.get_pixel(ox-1,oy-1);
|
||||||
|
b = aux.get_pixel(ox,oy-1);
|
||||||
|
c = aux.get_pixel(ox+1,oy-1);
|
||||||
|
d = aux.get_pixel(ox-1,oy);
|
||||||
|
e = aux.get_pixel(ox,oy);
|
||||||
|
f = aux.get_pixel(ox+1,oy);
|
||||||
|
g = aux.get_pixel(ox-1,oy+1);
|
||||||
|
h = aux.get_pixel(ox,oy+1);
|
||||||
|
i = aux.get_pixel(ox+1,oy+1);
|
||||||
|
|
||||||
|
match(index):
|
||||||
|
0:
|
||||||
|
p = d if (similarColors(d,b) && !similarColors(d,h)
|
||||||
|
&& !similarColors(b,f)) else e;
|
||||||
|
1:
|
||||||
|
p = b if ((similarColors(d,b) && !similarColors(d,h) &&
|
||||||
|
!similarColors(b,f) && !similarColors(e,c)) ||
|
||||||
|
(similarColors(b,f) && !similarColors(d,b) &&
|
||||||
|
!similarColors(f,h) && !similarColors(e,a))) else e;
|
||||||
|
2:
|
||||||
|
p = f if (similarColors(b,f) && !similarColors(d,b) &&
|
||||||
|
!similarColors(f,h)) else e;
|
||||||
|
3:
|
||||||
|
p = d if ((similarColors(d,h) && !similarColors(f,h) &&
|
||||||
|
!similarColors(d,b) && !similarColors(e,a)) ||
|
||||||
|
(similarColors(d,b) && !similarColors(d,h) &&
|
||||||
|
!similarColors(b,f) && !similarColors(e,g))) else e;
|
||||||
|
4:
|
||||||
|
p = e
|
||||||
|
5:
|
||||||
|
p = f if((similarColors(b,f) && !similarColors(d,b) &&
|
||||||
|
!similarColors(f,h) && !similarColors(e,i))
|
||||||
|
|| (similarColors(f,h) && !similarColors(b,f) &&
|
||||||
|
!similarColors(d,h) && !similarColors(e,c))) else e;
|
||||||
|
6:
|
||||||
|
p = d if (similarColors(d,h) && !similarColors(f,h) &&
|
||||||
|
!similarColors(d,b)) else e;
|
||||||
|
7:
|
||||||
|
p = h if ((similarColors(f,h) && !similarColors(f,b) &&
|
||||||
|
!similarColors(d,h) && !similarColors(e,g))
|
||||||
|
|| (similarColors(d,h) && !similarColors(f,h) &&
|
||||||
|
!similarColors(d,b) && !similarColors(e,i))) else e;
|
||||||
|
8:
|
||||||
|
p = f if (similarColors(f,h) && !similarColors(f,b) &&
|
||||||
|
!similarColors(d,h)) else e;
|
||||||
|
sprite.set_pixel(x, y, p)
|
||||||
|
sprite.unlock()
|
||||||
|
aux.unlock()
|
||||||
|
|
||||||
|
|
||||||
|
func fake_rotsprite(sprite : Image, angle : float) -> void:
|
||||||
|
sprite.copy_from(scale3X(sprite))
|
||||||
|
nn_rotate(sprite,angle)
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
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)
|
||||||
|
sprite.lock()
|
||||||
|
aux.lock()
|
||||||
|
var ox: int
|
||||||
|
var oy: int
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
# warning-ignore:integer_division
|
||||||
|
var center : Vector2 = Vector2(sprite.get_width() / 2, sprite.get_height() / 2)
|
||||||
|
for x in range(sprite.get_width()):
|
||||||
|
for y in range(sprite.get_height()):
|
||||||
|
ox = (x - center.x)*cos(angle) + (y - center.y)*sin(angle) + center.x
|
||||||
|
oy = -(x - center.x)*sin(angle) + (y - center.y)*cos(angle) + center.y
|
||||||
|
if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height():
|
||||||
|
sprite.set_pixel(x, y, aux.get_pixel(ox, oy))
|
||||||
|
else:
|
||||||
|
sprite.set_pixel(x, y, Color(0,0,0,0))
|
||||||
|
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 adjust_hsv(img: Image, id : int, delta : float) -> void:
|
||||||
|
var west_limit = Global.canvas.west_limit
|
||||||
|
var east_limit = Global.canvas.east_limit
|
||||||
|
var north_limit = Global.canvas.north_limit
|
||||||
|
var south_limit = Global.canvas.south_limit
|
||||||
|
img.lock()
|
||||||
|
|
||||||
|
match id:
|
||||||
|
0: # Hue
|
||||||
|
for i in range(west_limit, east_limit):
|
||||||
|
for j in range(north_limit, south_limit):
|
||||||
|
var c : Color = img.get_pixel(i,j)
|
||||||
|
var hue = range_lerp(c.h,0,1,-180,180)
|
||||||
|
hue = hue + delta
|
||||||
|
|
||||||
|
while(hue >= 180):
|
||||||
|
hue -= 360
|
||||||
|
while(hue < -180):
|
||||||
|
hue += 360
|
||||||
|
c.h = range_lerp(hue,-180,180,0,1)
|
||||||
|
img.set_pixel(i,j,c)
|
||||||
|
|
||||||
|
1: # Saturation
|
||||||
|
for i in range(west_limit, east_limit):
|
||||||
|
for j in range(north_limit, south_limit):
|
||||||
|
var c : Color = img.get_pixel(i,j)
|
||||||
|
var sat = c.s
|
||||||
|
if delta > 0:
|
||||||
|
sat = range_lerp(delta,0,100,c.s,1)
|
||||||
|
elif delta < 0:
|
||||||
|
sat = range_lerp(delta,-100,0,0,c.s)
|
||||||
|
c.s = sat
|
||||||
|
img.set_pixel(i,j,c)
|
||||||
|
|
||||||
|
2: # Value
|
||||||
|
for i in range(west_limit, east_limit):
|
||||||
|
for j in range(north_limit, south_limit):
|
||||||
|
var c : Color = img.get_pixel(i,j)
|
||||||
|
var val = c.v
|
||||||
|
if delta > 0:
|
||||||
|
val = range_lerp(delta,0,100,c.v,1)
|
||||||
|
elif delta < 0:
|
||||||
|
val = range_lerp(delta,-100,0,0,c.v)
|
||||||
|
|
||||||
|
c.v = val
|
||||||
|
img.set_pixel(i,j,c)
|
||||||
|
|
||||||
|
img.unlock()
|
||||||
|
|
||||||
|
|
||||||
|
# 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()
|
|
@ -1,26 +1,28 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
enum Grid_Types {CARTESIAN, ISOMETRIC, ALL}
|
enum Grid_Types {CARTESIAN, ISOMETRIC, ALL}
|
||||||
enum Pressure_Sensitivity {NONE, ALPHA, SIZE, ALPHA_AND_SIZE}
|
enum Pressure_Sensitivity {NONE, ALPHA, SIZE, ALPHA_AND_SIZE}
|
||||||
enum Brush_Types {PIXEL, CIRCLE, FILLED_CIRCLE, FILE, RANDOM_FILE, CUSTOM}
|
enum Brush_Types {PIXEL, CIRCLE, FILLED_CIRCLE, FILE, RANDOM_FILE, CUSTOM}
|
||||||
|
enum Direction {UP, DOWN, LEFT, RIGHT}
|
||||||
var root_directory := "."
|
enum Mouse_Button {LEFT, RIGHT}
|
||||||
var window_title := "" setget title_changed # Why doesn't Godot have get_window_title()?
|
enum Tools {PENCIL, ERASER, BUCKET, LIGHTENDARKEN, RECTSELECT, COLORPICKER, ZOOM}
|
||||||
var config_cache := ConfigFile.new()
|
enum Theme_Types {DARK, BLUE, CARAMEL, LIGHT}
|
||||||
var XDGDataPaths = preload("res://src/XDGDataPaths.gd")
|
enum Fill_Area {SAME_COLOR_AREA, SAME_COLOR_PIXELS}
|
||||||
var directory_module : Reference
|
enum Fill_With {COLOR, PATTERN}
|
||||||
|
enum Lighten_Darken_Mode {LIGHTEN, DARKEN}
|
||||||
|
enum Zoom_Mode {ZOOM_IN, ZOOM_OUT}
|
||||||
|
|
||||||
# Stuff for arrowkey-based canvas movements nyaa ^.^
|
# Stuff for arrowkey-based canvas movements nyaa ^.^
|
||||||
const low_speed_move_rate := 150.0
|
const low_speed_move_rate := 150.0
|
||||||
const medium_speed_move_rate := 750.0
|
const medium_speed_move_rate := 750.0
|
||||||
const high_speed_move_rate := 3750.0
|
const high_speed_move_rate := 3750.0
|
||||||
|
|
||||||
enum Direction {
|
var root_directory := "."
|
||||||
UP = 0,
|
var window_title := "" setget title_changed # Why doesn't Godot have get_window_title()?
|
||||||
DOWN = 1,
|
var config_cache := ConfigFile.new()
|
||||||
LEFT = 2,
|
var XDGDataPaths = preload("res://src/XDGDataPaths.gd")
|
||||||
RIGHT = 3
|
var directory_module : Reference
|
||||||
}
|
|
||||||
|
|
||||||
# Indices are as in the Direction enum
|
# Indices are as in the Direction enum
|
||||||
# This is the total time the key for
|
# This is the total time the key for
|
||||||
|
@ -51,10 +53,10 @@ var right_cursor_tool_texture : ImageTexture
|
||||||
|
|
||||||
var selected_pixels := []
|
var selected_pixels := []
|
||||||
var image_clipboard : Image
|
var image_clipboard : Image
|
||||||
var animation_tags := [] setget animation_tags_changed # [Name, Color, From, To]
|
var animation_tags := [] setget animation_tags_changed
|
||||||
var play_only_tags := true
|
var play_only_tags := true
|
||||||
|
|
||||||
var theme_type := "Dark"
|
var theme_type : int = Theme_Types.DARK
|
||||||
var is_default_image := true
|
var is_default_image := true
|
||||||
var default_image_width := 64
|
var default_image_width := 64
|
||||||
var default_image_height := 64
|
var default_image_height := 64
|
||||||
|
@ -68,45 +70,30 @@ var checker_size := 10
|
||||||
var checker_color_1 := Color(0.47, 0.47, 0.47, 1)
|
var checker_color_1 := Color(0.47, 0.47, 0.47, 1)
|
||||||
var checker_color_2 := Color(0.34, 0.35, 0.34, 1)
|
var checker_color_2 := Color(0.34, 0.35, 0.34, 1)
|
||||||
|
|
||||||
|
var autosave_interval := 5.0
|
||||||
|
var enable_autosave := true
|
||||||
|
|
||||||
# Tools & options
|
# Tools & options
|
||||||
var current_left_tool := "Pencil"
|
var current_tools := [Tools.PENCIL, Tools.ERASER]
|
||||||
var current_right_tool := "Eraser"
|
|
||||||
var show_left_tool_icon := true
|
var show_left_tool_icon := true
|
||||||
var show_right_tool_icon := true
|
var show_right_tool_icon := true
|
||||||
var left_square_indicator_visible := true
|
var left_square_indicator_visible := true
|
||||||
var right_square_indicator_visible := false
|
var right_square_indicator_visible := false
|
||||||
|
|
||||||
# 0 for area of same color, 1 for all pixels of the same color
|
var fill_areas := [Fill_Area.SAME_COLOR_AREA, Fill_Area.SAME_COLOR_AREA]
|
||||||
var left_fill_area := 0
|
var fill_with := [Fill_With.COLOR, Fill_With.COLOR]
|
||||||
var right_fill_area := 0
|
var fill_pattern_offsets := [Vector2.ZERO, Vector2.ZERO]
|
||||||
|
|
||||||
var left_fill_with := 0
|
var ld_modes := [Lighten_Darken_Mode.LIGHTEN, Lighten_Darken_Mode.LIGHTEN]
|
||||||
var right_fill_with := 0
|
var ld_amounts := [0.1, 0.1]
|
||||||
|
|
||||||
var left_fill_pattern_offset := Vector2.ZERO
|
var color_picker_for := [Mouse_Button.LEFT, Mouse_Button.RIGHT]
|
||||||
var right_fill_pattern_offset := Vector2.ZERO
|
|
||||||
|
|
||||||
# 0 for lighten, 1 for darken
|
var zoom_modes := [Zoom_Mode.ZOOM_IN, Zoom_Mode.ZOOM_OUT]
|
||||||
var left_ld := 0
|
|
||||||
var right_ld := 0
|
|
||||||
var left_ld_amount := 0.1
|
|
||||||
var right_ld_amount := 0.1
|
|
||||||
|
|
||||||
# 0 for the left, 1 for the right
|
var horizontal_mirror := [false, false]
|
||||||
var left_color_picker_for := 0
|
var vertical_mirror := [false, false]
|
||||||
var right_color_picker_for := 1
|
var pixel_perfect := [false, false]
|
||||||
|
|
||||||
# 0 for zoom in, 1 for zoom out
|
|
||||||
var left_zoom_mode := 0
|
|
||||||
var right_zoom_mode := 1
|
|
||||||
|
|
||||||
var left_horizontal_mirror := false
|
|
||||||
var left_vertical_mirror := false
|
|
||||||
var right_horizontal_mirror := false
|
|
||||||
var right_vertical_mirror := false
|
|
||||||
|
|
||||||
var left_pixel_perfect := false
|
|
||||||
var right_pixel_perfect := false
|
|
||||||
|
|
||||||
# View menu options
|
# View menu options
|
||||||
var tile_mode := false
|
var tile_mode := false
|
||||||
|
@ -122,29 +109,23 @@ var onion_skinning_future_rate := 1.0
|
||||||
var onion_skinning_blue_red := false
|
var onion_skinning_blue_red := false
|
||||||
|
|
||||||
# Brushes
|
# Brushes
|
||||||
var left_brush_size := 1
|
var brush_sizes := [1, 1]
|
||||||
var right_brush_size := 1
|
var current_brush_types := [Brush_Types.PIXEL, Brush_Types.PIXEL]
|
||||||
var current_left_brush_type = Brush_Types.PIXEL
|
|
||||||
var current_right_brush_type = Brush_Types.PIXEL
|
|
||||||
|
|
||||||
var brush_type_window_position := "left"
|
var brush_type_window_position : int = Mouse_Button.LEFT
|
||||||
var left_circle_points := []
|
var left_circle_points := []
|
||||||
var right_circle_points := []
|
var right_circle_points := []
|
||||||
|
|
||||||
var brushes_from_files := 0
|
var brushes_from_files := 0
|
||||||
var custom_brushes := []
|
var custom_brushes := []
|
||||||
var custom_left_brush_index := -1
|
var custom_brush_indexes := [-1, -1]
|
||||||
var custom_right_brush_index := -1
|
var custom_brush_images := [Image.new(), Image.new()]
|
||||||
var custom_left_brush_image : Image
|
var custom_brush_textures := [ImageTexture.new(), ImageTexture.new()]
|
||||||
var custom_right_brush_image : Image
|
|
||||||
var custom_left_brush_texture := ImageTexture.new()
|
|
||||||
var custom_right_brush_texture := ImageTexture.new()
|
|
||||||
|
|
||||||
# Patterns
|
# Patterns
|
||||||
var patterns := []
|
var patterns := []
|
||||||
var pattern_window_position := "left"
|
var pattern_window_position : int = Mouse_Button.LEFT
|
||||||
var pattern_left_image : Image
|
var pattern_images := [Image.new(), Image.new()]
|
||||||
var pattern_right_image : Image
|
|
||||||
|
|
||||||
# Palettes
|
# Palettes
|
||||||
var palettes := {}
|
var palettes := {}
|
||||||
|
@ -176,65 +157,48 @@ var zoom_level_label : Label
|
||||||
|
|
||||||
var import_sprites_dialog : FileDialog
|
var import_sprites_dialog : FileDialog
|
||||||
var export_dialog : AcceptDialog
|
var export_dialog : AcceptDialog
|
||||||
|
var preferences_dialog : AcceptDialog
|
||||||
|
|
||||||
var left_color_picker : ColorPickerButton
|
var color_pickers := []
|
||||||
var right_color_picker : ColorPickerButton
|
|
||||||
|
|
||||||
var color_switch_button : BaseButton
|
var color_switch_button : BaseButton
|
||||||
|
|
||||||
var left_tool_options_container : Container
|
var tool_options_containers := []
|
||||||
var right_tool_options_container : Container
|
|
||||||
|
|
||||||
var left_brush_type_container : Container
|
var brush_type_containers := []
|
||||||
var right_brush_type_container : Container
|
var brush_type_buttons := []
|
||||||
var left_brush_type_button : BaseButton
|
|
||||||
var right_brush_type_button : BaseButton
|
|
||||||
var brushes_popup : Popup
|
var brushes_popup : Popup
|
||||||
var file_brush_container : GridContainer
|
var file_brush_container : GridContainer
|
||||||
var project_brush_container : GridContainer
|
var project_brush_container : GridContainer
|
||||||
var patterns_popup : Popup
|
var patterns_popup : Popup
|
||||||
|
|
||||||
var left_brush_size_edit : SpinBox
|
var brush_size_edits := []
|
||||||
var left_brush_size_slider : HSlider
|
var brush_size_sliders := []
|
||||||
var right_brush_size_edit : SpinBox
|
|
||||||
var right_brush_size_slider : HSlider
|
|
||||||
|
|
||||||
var left_pixel_perfect_container : VBoxContainer
|
var pixel_perfect_containers := []
|
||||||
var right_pixel_perfect_container : VBoxContainer
|
|
||||||
|
|
||||||
var left_color_interpolation_container : Container
|
var color_interpolation_containers := []
|
||||||
var right_color_interpolation_container : Container
|
var interpolate_spinboxes := []
|
||||||
var left_interpolate_spinbox : SpinBox
|
var interpolate_sliders := []
|
||||||
var left_interpolate_slider : HSlider
|
|
||||||
var right_interpolate_spinbox : SpinBox
|
|
||||||
var right_interpolate_slider : HSlider
|
|
||||||
|
|
||||||
var left_fill_area_container : Container
|
var fill_area_containers := []
|
||||||
var left_fill_pattern_container : Container
|
var fill_pattern_containers := []
|
||||||
var right_fill_area_container : Container
|
|
||||||
var right_fill_pattern_container : Container
|
|
||||||
|
|
||||||
var left_ld_container : Container
|
var ld_containers := []
|
||||||
var left_ld_amount_slider : HSlider
|
var ld_amount_sliders := []
|
||||||
var left_ld_amount_spinbox : SpinBox
|
var ld_amount_spinboxes := []
|
||||||
var right_ld_container : Container
|
|
||||||
var right_ld_amount_slider : HSlider
|
|
||||||
var right_ld_amount_spinbox : SpinBox
|
|
||||||
|
|
||||||
var left_colorpicker_container : Container
|
var colorpicker_containers := []
|
||||||
var right_colorpicker_container : Container
|
|
||||||
|
|
||||||
var left_zoom_container : Container
|
var zoom_containers := []
|
||||||
var right_zoom_container : Container
|
|
||||||
|
|
||||||
var left_mirror_container : Container
|
var mirror_containers := []
|
||||||
var right_mirror_container : Container
|
|
||||||
|
|
||||||
var animation_timeline : Panel
|
var animation_timeline : Panel
|
||||||
|
|
||||||
var animation_timer : Timer
|
var animation_timer : Timer
|
||||||
var frame_ids : HBoxContainer
|
var frame_ids : HBoxContainer
|
||||||
var current_frame_label : Label
|
var current_frame_mark_label : Label
|
||||||
var onion_skinning_button : BaseButton
|
var onion_skinning_button : BaseButton
|
||||||
var loop_animation_button : BaseButton
|
var loop_animation_button : BaseButton
|
||||||
var play_forward : BaseButton
|
var play_forward : BaseButton
|
||||||
|
@ -313,58 +277,59 @@ func _ready() -> void:
|
||||||
|
|
||||||
import_sprites_dialog = find_node_by_name(root, "ImportSprites")
|
import_sprites_dialog = find_node_by_name(root, "ImportSprites")
|
||||||
export_dialog = find_node_by_name(root, "ExportDialog")
|
export_dialog = find_node_by_name(root, "ExportDialog")
|
||||||
|
preferences_dialog = find_node_by_name(root, "PreferencesDialog")
|
||||||
|
|
||||||
left_tool_options_container = find_node_by_name(root, "LeftToolOptions")
|
tool_options_containers.append(find_node_by_name(root, "LeftToolOptions"))
|
||||||
right_tool_options_container = find_node_by_name(root, "RightToolOptions")
|
tool_options_containers.append(find_node_by_name(root, "RightToolOptions"))
|
||||||
|
|
||||||
left_color_picker = find_node_by_name(root, "LeftColorPickerButton")
|
color_pickers.append(find_node_by_name(root, "LeftColorPickerButton"))
|
||||||
right_color_picker = find_node_by_name(root, "RightColorPickerButton")
|
color_pickers.append(find_node_by_name(root, "RightColorPickerButton"))
|
||||||
color_switch_button = find_node_by_name(root, "ColorSwitch")
|
color_switch_button = find_node_by_name(root, "ColorSwitch")
|
||||||
|
|
||||||
left_brush_type_container = find_node_by_name(left_tool_options_container, "LeftBrushType")
|
brush_type_containers.append(find_node_by_name(tool_options_containers[0], "LeftBrushType"))
|
||||||
right_brush_type_container = find_node_by_name(right_tool_options_container, "RightBrushType")
|
brush_type_containers.append(find_node_by_name(tool_options_containers[1], "RightBrushType"))
|
||||||
left_brush_type_button = find_node_by_name(left_brush_type_container, "LeftBrushTypeButton")
|
brush_type_buttons.append(find_node_by_name(brush_type_containers[0], "LeftBrushTypeButton"))
|
||||||
right_brush_type_button = find_node_by_name(right_brush_type_container, "RightBrushTypeButton")
|
brush_type_buttons.append(find_node_by_name(brush_type_containers[1], "RightBrushTypeButton"))
|
||||||
brushes_popup = find_node_by_name(root, "BrushesPopup")
|
brushes_popup = find_node_by_name(root, "BrushesPopup")
|
||||||
file_brush_container = find_node_by_name(brushes_popup, "FileBrushContainer")
|
file_brush_container = find_node_by_name(brushes_popup, "FileBrushContainer")
|
||||||
project_brush_container = find_node_by_name(brushes_popup, "ProjectBrushContainer")
|
project_brush_container = find_node_by_name(brushes_popup, "ProjectBrushContainer")
|
||||||
patterns_popup = find_node_by_name(root, "PatternsPopup")
|
patterns_popup = find_node_by_name(root, "PatternsPopup")
|
||||||
|
|
||||||
left_brush_size_edit = find_node_by_name(root, "LeftBrushSizeEdit")
|
brush_size_edits.append(find_node_by_name(root, "LeftBrushSizeEdit"))
|
||||||
left_brush_size_slider = find_node_by_name(root, "LeftBrushSizeSlider")
|
brush_size_sliders.append(find_node_by_name(root, "LeftBrushSizeSlider"))
|
||||||
right_brush_size_edit = find_node_by_name(root, "RightBrushSizeEdit")
|
brush_size_edits.append(find_node_by_name(root, "RightBrushSizeEdit"))
|
||||||
right_brush_size_slider = find_node_by_name(root, "RightBrushSizeSlider")
|
brush_size_sliders.append(find_node_by_name(root, "RightBrushSizeSlider"))
|
||||||
|
|
||||||
left_pixel_perfect_container = find_node_by_name(root, "LeftBrushPixelPerfectMode")
|
pixel_perfect_containers.append(find_node_by_name(root, "LeftBrushPixelPerfectMode"))
|
||||||
right_pixel_perfect_container = find_node_by_name(root, "RightBrushPixelPerfectMode")
|
pixel_perfect_containers.append(find_node_by_name(root, "RightBrushPixelPerfectMode"))
|
||||||
|
|
||||||
left_color_interpolation_container = find_node_by_name(root, "LeftColorInterpolation")
|
color_interpolation_containers.append(find_node_by_name(root, "LeftColorInterpolation"))
|
||||||
right_color_interpolation_container = find_node_by_name(root, "RightColorInterpolation")
|
color_interpolation_containers.append(find_node_by_name(root, "RightColorInterpolation"))
|
||||||
left_interpolate_spinbox = find_node_by_name(root, "LeftInterpolateFactor")
|
interpolate_spinboxes.append(find_node_by_name(root, "LeftInterpolateFactor"))
|
||||||
left_interpolate_slider = find_node_by_name(root, "LeftInterpolateSlider")
|
interpolate_sliders.append(find_node_by_name(root, "LeftInterpolateSlider"))
|
||||||
right_interpolate_spinbox = find_node_by_name(root, "RightInterpolateFactor")
|
interpolate_spinboxes.append(find_node_by_name(root, "RightInterpolateFactor"))
|
||||||
right_interpolate_slider = find_node_by_name(root, "RightInterpolateSlider")
|
interpolate_sliders.append(find_node_by_name(root, "RightInterpolateSlider"))
|
||||||
|
|
||||||
left_fill_area_container = find_node_by_name(root, "LeftFillArea")
|
fill_area_containers.append(find_node_by_name(root, "LeftFillArea"))
|
||||||
left_fill_pattern_container = find_node_by_name(root, "LeftFillPattern")
|
fill_pattern_containers.append(find_node_by_name(root, "LeftFillPattern"))
|
||||||
right_fill_area_container = find_node_by_name(root, "RightFillArea")
|
fill_area_containers.append(find_node_by_name(root, "RightFillArea"))
|
||||||
right_fill_pattern_container = find_node_by_name(root, "RightFillPattern")
|
fill_pattern_containers.append(find_node_by_name(root, "RightFillPattern"))
|
||||||
|
|
||||||
left_ld_container = find_node_by_name(root, "LeftLDOptions")
|
ld_containers.append(find_node_by_name(root, "LeftLDOptions"))
|
||||||
left_ld_amount_slider = find_node_by_name(root, "LeftLDAmountSlider")
|
ld_amount_sliders.append(find_node_by_name(root, "LeftLDAmountSlider"))
|
||||||
left_ld_amount_spinbox = find_node_by_name(root, "LeftLDAmountSpinbox")
|
ld_amount_spinboxes.append(find_node_by_name(root, "LeftLDAmountSpinbox"))
|
||||||
right_ld_container = find_node_by_name(root, "RightLDOptions")
|
ld_containers.append(find_node_by_name(root, "RightLDOptions"))
|
||||||
right_ld_amount_slider = find_node_by_name(root, "RightLDAmountSlider")
|
ld_amount_sliders.append(find_node_by_name(root, "RightLDAmountSlider"))
|
||||||
right_ld_amount_spinbox = find_node_by_name(root, "RightLDAmountSpinbox")
|
ld_amount_spinboxes.append(find_node_by_name(root, "RightLDAmountSpinbox"))
|
||||||
|
|
||||||
left_colorpicker_container = find_node_by_name(root, "LeftColorPickerOptions")
|
colorpicker_containers.append(find_node_by_name(root, "LeftColorPickerOptions"))
|
||||||
right_colorpicker_container = find_node_by_name(root, "RightColorPickerOptions")
|
colorpicker_containers.append(find_node_by_name(root, "RightColorPickerOptions"))
|
||||||
|
|
||||||
left_zoom_container = find_node_by_name(root, "LeftZoomOptions")
|
zoom_containers.append(find_node_by_name(root, "LeftZoomOptions"))
|
||||||
right_zoom_container = find_node_by_name(root, "RightZoomOptions")
|
zoom_containers.append(find_node_by_name(root, "RightZoomOptions"))
|
||||||
|
|
||||||
left_mirror_container = find_node_by_name(root, "LeftMirrorButtons")
|
mirror_containers.append(find_node_by_name(root, "LeftMirrorButtons"))
|
||||||
right_mirror_container = find_node_by_name(root, "RightMirrorButtons")
|
mirror_containers.append(find_node_by_name(root, "RightMirrorButtons"))
|
||||||
|
|
||||||
animation_timeline = find_node_by_name(root, "AnimationTimeline")
|
animation_timeline = find_node_by_name(root, "AnimationTimeline")
|
||||||
|
|
||||||
|
@ -372,7 +337,7 @@ func _ready() -> void:
|
||||||
frames_container = find_node_by_name(animation_timeline, "FramesContainer")
|
frames_container = find_node_by_name(animation_timeline, "FramesContainer")
|
||||||
animation_timer = find_node_by_name(animation_timeline, "AnimationTimer")
|
animation_timer = find_node_by_name(animation_timeline, "AnimationTimer")
|
||||||
frame_ids = find_node_by_name(animation_timeline, "FrameIDs")
|
frame_ids = find_node_by_name(animation_timeline, "FrameIDs")
|
||||||
current_frame_label = find_node_by_name(control, "CurrentFrame")
|
current_frame_mark_label = find_node_by_name(control, "CurrentFrameMark")
|
||||||
onion_skinning_button = find_node_by_name(animation_timeline, "OnionSkinning")
|
onion_skinning_button = find_node_by_name(animation_timeline, "OnionSkinning")
|
||||||
loop_animation_button = find_node_by_name(animation_timeline, "LoopAnim")
|
loop_animation_button = find_node_by_name(animation_timeline, "LoopAnim")
|
||||||
play_forward = find_node_by_name(animation_timeline, "PlayForward")
|
play_forward = find_node_by_name(animation_timeline, "PlayForward")
|
||||||
|
@ -401,13 +366,11 @@ func _ready() -> void:
|
||||||
|
|
||||||
error_dialog = find_node_by_name(root, "ErrorDialog")
|
error_dialog = find_node_by_name(root, "ErrorDialog")
|
||||||
|
|
||||||
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
layers.append(Layer.new())
|
||||||
# will new cels be linked boolean (4), Array of linked cels (5)]
|
|
||||||
layers.append([tr("Layer") + " 0", true, false, HBoxContainer.new(), false, []])
|
|
||||||
|
|
||||||
|
|
||||||
# Thanks to https://godotengine.org/qa/17524/how-to-find-an-instanced-scene-by-its-name
|
# Thanks to https://godotengine.org/qa/17524/how-to-find-an-instanced-scene-by-its-name
|
||||||
func find_node_by_name(root, node_name) -> Node:
|
func find_node_by_name(root : Node, node_name : String) -> Node:
|
||||||
if root.get_name() == node_name:
|
if root.get_name() == node_name:
|
||||||
return root
|
return root
|
||||||
for child in root.get_children():
|
for child in root.get_children():
|
||||||
|
@ -467,6 +430,7 @@ func undo(_canvases : Array, layer_index : int = -1) -> void:
|
||||||
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
||||||
elif action_name == "Change Frame Order":
|
elif action_name == "Change Frame Order":
|
||||||
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
||||||
|
canvas_parent.move_child(canvas_parent.get_node("TransparentChecker"), 0)
|
||||||
|
|
||||||
canvas.update()
|
canvas.update()
|
||||||
if !project_has_changed:
|
if !project_has_changed:
|
||||||
|
@ -498,6 +462,7 @@ func redo(_canvases : Array, layer_index : int = -1) -> void:
|
||||||
animation_timer.stop()
|
animation_timer.stop()
|
||||||
elif action_name == "Change Frame Order":
|
elif action_name == "Change Frame Order":
|
||||||
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
canvas_parent.move_child(_canvases[0], _canvases[0].frame)
|
||||||
|
canvas_parent.move_child(canvas_parent.get_node("TransparentChecker"), 0)
|
||||||
|
|
||||||
canvas.update()
|
canvas.update()
|
||||||
if !project_has_changed:
|
if !project_has_changed:
|
||||||
|
@ -523,7 +488,7 @@ func canvases_changed(value : Array) -> void:
|
||||||
frame_id.queue_free()
|
frame_id.queue_free()
|
||||||
|
|
||||||
for i in range(layers.size() - 1, -1, -1):
|
for i in range(layers.size() - 1, -1, -1):
|
||||||
frames_container.add_child(layers[i][3])
|
frames_container.add_child(layers[i].frame_container)
|
||||||
|
|
||||||
for j in range(canvases.size()):
|
for j in range(canvases.size()):
|
||||||
var label := Label.new()
|
var label := Label.new()
|
||||||
|
@ -536,9 +501,9 @@ func canvases_changed(value : Array) -> void:
|
||||||
var cel_button = load("res://src/UI/Timeline/CelButton.tscn").instance()
|
var cel_button = load("res://src/UI/Timeline/CelButton.tscn").instance()
|
||||||
cel_button.frame = j
|
cel_button.frame = j
|
||||||
cel_button.layer = i
|
cel_button.layer = i
|
||||||
cel_button.get_child(0).texture = Global.canvases[j].layers[i][1]
|
cel_button.get_child(0).texture = Global.canvases[j].layers[i].image_texture
|
||||||
|
|
||||||
layers[i][3].add_child(cel_button)
|
layers[i].frame_container.add_child(cel_button)
|
||||||
|
|
||||||
# This is useful in case tagged frames get deleted DURING the animation is playing
|
# This is useful in case tagged frames get deleted DURING the animation is playing
|
||||||
# otherwise, this code is useless in this context, since these values are being set
|
# otherwise, this code is useless in this context, since these values are being set
|
||||||
|
@ -547,9 +512,9 @@ func canvases_changed(value : Array) -> void:
|
||||||
animation_timeline.last_frame = canvases.size() - 1
|
animation_timeline.last_frame = canvases.size() - 1
|
||||||
if play_only_tags:
|
if play_only_tags:
|
||||||
for tag in animation_tags:
|
for tag in animation_tags:
|
||||||
if current_frame + 1 >= tag[2] && current_frame + 1 <= tag[3]:
|
if current_frame + 1 >= tag.from && current_frame + 1 <= tag.to:
|
||||||
animation_timeline.first_frame = tag[2] - 1
|
animation_timeline.first_frame = tag.from - 1
|
||||||
animation_timeline.last_frame = min(canvases.size() - 1, tag[3] - 1)
|
animation_timeline.last_frame = min(canvases.size() - 1, tag.to - 1)
|
||||||
|
|
||||||
|
|
||||||
func clear_canvases() -> void:
|
func clear_canvases() -> void:
|
||||||
|
@ -591,27 +556,27 @@ func layers_changed(value : Array) -> void:
|
||||||
for i in range(layers.size() - 1, -1, -1):
|
for i in range(layers.size() - 1, -1, -1):
|
||||||
var layer_container = load("res://src/UI/Timeline/LayerButton.tscn").instance()
|
var layer_container = load("res://src/UI/Timeline/LayerButton.tscn").instance()
|
||||||
layer_container.i = i
|
layer_container.i = i
|
||||||
if !layers[i][0]:
|
if layers[i].name == tr("Layer") + " 0":
|
||||||
layers[i][0] = tr("Layer") + " %s" % i
|
layers[i].name = tr("Layer") + " %s" % i
|
||||||
|
|
||||||
layers_container.add_child(layer_container)
|
layers_container.add_child(layer_container)
|
||||||
layer_container.label.text = layers[i][0]
|
layer_container.label.text = layers[i].name
|
||||||
layer_container.line_edit.text = layers[i][0]
|
layer_container.line_edit.text = layers[i].name
|
||||||
|
|
||||||
frames_container.add_child(layers[i][3])
|
frames_container.add_child(layers[i].frame_container)
|
||||||
for j in range(canvases.size()):
|
for j in range(canvases.size()):
|
||||||
var cel_button = load("res://src/UI/Timeline/CelButton.tscn").instance()
|
var cel_button = load("res://src/UI/Timeline/CelButton.tscn").instance()
|
||||||
cel_button.frame = j
|
cel_button.frame = j
|
||||||
cel_button.layer = i
|
cel_button.layer = i
|
||||||
cel_button.get_child(0).texture = Global.canvases[j].layers[i][1]
|
cel_button.get_child(0).texture = Global.canvases[j].layers[i].image_texture
|
||||||
|
|
||||||
layers[i][3].add_child(cel_button)
|
layers[i].frame_container.add_child(cel_button)
|
||||||
|
|
||||||
var layer_button = layers_container.get_child(layers_container.get_child_count() - 1 - current_layer)
|
var layer_button = layers_container.get_child(layers_container.get_child_count() - 1 - current_layer)
|
||||||
layer_button.pressed = true
|
layer_button.pressed = true
|
||||||
self.current_frame = current_frame # Call frame_changed to update UI
|
self.current_frame = current_frame # Call frame_changed to update UI
|
||||||
|
|
||||||
if layers[current_layer][2]:
|
if layers[current_layer].locked:
|
||||||
disable_button(remove_layer_button, true)
|
disable_button(remove_layer_button, true)
|
||||||
|
|
||||||
if layers.size() == 1:
|
if layers.size() == 1:
|
||||||
|
@ -619,13 +584,13 @@ func layers_changed(value : Array) -> void:
|
||||||
disable_button(move_up_layer_button, true)
|
disable_button(move_up_layer_button, true)
|
||||||
disable_button(move_down_layer_button, true)
|
disable_button(move_down_layer_button, true)
|
||||||
disable_button(merge_down_layer_button, true)
|
disable_button(merge_down_layer_button, true)
|
||||||
elif !layers[current_layer][2]:
|
elif !layers[current_layer].locked:
|
||||||
disable_button(remove_layer_button, false)
|
disable_button(remove_layer_button, false)
|
||||||
|
|
||||||
|
|
||||||
func frame_changed(value : int) -> void:
|
func frame_changed(value : int) -> void:
|
||||||
current_frame = value
|
current_frame = value
|
||||||
current_frame_label.text = tr("Current frame:") + " %s/%s" % [str(current_frame + 1), canvases.size()]
|
current_frame_mark_label.text = "%s/%s" % [str(current_frame + 1), canvases.size()]
|
||||||
|
|
||||||
var i := 0
|
var i := 0
|
||||||
for c in canvases: # De-select all the other canvases/frames
|
for c in canvases: # De-select all the other canvases/frames
|
||||||
|
@ -633,24 +598,24 @@ func frame_changed(value : int) -> void:
|
||||||
c.is_making_line = false
|
c.is_making_line = false
|
||||||
c.line_2d.set_point_position(1, c.line_2d.points[0])
|
c.line_2d.set_point_position(1, c.line_2d.points[0])
|
||||||
var text_color := Color.white
|
var text_color := Color.white
|
||||||
if theme_type == "Caramel" || theme_type == "Light":
|
if theme_type == Theme_Types.CARAMEL || theme_type == Theme_Types.LIGHT:
|
||||||
text_color = Color.black
|
text_color = Color.black
|
||||||
frame_ids.get_child(i).add_color_override("font_color", text_color)
|
frame_ids.get_child(i).add_color_override("font_color", text_color)
|
||||||
for layer in layers:
|
for layer in layers:
|
||||||
if i < layer[3].get_child_count():
|
if i < layer.frame_container.get_child_count():
|
||||||
layer[3].get_child(i).pressed = false
|
layer.frame_container.get_child(i).pressed = false
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# Select the new canvas/frame
|
# Select the new canvas/frame
|
||||||
canvas = canvases[current_frame]
|
canvas = canvases[current_frame]
|
||||||
canvas.visible = true
|
canvas.visible = true
|
||||||
frame_ids.get_child(current_frame).add_color_override("font_color", control.theme.get_color("Selected Color", "Label"))
|
frame_ids.get_child(current_frame).add_color_override("font_color", control.theme.get_color("Selected Color", "Label"))
|
||||||
if current_frame < layers[current_layer][3].get_child_count():
|
if current_frame < layers[current_layer].frame_container.get_child_count():
|
||||||
layers[current_layer][3].get_child(current_frame).pressed = true
|
layers[current_layer].frame_container.get_child(current_frame).pressed = true
|
||||||
|
|
||||||
if canvases.size() == 1:
|
if canvases.size() == 1:
|
||||||
disable_button(remove_frame_button, true)
|
disable_button(remove_frame_button, true)
|
||||||
elif !layers[current_layer][2]:
|
elif !layers[current_layer].locked:
|
||||||
disable_button(remove_frame_button, false)
|
disable_button(remove_frame_button, false)
|
||||||
|
|
||||||
Global.transparent_checker._ready() # To update the rect size
|
Global.transparent_checker._ready() # To update the rect size
|
||||||
|
@ -658,8 +623,8 @@ func frame_changed(value : int) -> void:
|
||||||
|
|
||||||
func layer_changed(value : int) -> void:
|
func layer_changed(value : int) -> void:
|
||||||
current_layer = value
|
current_layer = value
|
||||||
layer_opacity_slider.value = canvas.layers[current_layer][2] * 100
|
layer_opacity_slider.value = canvas.layers[current_layer].opacity * 100
|
||||||
layer_opacity_spinbox.value = canvas.layers[current_layer][2] * 100
|
layer_opacity_spinbox.value = canvas.layers[current_layer].opacity * 100
|
||||||
|
|
||||||
for container in layers_container.get_children():
|
for container in layers_container.get_children():
|
||||||
container.pressed = false
|
container.pressed = false
|
||||||
|
@ -681,7 +646,7 @@ func layer_changed(value : int) -> void:
|
||||||
disable_button(merge_down_layer_button, true)
|
disable_button(merge_down_layer_button, true)
|
||||||
|
|
||||||
if current_layer < layers.size():
|
if current_layer < layers.size():
|
||||||
if layers[current_layer][2]:
|
if layers[current_layer].locked:
|
||||||
disable_button(remove_layer_button, true)
|
disable_button(remove_layer_button, true)
|
||||||
else:
|
else:
|
||||||
if layers.size() > 1:
|
if layers.size() > 1:
|
||||||
|
@ -711,8 +676,8 @@ func disable_button(button : BaseButton, disable : bool) -> void:
|
||||||
|
|
||||||
if button is Button:
|
if button is Button:
|
||||||
var theme := theme_type
|
var theme := theme_type
|
||||||
if theme == "Caramel":
|
if theme == Theme_Types.CARAMEL:
|
||||||
theme = "Dark"
|
theme = Theme_Types.DARK
|
||||||
for c in button.get_children():
|
for c in button.get_children():
|
||||||
if c is TextureRect:
|
if c is TextureRect:
|
||||||
var normal_file_name = c.texture.resource_path.get_file().trim_suffix(".png").replace("_disabled", "")
|
var normal_file_name = c.texture.resource_path.get_file().trim_suffix(".png").replace("_disabled", "")
|
||||||
|
@ -739,13 +704,13 @@ func animation_tags_changed(value : Array) -> void:
|
||||||
tag_container.add_child(tag_c)
|
tag_container.add_child(tag_c)
|
||||||
var tag_position := tag_container.get_child_count() - 1
|
var tag_position := tag_container.get_child_count() - 1
|
||||||
tag_container.move_child(tag_c, tag_position)
|
tag_container.move_child(tag_c, tag_position)
|
||||||
tag_c.get_node("Label").text = tag[0]
|
tag_c.get_node("Label").text = tag.name
|
||||||
tag_c.get_node("Label").modulate = tag[1]
|
tag_c.get_node("Label").modulate = tag.color
|
||||||
tag_c.get_node("Line2D").default_color = tag[1]
|
tag_c.get_node("Line2D").default_color = tag.color
|
||||||
|
|
||||||
tag_c.rect_position.x = (tag[2] - 1) * 39 + tag[2]
|
tag_c.rect_position.x = (tag.from - 1) * 39 + tag.from
|
||||||
|
|
||||||
var size : int = tag[3] - tag[2]
|
var size : int = tag.to - tag.from
|
||||||
tag_c.rect_min_size.x = (size + 1) * 39
|
tag_c.rect_min_size.x = (size + 1) * 39
|
||||||
tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0)
|
tag_c.get_node("Line2D").points[2] = Vector2(tag_c.rect_min_size.x, 0)
|
||||||
tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32)
|
tag_c.get_node("Line2D").points[3] = Vector2(tag_c.rect_min_size.x, 32)
|
||||||
|
@ -757,9 +722,9 @@ func animation_tags_changed(value : Array) -> void:
|
||||||
animation_timeline.last_frame = canvases.size() - 1
|
animation_timeline.last_frame = canvases.size() - 1
|
||||||
if play_only_tags:
|
if play_only_tags:
|
||||||
for tag in animation_tags:
|
for tag in animation_tags:
|
||||||
if current_frame + 1 >= tag[2] && current_frame + 1 <= tag[3]:
|
if current_frame + 1 >= tag.from && current_frame + 1 <= tag.to:
|
||||||
animation_timeline.first_frame = tag[2] - 1
|
animation_timeline.first_frame = tag.from - 1
|
||||||
animation_timeline.last_frame = min(canvases.size() - 1, tag[3] - 1)
|
animation_timeline.last_frame = min(canvases.size() - 1, tag.to - 1)
|
||||||
|
|
||||||
|
|
||||||
func update_hint_tooltips() -> void:
|
func update_hint_tooltips() -> void:
|
||||||
|
@ -862,8 +827,8 @@ func create_brush_button(brush_img : Image, brush_type := Brush_Types.CUSTOM, hi
|
||||||
|
|
||||||
|
|
||||||
func remove_brush_buttons() -> void:
|
func remove_brush_buttons() -> void:
|
||||||
current_left_brush_type = Brush_Types.PIXEL
|
current_brush_types[0] = Brush_Types.PIXEL
|
||||||
current_right_brush_type = Brush_Types.PIXEL
|
current_brush_types[1] = Brush_Types.PIXEL
|
||||||
for child in project_brush_container.get_children():
|
for child in project_brush_container.get_children():
|
||||||
child.queue_free()
|
child.queue_free()
|
||||||
|
|
||||||
|
@ -884,56 +849,32 @@ func redo_custom_brush(_brush_button : BaseButton = null) -> void:
|
||||||
project_brush_container.remove_child(_brush_button)
|
project_brush_container.remove_child(_brush_button)
|
||||||
|
|
||||||
|
|
||||||
func update_left_custom_brush() -> void:
|
func update_custom_brush(mouse_button : int) -> void:
|
||||||
if current_left_brush_type == Brush_Types.PIXEL:
|
if current_brush_types[mouse_button] == Brush_Types.PIXEL:
|
||||||
var pixel := Image.new()
|
var pixel := Image.new()
|
||||||
pixel = preload("res://assets/graphics/pixel_image.png")
|
pixel = preload("res://assets/graphics/pixel_image.png")
|
||||||
left_brush_type_button.get_child(0).texture.create_from_image(pixel, 0)
|
brush_type_buttons[mouse_button].get_child(0).texture.create_from_image(pixel, 0)
|
||||||
elif current_left_brush_type == Brush_Types.CIRCLE:
|
elif current_brush_types[mouse_button] == Brush_Types.CIRCLE:
|
||||||
var pixel := Image.new()
|
var pixel := Image.new()
|
||||||
pixel = preload("res://assets/graphics/circle_9x9.png")
|
pixel = preload("res://assets/graphics/circle_9x9.png")
|
||||||
left_brush_type_button.get_child(0).texture.create_from_image(pixel, 0)
|
brush_type_buttons[mouse_button].get_child(0).texture.create_from_image(pixel, 0)
|
||||||
left_circle_points = plot_circle(left_brush_size)
|
left_circle_points = plot_circle(brush_sizes[0])
|
||||||
elif current_left_brush_type == Brush_Types.FILLED_CIRCLE:
|
right_circle_points = plot_circle(brush_sizes[1])
|
||||||
|
elif current_brush_types[mouse_button] == Brush_Types.FILLED_CIRCLE:
|
||||||
var pixel := Image.new()
|
var pixel := Image.new()
|
||||||
pixel = preload("res://assets/graphics/circle_filled_9x9.png")
|
pixel = preload("res://assets/graphics/circle_filled_9x9.png")
|
||||||
left_brush_type_button.get_child(0).texture.create_from_image(pixel, 0)
|
brush_type_buttons[mouse_button].get_child(0).texture.create_from_image(pixel, 0)
|
||||||
left_circle_points = plot_circle(left_brush_size)
|
left_circle_points = plot_circle(brush_sizes[0])
|
||||||
|
right_circle_points = plot_circle(brush_sizes[1])
|
||||||
else:
|
else:
|
||||||
var custom_brush := Image.new()
|
var custom_brush := Image.new()
|
||||||
custom_brush.copy_from(custom_brushes[custom_left_brush_index])
|
custom_brush.copy_from(custom_brushes[custom_brush_indexes[mouse_button]])
|
||||||
var custom_brush_size = custom_brush.get_size()
|
var custom_brush_size = custom_brush.get_size()
|
||||||
custom_brush.resize(custom_brush_size.x * left_brush_size, custom_brush_size.y * left_brush_size, Image.INTERPOLATE_NEAREST)
|
custom_brush.resize(custom_brush_size.x * brush_sizes[mouse_button], custom_brush_size.y * brush_sizes[mouse_button], Image.INTERPOLATE_NEAREST)
|
||||||
custom_left_brush_image = blend_image_with_color(custom_brush, left_color_picker.color, left_interpolate_spinbox.value / 100)
|
custom_brush_images[mouse_button] = blend_image_with_color(custom_brush, color_pickers[mouse_button].color, interpolate_spinboxes[mouse_button].value / 100)
|
||||||
custom_left_brush_texture.create_from_image(custom_left_brush_image, 0)
|
custom_brush_textures[mouse_button].create_from_image(custom_brush_images[mouse_button], 0)
|
||||||
|
|
||||||
left_brush_type_button.get_child(0).texture = custom_left_brush_texture
|
brush_type_buttons[mouse_button].get_child(0).texture = custom_brush_textures[mouse_button]
|
||||||
|
|
||||||
|
|
||||||
func update_right_custom_brush() -> void:
|
|
||||||
if current_right_brush_type == Brush_Types.PIXEL:
|
|
||||||
var pixel := Image.new()
|
|
||||||
pixel = preload("res://assets/graphics/pixel_image.png")
|
|
||||||
right_brush_type_button.get_child(0).texture.create_from_image(pixel, 0)
|
|
||||||
elif current_right_brush_type == Brush_Types.CIRCLE:
|
|
||||||
var pixel := Image.new()
|
|
||||||
pixel = preload("res://assets/graphics/circle_9x9.png")
|
|
||||||
right_brush_type_button.get_child(0).texture.create_from_image(pixel, 0)
|
|
||||||
right_circle_points = plot_circle(right_brush_size)
|
|
||||||
elif current_right_brush_type == Brush_Types.FILLED_CIRCLE:
|
|
||||||
var pixel := Image.new()
|
|
||||||
pixel = preload("res://assets/graphics/circle_filled_9x9.png")
|
|
||||||
right_brush_type_button.get_child(0).texture.create_from_image(pixel, 0)
|
|
||||||
right_circle_points = plot_circle(right_brush_size)
|
|
||||||
else:
|
|
||||||
var custom_brush := Image.new()
|
|
||||||
custom_brush.copy_from(custom_brushes[custom_right_brush_index])
|
|
||||||
var custom_brush_size = custom_brush.get_size()
|
|
||||||
custom_brush.resize(custom_brush_size.x * right_brush_size, custom_brush_size.y * right_brush_size, Image.INTERPOLATE_NEAREST)
|
|
||||||
custom_right_brush_image = blend_image_with_color(custom_brush, right_color_picker.color, right_interpolate_spinbox.value / 100)
|
|
||||||
custom_right_brush_texture.create_from_image(custom_right_brush_image, 0)
|
|
||||||
|
|
||||||
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:
|
func blend_image_with_color(image : Image, color : Color, interpolate_factor : float) -> Image:
|
||||||
|
@ -979,212 +920,6 @@ func plot_circle(r : int) -> Array:
|
||||||
return circle_points
|
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)
|
|
||||||
scaled.lock()
|
|
||||||
sprite.lock()
|
|
||||||
var a : Color
|
|
||||||
var b : Color
|
|
||||||
var c : Color
|
|
||||||
var d : Color
|
|
||||||
var e : Color
|
|
||||||
var f : Color
|
|
||||||
var g : Color
|
|
||||||
var h : Color
|
|
||||||
var i : Color
|
|
||||||
|
|
||||||
for x in range(1,sprite.get_width()-1):
|
|
||||||
for y in range(1,sprite.get_height()-1):
|
|
||||||
var xs : float = 3*x
|
|
||||||
var ys : float = 3*y
|
|
||||||
|
|
||||||
a = sprite.get_pixel(x-1,y-1)
|
|
||||||
b = sprite.get_pixel(x,y-1)
|
|
||||||
c = sprite.get_pixel(x+1,y-1)
|
|
||||||
d = sprite.get_pixel(x-1,y)
|
|
||||||
e = sprite.get_pixel(x,y)
|
|
||||||
f = sprite.get_pixel(x+1,y)
|
|
||||||
g = sprite.get_pixel(x-1,y+1)
|
|
||||||
h = sprite.get_pixel(x,y+1)
|
|
||||||
i = sprite.get_pixel(x+1,y+1)
|
|
||||||
|
|
||||||
var db : bool = similarColors(d, b, tol)
|
|
||||||
var dh : bool = similarColors(d, h, tol)
|
|
||||||
var bf : bool = similarColors(f, b, tol)
|
|
||||||
var ec : bool = similarColors(e, c, tol)
|
|
||||||
var ea : bool = similarColors(e, a, tol)
|
|
||||||
var fh : bool = similarColors(f, h, tol)
|
|
||||||
var eg : bool = similarColors(e, g, tol)
|
|
||||||
var ei : bool = similarColors(e, i, tol)
|
|
||||||
|
|
||||||
scaled.set_pixel(xs-1, ys-1, d if (db and !dh and !bf) else e )
|
|
||||||
scaled.set_pixel(xs, ys-1, b if (db and !dh and !bf and !ec) or
|
|
||||||
(bf and !db and !fh and !ea) else e)
|
|
||||||
scaled.set_pixel(xs+1, ys-1, f if (bf and !db and !fh) else e)
|
|
||||||
scaled.set_pixel(xs-1, ys, d if (dh and !fh and !db and !ea) or
|
|
||||||
(db and !dh and !bf and !eg) else e)
|
|
||||||
scaled.set_pixel(xs, ys, e);
|
|
||||||
scaled.set_pixel(xs+1, ys, f if (bf and !db and !fh and !ei) or
|
|
||||||
(fh and !bf and !dh and !ec) else e)
|
|
||||||
scaled.set_pixel(xs-1, ys+1, d if (dh and !fh and !db) else e)
|
|
||||||
scaled.set_pixel(xs, ys+1, h if (fh and !bf and !dh and !eg) or
|
|
||||||
(dh and !fh and !db and !ei) else e)
|
|
||||||
scaled.set_pixel(xs+1, ys+1, f if (fh and !bf and !dh) else e)
|
|
||||||
|
|
||||||
scaled.unlock()
|
|
||||||
sprite.unlock()
|
|
||||||
return scaled
|
|
||||||
|
|
||||||
|
|
||||||
func rotxel(sprite : Image, angle : float) -> void:
|
|
||||||
|
|
||||||
# If angle is simple, then nn rotation is the best
|
|
||||||
|
|
||||||
if angle == 0 || angle == PI/2 || angle == PI || angle == 2*PI:
|
|
||||||
nn_rotate(sprite, angle)
|
|
||||||
return
|
|
||||||
|
|
||||||
var aux : Image = Image.new()
|
|
||||||
aux.copy_from(sprite)
|
|
||||||
var center : Vector2 = Vector2(sprite.get_width()/2, sprite.get_height()/2)
|
|
||||||
var ox : int
|
|
||||||
var oy : int
|
|
||||||
var p : Color
|
|
||||||
aux.lock()
|
|
||||||
sprite.lock()
|
|
||||||
for x in range(sprite.get_width()):
|
|
||||||
for y in range(sprite.get_height()):
|
|
||||||
var dx = 3*(x - center.x)
|
|
||||||
var dy = 3*(y - center.y)
|
|
||||||
var found_pixel : bool = false
|
|
||||||
for k in range(9):
|
|
||||||
var i = -1 + k % 3
|
|
||||||
var j = -1 + int(k / 3)
|
|
||||||
var dir = atan2(dy + j, dx + i)
|
|
||||||
var mag = sqrt(pow(dx + i, 2) + pow(dy + j, 2))
|
|
||||||
dir -= angle
|
|
||||||
ox = round(center.x*3 + 1 + mag*cos(dir))
|
|
||||||
oy = round(center.y*3 + 1 + mag*sin(dir))
|
|
||||||
|
|
||||||
if (sprite.get_width() % 2 != 0):
|
|
||||||
ox += 1
|
|
||||||
oy += 1
|
|
||||||
|
|
||||||
if (ox >= 0 && ox < sprite.get_width()*3
|
|
||||||
&& oy >= 0 && oy < sprite.get_height()*3):
|
|
||||||
found_pixel = true
|
|
||||||
break
|
|
||||||
|
|
||||||
if !found_pixel:
|
|
||||||
sprite.set_pixel(x, y, Color(0,0,0,0))
|
|
||||||
continue
|
|
||||||
|
|
||||||
var fil : int = oy % 3
|
|
||||||
var col : int = ox % 3
|
|
||||||
var index : int = col + 3*fil
|
|
||||||
|
|
||||||
ox = round((ox - 1)/3.0);
|
|
||||||
oy = round((oy - 1)/3.0);
|
|
||||||
var a : Color
|
|
||||||
var b : Color
|
|
||||||
var c : Color
|
|
||||||
var d : Color
|
|
||||||
var e : Color
|
|
||||||
var f : Color
|
|
||||||
var g : Color
|
|
||||||
var h : Color
|
|
||||||
var i : Color
|
|
||||||
if (ox == 0 || ox == sprite.get_width() - 1 ||
|
|
||||||
oy == 0 || oy == sprite.get_height() - 1):
|
|
||||||
p = aux.get_pixel(ox, oy)
|
|
||||||
else:
|
|
||||||
a = aux.get_pixel(ox-1,oy-1);
|
|
||||||
b = aux.get_pixel(ox,oy-1);
|
|
||||||
c = aux.get_pixel(ox+1,oy-1);
|
|
||||||
d = aux.get_pixel(ox-1,oy);
|
|
||||||
e = aux.get_pixel(ox,oy);
|
|
||||||
f = aux.get_pixel(ox+1,oy);
|
|
||||||
g = aux.get_pixel(ox-1,oy+1);
|
|
||||||
h = aux.get_pixel(ox,oy+1);
|
|
||||||
i = aux.get_pixel(ox+1,oy+1);
|
|
||||||
|
|
||||||
match(index):
|
|
||||||
0:
|
|
||||||
p = d if (similarColors(d,b) && !similarColors(d,h)
|
|
||||||
&& !similarColors(b,f)) else e;
|
|
||||||
1:
|
|
||||||
p = b if ((similarColors(d,b) && !similarColors(d,h) &&
|
|
||||||
!similarColors(b,f) && !similarColors(e,c)) ||
|
|
||||||
(similarColors(b,f) && !similarColors(d,b) &&
|
|
||||||
!similarColors(f,h) && !similarColors(e,a))) else e;
|
|
||||||
2:
|
|
||||||
p = f if (similarColors(b,f) && !similarColors(d,b) &&
|
|
||||||
!similarColors(f,h)) else e;
|
|
||||||
3:
|
|
||||||
p = d if ((similarColors(d,h) && !similarColors(f,h) &&
|
|
||||||
!similarColors(d,b) && !similarColors(e,a)) ||
|
|
||||||
(similarColors(d,b) && !similarColors(d,h) &&
|
|
||||||
!similarColors(b,f) && !similarColors(e,g))) else e;
|
|
||||||
4:
|
|
||||||
p = e
|
|
||||||
5:
|
|
||||||
p = f if((similarColors(b,f) && !similarColors(d,b) &&
|
|
||||||
!similarColors(f,h) && !similarColors(e,i))
|
|
||||||
|| (similarColors(f,h) && !similarColors(b,f) &&
|
|
||||||
!similarColors(d,h) && !similarColors(e,c))) else e;
|
|
||||||
6:
|
|
||||||
p = d if (similarColors(d,h) && !similarColors(f,h) &&
|
|
||||||
!similarColors(d,b)) else e;
|
|
||||||
7:
|
|
||||||
p = h if ((similarColors(f,h) && !similarColors(f,b) &&
|
|
||||||
!similarColors(d,h) && !similarColors(e,g))
|
|
||||||
|| (similarColors(d,h) && !similarColors(f,h) &&
|
|
||||||
!similarColors(d,b) && !similarColors(e,i))) else e;
|
|
||||||
8:
|
|
||||||
p = f if (similarColors(f,h) && !similarColors(f,b) &&
|
|
||||||
!similarColors(d,h)) else e;
|
|
||||||
sprite.set_pixel(x, y, p)
|
|
||||||
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)
|
|
||||||
sprite.lock()
|
|
||||||
aux.lock()
|
|
||||||
var ox: int
|
|
||||||
var oy: int
|
|
||||||
var center : Vector2 = Vector2(sprite.get_width()/2, sprite.get_height()/2)
|
|
||||||
for x in range(sprite.get_width()):
|
|
||||||
for y in range(sprite.get_height()):
|
|
||||||
ox = (x - center.x)*cos(angle) + (y - center.y)*sin(angle) + center.x
|
|
||||||
oy = -(x - center.x)*sin(angle) + (y - center.y)*cos(angle) + center.y
|
|
||||||
if ox >= 0 && ox < sprite.get_width() && oy >= 0 && oy < sprite.get_height():
|
|
||||||
sprite.set_pixel(x, y, aux.get_pixel(ox, oy))
|
|
||||||
else:
|
|
||||||
sprite.set_pixel(x, y, Color(0,0,0,0))
|
|
||||||
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:
|
func _exit_tree() -> void:
|
||||||
config_cache.set_value("window", "screen", OS.current_screen)
|
config_cache.set_value("window", "screen", OS.current_screen)
|
||||||
config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen)
|
config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen)
|
||||||
|
|
|
@ -249,19 +249,19 @@ func import_patterns(priority_ordered_search_path: Array) -> void:
|
||||||
if Global.patterns.size() > 0:
|
if Global.patterns.size() > 0:
|
||||||
var image_size = Global.patterns[0].get_size()
|
var image_size = Global.patterns[0].get_size()
|
||||||
|
|
||||||
Global.pattern_left_image = Global.patterns[0]
|
Global.pattern_images[0] = Global.patterns[0]
|
||||||
var pattern_left_tex := ImageTexture.new()
|
var pattern_left_tex := ImageTexture.new()
|
||||||
pattern_left_tex.create_from_image(Global.pattern_left_image, 0)
|
pattern_left_tex.create_from_image(Global.pattern_images[0], 0)
|
||||||
Global.left_fill_pattern_container.get_child(0).get_child(0).texture = pattern_left_tex
|
Global.fill_pattern_containers[0].get_child(0).get_child(0).texture = pattern_left_tex
|
||||||
Global.left_fill_pattern_container.get_child(2).get_child(1).max_value = image_size.x - 1
|
Global.fill_pattern_containers[0].get_child(2).get_child(1).max_value = image_size.x - 1
|
||||||
Global.left_fill_pattern_container.get_child(3).get_child(1).max_value = image_size.y - 1
|
Global.fill_pattern_containers[0].get_child(3).get_child(1).max_value = image_size.y - 1
|
||||||
|
|
||||||
Global.pattern_right_image = Global.patterns[0]
|
Global.pattern_images[1] = Global.patterns[0]
|
||||||
var pattern_right_tex := ImageTexture.new()
|
var pattern_right_tex := ImageTexture.new()
|
||||||
pattern_right_tex.create_from_image(Global.pattern_right_image, 0)
|
pattern_right_tex.create_from_image(Global.pattern_images[1], 0)
|
||||||
Global.right_fill_pattern_container.get_child(0).get_child(0).texture = pattern_right_tex
|
Global.fill_pattern_containers[1].get_child(0).get_child(0).texture = pattern_right_tex
|
||||||
Global.right_fill_pattern_container.get_child(2).get_child(1).max_value = image_size.x - 1
|
Global.fill_pattern_containers[1].get_child(2).get_child(1).max_value = image_size.x - 1
|
||||||
Global.right_fill_pattern_container.get_child(3).get_child(1).max_value = image_size.y - 1
|
Global.fill_pattern_containers[1].get_child(3).get_child(1).max_value = image_size.y - 1
|
||||||
|
|
||||||
|
|
||||||
func import_gpl(path : String) -> Palette:
|
func import_gpl(path : String) -> Palette:
|
||||||
|
|
|
@ -3,7 +3,6 @@ extends Node
|
||||||
var current_save_path := ""
|
var current_save_path := ""
|
||||||
# Stores a filename of a backup file in user:// until user saves manually
|
# Stores a filename of a backup file in user:// until user saves manually
|
||||||
var backup_save_path = ""
|
var backup_save_path = ""
|
||||||
var default_autosave_interval := 5 # Minutes
|
|
||||||
|
|
||||||
onready var autosave_timer : Timer
|
onready var autosave_timer : Timer
|
||||||
|
|
||||||
|
@ -14,8 +13,7 @@ func _ready() -> void:
|
||||||
autosave_timer.process_mode = Timer.TIMER_PROCESS_IDLE
|
autosave_timer.process_mode = Timer.TIMER_PROCESS_IDLE
|
||||||
autosave_timer.connect("timeout", self, "_on_Autosave_timeout")
|
autosave_timer.connect("timeout", self, "_on_Autosave_timeout")
|
||||||
add_child(autosave_timer)
|
add_child(autosave_timer)
|
||||||
set_autosave_interval(default_autosave_interval)
|
update_autosave()
|
||||||
toggle_autosave(true) # Gets started from preferences dialog
|
|
||||||
|
|
||||||
|
|
||||||
func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
||||||
|
@ -62,9 +60,8 @@ func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
||||||
var layer_new_cels_linked := file.get_8()
|
var layer_new_cels_linked := file.get_8()
|
||||||
linked_cels.append(file.get_var())
|
linked_cels.append(file.get_var())
|
||||||
|
|
||||||
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
var l := Layer.new(layer_name, layer_visibility, layer_lock, HBoxContainer.new(), layer_new_cels_linked, [])
|
||||||
# will new cels be linked boolean (4), Array of linked cels (5)]
|
Global.layers.append(l)
|
||||||
Global.layers.append([layer_name, layer_visibility, layer_lock, HBoxContainer.new(), layer_new_cels_linked, []])
|
|
||||||
global_layer_line = file.get_line()
|
global_layer_line = file.get_line()
|
||||||
|
|
||||||
var frame_line := file.get_line()
|
var frame_line := file.get_line()
|
||||||
|
@ -82,21 +79,18 @@ func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
||||||
if file_major_version == 0 and file_minor_version < 7:
|
if file_major_version == 0 and file_minor_version < 7:
|
||||||
var layer_name_old_version = file.get_line()
|
var layer_name_old_version = file.get_line()
|
||||||
if frame == 0:
|
if frame == 0:
|
||||||
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
var l := Layer.new(layer_name_old_version)
|
||||||
# will new frames be linked boolean (4), Array of linked frames (5)]
|
Global.layers.append(l)
|
||||||
Global.layers.append([layer_name_old_version, true, false, HBoxContainer.new(), false, []])
|
|
||||||
var layer_transparency := 1.0
|
var layer_transparency := 1.0
|
||||||
if file_major_version >= 0 and file_minor_version > 5:
|
if file_major_version >= 0 and file_minor_version > 5:
|
||||||
layer_transparency = file.get_float()
|
layer_transparency = file.get_float()
|
||||||
var image := Image.new()
|
var image := Image.new()
|
||||||
image.create_from_data(width, height, false, Image.FORMAT_RGBA8, buffer)
|
image.create_from_data(width, height, false, Image.FORMAT_RGBA8, buffer)
|
||||||
image.lock()
|
image.lock()
|
||||||
var tex := ImageTexture.new()
|
canvas.layers.append(Cel.new(image, layer_transparency))
|
||||||
tex.create_from_image(image, 0)
|
|
||||||
canvas.layers.append([image, tex, layer_transparency])
|
|
||||||
if file_major_version >= 0 and file_minor_version >= 7:
|
if file_major_version >= 0 and file_minor_version >= 7:
|
||||||
if frame in linked_cels[layer_i]:
|
if frame in linked_cels[layer_i]:
|
||||||
Global.layers[layer_i][5].append(canvas)
|
Global.layers[layer_i].linked_cels.append(canvas)
|
||||||
|
|
||||||
layer_i += 1
|
layer_i += 1
|
||||||
layer_line = file.get_line()
|
layer_line = file.get_line()
|
||||||
|
@ -128,19 +122,19 @@ func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
||||||
Global.current_frame = frame - 1
|
Global.current_frame = frame - 1
|
||||||
Global.layers = Global.layers # Just to call Global.layers_changed
|
Global.layers = Global.layers # Just to call Global.layers_changed
|
||||||
# Load tool options
|
# Load tool options
|
||||||
Global.left_color_picker.color = file.get_var()
|
Global.color_pickers[0].color = file.get_var()
|
||||||
Global.right_color_picker.color = file.get_var()
|
Global.color_pickers[1].color = file.get_var()
|
||||||
Global.left_brush_size = file.get_8()
|
Global.brush_sizes[0] = file.get_8()
|
||||||
Global.left_brush_size_edit.value = Global.left_brush_size
|
Global.brush_size_edits[0].value = Global.brush_sizes[0]
|
||||||
Global.right_brush_size = file.get_8()
|
Global.brush_sizes[1] = file.get_8()
|
||||||
Global.right_brush_size_edit.value = Global.right_brush_size
|
Global.brush_size_edits[1].value = Global.brush_sizes[1]
|
||||||
if file_major_version == 0 and file_minor_version < 7:
|
if file_major_version == 0 and file_minor_version < 7:
|
||||||
var left_palette = file.get_var()
|
var left_palette = file.get_var()
|
||||||
var right_palette = file.get_var()
|
var right_palette = file.get_var()
|
||||||
for color in left_palette:
|
for color in left_palette:
|
||||||
Global.left_color_picker.get_picker().add_preset(color)
|
Global.color_pickers[0].get_picker().add_preset(color)
|
||||||
for color in right_palette:
|
for color in right_palette:
|
||||||
Global.right_color_picker.get_picker().add_preset(color)
|
Global.color_pickers[1].get_picker().add_preset(color)
|
||||||
|
|
||||||
# Load custom brushes
|
# Load custom brushes
|
||||||
Global.custom_brushes.resize(Global.brushes_from_files)
|
Global.custom_brushes.resize(Global.brushes_from_files)
|
||||||
|
@ -164,7 +158,7 @@ func open_pxo_file(path : String, untitled_backup : bool = false) -> void:
|
||||||
var tag_color : Color = file.get_var()
|
var tag_color : Color = file.get_var()
|
||||||
var tag_from := file.get_8()
|
var tag_from := file.get_8()
|
||||||
var tag_to := file.get_8()
|
var tag_to := file.get_8()
|
||||||
Global.animation_tags.append([tag_name, tag_color, tag_from, tag_to])
|
Global.animation_tags.append(AnimationTag.new(tag_name, tag_color, tag_from, tag_to))
|
||||||
Global.animation_tags = Global.animation_tags # To execute animation_tags_changed()
|
Global.animation_tags = Global.animation_tags # To execute animation_tags_changed()
|
||||||
tag_line = file.get_line()
|
tag_line = file.get_line()
|
||||||
|
|
||||||
|
@ -187,12 +181,12 @@ func save_pxo_file(path : String, autosave : bool) -> void:
|
||||||
# Store Global layers
|
# Store Global layers
|
||||||
for layer in Global.layers:
|
for layer in Global.layers:
|
||||||
file.store_line(".")
|
file.store_line(".")
|
||||||
file.store_line(layer[0]) # Layer name
|
file.store_line(layer.name)
|
||||||
file.store_8(layer[1]) # Layer visibility
|
file.store_8(layer.visible)
|
||||||
file.store_8(layer[2]) # Layer lock
|
file.store_8(layer.locked)
|
||||||
file.store_8(layer[4]) # Future cels linked
|
file.store_8(layer.new_cels_linked)
|
||||||
var linked_cels := []
|
var linked_cels := []
|
||||||
for canvas in layer[5]:
|
for canvas in layer.linked_cels:
|
||||||
linked_cels.append(canvas.frame)
|
linked_cels.append(canvas.frame)
|
||||||
file.store_var(linked_cels) # Linked cels as cel numbers
|
file.store_var(linked_cels) # Linked cels as cel numbers
|
||||||
|
|
||||||
|
@ -205,8 +199,8 @@ func save_pxo_file(path : String, autosave : bool) -> void:
|
||||||
file.store_16(canvas.size.y)
|
file.store_16(canvas.size.y)
|
||||||
for layer in canvas.layers: # Store canvas layers
|
for layer in canvas.layers: # Store canvas layers
|
||||||
file.store_line("-")
|
file.store_line("-")
|
||||||
file.store_buffer(layer[0].get_data())
|
file.store_buffer(layer.image.get_data())
|
||||||
file.store_float(layer[2]) # Layer transparency
|
file.store_float(layer.opacity)
|
||||||
file.store_line("END_LAYERS")
|
file.store_line("END_LAYERS")
|
||||||
|
|
||||||
# Store guides
|
# Store guides
|
||||||
|
@ -224,10 +218,10 @@ func save_pxo_file(path : String, autosave : bool) -> void:
|
||||||
file.store_line("END_FRAMES")
|
file.store_line("END_FRAMES")
|
||||||
|
|
||||||
# Save tool options
|
# Save tool options
|
||||||
var left_color : Color = Global.left_color_picker.color
|
var left_color : Color = Global.color_pickers[0].color
|
||||||
var right_color : Color = Global.right_color_picker.color
|
var right_color : Color = Global.color_pickers[1].color
|
||||||
var left_brush_size : int = Global.left_brush_size
|
var left_brush_size : int = Global.brush_sizes[0]
|
||||||
var right_brush_size : int = Global.right_brush_size
|
var right_brush_size : int = Global.brush_sizes[1]
|
||||||
file.store_var(left_color)
|
file.store_var(left_color)
|
||||||
file.store_var(right_color)
|
file.store_var(right_color)
|
||||||
file.store_8(left_brush_size)
|
file.store_8(left_brush_size)
|
||||||
|
@ -245,10 +239,10 @@ func save_pxo_file(path : String, autosave : bool) -> void:
|
||||||
# Store animation tags
|
# Store animation tags
|
||||||
for tag in Global.animation_tags:
|
for tag in Global.animation_tags:
|
||||||
file.store_line(".T/")
|
file.store_line(".T/")
|
||||||
file.store_line(tag[0]) # Tag name
|
file.store_line(tag.name)
|
||||||
file.store_var(tag[1]) # Tag color
|
file.store_var(tag.color)
|
||||||
file.store_8(tag[2]) # Tag "from", the first frame
|
file.store_8(tag.from)
|
||||||
file.store_8(tag[3]) # Tag "to", the last frame
|
file.store_8(tag.to)
|
||||||
file.store_line("END_FRAME_TAGS")
|
file.store_line("END_FRAME_TAGS")
|
||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
|
@ -271,16 +265,11 @@ func save_pxo_file(path : String, autosave : bool) -> void:
|
||||||
Global.notification_label("File failed to save")
|
Global.notification_label("File failed to save")
|
||||||
|
|
||||||
|
|
||||||
func toggle_autosave(enable : bool) -> void:
|
func update_autosave() -> void:
|
||||||
if enable:
|
autosave_timer.stop()
|
||||||
|
autosave_timer.wait_time = Global.autosave_interval * 60 # Interval parameter is in minutes, wait_time is seconds
|
||||||
|
if Global.enable_autosave:
|
||||||
autosave_timer.start()
|
autosave_timer.start()
|
||||||
else:
|
|
||||||
autosave_timer.stop()
|
|
||||||
|
|
||||||
|
|
||||||
func set_autosave_interval(interval : float) -> void:
|
|
||||||
autosave_timer.wait_time = interval * 60 # Interval parameter is in minutes, wait_time is seconds
|
|
||||||
autosave_timer.start()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_Autosave_timeout() -> void:
|
func _on_Autosave_timeout() -> void:
|
||||||
|
|
1093
src/Canvas.gd
1093
src/Canvas.gd
File diff suppressed because it is too large
Load diff
15
src/Classes/AnimationTag.gd
Normal file
15
src/Classes/AnimationTag.gd
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
class_name AnimationTag extends Reference
|
||||||
|
# A class for frame tag properties
|
||||||
|
|
||||||
|
|
||||||
|
var name : String
|
||||||
|
var color : Color
|
||||||
|
var from : int
|
||||||
|
var to : int
|
||||||
|
|
||||||
|
|
||||||
|
func _init(_name, _color, _from, _to) -> void:
|
||||||
|
name = _name
|
||||||
|
color = _color
|
||||||
|
from = _from
|
||||||
|
to = _to
|
18
src/Classes/Cel.gd
Normal file
18
src/Classes/Cel.gd
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class_name Cel extends Reference
|
||||||
|
# A class for cel properties
|
||||||
|
|
||||||
|
|
||||||
|
var image : Image setget image_changed
|
||||||
|
var image_texture : ImageTexture
|
||||||
|
var opacity : float
|
||||||
|
|
||||||
|
|
||||||
|
func _init(_image := Image.new(), _opacity := 1.0) -> void:
|
||||||
|
self.image = _image
|
||||||
|
opacity = _opacity
|
||||||
|
|
||||||
|
|
||||||
|
func image_changed(value : Image) -> void:
|
||||||
|
image = value
|
||||||
|
image_texture = ImageTexture.new()
|
||||||
|
image_texture.create_from_image(image, 0)
|
19
src/Classes/Layer.gd
Normal file
19
src/Classes/Layer.gd
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
class_name Layer extends Reference
|
||||||
|
# A class for layer properties
|
||||||
|
|
||||||
|
|
||||||
|
var name := ""
|
||||||
|
var visible := true
|
||||||
|
var locked := false
|
||||||
|
var frame_container : HBoxContainer
|
||||||
|
var new_cels_linked := false
|
||||||
|
var linked_cels := [] # Array of Canvases
|
||||||
|
|
||||||
|
|
||||||
|
func _init(_name := tr("Layer") + " 0", _visible := true, _locked := false, _frame_container := HBoxContainer.new(), _new_cels_linked := false, _linked_cels := []) -> void:
|
||||||
|
name = _name
|
||||||
|
visible = _visible
|
||||||
|
locked = _locked
|
||||||
|
frame_container = _frame_container
|
||||||
|
new_cels_linked = _new_cels_linked
|
||||||
|
linked_cels = _linked_cels
|
581
src/Main.gd
581
src/Main.gd
|
@ -11,12 +11,64 @@ var is_quitting_on_save := false
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
get_tree().set_auto_accept_quit(false)
|
get_tree().set_auto_accept_quit(false)
|
||||||
|
setup_application_window_size()
|
||||||
|
|
||||||
|
setup_file_menu()
|
||||||
|
setup_edit_menu()
|
||||||
|
setup_view_menu()
|
||||||
|
setup_image_menu()
|
||||||
|
setup_help_menu()
|
||||||
|
|
||||||
|
Global.window_title = "(" + tr("untitled") + ") - Pixelorama " + Global.current_version
|
||||||
|
|
||||||
|
Global.layers[0].name = tr("Layer") + " 0"
|
||||||
|
Global.layers_container.get_child(0).label.text = Global.layers[0].name
|
||||||
|
Global.layers_container.get_child(0).line_edit.text = Global.layers[0].name
|
||||||
|
|
||||||
|
Import.import_brushes(Global.directory_module.get_brushes_search_path_in_order())
|
||||||
|
Import.import_patterns(Global.directory_module.get_patterns_search_path_in_order())
|
||||||
|
|
||||||
|
Global.color_pickers[0].get_picker().presets_visible = false
|
||||||
|
Global.color_pickers[1].get_picker().presets_visible = false
|
||||||
|
|
||||||
|
$QuitAndSaveDialog.add_button("Save & Exit", false, "Save")
|
||||||
|
$QuitAndSaveDialog.get_ok().text = "Exit without saving"
|
||||||
|
|
||||||
|
if not Global.config_cache.has_section_key("preferences", "startup"):
|
||||||
|
Global.config_cache.set_value("preferences", "startup", true)
|
||||||
|
show_splash_screen()
|
||||||
|
|
||||||
|
handle_backup()
|
||||||
|
|
||||||
|
# If the user wants to run Pixelorama with arguments in terminal mode
|
||||||
|
# or open files with Pixelorama directly, then handle that
|
||||||
|
if OS.get_cmdline_args():
|
||||||
|
handle_loading_files(OS.get_cmdline_args())
|
||||||
|
get_tree().connect("files_dropped", self, "_on_files_dropped")
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event : InputEvent) -> void:
|
||||||
|
Global.left_cursor.position = get_global_mouse_position() + Vector2(-32, 32)
|
||||||
|
Global.left_cursor.texture = Global.left_cursor_tool_texture
|
||||||
|
Global.right_cursor.position = get_global_mouse_position() + Vector2(32, 32)
|
||||||
|
Global.right_cursor.texture = Global.right_cursor_tool_texture
|
||||||
|
|
||||||
|
if event is InputEventKey and (event.scancode == KEY_ENTER or event.scancode == KEY_KP_ENTER):
|
||||||
|
if get_focus_owner() is LineEdit:
|
||||||
|
get_focus_owner().release_focus()
|
||||||
|
|
||||||
|
if event.is_action_pressed("toggle_fullscreen"):
|
||||||
|
OS.window_fullscreen = !OS.window_fullscreen
|
||||||
|
|
||||||
|
if event.is_action_pressed("redo_secondary"): # Shift + Ctrl + Z
|
||||||
|
redone = true
|
||||||
|
Global.undo_redo.redo()
|
||||||
|
redone = false
|
||||||
|
|
||||||
|
|
||||||
|
func setup_application_window_size() -> void:
|
||||||
# Set a minimum window size to prevent UI elements from collapsing on each other.
|
# Set a minimum window size to prevent UI elements from collapsing on each other.
|
||||||
OS.min_window_size = Vector2(1024, 576)
|
OS.min_window_size = Vector2(1024, 576)
|
||||||
Global.loaded_locales = TranslationServer.get_loaded_locales()
|
|
||||||
|
|
||||||
# Make sure locales are always sorted, in the same order
|
|
||||||
Global.loaded_locales.sort()
|
|
||||||
|
|
||||||
# Restore the window position/size if values are present in the configuration cache
|
# Restore the window position/size if values are present in the configuration cache
|
||||||
if Global.config_cache.has_section_key("window", "screen"):
|
if Global.config_cache.has_section_key("window", "screen"):
|
||||||
|
@ -30,6 +82,8 @@ func _ready() -> void:
|
||||||
if Global.config_cache.has_section_key("window", "size"):
|
if Global.config_cache.has_section_key("window", "size"):
|
||||||
OS.window_size = Global.config_cache.get_value("window", "size")
|
OS.window_size = Global.config_cache.get_value("window", "size")
|
||||||
|
|
||||||
|
|
||||||
|
func setup_file_menu() -> void:
|
||||||
var file_menu_items := {
|
var file_menu_items := {
|
||||||
"New..." : InputMap.get_action_list("new_file")[0].get_scancode_with_modifiers(),
|
"New..." : InputMap.get_action_list("new_file")[0].get_scancode_with_modifiers(),
|
||||||
"Open..." : InputMap.get_action_list("open_file")[0].get_scancode_with_modifiers(),
|
"Open..." : InputMap.get_action_list("open_file")[0].get_scancode_with_modifiers(),
|
||||||
|
@ -41,12 +95,34 @@ func _ready() -> void:
|
||||||
"Export as..." : InputMap.get_action_list("export_file_as")[0].get_scancode_with_modifiers(),
|
"Export as..." : InputMap.get_action_list("export_file_as")[0].get_scancode_with_modifiers(),
|
||||||
"Quit" : InputMap.get_action_list("quit")[0].get_scancode_with_modifiers(),
|
"Quit" : InputMap.get_action_list("quit")[0].get_scancode_with_modifiers(),
|
||||||
}
|
}
|
||||||
|
file_menu = Global.file_menu.get_popup()
|
||||||
|
var i := 0
|
||||||
|
|
||||||
|
for item in file_menu_items.keys():
|
||||||
|
file_menu.add_item(item, i, file_menu_items[item])
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
file_menu.connect("id_pressed", self, "file_menu_id_pressed")
|
||||||
|
|
||||||
|
|
||||||
|
func setup_edit_menu() -> void:
|
||||||
var edit_menu_items := {
|
var edit_menu_items := {
|
||||||
"Undo" : InputMap.get_action_list("undo")[0].get_scancode_with_modifiers(),
|
"Undo" : InputMap.get_action_list("undo")[0].get_scancode_with_modifiers(),
|
||||||
"Redo" : InputMap.get_action_list("redo")[0].get_scancode_with_modifiers(),
|
"Redo" : InputMap.get_action_list("redo")[0].get_scancode_with_modifiers(),
|
||||||
"Clear Selection" : 0,
|
"Clear Selection" : 0,
|
||||||
"Preferences" : 0
|
"Preferences" : 0
|
||||||
}
|
}
|
||||||
|
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
|
||||||
|
var i := 0
|
||||||
|
|
||||||
|
for item in edit_menu_items.keys():
|
||||||
|
edit_menu.add_item(item, i, edit_menu_items[item])
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
edit_menu.connect("id_pressed", self, "edit_menu_id_pressed")
|
||||||
|
|
||||||
|
|
||||||
|
func setup_view_menu() -> void:
|
||||||
var view_menu_items := {
|
var view_menu_items := {
|
||||||
"Tile Mode" : InputMap.get_action_list("tile_mode")[0].get_scancode_with_modifiers(),
|
"Tile Mode" : InputMap.get_action_list("tile_mode")[0].get_scancode_with_modifiers(),
|
||||||
"Show Grid" : InputMap.get_action_list("show_grid")[0].get_scancode_with_modifiers(),
|
"Show Grid" : InputMap.get_action_list("show_grid")[0].get_scancode_with_modifiers(),
|
||||||
|
@ -54,6 +130,21 @@ func _ready() -> void:
|
||||||
"Show Guides" : InputMap.get_action_list("show_guides")[0].get_scancode_with_modifiers(),
|
"Show Guides" : InputMap.get_action_list("show_guides")[0].get_scancode_with_modifiers(),
|
||||||
"Show Animation Timeline" : 0
|
"Show Animation Timeline" : 0
|
||||||
}
|
}
|
||||||
|
view_menu = Global.view_menu.get_popup()
|
||||||
|
|
||||||
|
var i := 0
|
||||||
|
for item in view_menu_items.keys():
|
||||||
|
view_menu.add_check_item(item, i, view_menu_items[item])
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
view_menu.set_item_checked(2, true) # Show Rulers
|
||||||
|
view_menu.set_item_checked(3, true) # Show Guides
|
||||||
|
view_menu.set_item_checked(4, true) # Show Animation Timeline
|
||||||
|
view_menu.hide_on_checkable_item_selection = false
|
||||||
|
view_menu.connect("id_pressed", self, "view_menu_id_pressed")
|
||||||
|
|
||||||
|
|
||||||
|
func setup_image_menu() -> void:
|
||||||
var image_menu_items := {
|
var image_menu_items := {
|
||||||
"Scale Image" : 0,
|
"Scale Image" : 0,
|
||||||
"Crop Image" : 0,
|
"Crop Image" : 0,
|
||||||
|
@ -65,6 +156,19 @@ func _ready() -> void:
|
||||||
"Outline" : 0,
|
"Outline" : 0,
|
||||||
"Adjust Hue/Saturation/Value" : 0
|
"Adjust Hue/Saturation/Value" : 0
|
||||||
}
|
}
|
||||||
|
var image_menu : PopupMenu = Global.image_menu.get_popup()
|
||||||
|
|
||||||
|
var i := 0
|
||||||
|
for item in image_menu_items.keys():
|
||||||
|
image_menu.add_item(item, i, image_menu_items[item])
|
||||||
|
if i == 4:
|
||||||
|
image_menu.add_separator()
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
image_menu.connect("id_pressed", self, "image_menu_id_pressed")
|
||||||
|
|
||||||
|
|
||||||
|
func setup_help_menu() -> void:
|
||||||
var help_menu_items := {
|
var help_menu_items := {
|
||||||
"View Splash Screen" : 0,
|
"View Splash Screen" : 0,
|
||||||
"Online Docs" : 0,
|
"Online Docs" : 0,
|
||||||
|
@ -72,86 +176,17 @@ func _ready() -> void:
|
||||||
"Changelog" : 0,
|
"Changelog" : 0,
|
||||||
"About Pixelorama" : 0
|
"About Pixelorama" : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load language
|
|
||||||
if Global.config_cache.has_section_key("preferences", "locale"):
|
|
||||||
var saved_locale : String = Global.config_cache.get_value("preferences", "locale")
|
|
||||||
TranslationServer.set_locale(saved_locale)
|
|
||||||
|
|
||||||
# Set the language option menu's default selected option to the loaded locale
|
|
||||||
var locale_index: int = Global.loaded_locales.find(saved_locale)
|
|
||||||
$PreferencesDialog.languages.get_child(0).pressed = false # Unset System Language option in preferences
|
|
||||||
$PreferencesDialog.languages.get_child(locale_index + 1).pressed = true
|
|
||||||
else: # If the user doesn't have a language preference, set it to their OS' locale
|
|
||||||
TranslationServer.set_locale(OS.get_locale())
|
|
||||||
|
|
||||||
if "zh" in TranslationServer.get_locale():
|
|
||||||
theme.default_font = preload("res://assets/fonts/CJK/NotoSansCJKtc-Regular.tres")
|
|
||||||
else:
|
|
||||||
theme.default_font = preload("res://assets/fonts/Roboto-Regular.tres")
|
|
||||||
|
|
||||||
|
|
||||||
file_menu = Global.file_menu.get_popup()
|
|
||||||
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
|
|
||||||
view_menu = Global.view_menu.get_popup()
|
|
||||||
var image_menu : PopupMenu = Global.image_menu.get_popup()
|
|
||||||
var help_menu : PopupMenu = Global.help_menu.get_popup()
|
var help_menu : PopupMenu = Global.help_menu.get_popup()
|
||||||
|
|
||||||
var i = 0
|
var i := 0
|
||||||
for item in file_menu_items.keys():
|
|
||||||
file_menu.add_item(item, i, file_menu_items[item])
|
|
||||||
i += 1
|
|
||||||
i = 0
|
|
||||||
for item in edit_menu_items.keys():
|
|
||||||
edit_menu.add_item(item, i, edit_menu_items[item])
|
|
||||||
i += 1
|
|
||||||
i = 0
|
|
||||||
for item in view_menu_items.keys():
|
|
||||||
view_menu.add_check_item(item, i, view_menu_items[item])
|
|
||||||
i += 1
|
|
||||||
view_menu.set_item_checked(2, true) # Show Rulers
|
|
||||||
view_menu.set_item_checked(3, true) # Show Guides
|
|
||||||
view_menu.set_item_checked(4, true) # Show Animation Timeline
|
|
||||||
view_menu.hide_on_checkable_item_selection = false
|
|
||||||
i = 0
|
|
||||||
for item in image_menu_items.keys():
|
|
||||||
image_menu.add_item(item, i, image_menu_items[item])
|
|
||||||
if i == 4:
|
|
||||||
image_menu.add_separator()
|
|
||||||
i += 1
|
|
||||||
i = 0
|
|
||||||
for item in help_menu_items.keys():
|
for item in help_menu_items.keys():
|
||||||
help_menu.add_item(item, i, help_menu_items[item])
|
help_menu.add_item(item, i, help_menu_items[item])
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
file_menu.connect("id_pressed", self, "file_menu_id_pressed")
|
|
||||||
edit_menu.connect("id_pressed", self, "edit_menu_id_pressed")
|
|
||||||
view_menu.connect("id_pressed", self, "view_menu_id_pressed")
|
|
||||||
image_menu.connect("id_pressed", self, "image_menu_id_pressed")
|
|
||||||
help_menu.connect("id_pressed", self, "help_menu_id_pressed")
|
help_menu.connect("id_pressed", self, "help_menu_id_pressed")
|
||||||
|
|
||||||
# Checks to see if it's 3.1.x
|
|
||||||
if Engine.get_version_info().major == 3 and Engine.get_version_info().minor < 2:
|
|
||||||
Global.left_color_picker.get_picker().move_child(Global.left_color_picker.get_picker().get_child(0), 1)
|
|
||||||
Global.right_color_picker.get_picker().move_child(Global.right_color_picker.get_picker().get_child(0), 1)
|
|
||||||
|
|
||||||
Global.window_title = "(" + tr("untitled") + ") - Pixelorama " + Global.current_version
|
|
||||||
|
|
||||||
Global.layers[0][0] = tr("Layer") + " 0"
|
|
||||||
Global.layers_container.get_child(0).label.text = Global.layers[0][0]
|
|
||||||
Global.layers_container.get_child(0).line_edit.text = Global.layers[0][0]
|
|
||||||
|
|
||||||
Import.import_brushes(Global.directory_module.get_brushes_search_path_in_order())
|
|
||||||
Import.import_patterns(Global.directory_module.get_patterns_search_path_in_order())
|
|
||||||
|
|
||||||
Global.left_color_picker.get_picker().presets_visible = false
|
|
||||||
Global.right_color_picker.get_picker().presets_visible = false
|
|
||||||
$QuitAndSaveDialog.add_button("Save & Exit", false, "Save")
|
|
||||||
$QuitAndSaveDialog.get_ok().text = "Exit without saving"
|
|
||||||
|
|
||||||
if not Global.config_cache.has_section_key("preferences", "startup"):
|
|
||||||
Global.config_cache.set_value("preferences", "startup", true)
|
|
||||||
|
|
||||||
|
func show_splash_screen() -> void:
|
||||||
# Wait for the window to adjust itself, so the popup is correctly centered
|
# Wait for the window to adjust itself, so the popup is correctly centered
|
||||||
yield(get_tree().create_timer(0.01), "timeout")
|
yield(get_tree().create_timer(0.01), "timeout")
|
||||||
if Global.config_cache.get_value("preferences", "startup"):
|
if Global.config_cache.get_value("preferences", "startup"):
|
||||||
|
@ -160,6 +195,8 @@ func _ready() -> void:
|
||||||
else:
|
else:
|
||||||
Global.can_draw = true
|
Global.can_draw = true
|
||||||
|
|
||||||
|
|
||||||
|
func handle_backup() -> void:
|
||||||
# If backup file exists then Pixelorama was not closed properly (probably crashed) - reopen backup
|
# If backup file exists then Pixelorama was not closed properly (probably crashed) - reopen backup
|
||||||
$BackupConfirmation.get_cancel().text = tr("Delete")
|
$BackupConfirmation.get_cancel().text = tr("Delete")
|
||||||
if Global.config_cache.has_section("backups"):
|
if Global.config_cache.has_section("backups"):
|
||||||
|
@ -183,34 +220,16 @@ func _ready() -> void:
|
||||||
if Global.open_last_project:
|
if Global.open_last_project:
|
||||||
load_last_project()
|
load_last_project()
|
||||||
|
|
||||||
if OS.get_cmdline_args():
|
|
||||||
for arg in OS.get_cmdline_args():
|
|
||||||
if arg.get_extension().to_lower() == "pxo":
|
|
||||||
_on_OpenSprite_file_selected(arg)
|
|
||||||
else:
|
|
||||||
if arg == OS.get_cmdline_args()[0]:
|
|
||||||
$ImportSprites.new_frame = false
|
|
||||||
$ImportSprites._on_ImportSprites_files_selected([arg])
|
|
||||||
$ImportSprites.new_frame = true
|
|
||||||
|
|
||||||
|
func handle_loading_files(files : PoolStringArray) -> void:
|
||||||
func _input(event : InputEvent) -> void:
|
for file in files:
|
||||||
Global.left_cursor.position = get_global_mouse_position() + Vector2(-32, 32)
|
if file.get_extension().to_lower() == "pxo":
|
||||||
Global.left_cursor.texture = Global.left_cursor_tool_texture
|
_on_OpenSprite_file_selected(file)
|
||||||
Global.right_cursor.position = get_global_mouse_position() + Vector2(32, 32)
|
else:
|
||||||
Global.right_cursor.texture = Global.right_cursor_tool_texture
|
if file == files[0]:
|
||||||
|
$ImportSprites.new_frame = false
|
||||||
if event is InputEventKey and (event.scancode == KEY_ENTER or event.scancode == KEY_KP_ENTER):
|
$ImportSprites._on_ImportSprites_files_selected([file])
|
||||||
if get_focus_owner() is LineEdit:
|
$ImportSprites.new_frame = true
|
||||||
get_focus_owner().release_focus()
|
|
||||||
|
|
||||||
if event.is_action_pressed("toggle_fullscreen"):
|
|
||||||
OS.window_fullscreen = !OS.window_fullscreen
|
|
||||||
|
|
||||||
if event.is_action_pressed("redo_secondary"): # Shift + Ctrl + Z
|
|
||||||
redone = true
|
|
||||||
Global.undo_redo.redo()
|
|
||||||
redone = false
|
|
||||||
|
|
||||||
|
|
||||||
func _notification(what : int) -> void:
|
func _notification(what : int) -> void:
|
||||||
|
@ -218,53 +237,85 @@ func _notification(what : int) -> void:
|
||||||
show_quit_dialog()
|
show_quit_dialog()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_files_dropped(_files : PoolStringArray, _screen : int) -> void:
|
||||||
|
handle_loading_files(_files)
|
||||||
|
|
||||||
|
|
||||||
|
func on_new_project_file_menu_option_pressed(id : int) -> void:
|
||||||
|
if Global.project_has_changed:
|
||||||
|
unsaved_canvas_state = id
|
||||||
|
$UnsavedCanvasDialog.popup_centered()
|
||||||
|
else:
|
||||||
|
$CreateNewImage.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func open_project_file() -> void:
|
||||||
|
$OpenSprite.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
opensprite_file_selected = false
|
||||||
|
|
||||||
|
|
||||||
|
func on_open_last_project_file_menu_option_pressed(id : int) -> void:
|
||||||
|
# Check if last project path is set and if yes then open
|
||||||
|
if Global.config_cache.has_section_key("preferences", "last_project_path"):
|
||||||
|
if Global.project_has_changed:
|
||||||
|
unsaved_canvas_state = id
|
||||||
|
$UnsavedCanvasDialog.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
else:
|
||||||
|
load_last_project()
|
||||||
|
else: # if not then warn user that he didn't edit any project yet
|
||||||
|
Global.error_dialog.set_text("You haven't saved or opened any project in Pixelorama yet!")
|
||||||
|
Global.error_dialog.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func save_project_file() -> void:
|
||||||
|
is_quitting_on_save = false
|
||||||
|
if OpenSave.current_save_path == "":
|
||||||
|
$SaveSprite.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
else:
|
||||||
|
_on_SaveSprite_file_selected(OpenSave.current_save_path)
|
||||||
|
|
||||||
|
|
||||||
|
func save_project_file_as() -> void:
|
||||||
|
is_quitting_on_save = false
|
||||||
|
$SaveSprite.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func import_file() -> void:
|
||||||
|
$ImportSprites.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
opensprite_file_selected = false
|
||||||
|
|
||||||
|
|
||||||
|
func export_file() -> void:
|
||||||
|
if $ExportDialog.was_exported == false:
|
||||||
|
$ExportDialog.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
else:
|
||||||
|
$ExportDialog.external_export()
|
||||||
|
|
||||||
|
|
||||||
func file_menu_id_pressed(id : int) -> void:
|
func file_menu_id_pressed(id : int) -> void:
|
||||||
match id:
|
match id:
|
||||||
0: # New
|
0: # New
|
||||||
if Global.project_has_changed:
|
on_new_project_file_menu_option_pressed(id)
|
||||||
unsaved_canvas_state = id
|
|
||||||
$UnsavedCanvasDialog.popup_centered()
|
|
||||||
else:
|
|
||||||
$CreateNewImage.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
1: # Open
|
1: # Open
|
||||||
$OpenSprite.popup_centered()
|
open_project_file()
|
||||||
Global.dialog_open(true)
|
|
||||||
opensprite_file_selected = false
|
|
||||||
2: # Open last project
|
2: # Open last project
|
||||||
# Check if last project path is set and if yes then open
|
on_open_last_project_file_menu_option_pressed(id)
|
||||||
if Global.config_cache.has_section_key("preferences", "last_project_path"):
|
|
||||||
if Global.project_has_changed:
|
|
||||||
unsaved_canvas_state = id
|
|
||||||
$UnsavedCanvasDialog.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
else:
|
|
||||||
load_last_project()
|
|
||||||
else: # if not then warn user that he didn't edit any project yet
|
|
||||||
Global.error_dialog.set_text("You haven't saved or opened any project in Pixelorama yet!")
|
|
||||||
Global.error_dialog.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
3: # Save
|
3: # Save
|
||||||
is_quitting_on_save = false
|
save_project_file()
|
||||||
if OpenSave.current_save_path == "":
|
|
||||||
$SaveSprite.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
else:
|
|
||||||
_on_SaveSprite_file_selected(OpenSave.current_save_path)
|
|
||||||
4: # Save as
|
4: # Save as
|
||||||
is_quitting_on_save = false
|
save_project_file_as()
|
||||||
$SaveSprite.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
5: # Import
|
5: # Import
|
||||||
$ImportSprites.popup_centered()
|
import_file()
|
||||||
Global.dialog_open(true)
|
|
||||||
opensprite_file_selected = false
|
|
||||||
6: # Export
|
6: # Export
|
||||||
if $ExportDialog.was_exported == false:
|
export_file()
|
||||||
$ExportDialog.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
else:
|
|
||||||
$ExportDialog.external_export()
|
|
||||||
7: # Export as
|
7: # Export as
|
||||||
$ExportDialog.popup_centered()
|
$ExportDialog.popup_centered()
|
||||||
Global.dialog_open(true)
|
Global.dialog_open(true)
|
||||||
|
@ -293,134 +344,190 @@ func edit_menu_id_pressed(id : int) -> void:
|
||||||
Global.dialog_open(true)
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_tile_mode() -> void:
|
||||||
|
Global.tile_mode = !Global.tile_mode
|
||||||
|
view_menu.set_item_checked(0, Global.tile_mode)
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_show_grid() -> void:
|
||||||
|
Global.draw_grid = !Global.draw_grid
|
||||||
|
view_menu.set_item_checked(1, Global.draw_grid)
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_show_rulers() -> void:
|
||||||
|
Global.show_rulers = !Global.show_rulers
|
||||||
|
view_menu.set_item_checked(2, Global.show_rulers)
|
||||||
|
Global.horizontal_ruler.visible = Global.show_rulers
|
||||||
|
Global.vertical_ruler.visible = Global.show_rulers
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_show_guides() -> void:
|
||||||
|
Global.show_guides = !Global.show_guides
|
||||||
|
view_menu.set_item_checked(3, Global.show_guides)
|
||||||
|
for canvas in Global.canvases:
|
||||||
|
for guide in canvas.get_children():
|
||||||
|
if guide is Guide:
|
||||||
|
guide.visible = Global.show_guides
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_show_anim_timeline() -> void:
|
||||||
|
Global.show_animation_timeline = !Global.show_animation_timeline
|
||||||
|
view_menu.set_item_checked(4, Global.show_animation_timeline)
|
||||||
|
Global.animation_timeline.visible = Global.show_animation_timeline
|
||||||
|
|
||||||
|
|
||||||
func view_menu_id_pressed(id : int) -> void:
|
func view_menu_id_pressed(id : int) -> void:
|
||||||
match id:
|
match id:
|
||||||
0: # Tile mode
|
0: # Tile mode
|
||||||
Global.tile_mode = !Global.tile_mode
|
toggle_tile_mode()
|
||||||
view_menu.set_item_checked(0, Global.tile_mode)
|
|
||||||
1: # Show grid
|
1: # Show grid
|
||||||
Global.draw_grid = !Global.draw_grid
|
toggle_show_grid()
|
||||||
view_menu.set_item_checked(1, Global.draw_grid)
|
|
||||||
2: # Show rulers
|
2: # Show rulers
|
||||||
Global.show_rulers = !Global.show_rulers
|
toggle_show_rulers()
|
||||||
view_menu.set_item_checked(2, Global.show_rulers)
|
|
||||||
Global.horizontal_ruler.visible = Global.show_rulers
|
|
||||||
Global.vertical_ruler.visible = Global.show_rulers
|
|
||||||
3: # Show guides
|
3: # Show guides
|
||||||
Global.show_guides = !Global.show_guides
|
toggle_show_guides()
|
||||||
view_menu.set_item_checked(3, Global.show_guides)
|
|
||||||
for canvas in Global.canvases:
|
|
||||||
for guide in canvas.get_children():
|
|
||||||
if guide is Guide:
|
|
||||||
guide.visible = Global.show_guides
|
|
||||||
4: # Show animation timeline
|
4: # Show animation timeline
|
||||||
Global.show_animation_timeline = !Global.show_animation_timeline
|
toggle_show_anim_timeline()
|
||||||
view_menu.set_item_checked(4, Global.show_animation_timeline)
|
|
||||||
Global.animation_timeline.visible = Global.show_animation_timeline
|
|
||||||
|
|
||||||
Global.canvas.update()
|
Global.canvas.update()
|
||||||
|
|
||||||
|
|
||||||
|
func show_scale_image_popup() -> void:
|
||||||
|
$ScaleImage.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func crop_image() -> void:
|
||||||
|
# Use first cel as a starting rectangle
|
||||||
|
var used_rect : Rect2 = Global.canvases[0].layers[0].image.get_used_rect()
|
||||||
|
|
||||||
|
for c in Global.canvases:
|
||||||
|
# However, if first cel is empty, loop through all cels until we find one that isn't
|
||||||
|
for layer in c.layers:
|
||||||
|
if used_rect != Rect2(0, 0, 0, 0):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if layer[0].get_used_rect() != Rect2(0, 0, 0, 0):
|
||||||
|
used_rect = layer.image.get_used_rect()
|
||||||
|
|
||||||
|
# Merge all layers with content
|
||||||
|
for layer in c.layers:
|
||||||
|
if layer.image.get_used_rect() != Rect2(0, 0, 0, 0):
|
||||||
|
used_rect = used_rect.merge(layer.image.get_used_rect())
|
||||||
|
|
||||||
|
# If no layer has any content, just return
|
||||||
|
if used_rect == Rect2(0, 0, 0, 0):
|
||||||
|
return
|
||||||
|
|
||||||
|
var width := used_rect.size.x
|
||||||
|
var height := used_rect.size.y
|
||||||
|
Global.undos += 1
|
||||||
|
Global.undo_redo.create_action("Scale")
|
||||||
|
for c in Global.canvases:
|
||||||
|
Global.undo_redo.add_do_property(c, "size", Vector2(width, height).floor())
|
||||||
|
# Loop through all the layers to crop them
|
||||||
|
for j in range(Global.canvas.layers.size() - 1, -1, -1):
|
||||||
|
var sprite : Image = c.layers[j].image.get_rect(used_rect)
|
||||||
|
Global.undo_redo.add_do_property(c.layers[j].image, "data", sprite.data)
|
||||||
|
Global.undo_redo.add_undo_property(c.layers[j].image, "data", c.layers[j].image.data)
|
||||||
|
|
||||||
|
Global.undo_redo.add_undo_property(c, "size", c.size)
|
||||||
|
Global.undo_redo.add_undo_method(Global, "undo", Global.canvases)
|
||||||
|
Global.undo_redo.add_do_method(Global, "redo", Global.canvases)
|
||||||
|
Global.undo_redo.commit_action()
|
||||||
|
|
||||||
|
|
||||||
|
func flip_image_horizontal() -> void:
|
||||||
|
var canvas : Canvas = Global.canvas
|
||||||
|
canvas.handle_undo("Draw")
|
||||||
|
canvas.layers[Global.current_layer].image.unlock()
|
||||||
|
canvas.layers[Global.current_layer].image.flip_x()
|
||||||
|
canvas.layers[Global.current_layer].image.lock()
|
||||||
|
canvas.handle_redo("Draw")
|
||||||
|
|
||||||
|
|
||||||
|
func flip_image_vertical() -> void:
|
||||||
|
var canvas : Canvas = Global.canvas
|
||||||
|
canvas.handle_undo("Draw")
|
||||||
|
canvas.layers[Global.current_layer].image.unlock()
|
||||||
|
canvas.layers[Global.current_layer].image.flip_y()
|
||||||
|
canvas.layers[Global.current_layer].image.lock()
|
||||||
|
canvas.handle_redo("Draw")
|
||||||
|
|
||||||
|
|
||||||
|
func show_rotate_image_popup() -> void:
|
||||||
|
var image : Image = Global.canvas.layers[Global.current_layer].image
|
||||||
|
$RotateImage.set_sprite(image)
|
||||||
|
$RotateImage.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func invert_image_colors() -> void:
|
||||||
|
var image : Image = Global.canvas.layers[Global.current_layer].image
|
||||||
|
Global.canvas.handle_undo("Draw")
|
||||||
|
for xx in image.get_size().x:
|
||||||
|
for yy in image.get_size().y:
|
||||||
|
var px_color = image.get_pixel(xx, yy).inverted()
|
||||||
|
if px_color.a == 0:
|
||||||
|
continue
|
||||||
|
image.set_pixel(xx, yy, px_color)
|
||||||
|
Global.canvas.handle_redo("Draw")
|
||||||
|
|
||||||
|
|
||||||
|
func desaturate_image() -> void:
|
||||||
|
var image : Image = Global.canvas.layers[Global.current_layer].image
|
||||||
|
Global.canvas.handle_undo("Draw")
|
||||||
|
for xx in image.get_size().x:
|
||||||
|
for yy in image.get_size().y:
|
||||||
|
var px_color = image.get_pixel(xx, yy)
|
||||||
|
if px_color.a == 0:
|
||||||
|
continue
|
||||||
|
var gray = image.get_pixel(xx, yy).v
|
||||||
|
px_color = Color(gray, gray, gray, px_color.a)
|
||||||
|
image.set_pixel(xx, yy, px_color)
|
||||||
|
Global.canvas.handle_redo("Draw")
|
||||||
|
|
||||||
|
|
||||||
|
func show_add_outline_popup() -> void:
|
||||||
|
$OutlineDialog.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
|
func show_hsv_configuration_popup() -> void:
|
||||||
|
$HSVDialog.popup_centered()
|
||||||
|
Global.dialog_open(true)
|
||||||
|
|
||||||
|
|
||||||
func image_menu_id_pressed(id : int) -> void:
|
func image_menu_id_pressed(id : int) -> void:
|
||||||
if Global.layers[Global.current_layer][2]: # No changes if the layer is locked
|
if Global.layers[Global.current_layer].locked: # No changes if the layer is locked
|
||||||
return
|
return
|
||||||
match id:
|
match id:
|
||||||
0: # Scale Image
|
0: # Scale Image
|
||||||
$ScaleImage.popup_centered()
|
show_scale_image_popup()
|
||||||
Global.dialog_open(true)
|
|
||||||
|
|
||||||
1: # Crop Image
|
1: # Crop Image
|
||||||
# Use first cel as a starting rectangle
|
crop_image()
|
||||||
var used_rect : Rect2 = Global.canvases[0].layers[0][0].get_used_rect()
|
|
||||||
|
|
||||||
for c in Global.canvases:
|
|
||||||
# However, if first cel is empty, loop through all cels until we find one that isn't
|
|
||||||
for layer in c.layers:
|
|
||||||
if used_rect != Rect2(0, 0, 0, 0):
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if layer[0].get_used_rect() != Rect2(0, 0, 0, 0):
|
|
||||||
used_rect = layer[0].get_used_rect()
|
|
||||||
|
|
||||||
# Merge all layers with content
|
|
||||||
for layer in c.layers:
|
|
||||||
if layer[0].get_used_rect() != Rect2(0, 0, 0, 0):
|
|
||||||
used_rect = used_rect.merge(layer[0].get_used_rect())
|
|
||||||
|
|
||||||
# If no layer has any content, just return
|
|
||||||
if used_rect == Rect2(0, 0, 0, 0):
|
|
||||||
return
|
|
||||||
|
|
||||||
var width := used_rect.size.x
|
|
||||||
var height := used_rect.size.y
|
|
||||||
Global.undos += 1
|
|
||||||
Global.undo_redo.create_action("Scale")
|
|
||||||
for c in Global.canvases:
|
|
||||||
Global.undo_redo.add_do_property(c, "size", Vector2(width, height).floor())
|
|
||||||
# Loop through all the layers to crop them
|
|
||||||
for j in range(Global.canvas.layers.size() - 1, -1, -1):
|
|
||||||
var sprite : Image = c.layers[j][0].get_rect(used_rect)
|
|
||||||
Global.undo_redo.add_do_property(c.layers[j][0], "data", sprite.data)
|
|
||||||
Global.undo_redo.add_undo_property(c.layers[j][0], "data", c.layers[j][0].data)
|
|
||||||
|
|
||||||
Global.undo_redo.add_undo_property(c, "size", c.size)
|
|
||||||
Global.undo_redo.add_undo_method(Global, "undo", Global.canvases)
|
|
||||||
Global.undo_redo.add_do_method(Global, "redo", Global.canvases)
|
|
||||||
Global.undo_redo.commit_action()
|
|
||||||
|
|
||||||
2: # Flip Horizontal
|
2: # Flip Horizontal
|
||||||
var canvas : Canvas = Global.canvas
|
flip_image_horizontal()
|
||||||
canvas.handle_undo("Draw")
|
|
||||||
canvas.layers[Global.current_layer][0].unlock()
|
|
||||||
canvas.layers[Global.current_layer][0].flip_x()
|
|
||||||
canvas.layers[Global.current_layer][0].lock()
|
|
||||||
canvas.handle_redo("Draw")
|
|
||||||
|
|
||||||
3: # Flip Vertical
|
3: # Flip Vertical
|
||||||
var canvas : Canvas = Global.canvas
|
flip_image_vertical()
|
||||||
canvas.handle_undo("Draw")
|
|
||||||
canvas.layers[Global.current_layer][0].unlock()
|
|
||||||
canvas.layers[Global.current_layer][0].flip_y()
|
|
||||||
canvas.layers[Global.current_layer][0].lock()
|
|
||||||
canvas.handle_redo("Draw")
|
|
||||||
|
|
||||||
4: # Rotate
|
4: # Rotate
|
||||||
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
show_rotate_image_popup()
|
||||||
$RotateImage.set_sprite(image)
|
|
||||||
$RotateImage.popup_centered()
|
|
||||||
Global.dialog_open(true)
|
|
||||||
|
|
||||||
5: # Invert Colors
|
5: # Invert Colors
|
||||||
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
invert_image_colors()
|
||||||
Global.canvas.handle_undo("Draw")
|
|
||||||
for xx in image.get_size().x:
|
|
||||||
for yy in image.get_size().y:
|
|
||||||
var px_color = image.get_pixel(xx, yy).inverted()
|
|
||||||
if px_color.a == 0:
|
|
||||||
continue
|
|
||||||
image.set_pixel(xx, yy, px_color)
|
|
||||||
Global.canvas.handle_redo("Draw")
|
|
||||||
|
|
||||||
6: # Desaturation
|
6: # Desaturation
|
||||||
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
desaturate_image()
|
||||||
Global.canvas.handle_undo("Draw")
|
|
||||||
for xx in image.get_size().x:
|
|
||||||
for yy in image.get_size().y:
|
|
||||||
var px_color = image.get_pixel(xx, yy)
|
|
||||||
if px_color.a == 0:
|
|
||||||
continue
|
|
||||||
var gray = image.get_pixel(xx, yy).v
|
|
||||||
px_color = Color(gray, gray, gray, px_color.a)
|
|
||||||
image.set_pixel(xx, yy, px_color)
|
|
||||||
Global.canvas.handle_redo("Draw")
|
|
||||||
|
|
||||||
7: # Outline
|
7: # Outline
|
||||||
$OutlineDialog.popup_centered()
|
show_add_outline_popup()
|
||||||
Global.dialog_open(true)
|
|
||||||
|
|
||||||
8: # HSV
|
8: # HSV
|
||||||
$HSVDialog.popup_centered()
|
show_hsv_configuration_popup()
|
||||||
Global.dialog_open(true)
|
|
||||||
|
|
||||||
|
|
||||||
func help_menu_id_pressed(id : int) -> void:
|
func help_menu_id_pressed(id : int) -> void:
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
[ext_resource path="res://src/UI/Dialogs/CreateNewImage.tscn" type="PackedScene" id=28]
|
[ext_resource path="res://src/UI/Dialogs/CreateNewImage.tscn" type="PackedScene" id=28]
|
||||||
[ext_resource path="res://src/UI/Dialogs/ImportSprites.tscn" type="PackedScene" id=29]
|
[ext_resource path="res://src/UI/Dialogs/ImportSprites.tscn" type="PackedScene" id=29]
|
||||||
[ext_resource path="res://src/UI/Dialogs/ScaleImage.tscn" type="PackedScene" id=31]
|
[ext_resource path="res://src/UI/Dialogs/ScaleImage.tscn" type="PackedScene" id=31]
|
||||||
[ext_resource path="res://src/UI/Dialogs/PreferencesDialog.tscn" type="PackedScene" id=32]
|
[ext_resource path="res://src/Preferences/PreferencesDialog.tscn" type="PackedScene" id=32]
|
||||||
[ext_resource path="res://src/UI/Dialogs/OutlineDialog.tscn" type="PackedScene" id=33]
|
[ext_resource path="res://src/UI/Dialogs/OutlineDialog.tscn" type="PackedScene" id=33]
|
||||||
[ext_resource path="res://src/UI/Dialogs/AboutDialog.tscn" type="PackedScene" id=34]
|
[ext_resource path="res://src/UI/Dialogs/AboutDialog.tscn" type="PackedScene" id=34]
|
||||||
[ext_resource path="res://src/UI/Dialogs/RotateImage.tscn" type="PackedScene" id=38]
|
[ext_resource path="res://src/UI/Dialogs/RotateImage.tscn" type="PackedScene" id=38]
|
||||||
|
|
|
@ -27,8 +27,8 @@ func open(palette : String) -> void:
|
||||||
self.popup_centered()
|
self.popup_centered()
|
||||||
Global.dialog_open(true)
|
Global.dialog_open(true)
|
||||||
|
|
||||||
left_color_button.modulate = Global.left_color_picker.color
|
left_color_button.modulate = Global.color_pickers[0].color
|
||||||
right_color_button.modulate = Global.right_color_picker.color
|
right_color_button.modulate = Global.color_pickers[1].color
|
||||||
|
|
||||||
|
|
||||||
func _display_palette() -> void:
|
func _display_palette() -> void:
|
||||||
|
@ -177,12 +177,12 @@ func _refresh_hint_tooltip(_index : int) -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_LeftColor_pressed() -> void:
|
func _on_LeftColor_pressed() -> void:
|
||||||
color_picker.color = Global.left_color_picker.color
|
color_picker.color = Global.color_pickers[0].color
|
||||||
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
||||||
|
|
||||||
|
|
||||||
func _on_RightColor_pressed() -> void:
|
func _on_RightColor_pressed() -> void:
|
||||||
color_picker.color = Global.right_color_picker.color
|
color_picker.color = Global.color_pickers[1].color
|
||||||
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
_on_EditPaletteColorPicker_color_changed(color_picker.color)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -165,11 +165,11 @@ func on_color_select(index : int) -> void:
|
||||||
var color : Color = Global.palettes[current_palette].get_color(index)
|
var color : Color = Global.palettes[current_palette].get_color(index)
|
||||||
|
|
||||||
if Input.is_action_just_pressed("left_mouse"):
|
if Input.is_action_just_pressed("left_mouse"):
|
||||||
Global.left_color_picker.color = color
|
Global.color_pickers[0].color = color
|
||||||
Global.update_left_custom_brush()
|
Global.update_custom_brush(0)
|
||||||
elif Input.is_action_just_pressed("right_mouse"):
|
elif Input.is_action_just_pressed("right_mouse"):
|
||||||
Global.right_color_picker.color = color
|
Global.color_pickers[1].color = color
|
||||||
Global.update_right_custom_brush()
|
Global.update_custom_brush(1)
|
||||||
|
|
||||||
|
|
||||||
func _load_palettes() -> void:
|
func _load_palettes() -> void:
|
||||||
|
@ -195,7 +195,7 @@ func _load_palettes() -> void:
|
||||||
# You need these two lines because when you remove a palette
|
# You need these two lines because when you remove a palette
|
||||||
# Then this just won't work and _on_PaletteOptionButton_item_selected
|
# Then this just won't work and _on_PaletteOptionButton_item_selected
|
||||||
# method won't fire.
|
# method won't fire.
|
||||||
Global.palette_option_button.selected
|
Global.palette_option_button.selected = index
|
||||||
on_palette_select("Default")
|
on_palette_select("Default")
|
||||||
Global.palette_option_button.select(index)
|
Global.palette_option_button.select(index)
|
||||||
|
|
||||||
|
|
50
src/Preferences/HandleLanguages.gd
Normal file
50
src/Preferences/HandleLanguages.gd
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
Global.loaded_locales = TranslationServer.get_loaded_locales()
|
||||||
|
|
||||||
|
# Make sure locales are always sorted, in the same order
|
||||||
|
Global.loaded_locales.sort()
|
||||||
|
|
||||||
|
# Load language
|
||||||
|
if Global.config_cache.has_section_key("preferences", "locale"):
|
||||||
|
var saved_locale : String = Global.config_cache.get_value("preferences", "locale")
|
||||||
|
TranslationServer.set_locale(saved_locale)
|
||||||
|
|
||||||
|
# Set the language option menu's default selected option to the loaded locale
|
||||||
|
var locale_index: int = Global.loaded_locales.find(saved_locale)
|
||||||
|
get_child(0).pressed = false # Unset System Language option in preferences
|
||||||
|
get_child(locale_index + 1).pressed = true
|
||||||
|
else: # If the user doesn't have a language preference, set it to their OS' locale
|
||||||
|
TranslationServer.set_locale(OS.get_locale())
|
||||||
|
|
||||||
|
if "zh" in TranslationServer.get_locale():
|
||||||
|
Global.control.theme.default_font = preload("res://assets/fonts/CJK/NotoSansCJKtc-Regular.tres")
|
||||||
|
else:
|
||||||
|
Global.control.theme.default_font = preload("res://assets/fonts/Roboto-Regular.tres")
|
||||||
|
|
||||||
|
for child in get_children():
|
||||||
|
if child is Button:
|
||||||
|
child.connect("pressed", self, "_on_Language_pressed", [child.get_index()])
|
||||||
|
child.hint_tooltip = child.name
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Language_pressed(index : int) -> void:
|
||||||
|
get_child(index).pressed = true
|
||||||
|
if index == 0:
|
||||||
|
TranslationServer.set_locale(OS.get_locale())
|
||||||
|
else:
|
||||||
|
TranslationServer.set_locale(Global.loaded_locales[index - 1])
|
||||||
|
|
||||||
|
if "zh" in TranslationServer.get_locale():
|
||||||
|
Global.control.theme.default_font = preload("res://assets/fonts/CJK/NotoSansCJKtc-Regular.tres")
|
||||||
|
else:
|
||||||
|
Global.control.theme.default_font = preload("res://assets/fonts/Roboto-Regular.tres")
|
||||||
|
|
||||||
|
Global.config_cache.set_value("preferences", "locale", TranslationServer.get_locale())
|
||||||
|
Global.config_cache.save("user://cache.ini")
|
||||||
|
|
||||||
|
# Update Translations
|
||||||
|
Global.update_hint_tooltips()
|
||||||
|
Global.preferences_dialog._on_PreferencesDialog_popup_hide()
|
||||||
|
Global.preferences_dialog._on_PreferencesDialog_about_to_show(true)
|
125
src/Preferences/HandleShortcuts.gd
Normal file
125
src/Preferences/HandleShortcuts.gd
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var default_shortcuts_preset := {}
|
||||||
|
var custom_shortcuts_preset := {}
|
||||||
|
var action_being_edited := ""
|
||||||
|
var shortcut_already_assigned = false
|
||||||
|
var old_input_event : InputEventKey
|
||||||
|
var new_input_event : InputEventKey
|
||||||
|
|
||||||
|
onready var shortcut_selector_popup = Global.preferences_dialog.get_node("Popups/ShortcutSelector")
|
||||||
|
onready var theme_font_color : Color = Global.preferences_dialog.get_node("Popups/ShortcutSelector/EnteredShortcut").get_color("font_color")
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
# Disable input until the shortcut selector is displayed
|
||||||
|
set_process_input(false)
|
||||||
|
|
||||||
|
# Get default preset for shortcuts from project input map
|
||||||
|
# Buttons in shortcuts selector should be called the same as actions
|
||||||
|
for shortcut_grid_item in get_node("Shortcuts").get_children():
|
||||||
|
if shortcut_grid_item is Button:
|
||||||
|
var input_events = InputMap.get_action_list(shortcut_grid_item.name)
|
||||||
|
if input_events.size() > 1:
|
||||||
|
printerr("Every shortcut action should have just one input event assigned in input map")
|
||||||
|
shortcut_grid_item.text = (input_events[0] as InputEventKey).as_text()
|
||||||
|
shortcut_grid_item.connect("pressed", self, "_on_Shortcut_button_pressed", [shortcut_grid_item])
|
||||||
|
default_shortcuts_preset[shortcut_grid_item.name] = input_events[0]
|
||||||
|
|
||||||
|
# Load custom shortcuts from the config file
|
||||||
|
custom_shortcuts_preset = default_shortcuts_preset.duplicate()
|
||||||
|
for action in default_shortcuts_preset:
|
||||||
|
var saved_input_event = Global.config_cache.get_value("shortcuts", action, 0)
|
||||||
|
if saved_input_event is InputEventKey:
|
||||||
|
custom_shortcuts_preset[action] = saved_input_event
|
||||||
|
|
||||||
|
var shortcuts_preset = Global.config_cache.get_value("shortcuts", "shortcuts_preset", 0)
|
||||||
|
get_node("HBoxContainer/PresetOptionButton").select(shortcuts_preset)
|
||||||
|
_on_PresetOptionButton_item_selected(shortcuts_preset)
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event : InputEvent) -> void:
|
||||||
|
if event is InputEventKey:
|
||||||
|
if event.pressed:
|
||||||
|
if event.scancode == KEY_ESCAPE:
|
||||||
|
shortcut_selector_popup.hide()
|
||||||
|
else:
|
||||||
|
# Check if shortcut was already used
|
||||||
|
for action in InputMap.get_actions():
|
||||||
|
for input_event in InputMap.get_action_list(action):
|
||||||
|
if input_event is InputEventKey:
|
||||||
|
if OS.get_scancode_string(input_event.get_scancode_with_modifiers()) == OS.get_scancode_string(event.get_scancode_with_modifiers()):
|
||||||
|
shortcut_selector_popup.get_node("EnteredShortcut").text = tr("Already assigned")
|
||||||
|
shortcut_selector_popup.get_node("EnteredShortcut").add_color_override("font_color", Color.crimson)
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
shortcut_already_assigned = true
|
||||||
|
return
|
||||||
|
|
||||||
|
# Store new shortcut
|
||||||
|
shortcut_already_assigned = false
|
||||||
|
old_input_event = InputMap.get_action_list(action_being_edited)[0]
|
||||||
|
new_input_event = event
|
||||||
|
shortcut_selector_popup.get_node("EnteredShortcut").text = OS.get_scancode_string(event.get_scancode_with_modifiers())
|
||||||
|
shortcut_selector_popup.get_node("EnteredShortcut").add_color_override("font_color", theme_font_color)
|
||||||
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_PresetOptionButton_item_selected(id : int) -> void:
|
||||||
|
# Only custom preset which is modifiable
|
||||||
|
toggle_shortcut_buttons(true if id == 1 else false)
|
||||||
|
match id:
|
||||||
|
0:
|
||||||
|
apply_shortcuts_preset(default_shortcuts_preset)
|
||||||
|
1:
|
||||||
|
apply_shortcuts_preset(custom_shortcuts_preset)
|
||||||
|
Global.config_cache.set_value("shortcuts", "shortcuts_preset", id)
|
||||||
|
Global.config_cache.save("user://cache.ini")
|
||||||
|
|
||||||
|
|
||||||
|
func apply_shortcuts_preset(preset) -> void:
|
||||||
|
for action in preset:
|
||||||
|
var old_input_event : InputEventKey = InputMap.get_action_list(action)[0]
|
||||||
|
set_action_shortcut(action, old_input_event, preset[action])
|
||||||
|
get_node("Shortcuts/" + action).text = OS.get_scancode_string(preset[action].get_scancode_with_modifiers())
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_shortcut_buttons(enabled : bool) -> void:
|
||||||
|
for shortcut_grid_item in get_node("Shortcuts").get_children():
|
||||||
|
if shortcut_grid_item is Button:
|
||||||
|
shortcut_grid_item.disabled = not enabled
|
||||||
|
if shortcut_grid_item.disabled:
|
||||||
|
shortcut_grid_item.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
||||||
|
else:
|
||||||
|
shortcut_grid_item.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
||||||
|
|
||||||
|
|
||||||
|
func set_action_shortcut(action : String, old_input : InputEventKey, new_input : InputEventKey) -> void:
|
||||||
|
InputMap.action_erase_event(action, old_input)
|
||||||
|
InputMap.action_add_event(action, new_input)
|
||||||
|
Global.update_hint_tooltips()
|
||||||
|
# Set shortcut to switch colors button
|
||||||
|
if action == "switch_colors":
|
||||||
|
Global.color_switch_button.shortcut.shortcut = InputMap.get_action_list("switch_colors")[0]
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Shortcut_button_pressed(button : Button) -> void:
|
||||||
|
set_process_input(true)
|
||||||
|
action_being_edited = button.name
|
||||||
|
new_input_event = InputMap.get_action_list(button.name)[0]
|
||||||
|
shortcut_already_assigned = true
|
||||||
|
shortcut_selector_popup.popup_centered()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_ShortcutSelector_popup_hide() -> void:
|
||||||
|
set_process_input(false)
|
||||||
|
shortcut_selector_popup.get_node("EnteredShortcut").text = ""
|
||||||
|
|
||||||
|
|
||||||
|
func _on_ShortcutSelector_confirmed() -> void:
|
||||||
|
if not shortcut_already_assigned:
|
||||||
|
set_action_shortcut(action_being_edited, old_input_event, new_input_event)
|
||||||
|
custom_shortcuts_preset[action_being_edited] = new_input_event
|
||||||
|
Global.config_cache.set_value("shortcuts", action_being_edited, new_input_event)
|
||||||
|
Global.config_cache.save("user://cache.ini")
|
||||||
|
get_node("Shortcuts/" + action_being_edited).text = OS.get_scancode_string(new_input_event.get_scancode_with_modifiers())
|
||||||
|
shortcut_selector_popup.hide()
|
123
src/Preferences/HandleThemes.gd
Normal file
123
src/Preferences/HandleThemes.gd
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
for child in get_children():
|
||||||
|
if child is Button:
|
||||||
|
child.connect("pressed", self, "_on_Theme_pressed", [child.get_index()])
|
||||||
|
|
||||||
|
if Global.config_cache.has_section_key("preferences", "theme"):
|
||||||
|
var theme_id = Global.config_cache.get_value("preferences", "theme")
|
||||||
|
change_theme(theme_id)
|
||||||
|
get_child(theme_id).pressed = true
|
||||||
|
else:
|
||||||
|
change_theme(0)
|
||||||
|
get_child(0).pressed = true
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Theme_pressed(index : int) -> void:
|
||||||
|
get_child(index).pressed = true
|
||||||
|
change_theme(index)
|
||||||
|
|
||||||
|
Global.config_cache.set_value("preferences", "theme", index)
|
||||||
|
Global.config_cache.save("user://cache.ini")
|
||||||
|
|
||||||
|
|
||||||
|
func change_theme(ID : int) -> void:
|
||||||
|
var font = Global.control.theme.default_font
|
||||||
|
var main_theme : Theme
|
||||||
|
var top_menu_style
|
||||||
|
var ruler_style
|
||||||
|
if ID == 0: # Dark Theme
|
||||||
|
Global.theme_type = Global.Theme_Types.DARK
|
||||||
|
main_theme = preload("res://assets/themes/dark/theme.tres")
|
||||||
|
top_menu_style = preload("res://assets/themes/dark/top_menu_style.tres")
|
||||||
|
ruler_style = preload("res://assets/themes/dark/ruler_style.tres")
|
||||||
|
elif ID == 1: # Gray Theme
|
||||||
|
Global.theme_type = Global.Theme_Types.DARK
|
||||||
|
main_theme = preload("res://assets/themes/gray/theme.tres")
|
||||||
|
top_menu_style = preload("res://assets/themes/gray/top_menu_style.tres")
|
||||||
|
ruler_style = preload("res://assets/themes/dark/ruler_style.tres")
|
||||||
|
elif ID == 2: # Godot's Theme
|
||||||
|
Global.theme_type = Global.Theme_Types.BLUE
|
||||||
|
main_theme = preload("res://assets/themes/blue/theme.tres")
|
||||||
|
top_menu_style = preload("res://assets/themes/blue/top_menu_style.tres")
|
||||||
|
ruler_style = preload("res://assets/themes/blue/ruler_style.tres")
|
||||||
|
elif ID == 3: # Caramel Theme
|
||||||
|
Global.theme_type = Global.Theme_Types.CARAMEL
|
||||||
|
main_theme = preload("res://assets/themes/caramel/theme.tres")
|
||||||
|
top_menu_style = preload("res://assets/themes/caramel/top_menu_style.tres")
|
||||||
|
ruler_style = preload("res://assets/themes/caramel/ruler_style.tres")
|
||||||
|
elif ID == 4: # Light Theme
|
||||||
|
Global.theme_type = Global.Theme_Types.LIGHT
|
||||||
|
main_theme = preload("res://assets/themes/light/theme.tres")
|
||||||
|
top_menu_style = preload("res://assets/themes/light/top_menu_style.tres")
|
||||||
|
ruler_style = preload("res://assets/themes/light/ruler_style.tres")
|
||||||
|
|
||||||
|
Global.control.theme = main_theme
|
||||||
|
Global.control.theme.default_font = font
|
||||||
|
var default_clear_color : Color = main_theme.get_stylebox("panel", "PanelContainer").bg_color
|
||||||
|
VisualServer.set_default_clear_color(Color(default_clear_color))
|
||||||
|
(Global.animation_timeline.get_stylebox("panel", "Panel") as StyleBoxFlat).bg_color = main_theme.get_stylebox("panel", "Panel").bg_color
|
||||||
|
var layer_button_panel_container : PanelContainer = Global.find_node_by_name(Global.animation_timeline, "LayerButtonPanelContainer")
|
||||||
|
(layer_button_panel_container.get_stylebox("panel", "PanelContainer") as StyleBoxFlat).bg_color = default_clear_color
|
||||||
|
|
||||||
|
Global.top_menu_container.add_stylebox_override("panel", top_menu_style)
|
||||||
|
Global.horizontal_ruler.add_stylebox_override("normal", ruler_style)
|
||||||
|
Global.horizontal_ruler.add_stylebox_override("pressed", ruler_style)
|
||||||
|
Global.horizontal_ruler.add_stylebox_override("hover", ruler_style)
|
||||||
|
Global.horizontal_ruler.add_stylebox_override("focus", ruler_style)
|
||||||
|
Global.vertical_ruler.add_stylebox_override("normal", ruler_style)
|
||||||
|
Global.vertical_ruler.add_stylebox_override("pressed", ruler_style)
|
||||||
|
Global.vertical_ruler.add_stylebox_override("hover", ruler_style)
|
||||||
|
Global.vertical_ruler.add_stylebox_override("focus", ruler_style)
|
||||||
|
|
||||||
|
var fake_vsplit_grabber : TextureRect = Global.find_node_by_name(Global.animation_timeline, "FakeVSplitContainerGrabber")
|
||||||
|
|
||||||
|
if Global.theme_type == Global.Theme_Types.DARK or Global.theme_type == Global.Theme_Types.BLUE:
|
||||||
|
fake_vsplit_grabber.texture = preload("res://assets/themes/dark/icons/vsplit.png")
|
||||||
|
else:
|
||||||
|
fake_vsplit_grabber.texture = preload("res://assets/themes/light/icons/vsplit.png")
|
||||||
|
|
||||||
|
for button in get_tree().get_nodes_in_group("UIButtons"):
|
||||||
|
if button is TextureButton:
|
||||||
|
var last_backslash = button.texture_normal.resource_path.get_base_dir().find_last("/")
|
||||||
|
var button_category = button.texture_normal.resource_path.get_base_dir().right(last_backslash + 1)
|
||||||
|
var normal_file_name = button.texture_normal.resource_path.get_file()
|
||||||
|
var theme_type := Global.theme_type
|
||||||
|
if theme_type == Global.Theme_Types.BLUE:
|
||||||
|
theme_type = Global.Theme_Types.DARK
|
||||||
|
|
||||||
|
var theme_type_string : String = Global.Theme_Types.keys()[theme_type].to_lower()
|
||||||
|
button.texture_normal = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type_string, button_category, normal_file_name])
|
||||||
|
if button.texture_pressed:
|
||||||
|
var pressed_file_name = button.texture_pressed.resource_path.get_file()
|
||||||
|
button.texture_pressed = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type_string, button_category, pressed_file_name])
|
||||||
|
if button.texture_hover:
|
||||||
|
var hover_file_name = button.texture_hover.resource_path.get_file()
|
||||||
|
button.texture_hover = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type_string, button_category, hover_file_name])
|
||||||
|
if button.texture_disabled:
|
||||||
|
var disabled_file_name = button.texture_disabled.resource_path.get_file()
|
||||||
|
button.texture_disabled = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type_string, button_category, disabled_file_name])
|
||||||
|
elif button is Button:
|
||||||
|
var texture : TextureRect
|
||||||
|
for child in button.get_children():
|
||||||
|
if child is TextureRect:
|
||||||
|
texture = child
|
||||||
|
break
|
||||||
|
|
||||||
|
if texture:
|
||||||
|
var last_backslash = texture.texture.resource_path.get_base_dir().find_last("/")
|
||||||
|
var button_category = texture.texture.resource_path.get_base_dir().right(last_backslash + 1)
|
||||||
|
var normal_file_name = texture.texture.resource_path.get_file()
|
||||||
|
var theme_type := Global.theme_type
|
||||||
|
if theme_type == Global.Theme_Types.CARAMEL or (theme_type == Global.Theme_Types.BLUE and button_category != "tools"):
|
||||||
|
theme_type = Global.Theme_Types.DARK
|
||||||
|
|
||||||
|
var theme_type_string : String = Global.Theme_Types.keys()[theme_type].to_lower()
|
||||||
|
texture.texture = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type_string, button_category, normal_file_name])
|
||||||
|
|
||||||
|
# Make sure the frame text gets updated
|
||||||
|
Global.current_frame = Global.current_frame
|
||||||
|
|
||||||
|
Global.preferences_dialog.get_node("Popups/ShortcutSelector").theme = main_theme
|
125
src/Preferences/PreferencesDialog.gd
Normal file
125
src/Preferences/PreferencesDialog.gd
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
extends AcceptDialog
|
||||||
|
|
||||||
|
# Preferences table: [Prop name in Global, relative node path, value type]
|
||||||
|
var preferences = [
|
||||||
|
["open_last_project", "General/OpenLastProject", "pressed"],
|
||||||
|
["smooth_zoom", "General/SmoothZoom", "pressed"],
|
||||||
|
["pressure_sensitivity_mode", "General/PressureSentivity/PressureSensitivityOptionButton", "selected"],
|
||||||
|
["show_left_tool_icon", "General/GridContainer/LeftToolIconCheckbox", "pressed"],
|
||||||
|
["show_right_tool_icon", "General/GridContainer/RightToolIconCheckbox", "pressed"],
|
||||||
|
["left_square_indicator_visible", "General/GridContainer/LeftIndicatorCheckbox", "pressed"],
|
||||||
|
["right_square_indicator_visible", "General/GridContainer/RightIndicatorCheckbox", "pressed"],
|
||||||
|
["autosave_interval", "General/AutosaveInterval/AutosaveInterval", "value"],
|
||||||
|
["enable_autosave", "General/EnableAutosave", "pressed"],
|
||||||
|
|
||||||
|
["default_image_width", "Image/ImageOptions/ImageDefaultWidth", "value"],
|
||||||
|
["default_image_height", "Image/ImageOptions/ImageDefaultHeight", "value"],
|
||||||
|
["default_fill_color", "Image/ImageOptions/DefaultFillColor", "color"],
|
||||||
|
|
||||||
|
["grid_width", "Canvas/GridOptions/GridWidthValue", "value"],
|
||||||
|
["grid_height", "Canvas/GridOptions/GridHeightValue", "value"],
|
||||||
|
["grid_color", "Canvas/GridOptions/GridColor", "color"],
|
||||||
|
["guide_color", "Canvas/GuideOptions/GuideColor", "color"],
|
||||||
|
["checker_size", "Canvas/CheckerOptions/CheckerSizeValue", "value"],
|
||||||
|
["checker_color_1", "Canvas/CheckerOptions/CheckerColor1", "color"],
|
||||||
|
["checker_color_2", "Canvas/CheckerOptions/CheckerColor2", "color"],
|
||||||
|
]
|
||||||
|
|
||||||
|
onready var list : ItemList = $HSplitContainer/List
|
||||||
|
onready var right_side : VBoxContainer = $HSplitContainer/ScrollContainer/VBoxContainer
|
||||||
|
onready var general = $HSplitContainer/ScrollContainer/VBoxContainer/General
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
# Replace OK with Close since preference changes are being applied immediately, not after OK confirmation
|
||||||
|
get_ok().text = tr("Close")
|
||||||
|
|
||||||
|
for pref in preferences:
|
||||||
|
var node = right_side.get_node(pref[1])
|
||||||
|
|
||||||
|
if Global.config_cache.has_section_key("preferences", pref[0]):
|
||||||
|
var value = Global.config_cache.get_value("preferences", pref[0])
|
||||||
|
Global.set(pref[0], value)
|
||||||
|
node.set(pref[2], value)
|
||||||
|
|
||||||
|
match pref[2]:
|
||||||
|
"pressed":
|
||||||
|
node.connect("toggled", self, "_on_Preference_toggled", [pref[0]])
|
||||||
|
"value":
|
||||||
|
node.connect("value_changed", self, "_on_Preference_value_changed", [pref[0]])
|
||||||
|
"color":
|
||||||
|
node.get_picker().presets_visible = false
|
||||||
|
node.connect("color_changed", self, "_on_Preference_color_changed", [pref[0]])
|
||||||
|
"selected":
|
||||||
|
node.connect("item_selected", self, "_on_Preference_item_selected", [pref[0]])
|
||||||
|
|
||||||
|
Global.transparent_checker._ready()
|
||||||
|
|
||||||
|
for canvas in Global.canvases:
|
||||||
|
for guide in canvas.get_children():
|
||||||
|
if guide is Guide:
|
||||||
|
guide.default_color = Global.guide_color
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Preference_toggled(button_pressed : bool, prop : String) -> void:
|
||||||
|
Global.set(prop, button_pressed)
|
||||||
|
Global.config_cache.set_value("preferences", prop, button_pressed)
|
||||||
|
preference_update(prop)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Preference_value_changed(value : float, prop : String) -> void:
|
||||||
|
Global.set(prop, value)
|
||||||
|
Global.config_cache.set_value("preferences", prop, value)
|
||||||
|
preference_update(prop)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Preference_color_changed(color : Color, prop : String) -> void:
|
||||||
|
Global.set(prop, color)
|
||||||
|
Global.config_cache.set_value("preferences", prop, color)
|
||||||
|
preference_update(prop)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_Preference_item_selected(id : int, prop : String) -> void:
|
||||||
|
Global.set(prop, id)
|
||||||
|
Global.config_cache.set_value("preferences", prop, id)
|
||||||
|
preference_update(prop)
|
||||||
|
|
||||||
|
|
||||||
|
func preference_update(prop : String) -> void:
|
||||||
|
if prop in ["autosave_interval", "enable_autosave"]:
|
||||||
|
OpenSave.update_autosave()
|
||||||
|
|
||||||
|
if prop in ["grid_width", "grid_height", "grid_color"]:
|
||||||
|
Global.canvas.update()
|
||||||
|
|
||||||
|
if prop in ["checker_size", "checker_color_1", "checker_color_2"]:
|
||||||
|
Global.transparent_checker._ready()
|
||||||
|
|
||||||
|
if prop in ["guide_color"]:
|
||||||
|
for canvas in Global.canvases:
|
||||||
|
for guide in canvas.get_children():
|
||||||
|
if guide is Guide:
|
||||||
|
guide.default_color = Global.guide_color
|
||||||
|
|
||||||
|
Global.config_cache.save("user://cache.ini")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_PreferencesDialog_about_to_show(changed_language := false) -> void:
|
||||||
|
list.add_item(" " + tr("General"))
|
||||||
|
list.add_item(" " + tr("Language"))
|
||||||
|
list.add_item(" " + tr("Themes"))
|
||||||
|
list.add_item(" " + tr("Canvas"))
|
||||||
|
list.add_item(" " + tr("Image"))
|
||||||
|
list.add_item(" " + tr("Shortcuts"))
|
||||||
|
|
||||||
|
list.select(1 if changed_language else 0)
|
||||||
|
general.get_node("AutosaveInterval/AutosaveInterval").suffix = tr("minute(s)")
|
||||||
|
|
||||||
|
|
||||||
|
func _on_PreferencesDialog_popup_hide() -> void:
|
||||||
|
list.clear()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_List_item_selected(index):
|
||||||
|
for child in right_side.get_children():
|
||||||
|
child.visible = child.name == ["General", "Languages", "Themes", "Canvas", "Image", "Shortcuts"][index]
|
|
@ -1,8 +1,15 @@
|
||||||
[gd_scene load_steps=4 format=2]
|
[gd_scene load_steps=9 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://src/UI/Dialogs/PreferencesDialog.gd" type="Script" id=1]
|
[ext_resource path="res://src/Preferences/PreferencesDialog.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://assets/fonts/Roboto-Regular.tres" type="DynamicFont" id=2]
|
[ext_resource path="res://assets/fonts/Roboto-Regular.tres" type="DynamicFont" id=2]
|
||||||
[ext_resource path="res://assets/fonts/CJK/NotoSansCJKtc-Regular.tres" type="DynamicFont" id=3]
|
[ext_resource path="res://assets/fonts/CJK/NotoSansCJKtc-Regular.tres" type="DynamicFont" id=3]
|
||||||
|
[ext_resource path="res://src/Preferences/HandleLanguages.gd" type="Script" id=4]
|
||||||
|
[ext_resource path="res://src/Preferences/HandleThemes.gd" type="Script" id=5]
|
||||||
|
[ext_resource path="res://src/Preferences/HandleShortcuts.gd" type="Script" id=6]
|
||||||
|
|
||||||
|
[sub_resource type="ButtonGroup" id=1]
|
||||||
|
|
||||||
|
[sub_resource type="ButtonGroup" id=2]
|
||||||
|
|
||||||
[node name="PreferencesDialog" type="AcceptDialog"]
|
[node name="PreferencesDialog" type="AcceptDialog"]
|
||||||
margin_left = -3.0
|
margin_left = -3.0
|
||||||
|
@ -33,12 +40,10 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Tree" type="Tree" parent="HSplitContainer"]
|
[node name="List" type="ItemList" parent="HSplitContainer"]
|
||||||
margin_right = 86.0
|
margin_right = 86.0
|
||||||
margin_bottom = 1110.0
|
margin_bottom = 1110.0
|
||||||
rect_min_size = Vector2( 85, 0 )
|
rect_min_size = Vector2( 85, 0 )
|
||||||
custom_constants/item_margin = -2
|
|
||||||
hide_root = true
|
|
||||||
|
|
||||||
[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer"]
|
[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer"]
|
||||||
margin_left = 98.0
|
margin_left = 98.0
|
||||||
|
@ -49,15 +54,15 @@ size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/ScrollContainer"]
|
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/ScrollContainer"]
|
||||||
margin_right = 506.0
|
margin_right = 506.0
|
||||||
margin_bottom = 1286.0
|
margin_bottom = 180.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="General" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
[node name="General" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 180.0
|
margin_bottom = 180.0
|
||||||
|
|
||||||
[node name="SmoothZoom" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="SmoothZoom" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
hint_tooltip = "Adds a smoother transition when zooming in or out"
|
hint_tooltip = "Adds a smoother transition when zooming in or out"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -66,19 +71,19 @@ text = "Smooth Zoom"
|
||||||
|
|
||||||
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
|
|
||||||
[node name="GridContainer" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="GridContainer" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_top = 36.0
|
margin_top = 36.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 88.0
|
margin_bottom = 88.0
|
||||||
custom_constants/vseparation = 4
|
custom_constants/vseparation = 4
|
||||||
custom_constants/hseparation = 4
|
custom_constants/hseparation = 4
|
||||||
columns = 2
|
columns = 2
|
||||||
|
|
||||||
[node name="LeftIndicatorCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
[node name="LeftIndicatorCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
||||||
margin_right = 245.0
|
margin_right = 251.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
hint_tooltip = "Show left mouse pixel indicator or brush on the canvas when drawing"
|
hint_tooltip = "Show left mouse pixel indicator or brush on the canvas when drawing"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -87,8 +92,8 @@ pressed = true
|
||||||
text = "Left pixel indicator"
|
text = "Left pixel indicator"
|
||||||
|
|
||||||
[node name="RightIndicatorCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
[node name="RightIndicatorCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
||||||
margin_left = 249.0
|
margin_left = 255.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
hint_tooltip = "Show right mouse pixel indicator or brush on the canvas when drawing"
|
hint_tooltip = "Show right mouse pixel indicator or brush on the canvas when drawing"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -97,7 +102,7 @@ text = "Right pixel indicator"
|
||||||
|
|
||||||
[node name="LeftToolIconCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
[node name="LeftToolIconCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 245.0
|
margin_right = 251.0
|
||||||
margin_bottom = 52.0
|
margin_bottom = 52.0
|
||||||
hint_tooltip = "Displays an icon of the selected left tool next to the cursor on the canvas"
|
hint_tooltip = "Displays an icon of the selected left tool next to the cursor on the canvas"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -106,9 +111,9 @@ pressed = true
|
||||||
text = "Show left tool icon"
|
text = "Show left tool icon"
|
||||||
|
|
||||||
[node name="RightToolIconCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
[node name="RightToolIconCheckbox" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer"]
|
||||||
margin_left = 249.0
|
margin_left = 255.0
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 52.0
|
margin_bottom = 52.0
|
||||||
hint_tooltip = "Displays an icon of the selected right tool next to the cursor on the canvas"
|
hint_tooltip = "Displays an icon of the selected right tool next to the cursor on the canvas"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -118,14 +123,14 @@ text = "Show right tool icon"
|
||||||
|
|
||||||
[node name="HSeparator3" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="HSeparator3" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_top = 92.0
|
margin_top = 92.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 96.0
|
margin_bottom = 96.0
|
||||||
|
|
||||||
[node name="PressureSentivity" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="PressureSentivity" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
visible = false
|
visible = false
|
||||||
margin_top = 116.0
|
margin_top = 100.0
|
||||||
margin_right = 334.0
|
margin_right = 506.0
|
||||||
margin_bottom = 136.0
|
margin_bottom = 120.0
|
||||||
|
|
||||||
[node name="PressureSensitivityLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/PressureSentivity"]
|
[node name="PressureSensitivityLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/PressureSentivity"]
|
||||||
margin_top = 3.0
|
margin_top = 3.0
|
||||||
|
@ -143,7 +148,7 @@ selected = 1
|
||||||
|
|
||||||
[node name="OpenLastProject" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="OpenLastProject" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_top = 100.0
|
margin_top = 100.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 124.0
|
margin_bottom = 124.0
|
||||||
hint_tooltip = "Opens last opened project on startup"
|
hint_tooltip = "Opens last opened project on startup"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -151,7 +156,7 @@ text = "Open last project on startup"
|
||||||
|
|
||||||
[node name="EnableAutosave" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="EnableAutosave" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_top = 128.0
|
margin_top = 128.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 152.0
|
margin_bottom = 152.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
pressed = true
|
pressed = true
|
||||||
|
@ -162,7 +167,7 @@ __meta__ = {
|
||||||
|
|
||||||
[node name="AutosaveInterval" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
[node name="AutosaveInterval" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/General"]
|
||||||
margin_top = 156.0
|
margin_top = 156.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 180.0
|
margin_bottom = 180.0
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
|
@ -176,7 +181,7 @@ text = "Autosave interval:"
|
||||||
|
|
||||||
[node name="AutosaveInterval" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/AutosaveInterval"]
|
[node name="AutosaveInterval" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/General/AutosaveInterval"]
|
||||||
margin_left = 119.0
|
margin_left = 119.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
@ -191,171 +196,196 @@ __meta__ = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Languages" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
[node name="Languages" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||||
|
visible = false
|
||||||
margin_top = 184.0
|
margin_top = 184.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 632.0
|
margin_bottom = 632.0
|
||||||
|
script = ExtResource( 4 )
|
||||||
|
|
||||||
[node name="System Language" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="System Language" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
pressed = true
|
pressed = true
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "System Language"
|
text = "System Language"
|
||||||
|
|
||||||
[node name="Czech" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Czech" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 52.0
|
margin_bottom = 52.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Czech [cs]"
|
text = "Czech [cs]"
|
||||||
|
|
||||||
[node name="German" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="German" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 56.0
|
margin_top = 56.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 80.0
|
margin_bottom = 80.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Deutsch [de]"
|
text = "Deutsch [de]"
|
||||||
|
|
||||||
[node name="Greek" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Greek" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 84.0
|
margin_top = 84.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 108.0
|
margin_bottom = 108.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
custom_fonts/font = ExtResource( 2 )
|
custom_fonts/font = ExtResource( 2 )
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Ελληνικά [el]"
|
text = "Ελληνικά [el]"
|
||||||
|
|
||||||
[node name="English" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="English" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 112.0
|
margin_top = 112.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 136.0
|
margin_bottom = 136.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "English [en]"
|
text = "English [en]"
|
||||||
|
|
||||||
[node name="Esperanto" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Esperanto" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 140.0
|
margin_top = 140.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 164.0
|
margin_bottom = 164.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Esperanto [eo]"
|
text = "Esperanto [eo]"
|
||||||
|
|
||||||
[node name="Spanish" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Spanish" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 168.0
|
margin_top = 168.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 192.0
|
margin_bottom = 192.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Español [es]"
|
text = "Español [es]"
|
||||||
|
|
||||||
[node name="French" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="French" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 196.0
|
margin_top = 196.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 220.0
|
margin_bottom = 220.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Français [fr]"
|
text = "Français [fr]"
|
||||||
|
|
||||||
[node name="Indonesian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Indonesian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 224.0
|
margin_top = 224.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 248.0
|
margin_bottom = 248.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Indonesian [id]"
|
text = "Indonesian [id]"
|
||||||
|
|
||||||
[node name="Italian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Italian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 252.0
|
margin_top = 252.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 276.0
|
margin_bottom = 276.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Italiano [it]"
|
text = "Italiano [it]"
|
||||||
|
|
||||||
[node name="Latvian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Latvian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 280.0
|
margin_top = 280.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 304.0
|
margin_bottom = 304.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Latvian [lv]"
|
text = "Latvian [lv]"
|
||||||
|
|
||||||
[node name="Polish" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Polish" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 308.0
|
margin_top = 308.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 332.0
|
margin_bottom = 332.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Polski [pl]"
|
text = "Polski [pl]"
|
||||||
|
|
||||||
[node name="Brazilian Portuguese" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Brazilian Portuguese" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 336.0
|
margin_top = 336.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 360.0
|
margin_bottom = 360.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Português Brasileiro [pt_BR]"
|
text = "Português Brasileiro [pt_BR]"
|
||||||
|
|
||||||
[node name="Russian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Russian" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 364.0
|
margin_top = 364.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 388.0
|
margin_bottom = 388.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "Русский [ru]"
|
text = "Русский [ru]"
|
||||||
|
|
||||||
[node name="Chinese Simplified" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Chinese Simplified" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 392.0
|
margin_top = 392.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 418.0
|
margin_bottom = 418.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
custom_fonts/font = ExtResource( 3 )
|
custom_fonts/font = ExtResource( 3 )
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "简体中文 [zh_CN]"
|
text = "简体中文 [zh_CN]"
|
||||||
|
|
||||||
[node name="Chinese Traditional" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
[node name="Chinese Traditional" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Languages"]
|
||||||
margin_top = 422.0
|
margin_top = 422.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 448.0
|
margin_bottom = 448.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
custom_fonts/font = ExtResource( 3 )
|
custom_fonts/font = ExtResource( 3 )
|
||||||
|
group = SubResource( 1 )
|
||||||
text = "繁體中文 [zh_TW]"
|
text = "繁體中文 [zh_TW]"
|
||||||
|
|
||||||
[node name="Themes" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
[node name="Themes" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||||
margin_top = 636.0
|
visible = false
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 772.0
|
margin_bottom = 136.0
|
||||||
|
script = ExtResource( 5 )
|
||||||
|
|
||||||
[node name="Dark Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
[node name="Dark Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 2 )
|
||||||
text = "Dark"
|
text = "Dark"
|
||||||
|
|
||||||
[node name="Gray Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
[node name="Gray Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 52.0
|
margin_bottom = 52.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 2 )
|
||||||
text = "Gray"
|
text = "Gray"
|
||||||
|
|
||||||
[node name="Blue Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
[node name="Blue Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
||||||
margin_top = 56.0
|
margin_top = 56.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 80.0
|
margin_bottom = 80.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 2 )
|
||||||
text = "Blue"
|
text = "Blue"
|
||||||
|
|
||||||
[node name="Caramel Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
[node name="Caramel Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
||||||
margin_top = 84.0
|
margin_top = 84.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 108.0
|
margin_bottom = 108.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 2 )
|
||||||
text = "Caramel"
|
text = "Caramel"
|
||||||
|
|
||||||
[node name="Light Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
[node name="Light Theme" type="CheckBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Themes"]
|
||||||
margin_top = 112.0
|
margin_top = 112.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 136.0
|
margin_bottom = 136.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
group = SubResource( 2 )
|
||||||
text = "Light"
|
text = "Light"
|
||||||
|
|
||||||
[node name="Canvas" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
[node name="Canvas" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||||
margin_top = 776.0
|
visible = false
|
||||||
margin_right = 494.0
|
margin_top = 184.0
|
||||||
margin_bottom = 968.0
|
margin_right = 506.0
|
||||||
|
margin_bottom = 376.0
|
||||||
|
|
||||||
[node name="GuideOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
[node name="GuideOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
custom_constants/vseparation = 4
|
custom_constants/vseparation = 4
|
||||||
custom_constants/hseparation = 4
|
custom_constants/hseparation = 4
|
||||||
|
@ -372,7 +402,7 @@ text = "Guides color:"
|
||||||
|
|
||||||
[node name="GuideColor" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GuideOptions"]
|
[node name="GuideColor" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GuideOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
rect_min_size = Vector2( 64, 20 )
|
rect_min_size = Vector2( 64, 20 )
|
||||||
hint_tooltip = "A color of ruler guides displayed on the canvas"
|
hint_tooltip = "A color of ruler guides displayed on the canvas"
|
||||||
|
@ -382,12 +412,12 @@ color = Color( 0.63, 0.13, 0.94, 1 )
|
||||||
|
|
||||||
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
||||||
margin_top = 24.0
|
margin_top = 24.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 28.0
|
margin_bottom = 28.0
|
||||||
|
|
||||||
[node name="GridOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
[node name="GridOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
||||||
margin_top = 32.0
|
margin_top = 32.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 108.0
|
margin_bottom = 108.0
|
||||||
custom_constants/vseparation = 4
|
custom_constants/vseparation = 4
|
||||||
custom_constants/hseparation = 4
|
custom_constants/hseparation = 4
|
||||||
|
@ -404,13 +434,14 @@ text = "Grid width:"
|
||||||
|
|
||||||
[node name="GridWidthValue" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions"]
|
[node name="GridWidthValue" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
hint_tooltip = "Sets how far apart are vertical lines of the grid"
|
hint_tooltip = "Sets how far apart are vertical lines of the grid"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
min_value = 1.0
|
min_value = 1.0
|
||||||
max_value = 16384.0
|
max_value = 16384.0
|
||||||
value = 1.0
|
value = 1.0
|
||||||
|
rounded = true
|
||||||
align = 2
|
align = 2
|
||||||
suffix = "px"
|
suffix = "px"
|
||||||
|
|
||||||
|
@ -425,7 +456,7 @@ text = "Grid height:"
|
||||||
[node name="GridHeightValue" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions"]
|
[node name="GridHeightValue" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 52.0
|
margin_bottom = 52.0
|
||||||
hint_tooltip = "Sets how far apart are horizontal lines of the grid"
|
hint_tooltip = "Sets how far apart are horizontal lines of the grid"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -433,6 +464,7 @@ size_flags_horizontal = 3
|
||||||
min_value = 1.0
|
min_value = 1.0
|
||||||
max_value = 16384.0
|
max_value = 16384.0
|
||||||
value = 1.0
|
value = 1.0
|
||||||
|
rounded = true
|
||||||
align = 2
|
align = 2
|
||||||
suffix = "px"
|
suffix = "px"
|
||||||
|
|
||||||
|
@ -447,7 +479,7 @@ text = "Grid color:"
|
||||||
[node name="GridColor" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions"]
|
[node name="GridColor" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_top = 56.0
|
margin_top = 56.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 76.0
|
margin_bottom = 76.0
|
||||||
rect_min_size = Vector2( 64, 20 )
|
rect_min_size = Vector2( 64, 20 )
|
||||||
hint_tooltip = "A color of the grid"
|
hint_tooltip = "A color of the grid"
|
||||||
|
@ -455,12 +487,12 @@ mouse_default_cursor_shape = 2
|
||||||
|
|
||||||
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
||||||
margin_top = 112.0
|
margin_top = 112.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 116.0
|
margin_bottom = 116.0
|
||||||
|
|
||||||
[node name="CheckerOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
[node name="CheckerOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas"]
|
||||||
margin_top = 120.0
|
margin_top = 120.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 192.0
|
margin_bottom = 192.0
|
||||||
custom_constants/vseparation = 4
|
custom_constants/vseparation = 4
|
||||||
custom_constants/hseparation = 4
|
custom_constants/hseparation = 4
|
||||||
|
@ -477,13 +509,15 @@ text = "Checker size:"
|
||||||
|
|
||||||
[node name="CheckerSizeValue" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions"]
|
[node name="CheckerSizeValue" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_right = 188.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
hint_tooltip = "Size of the transparent checker background"
|
hint_tooltip = "Size of the transparent checker background"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
min_value = 1.0
|
min_value = 1.0
|
||||||
max_value = 16384.0
|
max_value = 16384.0
|
||||||
value = 10.0
|
value = 10.0
|
||||||
|
rounded = true
|
||||||
align = 2
|
align = 2
|
||||||
suffix = "px"
|
suffix = "px"
|
||||||
|
|
||||||
|
@ -498,7 +532,7 @@ text = "Checker color 1:"
|
||||||
[node name="CheckerColor1" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions"]
|
[node name="CheckerColor1" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 188.0
|
margin_right = 506.0
|
||||||
margin_bottom = 48.0
|
margin_bottom = 48.0
|
||||||
rect_min_size = Vector2( 64, 20 )
|
rect_min_size = Vector2( 64, 20 )
|
||||||
hint_tooltip = "First color of the transparent checker background"
|
hint_tooltip = "First color of the transparent checker background"
|
||||||
|
@ -516,7 +550,7 @@ text = "Checker color 2:"
|
||||||
[node name="CheckerColor2" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions"]
|
[node name="CheckerColor2" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_top = 52.0
|
margin_top = 52.0
|
||||||
margin_right = 188.0
|
margin_right = 506.0
|
||||||
margin_bottom = 72.0
|
margin_bottom = 72.0
|
||||||
rect_min_size = Vector2( 64, 20 )
|
rect_min_size = Vector2( 64, 20 )
|
||||||
hint_tooltip = "Second color of the transparent checker background"
|
hint_tooltip = "Second color of the transparent checker background"
|
||||||
|
@ -524,12 +558,13 @@ mouse_default_cursor_shape = 2
|
||||||
color = Color( 0.341176, 0.34902, 0.341176, 1 )
|
color = Color( 0.341176, 0.34902, 0.341176, 1 )
|
||||||
|
|
||||||
[node name="Image" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
[node name="Image" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||||
margin_top = 972.0
|
visible = false
|
||||||
margin_right = 494.0
|
margin_top = 184.0
|
||||||
margin_bottom = 1048.0
|
margin_right = 506.0
|
||||||
|
margin_bottom = 260.0
|
||||||
|
|
||||||
[node name="ImageOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image"]
|
[node name="ImageOptions" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 76.0
|
margin_bottom = 76.0
|
||||||
custom_constants/vseparation = 4
|
custom_constants/vseparation = 4
|
||||||
custom_constants/hseparation = 4
|
custom_constants/hseparation = 4
|
||||||
|
@ -546,7 +581,7 @@ text = "Default width:"
|
||||||
|
|
||||||
[node name="ImageDefaultWidth" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions"]
|
[node name="ImageDefaultWidth" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 24.0
|
margin_bottom = 24.0
|
||||||
hint_tooltip = "A default width of a new image"
|
hint_tooltip = "A default width of a new image"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -554,6 +589,7 @@ size_flags_horizontal = 3
|
||||||
min_value = 1.0
|
min_value = 1.0
|
||||||
max_value = 16384.0
|
max_value = 16384.0
|
||||||
value = 64.0
|
value = 64.0
|
||||||
|
rounded = true
|
||||||
align = 2
|
align = 2
|
||||||
suffix = "px"
|
suffix = "px"
|
||||||
|
|
||||||
|
@ -568,13 +604,14 @@ text = "Default height:"
|
||||||
[node name="ImageDefaultHeight" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions"]
|
[node name="ImageDefaultHeight" type="SpinBox" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_top = 28.0
|
margin_top = 28.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 52.0
|
margin_bottom = 52.0
|
||||||
hint_tooltip = "A default height of a new image"
|
hint_tooltip = "A default height of a new image"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
min_value = 1.0
|
min_value = 1.0
|
||||||
max_value = 16384.0
|
max_value = 16384.0
|
||||||
value = 64.0
|
value = 64.0
|
||||||
|
rounded = true
|
||||||
align = 2
|
align = 2
|
||||||
suffix = "px"
|
suffix = "px"
|
||||||
|
|
||||||
|
@ -589,7 +626,7 @@ text = "Default fill color:"
|
||||||
[node name="DefaultFillColor" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions"]
|
[node name="DefaultFillColor" type="ColorPickerButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions"]
|
||||||
margin_left = 114.0
|
margin_left = 114.0
|
||||||
margin_top = 56.0
|
margin_top = 56.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 76.0
|
margin_bottom = 76.0
|
||||||
rect_min_size = Vector2( 64, 20 )
|
rect_min_size = Vector2( 64, 20 )
|
||||||
hint_tooltip = "A default background color of a new image"
|
hint_tooltip = "A default background color of a new image"
|
||||||
|
@ -597,12 +634,14 @@ mouse_default_cursor_shape = 2
|
||||||
color = Color( 0, 0, 0, 0 )
|
color = Color( 0, 0, 0, 0 )
|
||||||
|
|
||||||
[node name="Shortcuts" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
[node name="Shortcuts" type="VBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer"]
|
||||||
margin_top = 1052.0
|
visible = false
|
||||||
margin_right = 494.0
|
margin_top = 184.0
|
||||||
margin_bottom = 1286.0
|
margin_right = 506.0
|
||||||
|
margin_bottom = 418.0
|
||||||
|
script = ExtResource( 6 )
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
[node name="HBoxContainer" type="HBoxContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
hint_tooltip = "Only custom preset can be modified"
|
hint_tooltip = "Only custom preset can be modified"
|
||||||
|
|
||||||
|
@ -614,7 +653,7 @@ text = "Preset:"
|
||||||
|
|
||||||
[node name="PresetOptionButton" type="OptionButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/HBoxContainer"]
|
[node name="PresetOptionButton" type="OptionButton" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/HBoxContainer"]
|
||||||
margin_left = 49.0
|
margin_left = 49.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
hint_tooltip = "Only custom preset can be modified"
|
hint_tooltip = "Only custom preset can be modified"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
@ -625,12 +664,12 @@ selected = 0
|
||||||
|
|
||||||
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
||||||
margin_top = 24.0
|
margin_top = 24.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 28.0
|
margin_bottom = 28.0
|
||||||
|
|
||||||
[node name="Shortcuts" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
[node name="Shortcuts" type="GridContainer" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts"]
|
||||||
margin_top = 32.0
|
margin_top = 32.0
|
||||||
margin_right = 494.0
|
margin_right = 506.0
|
||||||
margin_bottom = 234.0
|
margin_bottom = 234.0
|
||||||
custom_constants/vseparation = 2
|
custom_constants/vseparation = 2
|
||||||
custom_constants/hseparation = 5
|
custom_constants/hseparation = 5
|
||||||
|
@ -642,7 +681,7 @@ margin_bottom = 14.0
|
||||||
|
|
||||||
[node name="LeftToolLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="LeftToolLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 14.0
|
margin_bottom = 14.0
|
||||||
hint_tooltip = "A tool assigned to the left mouse button"
|
hint_tooltip = "A tool assigned to the left mouse button"
|
||||||
mouse_filter = 0
|
mouse_filter = 0
|
||||||
|
@ -650,8 +689,8 @@ text = "Left Tool:"
|
||||||
align = 1
|
align = 1
|
||||||
|
|
||||||
[node name="RightToolLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="RightToolLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 14.0
|
margin_bottom = 14.0
|
||||||
hint_tooltip = "A tool assigned to the right mouse button"
|
hint_tooltip = "A tool assigned to the right mouse button"
|
||||||
mouse_filter = 0
|
mouse_filter = 0
|
||||||
|
@ -665,20 +704,21 @@ margin_bottom = 20.0
|
||||||
|
|
||||||
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
visible = false
|
visible = false
|
||||||
margin_top = 18.0
|
margin_left = 184.0
|
||||||
margin_right = 137.0
|
margin_top = 16.0
|
||||||
margin_bottom = 22.0
|
margin_right = 321.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
|
||||||
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="HSeparator2" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 16.0
|
margin_top = 16.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
|
|
||||||
[node name="HSeparator3" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="HSeparator3" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 16.0
|
margin_top = 16.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 20.0
|
margin_bottom = 20.0
|
||||||
|
|
||||||
[node name="RectSelectLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="RectSelectLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -690,14 +730,14 @@ text = "Rectangular Selection"
|
||||||
[node name="left_rectangle_select_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_rectangle_select_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 22.0
|
margin_top = 22.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 42.0
|
margin_bottom = 42.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="right_rectangle_select_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_rectangle_select_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 22.0
|
margin_top = 22.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 42.0
|
margin_bottom = 42.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
@ -710,14 +750,14 @@ text = "Zoom"
|
||||||
[node name="left_zoom_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_zoom_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 44.0
|
margin_top = 44.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 64.0
|
margin_bottom = 64.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="right_zoom_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_zoom_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 44.0
|
margin_top = 44.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 64.0
|
margin_bottom = 64.0
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
@ -730,13 +770,13 @@ text = "Color Picker"
|
||||||
[node name="left_colorpicker_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_colorpicker_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 66.0
|
margin_top = 66.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 86.0
|
margin_bottom = 86.0
|
||||||
|
|
||||||
[node name="right_colorpicker_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_colorpicker_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 66.0
|
margin_top = 66.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 86.0
|
margin_bottom = 86.0
|
||||||
|
|
||||||
[node name="PencilLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="PencilLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -748,13 +788,13 @@ text = "Pencil"
|
||||||
[node name="left_pencil_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_pencil_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 88.0
|
margin_top = 88.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 108.0
|
margin_bottom = 108.0
|
||||||
|
|
||||||
[node name="right_pencil_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_pencil_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 88.0
|
margin_top = 88.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 108.0
|
margin_bottom = 108.0
|
||||||
|
|
||||||
[node name="EraserLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="EraserLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -766,13 +806,13 @@ text = "Eraser"
|
||||||
[node name="left_eraser_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_eraser_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 110.0
|
margin_top = 110.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 130.0
|
margin_bottom = 130.0
|
||||||
|
|
||||||
[node name="right_eraser_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_eraser_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 110.0
|
margin_top = 110.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 130.0
|
margin_bottom = 130.0
|
||||||
|
|
||||||
[node name="BucketLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="BucketLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -784,13 +824,13 @@ text = "Bucket"
|
||||||
[node name="left_fill_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_fill_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 132.0
|
margin_top = 132.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 152.0
|
margin_bottom = 152.0
|
||||||
|
|
||||||
[node name="right_fill_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_fill_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 132.0
|
margin_top = 132.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 152.0
|
margin_bottom = 152.0
|
||||||
|
|
||||||
[node name="LightenDarkenLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="LightenDarkenLabel" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -802,13 +842,13 @@ text = "Lighten/Darken"
|
||||||
[node name="left_lightdark_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="left_lightdark_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 154.0
|
margin_top = 154.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 174.0
|
margin_bottom = 174.0
|
||||||
|
|
||||||
[node name="right_lightdark_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="right_lightdark_tool" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 154.0
|
margin_top = 154.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 174.0
|
margin_bottom = 174.0
|
||||||
|
|
||||||
[node name="HSeparator4" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="HSeparator4" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -819,13 +859,13 @@ margin_bottom = 180.0
|
||||||
[node name="HSeparator5" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="HSeparator5" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 176.0
|
margin_top = 176.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 180.0
|
margin_bottom = 180.0
|
||||||
|
|
||||||
[node name="HSeparator6" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="HSeparator6" type="HSeparator" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 320.0
|
margin_left = 326.0
|
||||||
margin_top = 176.0
|
margin_top = 176.0
|
||||||
margin_right = 493.0
|
margin_right = 505.0
|
||||||
margin_bottom = 180.0
|
margin_bottom = 180.0
|
||||||
|
|
||||||
[node name="Switch Colors" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="Switch Colors" type="Label" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
|
@ -837,7 +877,7 @@ text = "Switch Colors"
|
||||||
[node name="switch_colors" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
[node name="switch_colors" type="Button" parent="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/Shortcuts"]
|
||||||
margin_left = 142.0
|
margin_left = 142.0
|
||||||
margin_top = 182.0
|
margin_top = 182.0
|
||||||
margin_right = 315.0
|
margin_right = 321.0
|
||||||
margin_bottom = 202.0
|
margin_bottom = 202.0
|
||||||
|
|
||||||
[node name="Popups" type="Node" parent="."]
|
[node name="Popups" type="Node" parent="."]
|
||||||
|
@ -865,26 +905,7 @@ __meta__ = {
|
||||||
}
|
}
|
||||||
[connection signal="about_to_show" from="." to="." method="_on_PreferencesDialog_about_to_show"]
|
[connection signal="about_to_show" from="." to="." method="_on_PreferencesDialog_about_to_show"]
|
||||||
[connection signal="popup_hide" from="." to="." method="_on_PreferencesDialog_popup_hide"]
|
[connection signal="popup_hide" from="." to="." method="_on_PreferencesDialog_popup_hide"]
|
||||||
[connection signal="item_selected" from="HSplitContainer/Tree" to="." method="_on_Tree_item_selected"]
|
[connection signal="item_selected" from="HSplitContainer/List" to="." method="_on_List_item_selected"]
|
||||||
[connection signal="pressed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/SmoothZoom" to="." method="_on_SmoothZoom_pressed"]
|
[connection signal="item_selected" from="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/HBoxContainer/PresetOptionButton" to="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts" method="_on_PresetOptionButton_item_selected"]
|
||||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/LeftIndicatorCheckbox" to="." method="_on_LeftIndicatorCheckbox_toggled"]
|
[connection signal="confirmed" from="Popups/ShortcutSelector" to="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts" method="_on_ShortcutSelector_confirmed"]
|
||||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/RightIndicatorCheckbox" to="." method="_on_RightIndicatorCheckbox_toggled"]
|
[connection signal="popup_hide" from="Popups/ShortcutSelector" to="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts" method="_on_ShortcutSelector_popup_hide"]
|
||||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/LeftToolIconCheckbox" to="." method="_on_LeftToolIconCheckbox_toggled"]
|
|
||||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/RightToolIconCheckbox" to="." method="_on_RightToolIconCheckbox_toggled"]
|
|
||||||
[connection signal="item_selected" from="HSplitContainer/ScrollContainer/VBoxContainer/General/PressureSentivity/PressureSensitivityOptionButton" to="." method="_on_PressureSensitivityOptionButton_item_selected"]
|
|
||||||
[connection signal="pressed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/OpenLastProject" to="." method="_on_OpenLastProject_pressed"]
|
|
||||||
[connection signal="toggled" from="HSplitContainer/ScrollContainer/VBoxContainer/General/EnableAutosave" to="." method="_on_EnableAutosave_toggled"]
|
|
||||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/General/AutosaveInterval/AutosaveInterval" to="." method="_on_AutosaveInterval_value_changed"]
|
|
||||||
[connection signal="color_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GuideOptions/GuideColor" to="." method="_on_GuideColor_color_changed"]
|
|
||||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridWidthValue" to="." method="_on_GridWidthValue_value_changed"]
|
|
||||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridHeightValue" to="." method="_on_GridHeightValue_value_changed"]
|
|
||||||
[connection signal="color_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridColor" to="." method="_on_GridColor_color_changed"]
|
|
||||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions/CheckerSizeValue" to="." method="_on_CheckerSize_value_changed"]
|
|
||||||
[connection signal="color_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions/CheckerColor1" to="." method="_on_CheckerColor1_color_changed"]
|
|
||||||
[connection signal="color_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions/CheckerColor2" to="." method="_on_CheckerColor2_color_changed"]
|
|
||||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions/ImageDefaultWidth" to="." method="_on_ImageDefaultWidth_value_changed"]
|
|
||||||
[connection signal="value_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions/ImageDefaultHeight" to="." method="_on_ImageDefaultHeight_value_changed"]
|
|
||||||
[connection signal="color_changed" from="HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions/DefaultFillColor" to="." method="_on_DefaultBackground_color_changed"]
|
|
||||||
[connection signal="item_selected" from="HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts/HBoxContainer/PresetOptionButton" to="." method="_on_PresetOptionButton_item_selected"]
|
|
||||||
[connection signal="confirmed" from="Popups/ShortcutSelector" to="." method="_on_ShortcutSelector_confirmed"]
|
|
||||||
[connection signal="popup_hide" from="Popups/ShortcutSelector" to="." method="_on_ShortcutSelector_popup_hide"]
|
|
|
@ -20,24 +20,24 @@ func _ready() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta : float) -> void:
|
func _process(_delta : float) -> void:
|
||||||
if Global.layers[Global.current_layer][2]:
|
if Global.layers[Global.current_layer].locked:
|
||||||
return
|
return
|
||||||
var mouse_pos: Vector2 = get_local_mouse_position() - Global.canvas.location
|
var mouse_pos: Vector2 = get_local_mouse_position() - Global.canvas.location
|
||||||
var mouse_pos_floored := mouse_pos.floor()
|
var mouse_pos_floored := mouse_pos.floor()
|
||||||
var start_pos := polygon[0]
|
var start_pos := polygon[0]
|
||||||
var end_pos := polygon[2]
|
var end_pos := polygon[2]
|
||||||
var current_layer_index : int = Global.current_layer
|
var current_layer_index : int = Global.current_layer
|
||||||
var layer : Image = Global.canvas.layers[current_layer_index][0]
|
var layer : Image = Global.canvas.layers[current_layer_index].image
|
||||||
|
|
||||||
if end_pos == start_pos:
|
if end_pos == start_pos:
|
||||||
visible = false
|
visible = false
|
||||||
else:
|
else:
|
||||||
visible = true
|
visible = true
|
||||||
|
|
||||||
if Global.can_draw and Global.has_focus and point_in_rectangle(mouse_pos, polygon[0], polygon[2]) and Global.selected_pixels.size() > 0 and (Global.current_left_tool == "RectSelect" or Global.current_right_tool == "RectSelect"):
|
if Global.can_draw and Global.has_focus and point_in_rectangle(mouse_pos, polygon[0], polygon[2]) and Global.selected_pixels.size() > 0 and (Global.current_tools[0] == Global.Tools.RECTSELECT or Global.current_tools[1] == Global.Tools.RECTSELECT):
|
||||||
get_parent().get_parent().mouse_default_cursor_shape = Input.CURSOR_MOVE
|
get_parent().get_parent().mouse_default_cursor_shape = Input.CURSOR_MOVE
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
if (Global.current_left_tool == "RectSelect" && Input.is_action_just_pressed("left_mouse")) || (Global.current_right_tool == "RectSelect" && Input.is_action_just_pressed("right_mouse")):
|
if (Global.current_tools[0] == Global.Tools.RECTSELECT && Input.is_action_just_pressed("left_mouse")) || (Global.current_tools[1] == Global.Tools.RECTSELECT && Input.is_action_just_pressed("right_mouse")):
|
||||||
# Begin dragging
|
# Begin dragging
|
||||||
is_dragging = true
|
is_dragging = true
|
||||||
if Input.is_key_pressed(KEY_SHIFT):
|
if Input.is_key_pressed(KEY_SHIFT):
|
||||||
|
@ -72,7 +72,7 @@ func _process(_delta : float) -> void:
|
||||||
get_parent().get_parent().mouse_default_cursor_shape = Input.CURSOR_ARROW
|
get_parent().get_parent().mouse_default_cursor_shape = Input.CURSOR_ARROW
|
||||||
|
|
||||||
if is_dragging:
|
if is_dragging:
|
||||||
if (Global.current_left_tool == "RectSelect" && Input.is_action_pressed("left_mouse")) || (Global.current_right_tool == "RectSelect" && Input.is_action_pressed("right_mouse")):
|
if (Global.current_tools[0] == Global.Tools.RECTSELECT && Input.is_action_pressed("left_mouse")) || (Global.current_tools[1] == Global.Tools.RECTSELECT && Input.is_action_pressed("right_mouse")):
|
||||||
# Drag
|
# Drag
|
||||||
start_pos.x = orig_x + mouse_pos_floored.x
|
start_pos.x = orig_x + mouse_pos_floored.x
|
||||||
end_pos.x = diff_x + mouse_pos_floored.x
|
end_pos.x = diff_x + mouse_pos_floored.x
|
||||||
|
@ -84,7 +84,7 @@ func _process(_delta : float) -> void:
|
||||||
polygon[2] = end_pos
|
polygon[2] = end_pos
|
||||||
polygon[3] = Vector2(start_pos.x, end_pos.y)
|
polygon[3] = Vector2(start_pos.x, end_pos.y)
|
||||||
|
|
||||||
if (Global.current_left_tool == "RectSelect" && Input.is_action_just_released("left_mouse")) || (Global.current_right_tool == "RectSelect" && Input.is_action_just_released("right_mouse")):
|
if (Global.current_tools[0] == Global.Tools.RECTSELECT && Input.is_action_just_released("left_mouse")) || (Global.current_tools[1] == Global.Tools.RECTSELECT && Input.is_action_just_released("right_mouse")):
|
||||||
# Release Drag
|
# Release Drag
|
||||||
is_dragging = false
|
is_dragging = false
|
||||||
if move_pixels:
|
if move_pixels:
|
||||||
|
|
|
@ -12,76 +12,52 @@ func _on_BrushButton_pressed() -> void:
|
||||||
_on_DeleteButton_pressed()
|
_on_DeleteButton_pressed()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Change left brush
|
# Change brush
|
||||||
if Global.brush_type_window_position == "left":
|
Global.current_brush_types[Global.brush_type_window_position] = brush_type
|
||||||
Global.current_left_brush_type = brush_type
|
Global.custom_brush_indexes[Global.brush_type_window_position] = custom_brush_index
|
||||||
Global.custom_left_brush_index = custom_brush_index
|
if custom_brush_index > -1: # Custom brush
|
||||||
if custom_brush_index > -1: # Custom brush
|
if Global.current_tools[Global.brush_type_window_position] == Global.Tools.PENCIL:
|
||||||
if Global.current_left_tool == "Pencil":
|
Global.color_interpolation_containers[Global.brush_type_window_position].visible = true
|
||||||
Global.left_color_interpolation_container.visible = true
|
|
||||||
# if hint_tooltip == "":
|
# if hint_tooltip == "":
|
||||||
# Global.left_brush_type_label.text = tr("Custom brush")
|
# Global.left_brush_type_label.text = tr("Custom brush")
|
||||||
# else:
|
# else:
|
||||||
# Global.left_brush_type_label.text = tr("Brush:") + " %s" % hint_tooltip
|
# Global.left_brush_type_label.text = tr("Brush:") + " %s" % hint_tooltip
|
||||||
elif custom_brush_index == -3: # Pixel brush
|
elif custom_brush_index == -3: # Pixel brush
|
||||||
Global.left_color_interpolation_container.visible = false
|
Global.color_interpolation_containers[Global.brush_type_window_position].visible = false
|
||||||
# Global.left_brush_type_label.text = tr("Brush: Pixel")
|
# Global.left_brush_type_label.text = tr("Brush: Pixel")
|
||||||
elif custom_brush_index == -2: # Circle brush
|
elif custom_brush_index == -2: # Circle brush
|
||||||
Global.left_color_interpolation_container.visible = false
|
Global.color_interpolation_containers[Global.brush_type_window_position].visible = false
|
||||||
# Global.left_brush_type_label.text = tr("Brush: Circle")
|
# Global.left_brush_type_label.text = tr("Brush: Circle")
|
||||||
elif custom_brush_index == -1: # Filled Circle brush
|
elif custom_brush_index == -1: # Filled Circle brush
|
||||||
Global.left_color_interpolation_container.visible = false
|
Global.color_interpolation_containers[Global.brush_type_window_position].visible = false
|
||||||
# Global.left_brush_type_label.text = tr("Brush: Filled Circle")
|
# Global.left_brush_type_label.text = tr("Brush: Filled Circle")
|
||||||
|
|
||||||
Global.update_left_custom_brush()
|
Global.update_custom_brush(Global.brush_type_window_position)
|
||||||
Global.brushes_popup.hide()
|
Global.brushes_popup.hide()
|
||||||
|
|
||||||
else: # Change right brush
|
|
||||||
Global.current_right_brush_type = brush_type
|
|
||||||
Global.custom_right_brush_index = custom_brush_index
|
|
||||||
if custom_brush_index > -1:
|
|
||||||
if Global.current_right_tool == "Pencil":
|
|
||||||
Global.right_color_interpolation_container.visible = true
|
|
||||||
# if hint_tooltip == "":
|
|
||||||
# Global.right_brush_type_label.text = tr("Custom brush")
|
|
||||||
# else:
|
|
||||||
# Global.right_brush_type_label.text = tr("Brush:") + " %s" % hint_tooltip
|
|
||||||
elif custom_brush_index == -3: # Pixel brush
|
|
||||||
Global.right_color_interpolation_container.visible = false
|
|
||||||
# Global.right_brush_type_label.text = tr("Brush: Pixel")
|
|
||||||
elif custom_brush_index == -2: # Circle brush
|
|
||||||
Global.right_color_interpolation_container.visible = false
|
|
||||||
# Global.right_brush_type_label.text = tr("Brush: Circle")
|
|
||||||
elif custom_brush_index == -1: # Filled Circle brush
|
|
||||||
Global.right_color_interpolation_container.visible = false
|
|
||||||
# Global.right_brush_type_label.text = tr("Brush: Filled Circle")
|
|
||||||
|
|
||||||
Global.update_right_custom_brush()
|
|
||||||
Global.brushes_popup.hide()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_DeleteButton_pressed() -> void:
|
func _on_DeleteButton_pressed() -> void:
|
||||||
if brush_type == Global.Brush_Types.CUSTOM:
|
if brush_type == Global.Brush_Types.CUSTOM:
|
||||||
if Global.custom_left_brush_index == custom_brush_index:
|
if Global.custom_brush_indexes[0] == custom_brush_index:
|
||||||
Global.custom_left_brush_index = -3
|
Global.custom_brush_indexes[0] = -3
|
||||||
Global.current_left_brush_type = Global.Brush_Types.PIXEL
|
Global.current_brush_types[0] = Global.Brush_Types.PIXEL
|
||||||
# Global.left_brush_type_label.text = "Brush: Pixel"
|
# Global.left_brush_type_label.text = "Brush: Pixel"
|
||||||
Global.update_left_custom_brush()
|
Global.update_custom_brush(0)
|
||||||
if Global.custom_right_brush_index == custom_brush_index:
|
if Global.custom_brush_indexes[1] == custom_brush_index:
|
||||||
Global.custom_right_brush_index = -3
|
Global.custom_brush_indexes[1] = -3
|
||||||
Global.current_right_brush_type = Global.Brush_Types.PIXEL
|
Global.current_brush_types[1] = Global.Brush_Types.PIXEL
|
||||||
# Global.right_brush_type_label.text = "Brush: Pixel"
|
# Global.right_brush_type_label.text = "Brush: Pixel"
|
||||||
Global.update_right_custom_brush()
|
Global.update_custom_brush(1)
|
||||||
|
|
||||||
var project_brush_index = custom_brush_index - Global.brushes_from_files
|
var project_brush_index = custom_brush_index - Global.brushes_from_files
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
Global.undo_redo.create_action("Delete Custom Brush")
|
Global.undo_redo.create_action("Delete Custom Brush")
|
||||||
for i in range(project_brush_index, Global.project_brush_container.get_child_count()):
|
for i in range(project_brush_index, Global.project_brush_container.get_child_count()):
|
||||||
var bb = Global.project_brush_container.get_child(i)
|
var bb = Global.project_brush_container.get_child(i)
|
||||||
if Global.custom_left_brush_index == bb.custom_brush_index:
|
if Global.custom_brush_indexes[0] == bb.custom_brush_index:
|
||||||
Global.custom_left_brush_index -= 1
|
Global.custom_brush_indexes[0] -= 1
|
||||||
if Global.custom_right_brush_index == bb.custom_brush_index:
|
if Global.custom_brush_indexes[1] == bb.custom_brush_index:
|
||||||
Global.custom_right_brush_index -= 1
|
Global.custom_brush_indexes[1] -= 1
|
||||||
|
|
||||||
Global.undo_redo.add_do_property(bb, "custom_brush_index", bb.custom_brush_index - 1)
|
Global.undo_redo.add_do_property(bb, "custom_brush_index", bb.custom_brush_index - 1)
|
||||||
Global.undo_redo.add_undo_property(bb, "custom_brush_index", bb.custom_brush_index)
|
Global.undo_redo.add_undo_property(bb, "custom_brush_index", bb.custom_brush_index)
|
||||||
|
|
|
@ -1,7 +1,37 @@
|
||||||
[gd_scene load_steps=2 format=2]
|
[gd_scene load_steps=6 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://src/UI/BrushButton.tscn" type="PackedScene" id=2]
|
[ext_resource path="res://src/UI/BrushButton.tscn" type="PackedScene" id=2]
|
||||||
|
|
||||||
|
[sub_resource type="Image" id=5]
|
||||||
|
data = {
|
||||||
|
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0 ),
|
||||||
|
"format": "LumAlpha8",
|
||||||
|
"height": 9,
|
||||||
|
"mipmaps": false,
|
||||||
|
"width": 9
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="ImageTexture" id=2]
|
||||||
|
flags = 3
|
||||||
|
flags = 3
|
||||||
|
image = SubResource( 5 )
|
||||||
|
size = Vector2( 9, 9 )
|
||||||
|
|
||||||
|
[sub_resource type="Image" id=6]
|
||||||
|
data = {
|
||||||
|
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 0, 0, 0 ),
|
||||||
|
"format": "LumAlpha8",
|
||||||
|
"height": 9,
|
||||||
|
"mipmaps": false,
|
||||||
|
"width": 9
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="ImageTexture" id=4]
|
||||||
|
flags = 3
|
||||||
|
flags = 3
|
||||||
|
image = SubResource( 6 )
|
||||||
|
size = Vector2( 9, 9 )
|
||||||
|
|
||||||
[node name="BrushesPopup" type="Popup"]
|
[node name="BrushesPopup" type="Popup"]
|
||||||
margin_right = 226.0
|
margin_right = 226.0
|
||||||
margin_bottom = 144.0
|
margin_bottom = 144.0
|
||||||
|
@ -34,21 +64,27 @@ hint_tooltip = "Pixel brush"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
|
|
||||||
[node name="CircleBrushButton" parent="TabContainer/File/FileBrushContainer" instance=ExtResource( 2 )]
|
[node name="CircleBrushButton" parent="TabContainer/File/FileBrushContainer" instance=ExtResource( 2 )]
|
||||||
margin_left = 35.0
|
margin_left = 36.0
|
||||||
margin_right = 67.0
|
margin_right = 68.0
|
||||||
hint_tooltip = "Filled circle brush"
|
hint_tooltip = "Filled circle brush"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
brush_type = 1
|
brush_type = 1
|
||||||
custom_brush_index = -2
|
custom_brush_index = -2
|
||||||
|
|
||||||
|
[node name="BrushTexture" parent="TabContainer/File/FileBrushContainer/CircleBrushButton" index="0"]
|
||||||
|
texture = SubResource( 2 )
|
||||||
|
|
||||||
[node name="FilledCircleBrushButton" parent="TabContainer/File/FileBrushContainer" instance=ExtResource( 2 )]
|
[node name="FilledCircleBrushButton" parent="TabContainer/File/FileBrushContainer" instance=ExtResource( 2 )]
|
||||||
margin_left = 70.0
|
margin_left = 72.0
|
||||||
margin_right = 102.0
|
margin_right = 104.0
|
||||||
hint_tooltip = "Circle brush"
|
hint_tooltip = "Circle brush"
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
brush_type = 2
|
brush_type = 2
|
||||||
custom_brush_index = -1
|
custom_brush_index = -1
|
||||||
|
|
||||||
|
[node name="BrushTexture" parent="TabContainer/File/FileBrushContainer/FilledCircleBrushButton" index="0"]
|
||||||
|
texture = SubResource( 4 )
|
||||||
|
|
||||||
[node name="Project" type="ScrollContainer" parent="TabContainer"]
|
[node name="Project" type="ScrollContainer" parent="TabContainer"]
|
||||||
visible = false
|
visible = false
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
|
@ -63,3 +99,7 @@ scroll_horizontal_enabled = false
|
||||||
|
|
||||||
[node name="ProjectBrushContainer" type="GridContainer" parent="TabContainer/Project"]
|
[node name="ProjectBrushContainer" type="GridContainer" parent="TabContainer/Project"]
|
||||||
columns = 5
|
columns = 5
|
||||||
|
|
||||||
|
[editable path="TabContainer/File/FileBrushContainer/CircleBrushButton"]
|
||||||
|
|
||||||
|
[editable path="TabContainer/File/FileBrushContainer/FilledCircleBrushButton"]
|
||||||
|
|
|
@ -1,32 +1,25 @@
|
||||||
extends VBoxContainer
|
extends VBoxContainer
|
||||||
|
|
||||||
|
|
||||||
var previous_left_color := Color.black
|
var previous_colors := [Color.black, Color.white]
|
||||||
var previous_right_color := Color.white
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ColorSwitch_pressed() -> void:
|
func _on_ColorSwitch_pressed() -> void:
|
||||||
var temp: Color = Global.left_color_picker.color
|
var temp : Color = Global.color_pickers[0].color
|
||||||
Global.left_color_picker.color = Global.right_color_picker.color
|
Global.color_pickers[0].color = Global.color_pickers[1].color
|
||||||
Global.right_color_picker.color = temp
|
Global.color_pickers[1].color = temp
|
||||||
Global.update_left_custom_brush()
|
Global.update_custom_brush(0)
|
||||||
Global.update_right_custom_brush()
|
Global.update_custom_brush(1)
|
||||||
|
|
||||||
|
|
||||||
func _on_ColorPickerButton_color_changed(color : Color, right : bool):
|
func _on_ColorPickerButton_color_changed(color : Color, right : bool):
|
||||||
|
var mouse_button := int(right)
|
||||||
# If the color changed while it's on full transparency, make it opaque (GH issue #54)
|
# If the color changed while it's on full transparency, make it opaque (GH issue #54)
|
||||||
if right:
|
if color.a == 0:
|
||||||
if color.a == 0:
|
if previous_colors[mouse_button].r != color.r or previous_colors[mouse_button].g != color.g or previous_colors[mouse_button].b != color.b:
|
||||||
if previous_right_color.r != color.r or previous_right_color.g != color.g or previous_right_color.b != color.b:
|
Global.color_pickers[mouse_button].color.a = 1
|
||||||
Global.right_color_picker.color.a = 1
|
Global.update_custom_brush(mouse_button)
|
||||||
Global.update_right_custom_brush()
|
previous_colors[mouse_button] = color
|
||||||
previous_right_color = color
|
|
||||||
else:
|
|
||||||
if color.a == 0:
|
|
||||||
if previous_left_color.r != color.r or previous_left_color.g != color.g or previous_left_color.b != color.b:
|
|
||||||
Global.left_color_picker.color.a = 1
|
|
||||||
Global.update_left_custom_brush()
|
|
||||||
previous_left_color = color
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ColorPickerButton_pressed() -> void:
|
func _on_ColorPickerButton_pressed() -> void:
|
||||||
|
@ -38,10 +31,10 @@ func _on_ColorPickerButton_popup_closed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_ColorDefaults_pressed() -> void:
|
func _on_ColorDefaults_pressed() -> void:
|
||||||
Global.left_color_picker.color = Color.black
|
Global.color_pickers[0].color = Color.black
|
||||||
Global.right_color_picker.color = Color.white
|
Global.color_pickers[1].color = Color.white
|
||||||
Global.update_left_custom_brush()
|
Global.update_custom_brush(0)
|
||||||
Global.update_right_custom_brush()
|
Global.update_custom_brush(1)
|
||||||
|
|
||||||
|
|
||||||
func _on_FitToFrameButton_pressed() -> void:
|
func _on_FitToFrameButton_pressed() -> void:
|
||||||
|
@ -57,132 +50,89 @@ func _on_100ZoomButton_pressed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_BrushTypeButton_pressed(right : bool) -> void:
|
func _on_BrushTypeButton_pressed(right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.brushes_popup.popup(Rect2(Global.right_brush_type_button.rect_global_position, Vector2(226, 72)))
|
Global.brushes_popup.popup(Rect2(Global.brush_type_buttons[mouse_button].rect_global_position, Vector2(226, 72)))
|
||||||
Global.brush_type_window_position = "right"
|
Global.brush_type_window_position = mouse_button
|
||||||
else:
|
|
||||||
Global.brushes_popup.popup(Rect2(Global.left_brush_type_button.rect_global_position, Vector2(226, 72)))
|
|
||||||
Global.brush_type_window_position = "left"
|
|
||||||
|
|
||||||
|
|
||||||
func _on_BrushSizeEdit_value_changed(value : float, right : bool) -> void:
|
func _on_BrushSizeEdit_value_changed(value : float, right : bool) -> void:
|
||||||
|
var mouse_button := int(right)
|
||||||
var new_size = int(value)
|
var new_size = int(value)
|
||||||
if right:
|
Global.brush_size_edits[mouse_button].value = value
|
||||||
Global.right_brush_size_edit.value = value
|
Global.brush_size_sliders[mouse_button].value = value
|
||||||
Global.right_brush_size_slider.value = value
|
Global.brush_sizes[mouse_button] = new_size
|
||||||
Global.right_brush_size = new_size
|
Global.update_custom_brush(mouse_button)
|
||||||
Global.update_right_custom_brush()
|
|
||||||
else:
|
|
||||||
Global.left_brush_size_edit.value = value
|
|
||||||
Global.left_brush_size_slider.value = value
|
|
||||||
Global.left_brush_size = new_size
|
|
||||||
Global.update_left_custom_brush()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PixelPerfectMode_toggled(button_pressed : bool, right : bool) -> void:
|
func _on_PixelPerfectMode_toggled(button_pressed : bool, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_pixel_perfect = button_pressed
|
Global.pixel_perfect[mouse_button] = button_pressed
|
||||||
else:
|
|
||||||
Global.left_pixel_perfect = button_pressed
|
|
||||||
|
|
||||||
|
|
||||||
func _on_InterpolateFactor_value_changed(value : float, right : bool) -> void:
|
func _on_InterpolateFactor_value_changed(value : float, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_interpolate_spinbox.value = value
|
Global.interpolate_spinboxes[mouse_button].value = value
|
||||||
Global.right_interpolate_slider.value = value
|
Global.interpolate_sliders[mouse_button].value = value
|
||||||
Global.update_right_custom_brush()
|
Global.update_custom_brush(mouse_button)
|
||||||
else:
|
|
||||||
Global.left_interpolate_spinbox.value = value
|
|
||||||
Global.left_interpolate_slider.value = value
|
|
||||||
Global.update_left_custom_brush()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_FillAreaOptions_item_selected(ID : int, right : bool) -> void:
|
func _on_FillAreaOptions_item_selected(ID : int, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_fill_area = ID
|
Global.fill_areas[mouse_button] = ID
|
||||||
else:
|
|
||||||
Global.left_fill_area = ID
|
|
||||||
|
|
||||||
|
|
||||||
func _on_FillWithOptions_item_selected(ID : int, right : bool) -> void:
|
func _on_FillWithOptions_item_selected(ID : int, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_fill_with = ID
|
Global.fill_with[mouse_button] = ID
|
||||||
if ID == 1:
|
if ID == 1:
|
||||||
Global.right_fill_pattern_container.visible = true
|
Global.fill_pattern_containers[mouse_button].visible = true
|
||||||
else:
|
|
||||||
Global.right_fill_pattern_container.visible = false
|
|
||||||
else:
|
else:
|
||||||
Global.left_fill_with = ID
|
Global.fill_pattern_containers[mouse_button].visible = false
|
||||||
if ID == 1:
|
|
||||||
Global.left_fill_pattern_container.visible = true
|
|
||||||
else:
|
|
||||||
Global.left_fill_pattern_container.visible = false
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PatternTypeButton_pressed(right : bool) -> void:
|
func _on_PatternTypeButton_pressed(right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.pattern_window_position = "right"
|
Global.pattern_window_position = mouse_button
|
||||||
Global.patterns_popup.popup(Rect2(Global.right_brush_type_button.rect_global_position, Vector2(226, 72)))
|
Global.patterns_popup.popup(Rect2(Global.brush_type_buttons[mouse_button].rect_global_position, Vector2(226, 72)))
|
||||||
else:
|
|
||||||
Global.pattern_window_position = "left"
|
|
||||||
Global.patterns_popup.popup(Rect2(Global.left_brush_type_button.rect_global_position, Vector2(226, 72)))
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PatternOffsetX_value_changed(value : float, right : bool) -> void:
|
func _on_PatternOffsetX_value_changed(value : float, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_fill_pattern_offset.x = value
|
Global.fill_pattern_offsets[mouse_button].x = value
|
||||||
else:
|
|
||||||
Global.left_fill_pattern_offset.x = value
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PatternOffsetY_value_changed(value : float, right : bool) -> void:
|
func _on_PatternOffsetY_value_changed(value : float, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_fill_pattern_offset.y = value
|
Global.fill_pattern_offsets[mouse_button].y = value
|
||||||
else:
|
|
||||||
Global.left_fill_pattern_offset.y = value
|
|
||||||
|
|
||||||
|
|
||||||
func _on_LightenDarken_item_selected(ID : int, right : bool) -> void:
|
func _on_LightenDarken_item_selected(ID : int, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_ld = ID
|
Global.ld_modes[mouse_button] = ID
|
||||||
else:
|
|
||||||
Global.left_ld = ID
|
|
||||||
|
|
||||||
|
|
||||||
func _on_LDAmount_value_changed(value : float, right : bool) -> void:
|
func _on_LDAmount_value_changed(value : float, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_ld_amount = value / 100
|
Global.ld_amounts[mouse_button] = value / 100
|
||||||
Global.right_ld_amount_slider.value = value
|
Global.ld_amount_sliders[mouse_button].value = value
|
||||||
Global.right_ld_amount_spinbox.value = value
|
Global.ld_amount_spinboxes[mouse_button].value = value
|
||||||
else:
|
|
||||||
Global.left_ld_amount = value / 100
|
|
||||||
Global.left_ld_amount_slider.value = value
|
|
||||||
Global.left_ld_amount_spinbox.value = value
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ForColorOptions_item_selected(ID : int, right : bool) -> void:
|
func _on_ForColorOptions_item_selected(ID : int, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_color_picker_for = ID
|
Global.color_picker_for[mouse_button] = ID
|
||||||
else:
|
|
||||||
Global.left_color_picker_for = ID
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ZoomModeOptions_item_selected(ID : int, right : bool) -> void:
|
func _on_ZoomModeOptions_item_selected(ID : int, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_zoom_mode = ID
|
Global.zoom_modes[mouse_button] = ID
|
||||||
else:
|
|
||||||
Global.left_zoom_mode = ID
|
|
||||||
|
|
||||||
|
|
||||||
func _on_HorizontalMirroring_toggled(button_pressed : bool, right : bool) -> void:
|
func _on_HorizontalMirroring_toggled(button_pressed : bool, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_horizontal_mirror = button_pressed
|
Global.horizontal_mirror[mouse_button] = button_pressed
|
||||||
else:
|
|
||||||
Global.left_horizontal_mirror = button_pressed
|
|
||||||
|
|
||||||
|
|
||||||
func _on_VerticalMirroring_toggled(button_pressed : bool, right : bool) -> void:
|
func _on_VerticalMirroring_toggled(button_pressed : bool, right : bool) -> void:
|
||||||
if right:
|
var mouse_button := int(right)
|
||||||
Global.right_vertical_mirror = button_pressed
|
Global.vertical_mirror[mouse_button] = button_pressed
|
||||||
else:
|
|
||||||
Global.left_vertical_mirror = button_pressed
|
|
||||||
|
|
|
@ -75,9 +75,7 @@ func _on_CreateNewImage_confirmed() -> void:
|
||||||
var fill_color : Color = fill_color_node.color
|
var fill_color : Color = fill_color_node.color
|
||||||
Global.clear_canvases()
|
Global.clear_canvases()
|
||||||
Global.layers.clear()
|
Global.layers.clear()
|
||||||
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
Global.layers.append(Layer.new())
|
||||||
# will new frames be linked boolean (4), Array of linked frames (5)]
|
|
||||||
Global.layers.append([tr("Layer") + " 0", true, false, HBoxContainer.new(), false, []])
|
|
||||||
Global.canvas = load("res://src/Canvas.tscn").instance()
|
Global.canvas = load("res://src/Canvas.tscn").instance()
|
||||||
Global.canvas.size = Vector2(width, height).floor()
|
Global.canvas.size = Vector2(width, height).floor()
|
||||||
|
|
||||||
|
@ -89,8 +87,8 @@ func _on_CreateNewImage_confirmed() -> void:
|
||||||
Global.layers = Global.layers # To trigger Global.layers_changed()
|
Global.layers = Global.layers # To trigger Global.layers_changed()
|
||||||
Global.project_has_changed = false
|
Global.project_has_changed = false
|
||||||
if fill_color.a > 0:
|
if fill_color.a > 0:
|
||||||
Global.canvas.layers[0][0].fill(fill_color)
|
Global.canvas.layers[0].image.fill(fill_color)
|
||||||
Global.canvas.layers[0][0].lock()
|
Global.canvas.layers[0].image.lock()
|
||||||
Global.canvas.update_texture(0)
|
Global.canvas.update_texture(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -147,8 +147,8 @@ func process_spritesheet() -> void:
|
||||||
# Range of frames determined by tags
|
# Range of frames determined by tags
|
||||||
var frames := []
|
var frames := []
|
||||||
if frame_current_tag > 0:
|
if frame_current_tag > 0:
|
||||||
var frame_start = Global.animation_tags[frame_current_tag - 1][2]
|
var frame_start = Global.animation_tags[frame_current_tag - 1].from
|
||||||
var frame_end = Global.animation_tags[frame_current_tag - 1][3]
|
var frame_end = Global.animation_tags[frame_current_tag - 1].to
|
||||||
frames = Global.canvases.slice(frame_start-1, frame_end-1, 1, true)
|
frames = Global.canvases.slice(frame_start-1, frame_end-1, 1, true)
|
||||||
else:
|
else:
|
||||||
frames = Global.canvases
|
frames = Global.canvases
|
||||||
|
@ -283,8 +283,8 @@ func get_proccessed_image_animation_tag_and_start_id(processed_image_id : int) -
|
||||||
for animation_tag in Global.animation_tags:
|
for animation_tag in Global.animation_tags:
|
||||||
# Check if processed image is in frame tag and assign frame tag and start id if yes
|
# Check if processed image is in frame tag and assign frame tag and start id if yes
|
||||||
# Then stop
|
# Then stop
|
||||||
if (processed_image_id + 1) >= animation_tag[2] and (processed_image_id + 1) <= animation_tag[3]:
|
if (processed_image_id + 1) >= animation_tag.from and (processed_image_id + 1) <= animation_tag.to:
|
||||||
result_animation_tag_and_start_id = [animation_tag[0], animation_tag[2]]
|
result_animation_tag_and_start_id = [animation_tag.name, animation_tag.from]
|
||||||
break
|
break
|
||||||
return result_animation_tag_and_start_id
|
return result_animation_tag_and_start_id
|
||||||
|
|
||||||
|
@ -365,17 +365,17 @@ func blend_layers(image: Image, canvas: Canvas, origin: Vector2 = Vector2(0, 0))
|
||||||
image.lock()
|
image.lock()
|
||||||
var layer_i := 0
|
var layer_i := 0
|
||||||
for layer in canvas.layers:
|
for layer in canvas.layers:
|
||||||
if Global.layers[layer_i][1]:
|
if Global.layers[layer_i].visible:
|
||||||
var layer_image := Image.new()
|
var layer_image := Image.new()
|
||||||
layer_image.copy_from(layer[0])
|
layer_image.copy_from(layer.image)
|
||||||
layer_image.lock()
|
layer_image.lock()
|
||||||
if layer[2] < 1: # If we have layer transparency
|
if layer.opacity < 1: # If we have layer transparency
|
||||||
for xx in layer_image.get_size().x:
|
for xx in layer_image.get_size().x:
|
||||||
for yy in layer_image.get_size().y:
|
for yy in layer_image.get_size().y:
|
||||||
var pixel_color := layer_image.get_pixel(xx, yy)
|
var pixel_color := layer_image.get_pixel(xx, yy)
|
||||||
var alpha : float = pixel_color.a * layer[2]
|
var alpha : float = pixel_color.a * layer.opacity
|
||||||
layer_image.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha))
|
layer_image.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha))
|
||||||
canvas.blend_rect(image, layer_image, Rect2(canvas.position, canvas.size), origin)
|
DrawingAlgos.blend_rect(image, layer_image, Rect2(canvas.position, canvas.size), origin)
|
||||||
layer_i += 1
|
layer_i += 1
|
||||||
image.unlock()
|
image.unlock()
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ func create_frame_tag_list() -> void:
|
||||||
|
|
||||||
# Repopulate list with current tag list
|
# Repopulate list with current tag list
|
||||||
for item in Global.animation_tags:
|
for item in Global.animation_tags:
|
||||||
frame_container.add_item(item[0])
|
frame_container.add_item(item.name)
|
||||||
|
|
||||||
|
|
||||||
func store_export_settings() -> void:
|
func store_export_settings() -> void:
|
||||||
|
|
|
@ -23,7 +23,7 @@ func _ready() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_HSVDialog_about_to_show() -> void:
|
func _on_HSVDialog_about_to_show() -> void:
|
||||||
current_layer = Global.canvas.layers[Global.current_layer][0]
|
current_layer = Global.canvas.layers[Global.current_layer].image
|
||||||
preview_image.copy_from(current_layer)
|
preview_image.copy_from(current_layer)
|
||||||
update_preview()
|
update_preview()
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@ func _on_Cancel_pressed() -> void:
|
||||||
|
|
||||||
func _on_Apply_pressed() -> void:
|
func _on_Apply_pressed() -> void:
|
||||||
Global.canvas.handle_undo("Draw")
|
Global.canvas.handle_undo("Draw")
|
||||||
Global.canvas.adjust_hsv(current_layer,0,hue_slider.value)
|
DrawingAlgos.adjust_hsv(current_layer,0,hue_slider.value)
|
||||||
Global.canvas.adjust_hsv(current_layer,1,sat_slider.value)
|
DrawingAlgos.adjust_hsv(current_layer,1,sat_slider.value)
|
||||||
Global.canvas.adjust_hsv(current_layer,2,val_slider.value)
|
DrawingAlgos.adjust_hsv(current_layer,2,val_slider.value)
|
||||||
Global.canvas.update_texture(Global.current_layer)
|
Global.canvas.update_texture(Global.current_layer)
|
||||||
Global.canvas.handle_redo("Draw")
|
Global.canvas.handle_redo("Draw")
|
||||||
reset()
|
reset()
|
||||||
|
@ -57,9 +57,9 @@ func reset() -> void:
|
||||||
|
|
||||||
func update_preview() -> void:
|
func update_preview() -> void:
|
||||||
preview_image.copy_from(current_layer)
|
preview_image.copy_from(current_layer)
|
||||||
Global.canvas.adjust_hsv(preview_image,0,hue_slider.value)
|
DrawingAlgos.adjust_hsv(preview_image,0,hue_slider.value)
|
||||||
Global.canvas.adjust_hsv(preview_image,1,sat_slider.value)
|
DrawingAlgos.adjust_hsv(preview_image,1,sat_slider.value)
|
||||||
Global.canvas.adjust_hsv(preview_image,2,val_slider.value)
|
DrawingAlgos.adjust_hsv(preview_image,2,val_slider.value)
|
||||||
preview_texture.create_from_image(preview_image, 0)
|
preview_texture.create_from_image(preview_image, 0)
|
||||||
preview.texture = preview_texture
|
preview.texture = preview_texture
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
|
||||||
Global.layers.clear()
|
Global.layers.clear()
|
||||||
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
||||||
# will new frames be linked boolean (4), Array of linked frames (5)]
|
# will new frames be linked boolean (4), Array of linked frames (5)]
|
||||||
Global.layers.append([tr("Layer") + " 0", true, false, HBoxContainer.new(), false, []])
|
Global.layers.append(Layer.new())
|
||||||
Global.current_layer = 0
|
Global.current_layer = 0
|
||||||
|
|
||||||
var first_path : String = paths[0]
|
var first_path : String = paths[0]
|
||||||
|
@ -64,22 +64,14 @@ func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
|
||||||
canvas.size = image.get_size()
|
canvas.size = image.get_size()
|
||||||
image.convert(Image.FORMAT_RGBA8)
|
image.convert(Image.FORMAT_RGBA8)
|
||||||
image.lock()
|
image.lock()
|
||||||
var tex := ImageTexture.new()
|
canvas.layers.append(Cel.new(image, 1))
|
||||||
tex.create_from_image(image, 0)
|
|
||||||
# Store [Image, ImageTexture, Opacity]
|
|
||||||
canvas.layers.append([image, tex, 1])
|
|
||||||
|
|
||||||
for _i in range(1, Global.layers.size()):
|
for _i in range(1, Global.layers.size()):
|
||||||
var empty_sprite := Image.new()
|
var empty_sprite := Image.new()
|
||||||
empty_sprite.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
|
empty_sprite.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
|
||||||
empty_sprite.fill(Color(0, 0, 0, 0))
|
empty_sprite.fill(Color(0, 0, 0, 0))
|
||||||
empty_sprite.lock()
|
empty_sprite.lock()
|
||||||
|
canvas.layers.append(Cel.new(empty_sprite, 1))
|
||||||
var empty_tex := ImageTexture.new()
|
|
||||||
empty_tex.create_from_image(empty_sprite, 0)
|
|
||||||
|
|
||||||
# Store [Image, ImageTexture, Opacity]
|
|
||||||
canvas.layers.append([empty_sprite, empty_tex, 1])
|
|
||||||
|
|
||||||
canvas.frame = i
|
canvas.frame = i
|
||||||
Global.canvases.append(canvas)
|
Global.canvases.append(canvas)
|
||||||
|
@ -119,21 +111,14 @@ func _on_ImportSprites_files_selected(paths : PoolStringArray) -> void:
|
||||||
canvas.size = cropped_image.get_size()
|
canvas.size = cropped_image.get_size()
|
||||||
cropped_image.convert(Image.FORMAT_RGBA8)
|
cropped_image.convert(Image.FORMAT_RGBA8)
|
||||||
cropped_image.lock()
|
cropped_image.lock()
|
||||||
var tex := ImageTexture.new()
|
canvas.layers.append(Cel.new(cropped_image, 1))
|
||||||
tex.create_from_image(cropped_image, 0)
|
|
||||||
# Store [Image, ImageTexture, Opacity]
|
|
||||||
canvas.layers.append([cropped_image, tex, 1])
|
|
||||||
for _i in range(1, Global.layers.size()):
|
for _i in range(1, Global.layers.size()):
|
||||||
var empty_sprite := Image.new()
|
var empty_sprite := Image.new()
|
||||||
empty_sprite.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
|
empty_sprite.create(canvas.size.x, canvas.size.y, false, Image.FORMAT_RGBA8)
|
||||||
empty_sprite.fill(Color(0, 0, 0, 0))
|
empty_sprite.fill(Color(0, 0, 0, 0))
|
||||||
empty_sprite.lock()
|
empty_sprite.lock()
|
||||||
|
canvas.layers.append(Cel.new(empty_sprite, 1))
|
||||||
var empty_tex := ImageTexture.new()
|
|
||||||
empty_tex.create_from_image(empty_sprite, 0)
|
|
||||||
|
|
||||||
# Store [Image, ImageTexture, Opacity]
|
|
||||||
canvas.layers.append([empty_sprite, empty_tex, 1])
|
|
||||||
|
|
||||||
canvas.frame = i
|
canvas.frame = i
|
||||||
Global.canvases.append(canvas)
|
Global.canvases.append(canvas)
|
||||||
|
|
|
@ -10,7 +10,7 @@ func _on_OutlineDialog_confirmed() -> void:
|
||||||
var diagonal : bool = $OptionsContainer/DiagonalCheckBox.pressed
|
var diagonal : bool = $OptionsContainer/DiagonalCheckBox.pressed
|
||||||
var inside_image : bool = $OptionsContainer/InsideImageCheckBox.pressed
|
var inside_image : bool = $OptionsContainer/InsideImageCheckBox.pressed
|
||||||
|
|
||||||
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
var image : Image = Global.canvas.layers[Global.current_layer].image
|
||||||
if image.is_invisible():
|
if image.is_invisible():
|
||||||
return
|
return
|
||||||
var new_image := Image.new()
|
var new_image := Image.new()
|
||||||
|
|
|
@ -1,575 +0,0 @@
|
||||||
extends AcceptDialog
|
|
||||||
|
|
||||||
onready var tree : Tree = $HSplitContainer/Tree
|
|
||||||
onready var right_side : VBoxContainer = $HSplitContainer/ScrollContainer/VBoxContainer
|
|
||||||
onready var general = $HSplitContainer/ScrollContainer/VBoxContainer/General
|
|
||||||
onready var languages = $HSplitContainer/ScrollContainer/VBoxContainer/Languages
|
|
||||||
onready var themes = $HSplitContainer/ScrollContainer/VBoxContainer/Themes
|
|
||||||
onready var canvas = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas
|
|
||||||
onready var image = $HSplitContainer/ScrollContainer/VBoxContainer/Image
|
|
||||||
onready var shortcuts = $HSplitContainer/ScrollContainer/VBoxContainer/Shortcuts
|
|
||||||
|
|
||||||
onready var open_last_project_button = $HSplitContainer/ScrollContainer/VBoxContainer/General/OpenLastProject
|
|
||||||
onready var smooth_zoom_button = $HSplitContainer/ScrollContainer/VBoxContainer/General/SmoothZoom
|
|
||||||
onready var sensitivity_option = $HSplitContainer/ScrollContainer/VBoxContainer/General/PressureSentivity/PressureSensitivityOptionButton
|
|
||||||
onready var left_tool_icon = $HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/LeftToolIconCheckbox
|
|
||||||
onready var right_tool_icon = $HSplitContainer/ScrollContainer/VBoxContainer/General/GridContainer/RightToolIconCheckbox
|
|
||||||
|
|
||||||
onready var default_width_value = $HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions/ImageDefaultWidth
|
|
||||||
onready var default_height_value = $HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions/ImageDefaultHeight
|
|
||||||
onready var default_fill_color = $HSplitContainer/ScrollContainer/VBoxContainer/Image/ImageOptions/DefaultFillColor
|
|
||||||
|
|
||||||
onready var grid_width_value = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridWidthValue
|
|
||||||
onready var grid_height_value = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridHeightValue
|
|
||||||
onready var grid_color = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GridOptions/GridColor
|
|
||||||
onready var guide_color = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/GuideOptions/GuideColor
|
|
||||||
|
|
||||||
onready var checker_size_value = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions/CheckerSizeValue
|
|
||||||
onready var checker_color_1 = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions/CheckerColor1
|
|
||||||
onready var checker_color_2 = $HSplitContainer/ScrollContainer/VBoxContainer/Canvas/CheckerOptions/CheckerColor2
|
|
||||||
|
|
||||||
# Shortcuts
|
|
||||||
onready var theme_font_color : Color = $Popups/ShortcutSelector/EnteredShortcut.get_color("font_color")
|
|
||||||
var default_shortcuts_preset := {}
|
|
||||||
var custom_shortcuts_preset := {}
|
|
||||||
var action_being_edited := ""
|
|
||||||
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)
|
|
||||||
|
|
||||||
# Replace OK with Close since preference changes are being applied immediately, not after OK confirmation
|
|
||||||
get_ok().text = tr("Close")
|
|
||||||
|
|
||||||
for child in languages.get_children():
|
|
||||||
if child is Button:
|
|
||||||
child.connect("pressed", self, "_on_Language_pressed", [child])
|
|
||||||
child.hint_tooltip = child.name
|
|
||||||
|
|
||||||
for child in themes.get_children():
|
|
||||||
if child is Button:
|
|
||||||
child.connect("pressed", self, "_on_Theme_pressed", [child])
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "theme"):
|
|
||||||
var theme_id = Global.config_cache.get_value("preferences", "theme")
|
|
||||||
change_theme(theme_id)
|
|
||||||
themes.get_child(theme_id).pressed = true
|
|
||||||
else:
|
|
||||||
change_theme(0)
|
|
||||||
themes.get_child(0).pressed = true
|
|
||||||
|
|
||||||
# Set default values for General options
|
|
||||||
if Global.config_cache.has_section_key("preferences", "open_last_project"):
|
|
||||||
Global.open_last_project = Global.config_cache.get_value("preferences", "open_last_project")
|
|
||||||
open_last_project_button.pressed = Global.open_last_project
|
|
||||||
if Global.config_cache.has_section_key("preferences", "smooth_zoom"):
|
|
||||||
Global.smooth_zoom = Global.config_cache.get_value("preferences", "smooth_zoom")
|
|
||||||
smooth_zoom_button.pressed = Global.smooth_zoom
|
|
||||||
if Global.config_cache.has_section_key("preferences", "pressure_sensitivity"):
|
|
||||||
Global.pressure_sensitivity_mode = Global.config_cache.get_value("preferences", "pressure_sensitivity")
|
|
||||||
sensitivity_option.selected = Global.pressure_sensitivity_mode
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "show_left_tool_icon"):
|
|
||||||
Global.show_left_tool_icon = Global.config_cache.get_value("preferences", "show_left_tool_icon")
|
|
||||||
left_tool_icon.pressed = Global.show_left_tool_icon
|
|
||||||
if Global.config_cache.has_section_key("preferences", "show_right_tool_icon"):
|
|
||||||
Global.show_right_tool_icon = Global.config_cache.get_value("preferences", "show_right_tool_icon")
|
|
||||||
right_tool_icon.pressed = Global.show_right_tool_icon
|
|
||||||
|
|
||||||
# Get autosave settings
|
|
||||||
if Global.config_cache.has_section_key("preferences", "autosave_interval"):
|
|
||||||
var autosave_interval = Global.config_cache.get_value("preferences", "autosave_interval")
|
|
||||||
OpenSave.set_autosave_interval(autosave_interval)
|
|
||||||
general.get_node("AutosaveInterval/AutosaveInterval").value = autosave_interval
|
|
||||||
if Global.config_cache.has_section_key("preferences", "enable_autosave"):
|
|
||||||
var enable_autosave = Global.config_cache.get_value("preferences", "enable_autosave")
|
|
||||||
OpenSave.toggle_autosave(enable_autosave)
|
|
||||||
general.get_node("EnableAutosave").pressed = enable_autosave
|
|
||||||
|
|
||||||
# Set default values for Canvas options
|
|
||||||
if Global.config_cache.has_section_key("preferences", "grid_size"):
|
|
||||||
var grid_size = Global.config_cache.get_value("preferences", "grid_size")
|
|
||||||
Global.grid_width = int(grid_size.x)
|
|
||||||
Global.grid_height = int(grid_size.y)
|
|
||||||
grid_width_value.value = grid_size.x
|
|
||||||
grid_height_value.value = grid_size.y
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "grid_color"):
|
|
||||||
Global.grid_color = Global.config_cache.get_value("preferences", "grid_color")
|
|
||||||
grid_color.color = Global.grid_color
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "checker_size"):
|
|
||||||
var checker_size = Global.config_cache.get_value("preferences", "checker_size")
|
|
||||||
Global.checker_size = int(checker_size)
|
|
||||||
checker_size_value.value = checker_size
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "checker_color_1"):
|
|
||||||
Global.checker_color_1 = Global.config_cache.get_value("preferences", "checker_color_1")
|
|
||||||
checker_color_1.color = Global.checker_color_1
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "checker_color_2"):
|
|
||||||
Global.checker_color_2 = Global.config_cache.get_value("preferences", "checker_color_2")
|
|
||||||
checker_color_2.color = Global.checker_color_2
|
|
||||||
|
|
||||||
Global.transparent_checker._ready()
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "guide_color"):
|
|
||||||
Global.guide_color = Global.config_cache.get_value("preferences", "guide_color")
|
|
||||||
for canvas in Global.canvases:
|
|
||||||
for guide in canvas.get_children():
|
|
||||||
if guide is Guide:
|
|
||||||
guide.default_color = Global.guide_color
|
|
||||||
guide_color.color = Global.guide_color
|
|
||||||
|
|
||||||
# Set default values for Image
|
|
||||||
if Global.config_cache.has_section_key("preferences", "default_width"):
|
|
||||||
var default_width = Global.config_cache.get_value("preferences", "default_width")
|
|
||||||
Global.default_image_width = int(default_width)
|
|
||||||
default_width_value.value = Global.default_image_width
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "default_height"):
|
|
||||||
var default_height = Global.config_cache.get_value("preferences", "default_height")
|
|
||||||
Global.default_image_height = int(default_height)
|
|
||||||
default_height_value.value = Global.default_image_height
|
|
||||||
|
|
||||||
if Global.config_cache.has_section_key("preferences", "default_fill_color"):
|
|
||||||
var fill_color = Global.config_cache.get_value("preferences", "default_fill_color")
|
|
||||||
Global.default_fill_color = fill_color
|
|
||||||
default_fill_color.color = Global.default_fill_color
|
|
||||||
|
|
||||||
guide_color.get_picker().presets_visible = false
|
|
||||||
grid_color.get_picker().presets_visible = false
|
|
||||||
checker_color_1.get_picker().presets_visible = false
|
|
||||||
checker_color_2.get_picker().presets_visible = false
|
|
||||||
default_fill_color.get_picker().presets_visible = false
|
|
||||||
|
|
||||||
# Get default preset for shortcuts from project input map
|
|
||||||
# Buttons in shortcuts selector should be called the same as actions
|
|
||||||
for shortcut_grid_item in shortcuts.get_node("Shortcuts").get_children():
|
|
||||||
if shortcut_grid_item is Button:
|
|
||||||
var input_events = InputMap.get_action_list(shortcut_grid_item.name)
|
|
||||||
if input_events.size() > 1:
|
|
||||||
printerr("Every shortcut action should have just one input event assigned in input map")
|
|
||||||
shortcut_grid_item.text = (input_events[0] as InputEventKey).as_text()
|
|
||||||
shortcut_grid_item.connect("pressed", self, "_on_Shortcut_button_pressed", [shortcut_grid_item])
|
|
||||||
default_shortcuts_preset[shortcut_grid_item.name] = input_events[0]
|
|
||||||
|
|
||||||
# Load custom shortcuts from the config file
|
|
||||||
custom_shortcuts_preset = default_shortcuts_preset.duplicate()
|
|
||||||
for action in default_shortcuts_preset:
|
|
||||||
var saved_input_event = Global.config_cache.get_value("shortcuts", action, 0)
|
|
||||||
if saved_input_event is InputEventKey:
|
|
||||||
custom_shortcuts_preset[action] = saved_input_event
|
|
||||||
|
|
||||||
var shortcuts_preset = Global.config_cache.get_value("shortcuts", "shortcuts_preset", 0)
|
|
||||||
shortcuts.get_node("HBoxContainer/PresetOptionButton").select(shortcuts_preset)
|
|
||||||
_on_PresetOptionButton_item_selected(shortcuts_preset)
|
|
||||||
|
|
||||||
|
|
||||||
func _input(event : InputEvent) -> void:
|
|
||||||
if event is InputEventKey:
|
|
||||||
if event.pressed:
|
|
||||||
if event.scancode == KEY_ESCAPE:
|
|
||||||
$Popups/ShortcutSelector.hide()
|
|
||||||
else:
|
|
||||||
# Check if shortcut was already used
|
|
||||||
for action in InputMap.get_actions():
|
|
||||||
for input_event in InputMap.get_action_list(action):
|
|
||||||
if input_event is InputEventKey:
|
|
||||||
if OS.get_scancode_string(input_event.get_scancode_with_modifiers()) == OS.get_scancode_string(event.get_scancode_with_modifiers()):
|
|
||||||
$Popups/ShortcutSelector/EnteredShortcut.text = tr("Already assigned")
|
|
||||||
$Popups/ShortcutSelector/EnteredShortcut.add_color_override("font_color", Color.crimson)
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
shortcut_already_assigned = true
|
|
||||||
return
|
|
||||||
|
|
||||||
# Store new shortcut
|
|
||||||
shortcut_already_assigned = false
|
|
||||||
old_input_event = InputMap.get_action_list(action_being_edited)[0]
|
|
||||||
new_input_event = event
|
|
||||||
$Popups/ShortcutSelector/EnteredShortcut.text = OS.get_scancode_string(event.get_scancode_with_modifiers())
|
|
||||||
$Popups/ShortcutSelector/EnteredShortcut.add_color_override("font_color", theme_font_color)
|
|
||||||
get_tree().set_input_as_handled()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PreferencesDialog_about_to_show(changed_language := false) -> void:
|
|
||||||
var root := tree.create_item()
|
|
||||||
var general_button := tree.create_item(root)
|
|
||||||
var language_button := tree.create_item(root)
|
|
||||||
var theme_button := tree.create_item(root)
|
|
||||||
var canvas_button := tree.create_item(root)
|
|
||||||
var image_button := tree.create_item(root)
|
|
||||||
var shortcuts_button := tree.create_item(root)
|
|
||||||
|
|
||||||
general_button.set_text(0, " " + tr("General"))
|
|
||||||
# We use metadata to avoid being affected by translations
|
|
||||||
general_button.set_metadata(0, "General")
|
|
||||||
language_button.set_text(0, " " + tr("Language"))
|
|
||||||
language_button.set_metadata(0, "Language")
|
|
||||||
theme_button.set_text(0, " " + tr("Themes"))
|
|
||||||
theme_button.set_metadata(0, "Themes")
|
|
||||||
canvas_button.set_text(0, " " + tr("Canvas"))
|
|
||||||
canvas_button.set_metadata(0, "Canvas")
|
|
||||||
image_button.set_text(0, " " + tr("Image"))
|
|
||||||
image_button.set_metadata(0, "Image")
|
|
||||||
shortcuts_button.set_text(0, " " + tr("Shortcuts"))
|
|
||||||
shortcuts_button.set_metadata(0, "Shortcuts")
|
|
||||||
|
|
||||||
if changed_language:
|
|
||||||
language_button.select(0)
|
|
||||||
else:
|
|
||||||
general_button.select(0)
|
|
||||||
|
|
||||||
general.get_node("AutosaveInterval/AutosaveInterval").suffix = tr("minute(s)")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PreferencesDialog_popup_hide() -> void:
|
|
||||||
tree.clear()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_Tree_item_selected() -> void:
|
|
||||||
for child in right_side.get_children():
|
|
||||||
child.visible = false
|
|
||||||
var selected : String = tree.get_selected().get_metadata(0)
|
|
||||||
if "General" in selected:
|
|
||||||
general.visible = true
|
|
||||||
elif "Language" in selected:
|
|
||||||
languages.visible = true
|
|
||||||
elif "Themes" in selected:
|
|
||||||
themes.visible = true
|
|
||||||
elif "Canvas" in selected:
|
|
||||||
canvas.visible = true
|
|
||||||
elif "Image" in selected:
|
|
||||||
image.visible = true
|
|
||||||
elif "Shortcuts" in selected:
|
|
||||||
shortcuts.visible = true
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PressureSensitivityOptionButton_item_selected(id : int) -> void:
|
|
||||||
Global.pressure_sensitivity_mode = id
|
|
||||||
Global.config_cache.set_value("preferences", "pressure_sensitivity", id)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_SmoothZoom_pressed() -> void:
|
|
||||||
Global.smooth_zoom = !Global.smooth_zoom
|
|
||||||
Global.config_cache.set_value("preferences", "smooth_zoom", Global.smooth_zoom)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_Language_pressed(button : Button) -> void:
|
|
||||||
var index := 0
|
|
||||||
var i := -1
|
|
||||||
for child in languages.get_children():
|
|
||||||
if child is Button:
|
|
||||||
if child == button:
|
|
||||||
button.pressed = true
|
|
||||||
index = i
|
|
||||||
else:
|
|
||||||
child.pressed = false
|
|
||||||
i += 1
|
|
||||||
if index == -1:
|
|
||||||
TranslationServer.set_locale(OS.get_locale())
|
|
||||||
else:
|
|
||||||
TranslationServer.set_locale(Global.loaded_locales[index])
|
|
||||||
|
|
||||||
if "zh" in TranslationServer.get_locale():
|
|
||||||
Global.control.theme.default_font = preload("res://assets/fonts/CJK/NotoSansCJKtc-Regular.tres")
|
|
||||||
else:
|
|
||||||
Global.control.theme.default_font = preload("res://assets/fonts/Roboto-Regular.tres")
|
|
||||||
|
|
||||||
Global.config_cache.set_value("preferences", "locale", TranslationServer.get_locale())
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
# Update Translations
|
|
||||||
Global.update_hint_tooltips()
|
|
||||||
_on_PreferencesDialog_popup_hide()
|
|
||||||
_on_PreferencesDialog_about_to_show(true)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_Theme_pressed(button : Button) -> void:
|
|
||||||
var index := 0
|
|
||||||
var i := 0
|
|
||||||
for child in themes.get_children():
|
|
||||||
if child is Button:
|
|
||||||
if child == button:
|
|
||||||
button.pressed = true
|
|
||||||
index = i
|
|
||||||
else:
|
|
||||||
child.pressed = false
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
change_theme(index)
|
|
||||||
|
|
||||||
Global.config_cache.set_value("preferences", "theme", index)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func change_theme(ID : int) -> void:
|
|
||||||
var font = Global.control.theme.default_font
|
|
||||||
var main_theme : Theme
|
|
||||||
var top_menu_style
|
|
||||||
var ruler_style
|
|
||||||
if ID == 0: # Dark Theme
|
|
||||||
Global.theme_type = "Dark"
|
|
||||||
main_theme = preload("res://assets/themes/dark/theme.tres")
|
|
||||||
top_menu_style = preload("res://assets/themes/dark/top_menu_style.tres")
|
|
||||||
ruler_style = preload("res://assets/themes/dark/ruler_style.tres")
|
|
||||||
elif ID == 1: # Gray Theme
|
|
||||||
Global.theme_type = "Dark"
|
|
||||||
main_theme = preload("res://assets/themes/gray/theme.tres")
|
|
||||||
top_menu_style = preload("res://assets/themes/gray/top_menu_style.tres")
|
|
||||||
ruler_style = preload("res://assets/themes/dark/ruler_style.tres")
|
|
||||||
elif ID == 2: # Godot's Theme
|
|
||||||
Global.theme_type = "Blue"
|
|
||||||
main_theme = preload("res://assets/themes/blue/theme.tres")
|
|
||||||
top_menu_style = preload("res://assets/themes/blue/top_menu_style.tres")
|
|
||||||
ruler_style = preload("res://assets/themes/blue/ruler_style.tres")
|
|
||||||
elif ID == 3: # Caramel Theme
|
|
||||||
Global.theme_type = "Caramel"
|
|
||||||
main_theme = preload("res://assets/themes/caramel/theme.tres")
|
|
||||||
top_menu_style = preload("res://assets/themes/caramel/top_menu_style.tres")
|
|
||||||
ruler_style = preload("res://assets/themes/caramel/ruler_style.tres")
|
|
||||||
elif ID == 4: # Light Theme
|
|
||||||
Global.theme_type = "Light"
|
|
||||||
main_theme = preload("res://assets/themes/light/theme.tres")
|
|
||||||
top_menu_style = preload("res://assets/themes/light/top_menu_style.tres")
|
|
||||||
ruler_style = preload("res://assets/themes/light/ruler_style.tres")
|
|
||||||
|
|
||||||
Global.control.theme = main_theme
|
|
||||||
Global.control.theme.default_font = font
|
|
||||||
var default_clear_color : Color = main_theme.get_stylebox("panel", "PanelContainer").bg_color
|
|
||||||
VisualServer.set_default_clear_color(Color(default_clear_color))
|
|
||||||
(Global.animation_timeline.get_stylebox("panel", "Panel") as StyleBoxFlat).bg_color = main_theme.get_stylebox("panel", "Panel").bg_color
|
|
||||||
var layer_button_panel_container : PanelContainer = Global.find_node_by_name(Global.animation_timeline, "LayerButtonPanelContainer")
|
|
||||||
(layer_button_panel_container.get_stylebox("panel", "PanelContainer") as StyleBoxFlat).bg_color = default_clear_color
|
|
||||||
|
|
||||||
Global.top_menu_container.add_stylebox_override("panel", top_menu_style)
|
|
||||||
Global.horizontal_ruler.add_stylebox_override("normal", ruler_style)
|
|
||||||
Global.horizontal_ruler.add_stylebox_override("pressed", ruler_style)
|
|
||||||
Global.horizontal_ruler.add_stylebox_override("hover", ruler_style)
|
|
||||||
Global.horizontal_ruler.add_stylebox_override("focus", ruler_style)
|
|
||||||
Global.vertical_ruler.add_stylebox_override("normal", ruler_style)
|
|
||||||
Global.vertical_ruler.add_stylebox_override("pressed", ruler_style)
|
|
||||||
Global.vertical_ruler.add_stylebox_override("hover", ruler_style)
|
|
||||||
Global.vertical_ruler.add_stylebox_override("focus", ruler_style)
|
|
||||||
|
|
||||||
var fake_vsplit_grabber : TextureRect = Global.find_node_by_name(Global.animation_timeline, "FakeVSplitContainerGrabber")
|
|
||||||
|
|
||||||
if Global.theme_type == "Dark" or Global.theme_type == "Blue":
|
|
||||||
fake_vsplit_grabber.texture = preload("res://assets/themes/dark/icons/vsplit.png")
|
|
||||||
else:
|
|
||||||
fake_vsplit_grabber.texture = preload("res://assets/themes/light/icons/vsplit.png")
|
|
||||||
|
|
||||||
for button in get_tree().get_nodes_in_group("UIButtons"):
|
|
||||||
if button is TextureButton:
|
|
||||||
var last_backslash = button.texture_normal.resource_path.get_base_dir().find_last("/")
|
|
||||||
var button_category = button.texture_normal.resource_path.get_base_dir().right(last_backslash + 1)
|
|
||||||
var normal_file_name = button.texture_normal.resource_path.get_file()
|
|
||||||
var theme_type := Global.theme_type
|
|
||||||
if theme_type == "Blue":
|
|
||||||
theme_type = "Dark"
|
|
||||||
button.texture_normal = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type.to_lower(), button_category, normal_file_name])
|
|
||||||
if button.texture_pressed:
|
|
||||||
var pressed_file_name = button.texture_pressed.resource_path.get_file()
|
|
||||||
button.texture_pressed = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type.to_lower(), button_category, pressed_file_name])
|
|
||||||
if button.texture_hover:
|
|
||||||
var hover_file_name = button.texture_hover.resource_path.get_file()
|
|
||||||
button.texture_hover = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type.to_lower(), button_category, hover_file_name])
|
|
||||||
if button.texture_disabled:
|
|
||||||
var disabled_file_name = button.texture_disabled.resource_path.get_file()
|
|
||||||
button.texture_disabled = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type.to_lower(), button_category, disabled_file_name])
|
|
||||||
elif button is Button:
|
|
||||||
var texture : TextureRect
|
|
||||||
for child in button.get_children():
|
|
||||||
if child is TextureRect:
|
|
||||||
texture = child
|
|
||||||
break
|
|
||||||
|
|
||||||
if texture:
|
|
||||||
var last_backslash = texture.texture.resource_path.get_base_dir().find_last("/")
|
|
||||||
var button_category = texture.texture.resource_path.get_base_dir().right(last_backslash + 1)
|
|
||||||
var normal_file_name = texture.texture.resource_path.get_file()
|
|
||||||
var theme_type := Global.theme_type
|
|
||||||
if theme_type == "Caramel" or (theme_type == "Blue" and button_category != "tools"):
|
|
||||||
theme_type = "Dark"
|
|
||||||
|
|
||||||
texture.texture = load("res://assets/graphics/%s_themes/%s/%s" % [theme_type.to_lower(), button_category, normal_file_name])
|
|
||||||
|
|
||||||
# Make sure the frame text gets updated
|
|
||||||
Global.current_frame = Global.current_frame
|
|
||||||
|
|
||||||
$Popups/ShortcutSelector.theme = main_theme
|
|
||||||
|
|
||||||
|
|
||||||
func apply_shortcuts_preset(preset) -> void:
|
|
||||||
for action in preset:
|
|
||||||
var old_input_event : InputEventKey = InputMap.get_action_list(action)[0]
|
|
||||||
set_action_shortcut(action, old_input_event, preset[action])
|
|
||||||
shortcuts.get_node("Shortcuts/" + action).text = OS.get_scancode_string(preset[action].get_scancode_with_modifiers())
|
|
||||||
|
|
||||||
|
|
||||||
func toggle_shortcut_buttons(enabled : bool) -> void:
|
|
||||||
for shortcut_grid_item in shortcuts.get_node("Shortcuts").get_children():
|
|
||||||
if shortcut_grid_item is Button:
|
|
||||||
shortcut_grid_item.disabled = not enabled
|
|
||||||
if shortcut_grid_item.disabled:
|
|
||||||
shortcut_grid_item.mouse_default_cursor_shape = Control.CURSOR_FORBIDDEN
|
|
||||||
else:
|
|
||||||
shortcut_grid_item.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
||||||
|
|
||||||
|
|
||||||
func set_action_shortcut(action : String, old_input : InputEventKey, new_input : InputEventKey) -> void:
|
|
||||||
InputMap.action_erase_event(action, old_input)
|
|
||||||
InputMap.action_add_event(action, new_input)
|
|
||||||
Global.update_hint_tooltips()
|
|
||||||
# Set shortcut to switch colors button
|
|
||||||
if action == "switch_colors":
|
|
||||||
Global.color_switch_button.shortcut.shortcut = InputMap.get_action_list("switch_colors")[0]
|
|
||||||
|
|
||||||
|
|
||||||
func _on_GridWidthValue_value_changed(value : float) -> void:
|
|
||||||
Global.grid_width = value
|
|
||||||
Global.canvas.update()
|
|
||||||
Global.config_cache.set_value("preferences", "grid_size", Vector2(value, grid_height_value.value))
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_GridHeightValue_value_changed(value : float) -> void:
|
|
||||||
Global.grid_height = value
|
|
||||||
Global.canvas.update()
|
|
||||||
Global.config_cache.set_value("preferences", "grid_size", Vector2(grid_width_value.value, value))
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_GridColor_color_changed(color : Color) -> void:
|
|
||||||
Global.grid_color = color
|
|
||||||
Global.canvas.update()
|
|
||||||
Global.config_cache.set_value("preferences", "grid_color", color)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_CheckerSize_value_changed(value : float) -> void:
|
|
||||||
Global.checker_size = value
|
|
||||||
Global.transparent_checker._ready()
|
|
||||||
Global.config_cache.set_value("preferences", "checker_size", value)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_CheckerColor1_color_changed(color : Color) -> void:
|
|
||||||
Global.checker_color_1 = color
|
|
||||||
Global.transparent_checker._ready()
|
|
||||||
Global.config_cache.set_value("preferences", "checker_color_1", color)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_CheckerColor2_color_changed(color : Color) -> void:
|
|
||||||
Global.checker_color_2 = color
|
|
||||||
Global.transparent_checker._ready()
|
|
||||||
Global.config_cache.set_value("preferences", "checker_color_2", color)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_GuideColor_color_changed(color : Color) -> void:
|
|
||||||
Global.guide_color = color
|
|
||||||
for canvas in Global.canvases:
|
|
||||||
for guide in canvas.get_children():
|
|
||||||
if guide is Guide:
|
|
||||||
guide.default_color = color
|
|
||||||
Global.config_cache.set_value("preferences", "guide_color", color)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ImageDefaultWidth_value_changed(value: float) -> void:
|
|
||||||
Global.default_image_width = value
|
|
||||||
Global.config_cache.set_value("preferences", "default_width", value)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ImageDefaultHeight_value_changed(value: float) -> void:
|
|
||||||
Global.default_image_height = value
|
|
||||||
Global.config_cache.set_value("preferences", "default_height", value)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_DefaultBackground_color_changed(color: Color) -> void:
|
|
||||||
Global.default_fill_color = color
|
|
||||||
Global.config_cache.set_value("preferences", "default_fill_color", color)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_LeftIndicatorCheckbox_toggled(button_pressed : bool) -> void:
|
|
||||||
Global.left_square_indicator_visible = button_pressed
|
|
||||||
|
|
||||||
|
|
||||||
func _on_RightIndicatorCheckbox_toggled(button_pressed : bool) -> void:
|
|
||||||
Global.right_square_indicator_visible = button_pressed
|
|
||||||
|
|
||||||
|
|
||||||
func _on_LeftToolIconCheckbox_toggled(button_pressed : bool) -> void:
|
|
||||||
Global.show_left_tool_icon = button_pressed
|
|
||||||
Global.config_cache.set_value("preferences", "show_left_tool_icon", Global.show_left_tool_icon)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_RightToolIconCheckbox_toggled(button_pressed : bool) -> void:
|
|
||||||
Global.show_right_tool_icon = button_pressed
|
|
||||||
Global.config_cache.set_value("preferences", "show_right_tool_icon", Global.show_right_tool_icon)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_Shortcut_button_pressed(button : Button) -> void:
|
|
||||||
set_process_input(true)
|
|
||||||
action_being_edited = button.name
|
|
||||||
new_input_event = InputMap.get_action_list(button.name)[0]
|
|
||||||
shortcut_already_assigned = true
|
|
||||||
$Popups/ShortcutSelector.popup_centered()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ShortcutSelector_popup_hide() -> void:
|
|
||||||
set_process_input(false)
|
|
||||||
$Popups/ShortcutSelector/EnteredShortcut.text = ""
|
|
||||||
|
|
||||||
|
|
||||||
func _on_PresetOptionButton_item_selected(id : int) -> void:
|
|
||||||
# Only custom preset which is modifiable
|
|
||||||
toggle_shortcut_buttons(true if id == 1 else false)
|
|
||||||
match id:
|
|
||||||
0:
|
|
||||||
apply_shortcuts_preset(default_shortcuts_preset)
|
|
||||||
1:
|
|
||||||
apply_shortcuts_preset(custom_shortcuts_preset)
|
|
||||||
Global.config_cache.set_value("shortcuts", "shortcuts_preset", id)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_ShortcutSelector_confirmed() -> void:
|
|
||||||
if not shortcut_already_assigned:
|
|
||||||
set_action_shortcut(action_being_edited, old_input_event, new_input_event)
|
|
||||||
custom_shortcuts_preset[action_being_edited] = new_input_event
|
|
||||||
Global.config_cache.set_value("shortcuts", action_being_edited, new_input_event)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
shortcuts.get_node("Shortcuts/" + action_being_edited).text = OS.get_scancode_string(new_input_event.get_scancode_with_modifiers())
|
|
||||||
$Popups/ShortcutSelector.hide()
|
|
||||||
|
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_EnableAutosave_toggled(button_pressed : bool) -> void:
|
|
||||||
OpenSave.toggle_autosave(button_pressed)
|
|
||||||
Global.config_cache.set_value("preferences", "enable_autosave", button_pressed)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
||||||
|
|
||||||
|
|
||||||
func _on_AutosaveInterval_value_changed(value : float) -> void:
|
|
||||||
OpenSave.set_autosave_interval(value)
|
|
||||||
Global.config_cache.set_value("preferences", "autosave_interval", value)
|
|
||||||
Global.config_cache.save("user://cache.ini")
|
|
|
@ -32,11 +32,11 @@ func _on_RotateImage_confirmed() -> void:
|
||||||
Global.canvas.handle_undo("Draw")
|
Global.canvas.handle_undo("Draw")
|
||||||
match $VBoxContainer/HBoxContainer2/OptionButton.text:
|
match $VBoxContainer/HBoxContainer2/OptionButton.text:
|
||||||
"Rotxel":
|
"Rotxel":
|
||||||
Global.rotxel(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
DrawingAlgos.rotxel(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
||||||
"Nearest neighbour":
|
"Nearest neighbour":
|
||||||
Global.nn_rotate(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
DrawingAlgos.nn_rotate(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
||||||
"Upscale, Rotate and Downscale":
|
"Upscale, Rotate and Downscale":
|
||||||
Global.fake_rotsprite(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
DrawingAlgos.fake_rotsprite(layer,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
||||||
Global.canvas.handle_redo("Draw")
|
Global.canvas.handle_redo("Draw")
|
||||||
$VBoxContainer/HBoxContainer/HSlider.value = 0
|
$VBoxContainer/HBoxContainer/HSlider.value = 0
|
||||||
|
|
||||||
|
@ -45,11 +45,11 @@ func rotate() -> void:
|
||||||
sprite.copy_from(aux_img)
|
sprite.copy_from(aux_img)
|
||||||
match $VBoxContainer/HBoxContainer2/OptionButton.text:
|
match $VBoxContainer/HBoxContainer2/OptionButton.text:
|
||||||
"Rotxel":
|
"Rotxel":
|
||||||
Global.rotxel(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
DrawingAlgos.rotxel(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
||||||
"Nearest neighbour":
|
"Nearest neighbour":
|
||||||
Global.nn_rotate(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
DrawingAlgos.nn_rotate(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
||||||
"Upscale, Rotate and Downscale":
|
"Upscale, Rotate and Downscale":
|
||||||
Global.fake_rotsprite(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
DrawingAlgos.fake_rotsprite(sprite,$VBoxContainer/HBoxContainer/HSlider.value*PI/180)
|
||||||
texture.create_from_image(sprite, 0)
|
texture.create_from_image(sprite, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ func _on_ScaleImage_confirmed() -> void:
|
||||||
Global.undo_redo.add_do_property(c, "size", Vector2(width, height).floor())
|
Global.undo_redo.add_do_property(c, "size", Vector2(width, height).floor())
|
||||||
for i in range(c.layers.size() - 1, -1, -1):
|
for i in range(c.layers.size() - 1, -1, -1):
|
||||||
var sprite := Image.new()
|
var sprite := Image.new()
|
||||||
sprite.copy_from(c.layers[i][0])
|
sprite.copy_from(c.layers[i].image)
|
||||||
sprite.resize(width, height, interpolation)
|
sprite.resize(width, height, interpolation)
|
||||||
Global.undo_redo.add_do_property(c.layers[i][0], "data", sprite.data)
|
Global.undo_redo.add_do_property(c.layers[i].image, "data", sprite.data)
|
||||||
Global.undo_redo.add_undo_property(c.layers[i][0], "data", c.layers[i][0].data)
|
Global.undo_redo.add_undo_property(c.layers[i].image, "data", c.layers[i].image.data)
|
||||||
Global.undo_redo.add_undo_property(c, "size", c.size)
|
Global.undo_redo.add_undo_property(c, "size", c.size)
|
||||||
|
|
||||||
Global.undo_redo.add_undo_method(Global, "undo", Global.canvases)
|
Global.undo_redo.add_undo_method(Global, "undo", Global.canvases)
|
||||||
|
|
|
@ -14,16 +14,9 @@ func _ready() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_PatternButton_pressed() -> void:
|
func _on_PatternButton_pressed() -> void:
|
||||||
if Global.pattern_window_position == "left":
|
Global.pattern_images[Global.pattern_window_position] = image
|
||||||
Global.pattern_left_image = image
|
Global.fill_pattern_containers[Global.pattern_window_position].get_child(0).get_child(0).texture = texture
|
||||||
Global.left_fill_pattern_container.get_child(0).get_child(0).texture = texture
|
Global.fill_pattern_containers[Global.pattern_window_position].get_child(2).get_child(1).max_value = image_size.x - 1
|
||||||
Global.left_fill_pattern_container.get_child(2).get_child(1).max_value = image_size.x - 1
|
Global.fill_pattern_containers[Global.pattern_window_position].get_child(3).get_child(1).max_value = image_size.y - 1
|
||||||
Global.left_fill_pattern_container.get_child(3).get_child(1).max_value = image_size.y - 1
|
|
||||||
|
|
||||||
elif Global.pattern_window_position == "right":
|
|
||||||
Global.pattern_right_image = image
|
|
||||||
Global.right_fill_pattern_container.get_child(0).get_child(0).texture = texture
|
|
||||||
Global.right_fill_pattern_container.get_child(2).get_child(1).max_value = image_size.x - 1
|
|
||||||
Global.right_fill_pattern_container.get_child(3).get_child(1).max_value = image_size.y - 1
|
|
||||||
|
|
||||||
Global.patterns_popup.hide()
|
Global.patterns_popup.hide()
|
||||||
|
|
|
@ -4,7 +4,7 @@ var fps := 6.0
|
||||||
var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop
|
var animation_loop := 1 # 0 is no loop, 1 is cycle loop, 2 is ping-pong loop
|
||||||
var animation_forward := true
|
var animation_forward := true
|
||||||
var first_frame := 0
|
var first_frame := 0
|
||||||
var last_frame := Global.canvases.size() - 1
|
var last_frame : int = Global.canvases.size() - 1
|
||||||
|
|
||||||
var timeline_scroll : ScrollContainer
|
var timeline_scroll : ScrollContainer
|
||||||
var tag_scroll_container : ScrollContainer
|
var tag_scroll_container : ScrollContainer
|
||||||
|
@ -28,7 +28,7 @@ func add_frame() -> void:
|
||||||
new_canvas.size = Global.canvas.size
|
new_canvas.size = Global.canvas.size
|
||||||
new_canvas.frame = Global.canvases.size()
|
new_canvas.frame = Global.canvases.size()
|
||||||
|
|
||||||
var new_canvases: Array = Global.canvases.duplicate()
|
var new_canvases : Array = Global.canvases.duplicate()
|
||||||
new_canvases.append(new_canvas)
|
new_canvases.append(new_canvas)
|
||||||
|
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
|
@ -45,8 +45,8 @@ func add_frame() -> void:
|
||||||
Global.undo_redo.add_undo_property(c, "visible", c.visible)
|
Global.undo_redo.add_undo_property(c, "visible", c.visible)
|
||||||
|
|
||||||
for l_i in range(Global.layers.size()):
|
for l_i in range(Global.layers.size()):
|
||||||
if Global.layers[l_i][4]: # If the link button is pressed
|
if Global.layers[l_i].new_cels_linked: # If the link button is pressed
|
||||||
Global.layers[l_i][5].append(new_canvas)
|
Global.layers[l_i].linked_cels.append(new_canvas)
|
||||||
|
|
||||||
Global.undo_redo.add_undo_property(Global, "canvases", Global.canvases)
|
Global.undo_redo.add_undo_property(Global, "canvases", Global.canvases)
|
||||||
Global.undo_redo.add_undo_property(Global, "canvas", Global.canvas)
|
Global.undo_redo.add_undo_property(Global, "canvas", Global.canvas)
|
||||||
|
@ -61,32 +61,43 @@ func _on_DeleteFrame_pressed(frame := -1) -> void:
|
||||||
frame = Global.current_frame
|
frame = Global.current_frame
|
||||||
|
|
||||||
var canvas : Canvas = Global.canvases[frame]
|
var canvas : Canvas = Global.canvases[frame]
|
||||||
var new_canvases := Global.canvases.duplicate()
|
var new_canvases : Array = Global.canvases.duplicate()
|
||||||
new_canvases.erase(canvas)
|
new_canvases.erase(canvas)
|
||||||
var current_frame := Global.current_frame
|
var current_frame := Global.current_frame
|
||||||
if current_frame > 0 && current_frame == new_canvases.size(): # If it's the last frame
|
if current_frame > 0 && current_frame == new_canvases.size(): # If it's the last frame
|
||||||
current_frame -= 1
|
current_frame -= 1
|
||||||
|
|
||||||
var new_animation_tags := Global.animation_tags.duplicate(true)
|
var new_animation_tags := Global.animation_tags.duplicate()
|
||||||
|
# Loop through the tags to create new classes for them, so that they won't be the same
|
||||||
|
# as Global.animation_tags's classes. Needed for undo/redo to work properly.
|
||||||
|
for i in new_animation_tags.size():
|
||||||
|
new_animation_tags[i] = AnimationTag.new(new_animation_tags[i].name, new_animation_tags[i].color, new_animation_tags[i].from, new_animation_tags[i].to)
|
||||||
|
|
||||||
# Loop through the tags to see if the frame is in one
|
# Loop through the tags to see if the frame is in one
|
||||||
for tag in new_animation_tags:
|
for tag in new_animation_tags:
|
||||||
if frame + 1 >= tag[2] && frame + 1 <= tag[3]:
|
if frame + 1 >= tag.from && frame + 1 <= tag.to:
|
||||||
if tag[3] == tag[2]: # If we're deleting the only frame in the tag
|
if tag.from == tag.to: # If we're deleting the only frame in the tag
|
||||||
new_animation_tags.erase(tag)
|
new_animation_tags.erase(tag)
|
||||||
else:
|
else:
|
||||||
tag[3] -= 1
|
tag.to -= 1
|
||||||
elif frame + 1 < tag[2]:
|
elif frame + 1 < tag.from:
|
||||||
tag[2] -= 1
|
tag.from -= 1
|
||||||
tag[3] -= 1
|
tag.to -= 1
|
||||||
|
|
||||||
# Check if one of the cels of the frame is linked
|
# Check if one of the cels of the frame is linked
|
||||||
# if they are, unlink them too
|
# if they are, unlink them too
|
||||||
# this prevents removed cels being kept in linked memory
|
# this prevents removed cels being kept in linked memory
|
||||||
var new_layers := Global.layers.duplicate(true)
|
var new_layers : Array = Global.layers.duplicate()
|
||||||
|
# Loop through the array to create new classes for each element, so that they
|
||||||
|
# won't be the same as the original array's classes. Needed for undo/redo to work properly.
|
||||||
|
for i in new_layers.size():
|
||||||
|
var new_linked_cels = new_layers[i].linked_cels.duplicate()
|
||||||
|
new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels)
|
||||||
|
|
||||||
for layer in new_layers:
|
for layer in new_layers:
|
||||||
for linked in layer[5]:
|
for linked in layer.linked_cels:
|
||||||
if linked == Global.canvases[frame]:
|
if linked == Global.canvases[frame]:
|
||||||
layer[5].erase(linked)
|
layer.linked_cels.erase(linked)
|
||||||
|
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
Global.undo_redo.create_action("Remove Frame")
|
Global.undo_redo.create_action("Remove Frame")
|
||||||
|
@ -130,17 +141,20 @@ func _on_CopyFrame_pressed(frame := -1) -> void:
|
||||||
|
|
||||||
for layer in canvas.layers: # Copy every layer
|
for layer in canvas.layers: # Copy every layer
|
||||||
var sprite := Image.new()
|
var sprite := Image.new()
|
||||||
sprite.copy_from(layer[0])
|
sprite.copy_from(layer.image)
|
||||||
sprite.lock()
|
sprite.lock()
|
||||||
var tex := ImageTexture.new()
|
new_canvas.layers.append(Cel.new(sprite, layer.opacity))
|
||||||
tex.create_from_image(sprite, 0)
|
|
||||||
new_canvas.layers.append([sprite, tex, layer[2]])
|
var new_animation_tags := Global.animation_tags.duplicate()
|
||||||
|
# Loop through the tags to create new classes for them, so that they won't be the same
|
||||||
|
# as Global.animation_tags's classes. Needed for undo/redo to work properly.
|
||||||
|
for i in new_animation_tags.size():
|
||||||
|
new_animation_tags[i] = AnimationTag.new(new_animation_tags[i].name, new_animation_tags[i].color, new_animation_tags[i].from, new_animation_tags[i].to)
|
||||||
|
|
||||||
var new_animation_tags := Global.animation_tags.duplicate(true)
|
|
||||||
# Loop through the tags to see if the frame is in one
|
# Loop through the tags to see if the frame is in one
|
||||||
for tag in new_animation_tags:
|
for tag in new_animation_tags:
|
||||||
if frame + 1 >= tag[2] && frame + 1 <= tag[3]:
|
if frame + 1 >= tag.from && frame + 1 <= tag.to:
|
||||||
tag[3] += 1
|
tag.to += 1
|
||||||
|
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
Global.undo_redo.create_action("Add Frame")
|
Global.undo_redo.create_action("Add Frame")
|
||||||
|
@ -152,7 +166,7 @@ func _on_CopyFrame_pressed(frame := -1) -> void:
|
||||||
Global.undo_redo.add_do_property(Global, "current_frame", frame + 1)
|
Global.undo_redo.add_do_property(Global, "current_frame", frame + 1)
|
||||||
Global.undo_redo.add_do_property(Global, "animation_tags", new_animation_tags)
|
Global.undo_redo.add_do_property(Global, "animation_tags", new_animation_tags)
|
||||||
for i in range(Global.layers.size()):
|
for i in range(Global.layers.size()):
|
||||||
for child in Global.layers[i][3].get_children():
|
for child in Global.layers[i].frame_container.get_children():
|
||||||
Global.undo_redo.add_do_property(child, "pressed", false)
|
Global.undo_redo.add_do_property(child, "pressed", false)
|
||||||
Global.undo_redo.add_undo_property(child, "pressed", child.pressed)
|
Global.undo_redo.add_undo_property(child, "pressed", child.pressed)
|
||||||
for c in Global.canvases:
|
for c in Global.canvases:
|
||||||
|
@ -265,9 +279,9 @@ func play_animation(play : bool, forward_dir : bool) -> void:
|
||||||
last_frame = Global.canvases.size() - 1
|
last_frame = Global.canvases.size() - 1
|
||||||
if Global.play_only_tags:
|
if Global.play_only_tags:
|
||||||
for tag in Global.animation_tags:
|
for tag in Global.animation_tags:
|
||||||
if Global.current_frame + 1 >= tag[2] && Global.current_frame + 1 <= tag[3]:
|
if Global.current_frame + 1 >= tag.from && Global.current_frame + 1 <= tag.to:
|
||||||
first_frame = tag[2] - 1
|
first_frame = tag.from - 1
|
||||||
last_frame = min(Global.canvases.size() - 1, tag[3] - 1)
|
last_frame = min(Global.canvases.size() - 1, tag.to - 1)
|
||||||
|
|
||||||
if first_frame == last_frame:
|
if first_frame == last_frame:
|
||||||
if forward_dir:
|
if forward_dir:
|
||||||
|
@ -336,15 +350,11 @@ func _on_BlueRedMode_toggled(button_pressed : bool) -> void:
|
||||||
# Layer buttons
|
# Layer buttons
|
||||||
|
|
||||||
func add_layer(is_new := true) -> void:
|
func add_layer(is_new := true) -> void:
|
||||||
var layer_name = null
|
|
||||||
if !is_new: # Clone layer
|
|
||||||
layer_name = Global.layers[Global.current_layer][0] + " (" + tr("copy") + ")"
|
|
||||||
|
|
||||||
var new_layers : Array = Global.layers.duplicate()
|
var new_layers : Array = Global.layers.duplicate()
|
||||||
|
var l := Layer.new()
|
||||||
# Store [Layer name (0), Layer visibility boolean (1), Layer lock boolean (2), Frame container (3),
|
if !is_new: # Clone layer
|
||||||
# will new frames be linked boolean (4), Array of linked frames (5)]
|
l.name = Global.layers[Global.current_layer].name + " (" + tr("copy") + ")"
|
||||||
new_layers.append([layer_name, true, false, HBoxContainer.new(), false, []])
|
new_layers.append(l)
|
||||||
|
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
Global.undo_redo.create_action("Add Layer")
|
Global.undo_redo.create_action("Add Layer")
|
||||||
|
@ -354,15 +364,12 @@ func add_layer(is_new := true) -> void:
|
||||||
if is_new:
|
if is_new:
|
||||||
new_layer.create(c.size.x, c.size.y, false, Image.FORMAT_RGBA8)
|
new_layer.create(c.size.x, c.size.y, false, Image.FORMAT_RGBA8)
|
||||||
else: # Clone layer
|
else: # Clone layer
|
||||||
new_layer.copy_from(c.layers[Global.current_layer][0])
|
new_layer.copy_from(c.layers[Global.current_layer].image)
|
||||||
|
|
||||||
new_layer.lock()
|
new_layer.lock()
|
||||||
var new_layer_tex := ImageTexture.new()
|
|
||||||
new_layer_tex.create_from_image(new_layer, 0)
|
|
||||||
|
|
||||||
var new_canvas_layers : Array = c.layers.duplicate()
|
var new_canvas_layers : Array = c.layers.duplicate()
|
||||||
# Store [Image, ImageTexture, Opacity]
|
new_canvas_layers.append(Cel.new(new_layer, 1))
|
||||||
new_canvas_layers.append([new_layer, new_layer_tex, 1])
|
|
||||||
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
|
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
|
||||||
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
||||||
|
|
||||||
|
@ -409,11 +416,11 @@ func change_layer_order(rate : int) -> void:
|
||||||
new_layers[change] = temp
|
new_layers[change] = temp
|
||||||
Global.undo_redo.create_action("Change Layer Order")
|
Global.undo_redo.create_action("Change Layer Order")
|
||||||
for c in Global.canvases:
|
for c in Global.canvases:
|
||||||
var new_layers_canvas : Array = c.layers.duplicate()
|
var new_canvas_layers : Array = c.layers.duplicate()
|
||||||
var temp_canvas = new_layers_canvas[Global.current_layer]
|
var temp_canvas = new_canvas_layers[Global.current_layer]
|
||||||
new_layers_canvas[Global.current_layer] = new_layers_canvas[change]
|
new_canvas_layers[Global.current_layer] = new_canvas_layers[change]
|
||||||
new_layers_canvas[change] = temp_canvas
|
new_canvas_layers[change] = temp_canvas
|
||||||
Global.undo_redo.add_do_property(c, "layers", new_layers_canvas)
|
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
|
||||||
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
||||||
|
|
||||||
Global.undo_redo.add_do_property(Global, "current_layer", change)
|
Global.undo_redo.add_do_property(Global, "current_layer", change)
|
||||||
|
@ -427,39 +434,43 @@ func change_layer_order(rate : int) -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_MergeDownLayer_pressed() -> void:
|
func _on_MergeDownLayer_pressed() -> void:
|
||||||
var new_layers : Array = Global.layers.duplicate(true)
|
var new_layers : Array = Global.layers.duplicate()
|
||||||
|
# Loop through the array to create new classes for each element, so that they
|
||||||
|
# won't be the same as the original array's classes. Needed for undo/redo to work properly.
|
||||||
|
for i in new_layers.size():
|
||||||
|
var new_linked_cels = new_layers[i].linked_cels.duplicate()
|
||||||
|
new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels)
|
||||||
|
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
Global.undo_redo.create_action("Merge Layer")
|
Global.undo_redo.create_action("Merge Layer")
|
||||||
for c in Global.canvases:
|
for c in Global.canvases:
|
||||||
var new_layers_canvas : Array = c.layers.duplicate(true)
|
var new_canvas_layers : Array = c.layers.duplicate()
|
||||||
|
for i in new_canvas_layers.size():
|
||||||
|
new_canvas_layers[i] = Cel.new(new_canvas_layers[i].image, new_canvas_layers[i].opacity)
|
||||||
var selected_layer := Image.new()
|
var selected_layer := Image.new()
|
||||||
selected_layer.copy_from(new_layers_canvas[Global.current_layer][0])
|
selected_layer.copy_from(new_canvas_layers[Global.current_layer].image)
|
||||||
selected_layer.lock()
|
selected_layer.lock()
|
||||||
|
|
||||||
if c.layers[Global.current_layer][2] < 1: # If we have layer transparency
|
if c.layers[Global.current_layer].opacity < 1: # If we have layer transparency
|
||||||
for xx in selected_layer.get_size().x:
|
for xx in selected_layer.get_size().x:
|
||||||
for yy in selected_layer.get_size().y:
|
for yy in selected_layer.get_size().y:
|
||||||
var pixel_color : Color = selected_layer.get_pixel(xx, yy)
|
var pixel_color : Color = selected_layer.get_pixel(xx, yy)
|
||||||
var alpha : float = pixel_color.a * c.layers[Global.current_layer][2]
|
var alpha : float = pixel_color.a * c.layers[Global.current_layer].opacity
|
||||||
selected_layer.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha))
|
selected_layer.set_pixel(xx, yy, Color(pixel_color.r, pixel_color.g, pixel_color.b, alpha))
|
||||||
|
|
||||||
var new_layer := Image.new()
|
var new_layer := Image.new()
|
||||||
new_layer.copy_from(c.layers[Global.current_layer - 1][0])
|
new_layer.copy_from(c.layers[Global.current_layer - 1].image)
|
||||||
new_layer.lock()
|
new_layer.lock()
|
||||||
c.blend_rect(new_layer, selected_layer, Rect2(c.position, c.size), Vector2.ZERO)
|
DrawingAlgos.blend_rect(new_layer, selected_layer, Rect2(c.position, c.size), Vector2.ZERO)
|
||||||
new_layers_canvas.remove(Global.current_layer)
|
new_canvas_layers.remove(Global.current_layer)
|
||||||
if !selected_layer.is_invisible() and Global.layers[Global.current_layer - 1][5].size() > 1 and (c in Global.layers[Global.current_layer - 1][5]):
|
if !selected_layer.is_invisible() and Global.layers[Global.current_layer - 1].linked_cels.size() > 1 and (c in Global.layers[Global.current_layer - 1].linked_cels):
|
||||||
new_layers[Global.current_layer - 1][5].erase(c)
|
new_layers[Global.current_layer - 1].linked_cels.erase(c)
|
||||||
var tex := ImageTexture.new()
|
new_canvas_layers[Global.current_layer - 1].image = new_layer
|
||||||
tex.create_from_image(new_layer, 0)
|
|
||||||
new_layers_canvas[Global.current_layer - 1][0] = new_layer
|
|
||||||
new_layers_canvas[Global.current_layer - 1][1] = tex
|
|
||||||
else:
|
else:
|
||||||
Global.undo_redo.add_do_property(c.layers[Global.current_layer - 1][0], "data", new_layer.data)
|
Global.undo_redo.add_do_property(c.layers[Global.current_layer - 1].image, "data", new_layer.data)
|
||||||
Global.undo_redo.add_undo_property(c.layers[Global.current_layer - 1][0], "data", c.layers[Global.current_layer - 1][0].data)
|
Global.undo_redo.add_undo_property(c.layers[Global.current_layer - 1].image, "data", c.layers[Global.current_layer - 1].image.data)
|
||||||
|
|
||||||
Global.undo_redo.add_do_property(c, "layers", new_layers_canvas)
|
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
|
||||||
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
||||||
|
|
||||||
new_layers.remove(Global.current_layer)
|
new_layers.remove(Global.current_layer)
|
||||||
|
@ -474,7 +485,7 @@ func _on_MergeDownLayer_pressed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_OpacitySlider_value_changed(value) -> void:
|
func _on_OpacitySlider_value_changed(value) -> void:
|
||||||
Global.canvas.layers[Global.current_layer][2] = value / 100
|
Global.canvas.layers[Global.current_layer].opacity = value / 100
|
||||||
Global.layer_opacity_slider.value = value
|
Global.layer_opacity_slider.value = value
|
||||||
Global.layer_opacity_slider.value = value
|
Global.layer_opacity_slider.value = value
|
||||||
Global.layer_opacity_spinbox.value = value
|
Global.layer_opacity_spinbox.value = value
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/timeline/onion_skinning_off.png" type="Texture" id=29]
|
[ext_resource path="res://assets/graphics/dark_themes/timeline/onion_skinning_off.png" type="Texture" id=29]
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/timeline/expandable.png" type="Texture" id=30]
|
[ext_resource path="res://assets/graphics/dark_themes/timeline/expandable.png" type="Texture" id=30]
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/timeline/loop.png" type="Texture" id=31]
|
[ext_resource path="res://assets/graphics/dark_themes/timeline/loop.png" type="Texture" id=31]
|
||||||
[ext_resource path="res://src/UI/Dialogs/FrameTagDialog.tscn" type="PackedScene" id=42]
|
[ext_resource path="res://src/UI/Timeline/FrameTagDialog.tscn" type="PackedScene" id=42]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=1]
|
[sub_resource type="StyleBoxFlat" id=1]
|
||||||
bg_color = Color( 0.0627451, 0.0627451, 0.0627451, 1 )
|
bg_color = Color( 0.0627451, 0.0627451, 0.0627451, 1 )
|
||||||
|
|
|
@ -8,7 +8,7 @@ onready var popup_menu : PopupMenu = $PopupMenu
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
hint_tooltip = "Frame: %s, Layer: %s" % [frame + 1, layer]
|
hint_tooltip = "Frame: %s, Layer: %s" % [frame + 1, layer]
|
||||||
if Global.canvases[frame] in Global.layers[layer][5]:
|
if Global.canvases[frame] in Global.layers[layer].linked_cels:
|
||||||
get_node("LinkedIndicator").visible = true
|
get_node("LinkedIndicator").visible = true
|
||||||
popup_menu.set_item_text(4, "Unlink Cel")
|
popup_menu.set_item_text(4, "Unlink Cel")
|
||||||
popup_menu.set_item_metadata(4, "Unlink Cel")
|
popup_menu.set_item_metadata(4, "Unlink Cel")
|
||||||
|
@ -53,20 +53,24 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
|
||||||
3: # Move Right
|
3: # Move Right
|
||||||
change_frame_order(1)
|
change_frame_order(1)
|
||||||
4: # Unlink Cel
|
4: # Unlink Cel
|
||||||
var cel_index : int = Global.layers[layer][5].find(Global.canvases[frame])
|
var cel_index : int = Global.layers[layer].linked_cels.find(Global.canvases[frame])
|
||||||
var c = Global.canvases[frame]
|
var c = Global.canvases[frame]
|
||||||
var new_layers := Global.layers.duplicate(true)
|
var new_layers : Array = Global.layers.duplicate()
|
||||||
var new_canvas_layers : Array = c.layers.duplicate(true)
|
# Loop through the array to create new classes for each element, so that they
|
||||||
|
# won't be the same as the original array's classes. Needed for undo/redo to work properly.
|
||||||
|
for i in new_layers.size():
|
||||||
|
var new_linked_cels = new_layers[i].linked_cels.duplicate()
|
||||||
|
new_layers[i] = Layer.new(new_layers[i].name, new_layers[i].visible, new_layers[i].locked, new_layers[i].frame_container, new_layers[i].new_cels_linked, new_linked_cels)
|
||||||
|
var new_canvas_layers : Array = c.layers.duplicate()
|
||||||
|
for i in new_canvas_layers.size():
|
||||||
|
new_canvas_layers[i] = Cel.new(new_canvas_layers[i].image, new_canvas_layers[i].opacity)
|
||||||
|
|
||||||
if popup_menu.get_item_metadata(4) == "Unlink Cel":
|
if popup_menu.get_item_metadata(4) == "Unlink Cel":
|
||||||
new_layers[layer][5].remove(cel_index)
|
new_layers[layer].linked_cels.remove(cel_index)
|
||||||
var sprite := Image.new()
|
var sprite := Image.new()
|
||||||
sprite.copy_from(Global.canvases[frame].layers[layer][0])
|
sprite.copy_from(Global.canvases[frame].layers[layer].image)
|
||||||
sprite.lock()
|
sprite.lock()
|
||||||
var tex := ImageTexture.new()
|
new_canvas_layers[layer].image = sprite
|
||||||
tex.create_from_image(sprite, 0)
|
|
||||||
new_canvas_layers[layer][0] = sprite
|
|
||||||
new_canvas_layers[layer][1] = tex
|
|
||||||
|
|
||||||
Global.undo_redo.create_action("Unlink Cel")
|
Global.undo_redo.create_action("Unlink Cel")
|
||||||
Global.undo_redo.add_do_property(Global, "layers", new_layers)
|
Global.undo_redo.add_do_property(Global, "layers", new_layers)
|
||||||
|
@ -78,14 +82,14 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
|
||||||
Global.undo_redo.add_do_method(Global, "redo", [Global.canvases[frame]], layer)
|
Global.undo_redo.add_do_method(Global, "redo", [Global.canvases[frame]], layer)
|
||||||
Global.undo_redo.commit_action()
|
Global.undo_redo.commit_action()
|
||||||
elif popup_menu.get_item_metadata(4) == "Link Cel":
|
elif popup_menu.get_item_metadata(4) == "Link Cel":
|
||||||
new_layers[layer][5].append(Global.canvases[frame])
|
new_layers[layer].linked_cels.append(Global.canvases[frame])
|
||||||
Global.undo_redo.create_action("Link Cel")
|
Global.undo_redo.create_action("Link Cel")
|
||||||
Global.undo_redo.add_do_property(Global, "layers", new_layers)
|
Global.undo_redo.add_do_property(Global, "layers", new_layers)
|
||||||
if new_layers[layer][5].size() > 1:
|
if new_layers[layer].linked_cels.size() > 1:
|
||||||
# If there are already linked cels, set the current cel's image
|
# If there are already linked cels, set the current cel's image
|
||||||
# to the first linked cel's image
|
# to the first linked cel's image
|
||||||
new_canvas_layers[layer][0] = new_layers[layer][5][0].layers[layer][0]
|
new_canvas_layers[layer].image = new_layers[layer].linked_cels[0].layers[layer].image
|
||||||
new_canvas_layers[layer][1] = new_layers[layer][5][0].layers[layer][1]
|
new_canvas_layers[layer].image_texture = new_layers[layer].linked_cels[0].layers[layer].image_texture
|
||||||
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
|
Global.undo_redo.add_do_property(c, "layers", new_canvas_layers)
|
||||||
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
Global.undo_redo.add_undo_property(c, "layers", c.layers)
|
||||||
|
|
||||||
|
@ -97,7 +101,7 @@ func _on_PopupMenu_id_pressed(ID : int) -> void:
|
||||||
|
|
||||||
func change_frame_order(rate : int) -> void:
|
func change_frame_order(rate : int) -> void:
|
||||||
var change = frame + rate
|
var change = frame + rate
|
||||||
var new_canvases := Global.canvases.duplicate()
|
var new_canvases : Array = Global.canvases.duplicate()
|
||||||
var temp = new_canvases[frame]
|
var temp = new_canvases[frame]
|
||||||
new_canvases[frame] = new_canvases[change]
|
new_canvases[frame] = new_canvases[change]
|
||||||
new_canvases[change] = temp
|
new_canvases[change] = temp
|
||||||
|
|
|
@ -25,10 +25,10 @@ func _on_FrameTagDialog_about_to_show() -> void:
|
||||||
var vbox_cont := VBoxContainer.new()
|
var vbox_cont := VBoxContainer.new()
|
||||||
var hbox_cont := HBoxContainer.new()
|
var hbox_cont := HBoxContainer.new()
|
||||||
var tag_label := Label.new()
|
var tag_label := Label.new()
|
||||||
if tag[2] == tag[3]:
|
if tag.from == tag.to:
|
||||||
tag_label.text = "Tag %s (Frame %s)" % [i + 1, tag[2]]
|
tag_label.text = "Tag %s (Frame %s)" % [i + 1, tag.from]
|
||||||
else:
|
else:
|
||||||
tag_label.text = "Tag %s (Frames %s-%s)" % [i + 1, tag[2], tag[3]]
|
tag_label.text = "Tag %s (Frames %s-%s)" % [i + 1, tag.from, tag.to]
|
||||||
hbox_cont.add_child(tag_label)
|
hbox_cont.add_child(tag_label)
|
||||||
|
|
||||||
var edit_button := Button.new()
|
var edit_button := Button.new()
|
||||||
|
@ -39,8 +39,8 @@ func _on_FrameTagDialog_about_to_show() -> void:
|
||||||
vbox_cont.add_child(hbox_cont)
|
vbox_cont.add_child(hbox_cont)
|
||||||
|
|
||||||
var name_label := Label.new()
|
var name_label := Label.new()
|
||||||
name_label.text = tag[0]
|
name_label.text = tag.name
|
||||||
name_label.modulate = tag[1]
|
name_label.modulate = tag.color
|
||||||
vbox_cont.add_child(name_label)
|
vbox_cont.add_child(name_label)
|
||||||
|
|
||||||
var hsep := HSeparator.new()
|
var hsep := HSeparator.new()
|
||||||
|
@ -70,10 +70,10 @@ func _on_AddTag_pressed() -> void:
|
||||||
func _on_EditButton_pressed(_tag_id : int) -> void:
|
func _on_EditButton_pressed(_tag_id : int) -> void:
|
||||||
options_dialog.popup_centered()
|
options_dialog.popup_centered()
|
||||||
current_tag_id = _tag_id
|
current_tag_id = _tag_id
|
||||||
options_dialog.get_node("GridContainer/NameLineEdit").text = Global.animation_tags[_tag_id][0]
|
options_dialog.get_node("GridContainer/NameLineEdit").text = Global.animation_tags[_tag_id].name
|
||||||
options_dialog.get_node("GridContainer/ColorPickerButton").color = Global.animation_tags[_tag_id][1]
|
options_dialog.get_node("GridContainer/ColorPickerButton").color = Global.animation_tags[_tag_id].color
|
||||||
options_dialog.get_node("GridContainer/FromSpinBox").value = Global.animation_tags[_tag_id][2]
|
options_dialog.get_node("GridContainer/FromSpinBox").value = Global.animation_tags[_tag_id].from
|
||||||
options_dialog.get_node("GridContainer/ToSpinBox").value = Global.animation_tags[_tag_id][3]
|
options_dialog.get_node("GridContainer/ToSpinBox").value = Global.animation_tags[_tag_id].to
|
||||||
if !delete_tag_button:
|
if !delete_tag_button:
|
||||||
delete_tag_button = options_dialog.add_button("Delete Tag", true, "delete_tag")
|
delete_tag_button = options_dialog.add_button("Delete Tag", true, "delete_tag")
|
||||||
else:
|
else:
|
||||||
|
@ -92,14 +92,19 @@ func _on_TagOptions_confirmed() -> void:
|
||||||
if tag_from > tag_to:
|
if tag_from > tag_to:
|
||||||
tag_from = tag_to
|
tag_from = tag_to
|
||||||
|
|
||||||
var new_animation_tags := Global.animation_tags.duplicate(true)
|
var new_animation_tags := Global.animation_tags.duplicate()
|
||||||
|
# Loop through the tags to create new classes for them, so that they won't be the same
|
||||||
|
# as Global.animation_tags's classes. Needed for undo/redo to work properly.
|
||||||
|
for i in new_animation_tags.size():
|
||||||
|
new_animation_tags[i] = AnimationTag.new(new_animation_tags[i].name, new_animation_tags[i].color, new_animation_tags[i].from, new_animation_tags[i].to)
|
||||||
|
|
||||||
if current_tag_id == Global.animation_tags.size():
|
if current_tag_id == Global.animation_tags.size():
|
||||||
new_animation_tags.append([tag_name, tag_color, tag_from, tag_to])
|
new_animation_tags.append(AnimationTag.new(tag_name, tag_color, tag_from, tag_to))
|
||||||
else:
|
else:
|
||||||
new_animation_tags[current_tag_id][0] = tag_name
|
new_animation_tags[current_tag_id].name = tag_name
|
||||||
new_animation_tags[current_tag_id][1] = tag_color
|
new_animation_tags[current_tag_id].color = tag_color
|
||||||
new_animation_tags[current_tag_id][2] = tag_from
|
new_animation_tags[current_tag_id].from = tag_from
|
||||||
new_animation_tags[current_tag_id][3] = tag_to
|
new_animation_tags[current_tag_id].to = tag_to
|
||||||
|
|
||||||
# Handle Undo/Redo
|
# Handle Undo/Redo
|
||||||
Global.undos += 1
|
Global.undos += 1
|
||||||
|
@ -114,7 +119,7 @@ func _on_TagOptions_confirmed() -> void:
|
||||||
|
|
||||||
func _on_TagOptions_custom_action(action : String) -> void:
|
func _on_TagOptions_custom_action(action : String) -> void:
|
||||||
if action == "delete_tag":
|
if action == "delete_tag":
|
||||||
var new_animation_tags := Global.animation_tags.duplicate(true)
|
var new_animation_tags := Global.animation_tags.duplicate()
|
||||||
new_animation_tags.remove(current_tag_id)
|
new_animation_tags.remove(current_tag_id)
|
||||||
# Handle Undo/Redo
|
# Handle Undo/Redo
|
||||||
Global.undos += 1
|
Global.undos += 1
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene load_steps=3 format=2]
|
[gd_scene load_steps=3 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://src/UI/Dialogs/FrameTagDialog.gd" type="Script" id=1]
|
[ext_resource path="res://src/UI/Timeline/FrameTagDialog.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://assets/graphics/dark_themes/timeline/new_frame.png" type="Texture" id=2]
|
[ext_resource path="res://assets/graphics/dark_themes/timeline/new_frame.png" type="Texture" id=2]
|
||||||
|
|
||||||
[node name="FrameTagDialog" type="AcceptDialog"]
|
[node name="FrameTagDialog" type="AcceptDialog"]
|
|
@ -16,7 +16,7 @@ func _ready() -> void:
|
||||||
label = Global.find_node_by_name(self, "Label")
|
label = Global.find_node_by_name(self, "Label")
|
||||||
line_edit = Global.find_node_by_name(self, "LineEdit")
|
line_edit = Global.find_node_by_name(self, "LineEdit")
|
||||||
|
|
||||||
if Global.layers[i][1]:
|
if Global.layers[i].visible:
|
||||||
Global.change_button_texturerect(visibility_button.get_child(0), "layer_visible.png")
|
Global.change_button_texturerect(visibility_button.get_child(0), "layer_visible.png")
|
||||||
visibility_button.get_child(0).rect_size = Vector2(24, 14)
|
visibility_button.get_child(0).rect_size = Vector2(24, 14)
|
||||||
visibility_button.get_child(0).rect_position = Vector2(4, 9)
|
visibility_button.get_child(0).rect_position = Vector2(4, 9)
|
||||||
|
@ -25,12 +25,12 @@ func _ready() -> void:
|
||||||
visibility_button.get_child(0).rect_size = Vector2(24, 8)
|
visibility_button.get_child(0).rect_size = Vector2(24, 8)
|
||||||
visibility_button.get_child(0).rect_position = Vector2(4, 12)
|
visibility_button.get_child(0).rect_position = Vector2(4, 12)
|
||||||
|
|
||||||
if Global.layers[i][2]:
|
if Global.layers[i].locked:
|
||||||
Global.change_button_texturerect(lock_button.get_child(0), "lock.png")
|
Global.change_button_texturerect(lock_button.get_child(0), "lock.png")
|
||||||
else:
|
else:
|
||||||
Global.change_button_texturerect(lock_button.get_child(0), "unlock.png")
|
Global.change_button_texturerect(lock_button.get_child(0), "unlock.png")
|
||||||
|
|
||||||
if Global.layers[i][4]: # If new layers will be linked
|
if Global.layers[i].new_cels_linked: # If new layers will be linked
|
||||||
Global.change_button_texturerect(linked_button.get_child(0), "linked_layer.png")
|
Global.change_button_texturerect(linked_button.get_child(0), "linked_layer.png")
|
||||||
else:
|
else:
|
||||||
Global.change_button_texturerect(linked_button.get_child(0), "unlinked_layer.png")
|
Global.change_button_texturerect(linked_button.get_child(0), "unlinked_layer.png")
|
||||||
|
@ -59,20 +59,20 @@ func save_layer_name(new_name : String) -> void:
|
||||||
line_edit.editable = false
|
line_edit.editable = false
|
||||||
label.text = new_name
|
label.text = new_name
|
||||||
Global.layers_changed_skip = true
|
Global.layers_changed_skip = true
|
||||||
Global.layers[i][0] = new_name
|
Global.layers[i].name = new_name
|
||||||
|
|
||||||
|
|
||||||
func _on_VisibilityButton_pressed() -> void:
|
func _on_VisibilityButton_pressed() -> void:
|
||||||
Global.layers[i][1] = !Global.layers[i][1]
|
Global.layers[i].visible = !Global.layers[i].visible
|
||||||
Global.canvas.update()
|
Global.canvas.update()
|
||||||
|
|
||||||
|
|
||||||
func _on_LockButton_pressed() -> void:
|
func _on_LockButton_pressed() -> void:
|
||||||
Global.layers[i][2] = !Global.layers[i][2]
|
Global.layers[i].locked = !Global.layers[i].locked
|
||||||
|
|
||||||
|
|
||||||
func _on_LinkButton_pressed() -> void:
|
func _on_LinkButton_pressed() -> void:
|
||||||
Global.layers[i][4] = !Global.layers[i][4]
|
Global.layers[i].new_cels_linked = !Global.layers[i].new_cels_linked
|
||||||
if Global.layers[i][4] && !Global.layers[i][5]:
|
if Global.layers[i].new_cels_linked && !Global.layers[i].linked_cels:
|
||||||
Global.layers[i][5].append(Global.canvas)
|
Global.layers[i].linked_cels.append(Global.canvas)
|
||||||
Global.layers[i][3].get_child(Global.current_frame)._ready()
|
Global.layers[i].frame_container.get_child(Global.current_frame)._ready()
|
||||||
|
|
|
@ -33,89 +33,66 @@ func _input(event : InputEvent) -> void:
|
||||||
|
|
||||||
func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_left := true) -> void:
|
func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_left := true) -> void:
|
||||||
var current_action := tool_pressed.name
|
var current_action := tool_pressed.name
|
||||||
|
var current_tool : int = Global.Tools.keys().find(current_action.to_upper())
|
||||||
|
var left_tool_name := str(Global.Tools.keys()[Global.current_tools[0]]).to_lower()
|
||||||
|
var right_tool_name := str(Global.Tools.keys()[Global.current_tools[1]]).to_lower()
|
||||||
|
var current_mouse_button := -1
|
||||||
|
|
||||||
if (mouse_press and Input.is_action_just_released("left_mouse")) or (!mouse_press and key_for_left):
|
if (mouse_press and Input.is_action_just_released("left_mouse")) or (!mouse_press and key_for_left):
|
||||||
Global.current_left_tool = current_action
|
left_tool_name = current_action.to_lower()
|
||||||
|
current_mouse_button = Global.Mouse_Button.LEFT
|
||||||
# Start from 1, so the label won't get invisible
|
|
||||||
for i in range(1, Global.left_tool_options_container.get_child_count()):
|
|
||||||
Global.left_tool_options_container.get_child(i).visible = false
|
|
||||||
|
|
||||||
Global.left_tool_options_container.get_node("EmptySpacer").visible = true
|
|
||||||
|
|
||||||
# Tool options visible depending on the selected tool
|
|
||||||
if current_action == "Pencil":
|
|
||||||
Global.left_brush_type_container.visible = true
|
|
||||||
Global.left_brush_size_slider.visible = true
|
|
||||||
Global.left_pixel_perfect_container.visible = true
|
|
||||||
Global.left_mirror_container.visible = true
|
|
||||||
if Global.current_left_brush_type == Global.Brush_Types.FILE or Global.current_left_brush_type == Global.Brush_Types.CUSTOM or Global.current_left_brush_type == Global.Brush_Types.RANDOM_FILE:
|
|
||||||
Global.left_color_interpolation_container.visible = true
|
|
||||||
elif current_action == "Eraser":
|
|
||||||
Global.left_brush_type_container.visible = true
|
|
||||||
Global.left_brush_size_slider.visible = true
|
|
||||||
Global.left_pixel_perfect_container.visible = true
|
|
||||||
Global.left_mirror_container.visible = true
|
|
||||||
elif current_action == "Bucket":
|
|
||||||
Global.left_fill_area_container.visible = true
|
|
||||||
Global.left_mirror_container.visible = true
|
|
||||||
elif current_action == "LightenDarken":
|
|
||||||
Global.left_brush_type_container.visible = true
|
|
||||||
Global.left_brush_size_slider.visible = true
|
|
||||||
Global.left_pixel_perfect_container.visible = true
|
|
||||||
Global.left_ld_container.visible = true
|
|
||||||
Global.left_mirror_container.visible = true
|
|
||||||
elif current_action == "ColorPicker":
|
|
||||||
Global.left_colorpicker_container.visible = true
|
|
||||||
elif current_action == "Zoom":
|
|
||||||
Global.left_zoom_container.visible = true
|
|
||||||
|
|
||||||
elif (mouse_press and Input.is_action_just_released("right_mouse")) or (!mouse_press and !key_for_left):
|
elif (mouse_press and Input.is_action_just_released("right_mouse")) or (!mouse_press and !key_for_left):
|
||||||
Global.current_right_tool = current_action
|
right_tool_name = current_action.to_lower()
|
||||||
# Start from 1, so the label won't get invisible
|
current_mouse_button = Global.Mouse_Button.RIGHT
|
||||||
for i in range(1, Global.right_tool_options_container.get_child_count()):
|
|
||||||
Global.right_tool_options_container.get_child(i).visible = false
|
|
||||||
|
|
||||||
Global.right_tool_options_container.get_node("EmptySpacer").visible = true
|
if current_mouse_button != -1:
|
||||||
|
Global.current_tools[current_mouse_button] = current_tool
|
||||||
|
# Start from 1, so the label won't get invisible
|
||||||
|
for i in range(1, Global.tool_options_containers[current_mouse_button].get_child_count()):
|
||||||
|
Global.tool_options_containers[current_mouse_button].get_child(i).visible = false
|
||||||
|
|
||||||
|
Global.tool_options_containers[current_mouse_button].get_node("EmptySpacer").visible = true
|
||||||
|
|
||||||
# Tool options visible depending on the selected tool
|
# Tool options visible depending on the selected tool
|
||||||
if current_action == "Pencil":
|
if current_tool == Global.Tools.PENCIL:
|
||||||
Global.right_brush_type_container.visible = true
|
Global.brush_type_containers[current_mouse_button].visible = true
|
||||||
Global.right_brush_size_slider.visible = true
|
Global.brush_size_sliders[current_mouse_button].visible = true
|
||||||
Global.right_pixel_perfect_container.visible = true
|
Global.pixel_perfect_containers[current_mouse_button].visible = true
|
||||||
Global.right_mirror_container.visible = true
|
Global.mirror_containers[current_mouse_button].visible = true
|
||||||
if Global.current_right_brush_type == Global.Brush_Types.FILE or Global.current_right_brush_type == Global.Brush_Types.CUSTOM or Global.current_right_brush_type == Global.Brush_Types.RANDOM_FILE:
|
if Global.current_brush_types[current_mouse_button] == Global.Brush_Types.FILE or Global.current_brush_types[current_mouse_button] == Global.Brush_Types.CUSTOM or Global.current_brush_types[current_mouse_button] == Global.Brush_Types.RANDOM_FILE:
|
||||||
Global.right_color_interpolation_container.visible = true
|
Global.color_interpolation_containers[current_mouse_button].visible = true
|
||||||
elif current_action == "Eraser":
|
elif current_tool == Global.Tools.ERASER:
|
||||||
Global.right_brush_type_container.visible = true
|
Global.brush_type_containers[current_mouse_button].visible = true
|
||||||
Global.right_brush_size_slider.visible = true
|
Global.brush_size_sliders[current_mouse_button].visible = true
|
||||||
Global.right_pixel_perfect_container.visible = true
|
Global.pixel_perfect_containers[current_mouse_button].visible = true
|
||||||
Global.right_mirror_container.visible = true
|
Global.mirror_containers[current_mouse_button].visible = true
|
||||||
elif current_action == "Bucket":
|
elif current_tool == Global.Tools.BUCKET:
|
||||||
Global.right_fill_area_container.visible = true
|
Global.fill_area_containers[current_mouse_button].visible = true
|
||||||
Global.right_mirror_container.visible = true
|
Global.mirror_containers[current_mouse_button].visible = true
|
||||||
elif current_action == "LightenDarken":
|
elif current_tool == Global.Tools.LIGHTENDARKEN:
|
||||||
Global.right_brush_type_container.visible = true
|
Global.brush_type_containers[current_mouse_button].visible = true
|
||||||
Global.right_brush_size_slider.visible = true
|
Global.brush_size_sliders[current_mouse_button].visible = true
|
||||||
Global.right_pixel_perfect_container.visible = true
|
Global.pixel_perfect_containers[current_mouse_button].visible = true
|
||||||
Global.right_ld_container.visible = true
|
Global.ld_containers[current_mouse_button].visible = true
|
||||||
Global.right_mirror_container.visible = true
|
Global.mirror_containers[current_mouse_button].visible = true
|
||||||
elif current_action == "ColorPicker":
|
elif current_tool == Global.Tools.COLORPICKER:
|
||||||
Global.right_colorpicker_container.visible = true
|
Global.colorpicker_containers[current_mouse_button].visible = true
|
||||||
elif current_action == "Zoom":
|
elif current_tool == Global.Tools.ZOOM:
|
||||||
Global.right_zoom_container.visible = true
|
Global.zoom_containers[current_mouse_button].visible = true
|
||||||
|
|
||||||
for t in tools:
|
for t in tools:
|
||||||
var tool_name : String = t[0].name
|
var tool_name : String = t[0].name.to_lower()
|
||||||
var texture_button : TextureRect = t[0].get_child(0)
|
var texture_button : TextureRect = t[0].get_child(0)
|
||||||
|
|
||||||
if tool_name == Global.current_left_tool and tool_name == Global.current_right_tool:
|
if tool_name == left_tool_name and tool_name == right_tool_name:
|
||||||
Global.change_button_texturerect(texture_button, "%s_l_r.png" % tool_name.to_lower())
|
Global.change_button_texturerect(texture_button, "%s_l_r.png" % tool_name.to_lower())
|
||||||
elif tool_name == Global.current_left_tool:
|
elif tool_name == left_tool_name:
|
||||||
Global.change_button_texturerect(texture_button, "%s_l.png" % tool_name.to_lower())
|
Global.change_button_texturerect(texture_button, "%s_l.png" % tool_name.to_lower())
|
||||||
elif tool_name == Global.current_right_tool:
|
elif tool_name == right_tool_name:
|
||||||
Global.change_button_texturerect(texture_button, "%s_r.png" % tool_name.to_lower())
|
Global.change_button_texturerect(texture_button, "%s_r.png" % tool_name.to_lower())
|
||||||
else:
|
else:
|
||||||
Global.change_button_texturerect(texture_button, "%s.png" % tool_name.to_lower())
|
Global.change_button_texturerect(texture_button, "%s.png" % tool_name.to_lower())
|
||||||
|
|
||||||
Global.left_cursor_tool_texture.create_from_image(load("res://assets/graphics/cursor_icons/%s_cursor.png" % Global.current_left_tool.to_lower()), 0)
|
Global.left_cursor_tool_texture.create_from_image(load("res://assets/graphics/cursor_icons/%s_cursor.png" % left_tool_name), 0)
|
||||||
Global.right_cursor_tool_texture.create_from_image(load("res://assets/graphics/cursor_icons/%s_cursor.png" % Global.current_right_tool.to_lower()), 0)
|
Global.right_cursor_tool_texture.create_from_image(load("res://assets/graphics/cursor_icons/%s_cursor.png" % right_tool_name), 0)
|
||||||
|
|
|
@ -7,6 +7,9 @@ margin_right = 1280.0
|
||||||
margin_bottom = 28.0
|
margin_bottom = 28.0
|
||||||
rect_min_size = Vector2( 0, 28 )
|
rect_min_size = Vector2( 0, 28 )
|
||||||
custom_styles/panel = ExtResource( 1 )
|
custom_styles/panel = ExtResource( 1 )
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
[node name="MenuItems" type="HBoxContainer" parent="."]
|
[node name="MenuItems" type="HBoxContainer" parent="."]
|
||||||
margin_left = 2.0
|
margin_left = 2.0
|
||||||
|
@ -17,40 +20,40 @@ __meta__ = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="FileMenu" type="MenuButton" parent="MenuItems"]
|
[node name="FileMenu" type="MenuButton" parent="MenuItems"]
|
||||||
margin_right = 29.0
|
margin_right = 35.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 20.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
text = "File"
|
text = "File"
|
||||||
switch_on_hover = true
|
switch_on_hover = true
|
||||||
|
|
||||||
[node name="EditMenu" type="MenuButton" parent="MenuItems"]
|
[node name="EditMenu" type="MenuButton" parent="MenuItems"]
|
||||||
margin_left = 33.0
|
margin_left = 39.0
|
||||||
margin_right = 64.0
|
margin_right = 75.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 20.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
text = "Edit"
|
text = "Edit"
|
||||||
switch_on_hover = true
|
switch_on_hover = true
|
||||||
|
|
||||||
[node name="ViewMenu" type="MenuButton" parent="MenuItems"]
|
[node name="ViewMenu" type="MenuButton" parent="MenuItems"]
|
||||||
margin_left = 68.0
|
margin_left = 79.0
|
||||||
margin_right = 104.0
|
margin_right = 121.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 20.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
text = "View"
|
text = "View"
|
||||||
switch_on_hover = true
|
switch_on_hover = true
|
||||||
|
|
||||||
[node name="ImageMenu" type="MenuButton" parent="MenuItems"]
|
[node name="ImageMenu" type="MenuButton" parent="MenuItems"]
|
||||||
margin_left = 108.0
|
margin_left = 125.0
|
||||||
margin_right = 152.0
|
margin_right = 177.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 20.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
text = "Image"
|
text = "Image"
|
||||||
switch_on_hover = true
|
switch_on_hover = true
|
||||||
|
|
||||||
[node name="HelpMenu" type="MenuButton" parent="MenuItems"]
|
[node name="HelpMenu" type="MenuButton" parent="MenuItems"]
|
||||||
margin_left = 156.0
|
margin_left = 181.0
|
||||||
margin_right = 191.0
|
margin_right = 223.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 20.0
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
text = "Help"
|
text = "Help"
|
||||||
switch_on_hover = true
|
switch_on_hover = true
|
||||||
|
@ -67,7 +70,7 @@ __meta__ = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="ZoomLevel" type="Label" parent="TopLabels"]
|
[node name="ZoomLevel" type="Label" parent="TopLabels"]
|
||||||
margin_top = 6.0
|
margin_top = 7.0
|
||||||
margin_right = 60.0
|
margin_right = 60.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 21.0
|
||||||
rect_min_size = Vector2( 60, 0 )
|
rect_min_size = Vector2( 60, 0 )
|
||||||
|
@ -76,8 +79,8 @@ align = 2
|
||||||
|
|
||||||
[node name="CursorPosition" type="Label" parent="TopLabels"]
|
[node name="CursorPosition" type="Label" parent="TopLabels"]
|
||||||
margin_left = 80.0
|
margin_left = 80.0
|
||||||
margin_top = 6.0
|
margin_top = 7.0
|
||||||
margin_right = 120.0
|
margin_right = 128.0
|
||||||
margin_bottom = 21.0
|
margin_bottom = 21.0
|
||||||
text = "[64×64]"
|
text = "[64×64]"
|
||||||
align = 2
|
align = 2
|
||||||
|
@ -98,12 +101,20 @@ __meta__ = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="CurrentFrame" type="Label" parent="HBoxContainer"]
|
[node name="CurrentFrame" type="Label" parent="HBoxContainer"]
|
||||||
margin_left = 113.0
|
margin_left = 106.0
|
||||||
margin_top = 6.0
|
margin_right = 198.0
|
||||||
margin_right = 216.0
|
margin_bottom = 28.0
|
||||||
margin_bottom = 21.0
|
size_flags_vertical = 1
|
||||||
text = "Current Frame: 1/1"
|
text = "Current frame:"
|
||||||
valign = 1
|
valign = 1
|
||||||
__meta__ = {
|
__meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[node name="CurrentFrameMark" type="Label" parent="HBoxContainer"]
|
||||||
|
margin_left = 202.0
|
||||||
|
margin_right = 223.0
|
||||||
|
margin_bottom = 28.0
|
||||||
|
size_flags_vertical = 1
|
||||||
|
text = "1/2"
|
||||||
|
valign = 1
|
||||||
|
|
|
@ -59,7 +59,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Tools" type="VBoxContainer" parent="ToolPanel/PanelContainer"]
|
[node name="ToolButtons" type="VBoxContainer" parent="ToolPanel/PanelContainer"]
|
||||||
margin_left = 7.0
|
margin_left = 7.0
|
||||||
margin_top = 7.0
|
margin_top = 7.0
|
||||||
margin_right = 39.0
|
margin_right = 39.0
|
||||||
|
@ -69,7 +69,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="RectSelect" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="RectSelect" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
|
@ -78,7 +78,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/RectSelect"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/RectSelect"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 12 )
|
texture = ExtResource( 12 )
|
||||||
|
@ -86,7 +86,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Zoom" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="Zoom" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_top = 36.0
|
margin_top = 36.0
|
||||||
|
@ -96,7 +96,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/Zoom"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/Zoom"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 21 )
|
texture = ExtResource( 21 )
|
||||||
|
@ -104,7 +104,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="ColorPicker" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="ColorPicker" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_top = 72.0
|
margin_top = 72.0
|
||||||
|
@ -114,7 +114,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/ColorPicker"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/ColorPicker"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 11 )
|
texture = ExtResource( 11 )
|
||||||
|
@ -122,7 +122,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Pencil" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="Pencil" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_top = 108.0
|
margin_top = 108.0
|
||||||
|
@ -132,7 +132,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/Pencil"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/Pencil"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 14 )
|
texture = ExtResource( 14 )
|
||||||
|
@ -140,7 +140,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Eraser" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="Eraser" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_top = 144.0
|
margin_top = 144.0
|
||||||
|
@ -150,7 +150,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/Eraser"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/Eraser"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 13 )
|
texture = ExtResource( 13 )
|
||||||
|
@ -158,7 +158,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Bucket" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="Bucket" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_top = 180.0
|
margin_top = 180.0
|
||||||
|
@ -168,7 +168,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/Bucket"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/Bucket"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 10 )
|
texture = ExtResource( 10 )
|
||||||
|
@ -176,7 +176,7 @@ __meta__ = {
|
||||||
"_edit_use_anchors_": false
|
"_edit_use_anchors_": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="LightenDarken" type="Button" parent="ToolPanel/PanelContainer/Tools" groups=[
|
[node name="LightenDarken" type="Button" parent="ToolPanel/PanelContainer/ToolButtons" groups=[
|
||||||
"UIButtons",
|
"UIButtons",
|
||||||
]]
|
]]
|
||||||
margin_top = 216.0
|
margin_top = 216.0
|
||||||
|
@ -186,7 +186,7 @@ rect_min_size = Vector2( 32, 32 )
|
||||||
mouse_default_cursor_shape = 2
|
mouse_default_cursor_shape = 2
|
||||||
button_mask = 3
|
button_mask = 3
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/Tools/LightenDarken"]
|
[node name="TextureRect" type="TextureRect" parent="ToolPanel/PanelContainer/ToolButtons/LightenDarken"]
|
||||||
margin_right = 32.0
|
margin_right = 32.0
|
||||||
margin_bottom = 32.0
|
margin_bottom = 32.0
|
||||||
texture = ExtResource( 15 )
|
texture = ExtResource( 15 )
|
||||||
|
|
Loading…
Reference in a new issue