diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c85f9340..3561dcc01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,15 +29,17 @@ Laurenz Reinthaler (Schweini07), kleonc, Variable-ind - Frame tags can now be set for frames larger than 100. ([#408](https://github.com/Orama-Interactive/Pixelorama/pull/408)) - The "lock aspect ratio" button in the create new image dialog has been changed to a texture button. - Improved the "Scale Image" dialog. It now automatically sets the size to the current project's size, has a button to lock aspect ratio, and resizing based on percentage. +- Having no active selection no longer treats all the pixels of the canvas as selected. This is also a performance boost, especially for larger images, as Pixelorama no longer has to loop through all of the pixels to select them. - Tile mode rects are now cached for a little speedup. ([#443](https://github.com/Orama-Interactive/Pixelorama/pull/443)) ### Fixed +- Fixed issue with pixels being selected outside of the canvas boundaries, when the selection rectangle was outside the canvas and its size got reduced. - Fixed layer button textures not being updated properly when changing theme. ([#404](https://github.com/Orama-Interactive/Pixelorama/issues/404)) - Keyboard shortcut conflicts between tool shortcuts and other shortcuts that use the "Control" key, like menu shortcuts, have been resolved. ([#407](https://github.com/Orama-Interactive/Pixelorama/pull/407)) - The opacity of a cel and the tile mode opacity are now multiplicative. ([#414](https://github.com/Orama-Interactive/Pixelorama/pull/414)) - Fixed an issue where adding a new layer did not select it, rather it was selecting the above layer of the previously selected layer. ([#424](https://github.com/Orama-Interactive/Pixelorama/pull/424)) - Fixed cel opacity not always being updated on the UI. ([#420](https://github.com/Orama-Interactive/Pixelorama/pull/420)) -- Loading empty backuped projects no longer result in a crash. ([#445](https://github.com/Orama-Interactive/Pixelorama/issues/445)) +- Loading empty backed up projects no longer result in a crash. ([#445](https://github.com/Orama-Interactive/Pixelorama/issues/445)) - Fixed potential index out of bounds error when loading backup files. ([#446](https://github.com/Orama-Interactive/Pixelorama/pull/446))

diff --git a/src/Classes/Drawers.gd b/src/Classes/Drawers.gd index 951a428c0..3be9ca9ed 100644 --- a/src/Classes/Drawers.gd +++ b/src/Classes/Drawers.gd @@ -75,7 +75,7 @@ func set_pixel(image: Image, position: Vector2, color: Color) -> void: var mirror_y = project.y_symmetry_point - position.y var mirror_x_inside : bool var mirror_y_inside : bool - var entire_image_selected : bool = project.selected_pixels.size() == project.size.x * project.size.y + var entire_image_selected : bool = project.selected_pixels.empty() if entire_image_selected: mirror_x_inside = mirror_x >= 0 and mirror_x < project.size.x mirror_y_inside = mirror_y >= 0 and mirror_y < project.size.y diff --git a/src/Classes/ImageEffect.gd b/src/Classes/ImageEffect.gd index 6daab2e00..9f4d711b0 100644 --- a/src/Classes/ImageEffect.gd +++ b/src/Classes/ImageEffect.gd @@ -66,7 +66,7 @@ func _confirmed() -> void: elif affect == ALL_PROJECTS: for project in Global.projects: var _pixels := [] - if selection_checkbox.pressed: + if selection_checkbox.pressed and project.selected_pixels: _pixels = project.selected_pixels.duplicate() else: for x in project.size.x: @@ -90,7 +90,7 @@ func set_nodes() -> void: func _on_SelectionCheckBox_toggled(button_pressed : bool) -> void: pixels.clear() - if button_pressed: + if button_pressed and Global.current_project.selected_pixels: pixels = Global.current_project.selected_pixels.duplicate() else: for x in Global.current_project.size.x: diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index b313c7d62..4d7a57e78 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -42,7 +42,6 @@ func _init(_frames := [], _name := tr("untitled"), _size := Vector2(64, 64)) -> name = _name size = _size update_tile_mode_rects() - select_all_pixels() undo_redo = UndoRedo.new() @@ -295,7 +294,6 @@ func deserialize(dict : Dictionary) -> void: size.x = dict.size_x size.y = dict.size_y update_tile_mode_rects() - select_all_pixels() if dict.has("save_path"): OpenSave.current_save_paths[Global.projects.find(self)] = dict.save_path if dict.has("frames"): @@ -366,8 +364,7 @@ func name_changed(value : String) -> void: func size_changed(value : Vector2) -> void: size = value update_tile_mode_rects() - if Global.selection_rectangle._selected_rect.has_no_area(): - select_all_pixels() + Global.selection_rectangle.set_rect(Global.selection_rectangle.get_rect()) func frames_changed(value : Array) -> void: diff --git a/src/Palette/PaletteContainer.gd b/src/Palette/PaletteContainer.gd index abe3e0df6..b11f94a4c 100644 --- a/src/Palette/PaletteContainer.gd +++ b/src/Palette/PaletteContainer.gd @@ -204,7 +204,7 @@ func create_palette_from_sprite() -> void: var palette : Palette = Global.palettes[current_palette] var pixels := [] - if selection_checkbox.pressed: + if selection_checkbox.pressed and current_project.selected_pixels: pixels = current_project.selected_pixels.duplicate() else: for x in current_project.size.x: diff --git a/src/SelectionRectangle.gd b/src/SelectionRectangle.gd index 06000ea87..479c4536d 100644 --- a/src/SelectionRectangle.gd +++ b/src/SelectionRectangle.gd @@ -39,7 +39,7 @@ func set_rect(rect : Rect2) -> void: var project : Project = Global.current_project if rect.has_no_area(): - project.select_all_pixels() + project.selected_pixels = [] else: project.clear_selection() for x in range(rect.position.x, rect.end.x): diff --git a/src/Tools/Base.gd b/src/Tools/Base.gd index b6364d3f8..2eac06798 100644 --- a/src/Tools/Base.gd +++ b/src/Tools/Base.gd @@ -77,8 +77,11 @@ func draw_indicator() -> void: func _get_draw_rect() -> Rect2: - var selected_pixels = Global.current_project.selected_pixels - return Rect2(selected_pixels[0].x, selected_pixels[0].y, selected_pixels[-1].x - selected_pixels[0].x + 1, selected_pixels[-1].y - selected_pixels[0].y + 1) + if Global.current_project.selected_pixels.empty(): + return Global.current_project.tile_mode_rects[Global.TileMode.NONE] + else: + var selected_pixels = Global.current_project.selected_pixels + return Rect2(selected_pixels[0].x, selected_pixels[0].y, selected_pixels[-1].x - selected_pixels[0].x + 1, selected_pixels[-1].y - selected_pixels[0].y + 1) func _get_draw_image() -> Image: diff --git a/src/Tools/Bucket.gd b/src/Tools/Bucket.gd index 11d56521a..aff4522f1 100644 --- a/src/Tools/Bucket.gd +++ b/src/Tools/Bucket.gd @@ -94,7 +94,9 @@ func update_pattern() -> void: func draw_start(position : Vector2) -> void: - if not position in Global.current_project.selected_pixels or Global.current_project.layers[Global.current_project.current_layer].locked: + if Global.current_project.layers[Global.current_project.current_layer].locked or !Global.current_project.tile_mode_rects[Global.TileMode.NONE].has_point(position): + return + if Global.current_project.selected_pixels and not position in Global.current_project.selected_pixels: return var undo_data = _get_undo_data() if _fill_area == 0: @@ -121,7 +123,15 @@ func fill_in_color(position : Vector2) -> void: return image.lock() - for i in project.selected_pixels: + var pixels := [] + if project.selected_pixels: + pixels = project.selected_pixels.duplicate() + else: + for x in Global.current_project.size.x: + for y in Global.current_project.size.y: + pixels.append(Vector2(x, y)) + + for i in pixels: if image.get_pixelv(i).is_equal_approx(color): _set_pixel(image, i.x, i.y, tool_slot.color) @@ -135,7 +145,7 @@ func fill_in_area(position : Vector2) -> void: var mirror_y = project.y_symmetry_point - position.y var mirror_x_inside : bool var mirror_y_inside : bool - var entire_image_selected : bool = project.selected_pixels.size() == project.size.x * project.size.y + var entire_image_selected : bool = project.selected_pixels.empty() if entire_image_selected: mirror_x_inside = mirror_x >= 0 and mirror_x < project.size.x mirror_y_inside = mirror_y >= 0 and mirror_y < project.size.y @@ -192,7 +202,7 @@ func _flood_fill(position : Vector2) -> void: func _set_pixel(image : Image, x : int, y : int, color : Color) -> void: var project : Project = Global.current_project - var entire_image_selected : bool = project.selected_pixels.size() == project.size.x * project.size.y + var entire_image_selected : bool = project.selected_pixels.empty() if entire_image_selected: if not _get_draw_rect().has_point(Vector2(x, y)): return diff --git a/src/Tools/Draw.gd b/src/Tools/Draw.gd index 24091068c..47a776543 100644 --- a/src/Tools/Draw.gd +++ b/src/Tools/Draw.gd @@ -281,7 +281,7 @@ func draw_tool_brush(position : Vector2) -> void: var mirror_y = (project.y_symmetry_point + 1) - dst.y - src_rect.size.y var mirror_x_inside : bool var mirror_y_inside : bool - var entire_image_selected : bool = project.selected_pixels.size() == project.size.x * project.size.y + var entire_image_selected : bool = project.selected_pixels.empty() if entire_image_selected: mirror_x_inside = mirror_x >= 0 and mirror_x < project.size.x mirror_y_inside = mirror_y >= 0 and mirror_y < project.size.y @@ -307,7 +307,7 @@ func draw_indicator() -> void: draw_indicator_at(_cursor, Vector2.ZERO, Color.blue) if Global.current_project.tile_mode and Global.current_project.get_tile_mode_rect().has_point(_cursor): var tile := _line_start if _draw_line else _cursor - if not tile in Global.current_project.selected_pixels: + if not Global.current_project.tile_mode_rects[Global.TileMode.NONE].has_point(tile): var offset := tile - tile.posmodv(Global.current_project.size) draw_indicator_at(_cursor, offset, Color.green) @@ -339,7 +339,7 @@ func _set_pixel(position : Vector2) -> void: if project.tile_mode and project.get_tile_mode_rect().has_point(position): position = position.posmodv(project.size) - var entire_image_selected : bool = project.selected_pixels.size() == project.size.x * project.size.y + var entire_image_selected : bool = project.selected_pixels.empty() if entire_image_selected: if not _get_draw_rect().has_point(position): return