1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-07 19:09:50 +00:00

Merge branch 'Orama-Interactive:master' into 3d-box

This commit is contained in:
Variable 2023-10-31 17:08:57 +05:00 committed by GitHub
commit b6aa769534
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 27 deletions

View file

@ -5,10 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<br><br> <br><br>
## [v1.0] - Unreleased ## [v1.0] - Unreleased
This update has been brought to you by the contributions of:
Fayez Akhtar ([@Variable-ind](https://github.com/Variable-ind))
Built using Godot 4.1.2 Built using Godot 4.1.2
### Added ### Added
- Support for multiple layer blend modes are finally here! [#911](https://github.com/Orama-Interactive/Pixelorama/pull/911)
- Export to webp and jpeg file formats. Webp is currently only for static images and does not support animations. - Export to webp and jpeg file formats. Webp is currently only for static images and does not support animations.
- Added some missing shortcuts for buttons. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - Added some missing shortcuts for buttons. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
- The brush increment/decrement shortcuts can now be changed. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - The brush increment/decrement shortcuts can now be changed. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
@ -19,12 +22,13 @@ Built using Godot 4.1.2
### Changed ### Changed
- The color picker has been vastly improved, thanks to the update to Godot 4. Users can now use the OKHSL color mode, and choose between four different picker shapes: HSV Rectangle (default), HSV Wheel, VHS Circle and OKHSL Circle. - The color picker has been vastly improved, thanks to the update to Godot 4. Users can now use the OKHSL color mode, and choose between four different picker shapes: HSV Rectangle (default), HSV Wheel, VHS Circle and OKHSL Circle.
- Every shader-based image effect is automatically working without the need to change renderers, and they all work now on the Web version. This comes at the cost of less compatibility, as the desktop version now requires OpenGL 3.3 minimum instead of 2.1, and the Web version requires WebGL 2 instead of WebGL 1. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - Every shader-based image effect is automatically working without the need to change renderers, and they all work now on the Web version. This comes at the cost of less compatibility, as the desktop version now requires OpenGL 3.3 minimum instead of 2.1, and the Web version requires WebGL 2 instead of WebGL 1. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
- When deleting an extension, a confirmation window now appears that lets users either to delete the palette permanently, move it to trash, or cancel. [#919](https://github.com/Orama-Interactive/Pixelorama/pull/919)
### Fixed ### Fixed
- Performance when drawing and doing operations such as bucket area fill should be better now. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900) - Performance when drawing and doing operations such as bucket area fill should be better now. [#900](https://github.com/Orama-Interactive/Pixelorama/pull/900)
- Dividing by zero in value sliders and spinboxes no longer crashes the program. - Dividing by zero in value sliders and spinboxes no longer crashes the program.
## [v0.11.3] - Unreleased ## [v0.11.3] - 2023-10-30
This update has been brought to you by the contributions of: This update has been brought to you by the contributions of:
Fayez Akhtar ([@Variable-ind](https://github.com/Variable-ind)) Fayez Akhtar ([@Variable-ind](https://github.com/Variable-ind))
@ -36,6 +40,7 @@ Built using Godot 3.5.2
### Fixed ### Fixed
- Fixed undo/redo history not working when the tool changes. [#916](https://github.com/Orama-Interactive/Pixelorama/pull/916) - Fixed undo/redo history not working when the tool changes. [#916](https://github.com/Orama-Interactive/Pixelorama/pull/916)
- Pixelorama no longer closes when the project fails to be saved if "Save & Exit" is selected. [#920](https://github.com/Orama-Interactive/Pixelorama/pull/920) - Pixelorama no longer closes when the project fails to be saved if "Save & Exit" is selected. [#920](https://github.com/Orama-Interactive/Pixelorama/pull/920)
- Projects with 3D cels saved in 1.x can now be opened in 0.11.3. [#928](https://github.com/Orama-Interactive/Pixelorama/pull/928)
## [v0.11.2] - 2023-08-31 ## [v0.11.2] - 2023-08-31
This update has been brought to you by the contributions of: This update has been brought to you by the contributions of:

View file

@ -1,6 +1,10 @@
extends Control extends Control
enum UninstallMode { KEEP_FILE, FILE_TO_BIN, REMOVE_PERMANENT }
const EXTENSIONS_PATH := "user://extensions" const EXTENSIONS_PATH := "user://extensions"
const BUG_EXTENSIONS_PATH := "user://give_in_bug_report"
const BIN_ACTION := "trash"
var extensions := {} ## Extension name: Extension class var extensions := {} ## Extension name: Extension class
var extension_selected := -1 var extension_selected := -1
@ -10,6 +14,7 @@ var damaged_extension: String
@onready var enable_button: Button = $HBoxContainer/EnableButton @onready var enable_button: Button = $HBoxContainer/EnableButton
@onready var uninstall_button: Button = $HBoxContainer/UninstallButton @onready var uninstall_button: Button = $HBoxContainer/UninstallButton
@onready var extension_parent: Node = Global.control.get_node("Extensions") @onready var extension_parent: Node = Global.control.get_node("Extensions")
@onready var delete_confirmation: ConfirmationDialog = %DeleteConfirmation
class Extension: class Extension:
@ -40,6 +45,7 @@ class Extension:
func _ready() -> void: func _ready() -> void:
delete_confirmation.add_button(tr("Move to Trash"), false, BIN_ACTION)
if OS.get_name() == "Web": if OS.get_name() == "Web":
$HBoxContainer/AddExtensionButton.disabled = true $HBoxContainer/AddExtensionButton.disabled = true
$HBoxContainer/OpenFolderButton.visible = false $HBoxContainer/OpenFolderButton.visible = false
@ -74,9 +80,18 @@ func install_extension(path: String) -> void:
_add_extension(file_name) _add_extension(file_name)
func _uninstall_extension(file_name := "", remove_file := true, item := extension_selected) -> void: func _uninstall_extension(
if remove_file: file_name := "", remove_mode := UninstallMode.REMOVE_PERMANENT, item := extension_selected
var err := DirAccess.remove_absolute(EXTENSIONS_PATH.path_join(file_name)) ) -> void:
var err := OK
match remove_mode:
UninstallMode.FILE_TO_BIN:
err = OS.move_to_trash(
ProjectSettings.globalize_path(EXTENSIONS_PATH).path_join(file_name)
)
UninstallMode.REMOVE_PERMANENT:
err = DirAccess.remove_absolute(EXTENSIONS_PATH.path_join(file_name))
if remove_mode != UninstallMode.KEEP_FILE:
if err != OK: if err != OK:
print(err) print(err)
return return
@ -94,16 +109,21 @@ func _uninstall_extension(file_name := "", remove_file := true, item := extensio
func _add_extension(file_name: String) -> void: func _add_extension(file_name: String) -> void:
var tester_file: FileAccess # For testing and deleting damaged extensions var tester_file: FileAccess # For testing and deleting damaged extensions
var remover_directory := DirAccess.open(EXTENSIONS_PATH)
# Remove any extension that was proven guilty before this extension is loaded # Remove any extension that was proven guilty before this extension is loaded
if remover_directory.file_exists(EXTENSIONS_PATH.path_join("Faulty.txt")): if FileAccess.file_exists(EXTENSIONS_PATH.path_join("Faulty.txt")):
# This code will only run if pixelorama crashed # This code will only run if pixelorama crashed
var faulty_path := EXTENSIONS_PATH.path_join("Faulty.txt") var faulty_path := EXTENSIONS_PATH.path_join("Faulty.txt")
tester_file = FileAccess.open(faulty_path, FileAccess.READ) tester_file = FileAccess.open(faulty_path, FileAccess.READ)
damaged_extension = tester_file.get_as_text() damaged_extension = tester_file.get_as_text()
tester_file.close() tester_file.close()
remover_directory.remove(EXTENSIONS_PATH.path_join(damaged_extension)) # don't delete the extension permanently
remover_directory.remove(EXTENSIONS_PATH.path_join("Faulty.txt")) # (so that it may be given to the developer in the bug report)
DirAccess.make_dir_recursive_absolute(BUG_EXTENSIONS_PATH)
DirAccess.rename_absolute(
EXTENSIONS_PATH.path_join(damaged_extension),
BUG_EXTENSIONS_PATH.path_join(damaged_extension)
)
DirAccess.remove_absolute(EXTENSIONS_PATH.path_join("Faulty.txt"))
# Don't load a deleted extension # Don't load a deleted extension
if damaged_extension == file_name: if damaged_extension == file_name:
@ -125,7 +145,7 @@ func _add_extension(file_name: String) -> void:
if item == -1: if item == -1:
print("Failed to find %s" % file_name) print("Failed to find %s" % file_name)
return return
_uninstall_extension(file_name, false, item) _uninstall_extension(file_name, UninstallMode.KEEP_FILE, item)
# Wait two frames so the previous nodes can get freed # Wait two frames so the previous nodes can get freed
await get_tree().process_frame await get_tree().process_frame
await get_tree().process_frame await get_tree().process_frame
@ -134,11 +154,14 @@ func _add_extension(file_name: String) -> void:
var file_path := EXTENSIONS_PATH.path_join(file_name) var file_path := EXTENSIONS_PATH.path_join(file_name)
var success := ProjectSettings.load_resource_pack(file_path) var success := ProjectSettings.load_resource_pack(file_path)
if !success: if !success:
print("Failed loading resource pack.") # Don't delete the extension
var dir := DirAccess.open(EXTENSIONS_PATH) # Context: pixelorama deletes v0.11.x extensions when you open v1.0, this will prevent it.
dir.remove(file_path) # OS.move_to_trash(file_path)
print("EXTENSION ERROR: Failed loading resource pack %s." % file_name)
print(" There may be errors in extension code or extension is incompatible")
# Delete the faulty.txt, (it's fate has already been decided)
DirAccess.remove_absolute(EXTENSIONS_PATH.path_join("Faulty.txt"))
return return
var extension_path := "res://src/Extensions/%s/" % file_name_no_ext var extension_path := "res://src/Extensions/%s/" % file_name_no_ext
var extension_config_file_path := extension_path.path_join("extension.json") var extension_config_file_path := extension_path.path_join("extension.json")
var extension_config_file := FileAccess.open(extension_config_file_path, FileAccess.READ) var extension_config_file := FileAccess.open(extension_config_file_path, FileAccess.READ)
@ -176,7 +199,7 @@ func _add_extension(file_name: String) -> void:
Global.dialog_open(true) Global.dialog_open(true)
print("Incompatible API") print("Incompatible API")
# Don't put it in faulty, (it's merely incompatible) # Don't put it in faulty, (it's merely incompatible)
remover_directory.remove(EXTENSIONS_PATH.path_join("Faulty.txt")) DirAccess.remove_absolute(EXTENSIONS_PATH.path_join("Faulty.txt"))
return return
var extension := Extension.new() var extension := Extension.new()
@ -192,7 +215,7 @@ func _add_extension(file_name: String) -> void:
# If an extension doesn't crash pixelorama then it is proven innocent # If an extension doesn't crash pixelorama then it is proven innocent
# And we should now delete its "Faulty.txt" file # And we should now delete its "Faulty.txt" file
remover_directory.remove(EXTENSIONS_PATH.path_join("Faulty.txt")) DirAccess.remove_absolute(EXTENSIONS_PATH.path_join("Faulty.txt"))
func _enable_extension(extension: Extension, save_to_config := true) -> void: func _enable_extension(extension: Extension, save_to_config := true) -> void:
@ -259,7 +282,7 @@ func _on_EnableButton_pressed() -> void:
func _on_UninstallButton_pressed() -> void: func _on_UninstallButton_pressed() -> void:
_uninstall_extension(extension_list.get_item_metadata(extension_selected)) delete_confirmation.popup_centered()
func _on_OpenFolderButton_pressed() -> void: func _on_OpenFolderButton_pressed() -> void:
@ -269,3 +292,15 @@ func _on_OpenFolderButton_pressed() -> void:
func _on_AddExtensionFileDialog_files_selected(paths: PackedStringArray) -> void: func _on_AddExtensionFileDialog_files_selected(paths: PackedStringArray) -> void:
for path in paths: for path in paths:
install_extension(path) install_extension(path)
func _on_delete_confirmation_custom_action(action: StringName) -> void:
if action == BIN_ACTION:
_uninstall_extension(
extension_list.get_item_metadata(extension_selected), UninstallMode.FILE_TO_BIN
)
delete_confirmation.hide()
func _on_delete_confirmation_confirmed() -> void:
_uninstall_extension(extension_list.get_item_metadata(extension_selected))

View file

@ -23,11 +23,11 @@ anchor_bottom = 1.0
offset_left = 8.0 offset_left = 8.0
offset_top = 8.0 offset_top = 8.0
offset_right = -8.0 offset_right = -8.0
offset_bottom = -36.0 offset_bottom = -49.0
size_flags_horizontal = 3 size_flags_horizontal = 3
theme_override_constants/separation = 20 theme_override_constants/separation = 20
theme_override_constants/autohide = 0 theme_override_constants/autohide = 0
split_offset = 1 split_offset = 150
[node name="List" type="ItemList" parent="HSplitContainer"] [node name="List" type="ItemList" parent="HSplitContainer"]
custom_minimum_size = Vector2(85, 0) custom_minimum_size = Vector2(85, 0)
@ -1300,6 +1300,21 @@ access = 2
filters = PackedStringArray("*.pck ; Godot Resource Pack File", "*.zip ;") filters = PackedStringArray("*.pck ; Godot Resource Pack File", "*.zip ;")
show_hidden_files = true show_hidden_files = true
[node name="DeleteConfirmation" type="ConfirmationDialog" parent="."]
unique_name_in_owner = true
position = Vector2i(0, 36)
size = Vector2i(500, 100)
ok_button_text = "Delete Permanently"
[node name="Label" type="Label" parent="DeleteConfirmation"]
offset_left = 8.0
offset_top = 8.0
offset_right = 492.0
offset_bottom = 51.0
text = "Delete Extension?"
horizontal_alignment = 1
vertical_alignment = 1
[connection signal="about_to_popup" from="." to="." method="_on_PreferencesDialog_about_to_show"] [connection signal="about_to_popup" from="." to="." method="_on_PreferencesDialog_about_to_show"]
[connection signal="visibility_changed" from="." to="." method="_on_PreferencesDialog_visibility_changed"] [connection signal="visibility_changed" from="." to="." method="_on_PreferencesDialog_visibility_changed"]
[connection signal="item_selected" from="HSplitContainer/List" to="." method="_on_List_item_selected"] [connection signal="item_selected" from="HSplitContainer/List" to="." method="_on_List_item_selected"]
@ -1312,3 +1327,5 @@ show_hidden_files = true
[connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/HBoxContainer/UninstallButton" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_UninstallButton_pressed"] [connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/HBoxContainer/UninstallButton" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_UninstallButton_pressed"]
[connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/HBoxContainer/OpenFolderButton" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_OpenFolderButton_pressed"] [connection signal="pressed" from="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions/HBoxContainer/OpenFolderButton" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_OpenFolderButton_pressed"]
[connection signal="files_selected" from="Popups/AddExtensionFileDialog" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_AddExtensionFileDialog_files_selected"] [connection signal="files_selected" from="Popups/AddExtensionFileDialog" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_AddExtensionFileDialog_files_selected"]
[connection signal="confirmed" from="DeleteConfirmation" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_delete_confirmation_confirmed"]
[connection signal="custom_action" from="DeleteConfirmation" to="HSplitContainer/VBoxContainer/ScrollContainer/RightSide/Extensions" method="_on_delete_confirmation_custom_action"]

View file

@ -77,6 +77,7 @@ var _object_names := {
func sprite_changed_this_frame(): func sprite_changed_this_frame():
_checker_update_qued = true _checker_update_qued = true
_old_cel_image = _cel.get_image() _old_cel_image = _cel.get_image()
Global.canvas.sprite_changed_this_frame = true
func _input(_event: InputEvent) -> void: func _input(_event: InputEvent) -> void:

View file

@ -70,7 +70,7 @@ func _input(event: InputEvent) -> void:
): ):
return return
var tmp_position: Vector2 = Global.main_viewport.get_local_mouse_position() var tmp_position := Global.main_viewport.get_local_mouse_position()
if get_velocity: if get_velocity:
var velocity := Input.get_vector( var velocity := Input.get_vector(
"move_mouse_left", "move_mouse_right", "move_mouse_up", "move_mouse_down" "move_mouse_left", "move_mouse_right", "move_mouse_up", "move_mouse_down"
@ -83,14 +83,12 @@ func _input(event: InputEvent) -> void:
var tmp_transform := get_canvas_transform().affine_inverse() var tmp_transform := get_canvas_transform().affine_inverse()
current_pixel = tmp_transform.basis_xform(tmp_position) + tmp_transform.origin current_pixel = tmp_transform.basis_xform(tmp_position) + tmp_transform.origin
if Global.has_focus:
queue_redraw()
sprite_changed_this_frame = false sprite_changed_this_frame = false
Tools.handle_draw(Vector2i(current_pixel.floor()), event) Tools.handle_draw(Vector2i(current_pixel.floor()), event)
if sprite_changed_this_frame: if sprite_changed_this_frame:
if Global.has_focus:
queue_redraw()
update_selected_cels_textures() update_selected_cels_textures()
@ -107,7 +105,7 @@ func update_texture(layer_i: int, frame_i := -1, project := Global.current_proje
frame_i = project.current_frame frame_i = project.current_frame
if frame_i < project.frames.size() and layer_i < project.layers.size(): if frame_i < project.frames.size() and layer_i < project.layers.size():
var current_cel: BaseCel = project.frames[frame_i].cels[layer_i] var current_cel := project.frames[frame_i].cels[layer_i]
current_cel.update_texture() current_cel.update_texture()
@ -116,7 +114,7 @@ func update_selected_cels_textures(project := Global.current_project) -> void:
var frame_index: int = cel_index[0] var frame_index: int = cel_index[0]
var layer_index: int = cel_index[1] var layer_index: int = cel_index[1]
if frame_index < project.frames.size() and layer_index < project.layers.size(): if frame_index < project.frames.size() and layer_index < project.layers.size():
var current_cel: BaseCel = project.frames[frame_index].cels[layer_index] var current_cel := project.frames[frame_index].cels[layer_index]
current_cel.update_texture() current_cel.update_texture()
@ -130,7 +128,8 @@ func draw_layers() -> void:
for i in Global.current_project.layers.size(): for i in Global.current_project.layers.size():
if current_cels[i] is GroupCel: if current_cels[i] is GroupCel:
continue continue
if Global.current_project.layers[i].is_visible_in_hierarchy(): var layer := Global.current_project.layers[i]
if layer.is_visible_in_hierarchy():
var cel_image := current_cels[i].get_image() var cel_image := current_cels[i].get_image()
textures.append(cel_image) textures.append(cel_image)
opacities.append(current_cels[i].opacity) opacities.append(current_cels[i].opacity)
@ -138,7 +137,7 @@ func draw_layers() -> void:
origins.append(Vector2(move_preview_location) / Vector2(cel_image.get_size())) origins.append(Vector2(move_preview_location) / Vector2(cel_image.get_size()))
else: else:
origins.append(Vector2.ZERO) origins.append(Vector2.ZERO)
blend_modes.append(Global.current_project.layers[i].blend_mode) blend_modes.append(layer.blend_mode)
var texture_array := Texture2DArray.new() var texture_array := Texture2DArray.new()
texture_array.create_from_images(textures) texture_array.create_from_images(textures)
material.set_shader_parameter("layers", texture_array) material.set_shader_parameter("layers", texture_array)