1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-01-18 17:19:50 +00:00

Change paste placement behavior

Paste now places the pasted content in the middle of the canvas view, instead of its original position. A new option in the Edit menu has been added, "Paste in Place", that preserves the previous behavior. This is similar to how GIMP works.
This commit is contained in:
Emmanouil Papadeas 2022-09-15 00:08:22 +03:00
parent 7558c2c891
commit a64f102b9a
5 changed files with 75 additions and 41 deletions

View file

@ -124,6 +124,9 @@ msgstr ""
msgid "Paste"
msgstr ""
msgid "Paste in Place"
msgstr ""
msgid "Delete"
msgstr ""

View file

@ -850,6 +850,11 @@ gradient_map={
"deadzone": 0.5,
"events": [ ]
}
paste_in_place={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":true,"shift":false,"control":true,"meta":false,"command":true,"pressed":false,"scancode":86,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
]
}
[locale]

View file

@ -8,7 +8,7 @@ enum ColorFrom { THEME, CUSTOM }
enum ButtonSize { SMALL, BIG }
enum FileMenu { NEW, OPEN, OPEN_LAST_PROJECT, RECENT, SAVE, SAVE_AS, EXPORT, EXPORT_AS, QUIT }
enum EditMenu { UNDO, REDO, COPY, CUT, PASTE, DELETE, NEW_BRUSH, PREFERENCES }
enum EditMenu { UNDO, REDO, COPY, CUT, PASTE, PASTE_IN_PLACE, DELETE, NEW_BRUSH, PREFERENCES }
enum ViewMenu {
TILE_MODE,
TILE_MODE_OFFSETS,
@ -253,6 +253,8 @@ func _initialize_keychain() -> void:
"cut": Keychain.MenuInputAction.new("", "Edit menu", true, "EditMenu", EditMenu.CUT),
"copy": Keychain.MenuInputAction.new("", "Edit menu", true, "EditMenu", EditMenu.COPY),
"paste": Keychain.MenuInputAction.new("", "Edit menu", true, "EditMenu", EditMenu.PASTE),
"paste_in_place":
Keychain.MenuInputAction.new("", "Edit menu", true, "EditMenu", EditMenu.PASTE_IN_PLACE),
"delete": Keychain.MenuInputAction.new("", "Edit menu", true, "EditMenu", EditMenu.DELETE),
"new_brush":
Keychain.MenuInputAction.new("", "Edit menu", true, "EditMenu", EditMenu.NEW_BRUSH),

View file

@ -3,6 +3,7 @@ extends Node2D
enum SelectionOperation { ADD, SUBTRACT, INTERSECT }
const KEY_MOVE_ACTION_NAMES := ["ui_up", "ui_down", "ui_left", "ui_right"]
const CLIPBOARD_FILE_PATH := "user://clipboard.txt"
var is_moving_content := false
var arrow_key_move := false
@ -682,10 +683,10 @@ func copy() -> void:
to_copy = image.get_rect(big_bounding_rectangle)
to_copy.lock()
# Remove unincluded pixels if the selection is not a single rectangle
var offset_pos := big_bounding_rectangle.position
for x in to_copy.get_size().x:
for y in to_copy.get_size().y:
var pos := Vector2(x, y)
var offset_pos = big_bounding_rectangle.position
if offset_pos.x < 0:
offset_pos.x = 0
if offset_pos.y < 0:
@ -704,9 +705,9 @@ func copy() -> void:
"big_bounding_rectangle": cl_big_bounding_rectangle,
"selection_offset": cl_selection_offset,
}
# Store to ".clipboard.txt" file
var clipboard_file := File.new()
clipboard_file.open("user://clipboard.txt", File.WRITE)
clipboard_file.open(CLIPBOARD_FILE_PATH, File.WRITE)
clipboard_file.store_var(transfer_clipboard, true)
clipboard_file.close()
@ -719,53 +720,66 @@ func copy() -> void:
container.get_child(0).get_child(0).texture = tex
func paste() -> void:
# Read from the ".clipboard.txt" file
func paste(in_place := false) -> void:
var clipboard_file := File.new()
if !clipboard_file.file_exists("user://clipboard.txt"):
if !clipboard_file.file_exists(CLIPBOARD_FILE_PATH):
return
clipboard_file.open("user://clipboard.txt", File.READ)
clipboard_file.open(CLIPBOARD_FILE_PATH, File.READ)
var clipboard = clipboard_file.get_var(true)
clipboard_file.close()
if typeof(clipboard) == TYPE_DICTIONARY:
# A sanity check
if not clipboard.has_all(
["image", "selection_map", "big_bounding_rectangle", "selection_offset"]
):
return
# Sanity checks
if typeof(clipboard) != TYPE_DICTIONARY:
return
if !clipboard.has_all(["image", "selection_map", "big_bounding_rectangle", "selection_offset"]):
return
if clipboard.image.is_empty():
return
if clipboard.image.is_empty():
return
clear_selection()
undo_data = get_undo_data(true)
var project: Project = Global.current_project
clear_selection()
undo_data = get_undo_data(true)
var project: Project = Global.current_project
original_bitmap.copy_from(project.selection_map)
original_big_bounding_rectangle = big_bounding_rectangle
original_offset = project.selection_offset
original_bitmap.copy_from(project.selection_map)
original_big_bounding_rectangle = big_bounding_rectangle
original_offset = project.selection_offset
var clip_map := SelectionMap.new()
clip_map.data = clipboard.selection_map
var max_size := Vector2(
max(clip_map.get_size().x, project.selection_map.get_size().x),
max(clip_map.get_size().y, project.selection_map.get_size().y)
)
var clip_map := SelectionMap.new()
clip_map.data = clipboard.selection_map
var max_size := Vector2(
max(clip_map.get_size().x, project.selection_map.get_size().x),
max(clip_map.get_size().y, project.selection_map.get_size().y)
)
project.selection_map = clip_map
project.selection_map.crop(max_size.x, max_size.y)
self.big_bounding_rectangle = clipboard.big_bounding_rectangle
project.selection_offset = clipboard.selection_offset
project.selection_map = clip_map
project.selection_map.crop(max_size.x, max_size.y)
project.selection_offset = clipboard.selection_offset
big_bounding_rectangle = clipboard.big_bounding_rectangle
if not in_place: # If "Paste" is selected, and not "Paste in Place"
var camera_center := Global.camera.get_camera_screen_center()
camera_center -= big_bounding_rectangle.size / 2
var max_pos := project.size - big_bounding_rectangle.size
if max_pos.x >= 0:
camera_center.x = clamp(camera_center.x, 0, max_pos.x)
else:
camera_center.x = 0
if max_pos.y >= 0:
camera_center.y = clamp(camera_center.y, 0, max_pos.y)
else:
camera_center.y = 0
big_bounding_rectangle.position = camera_center
project.selection_map.move_bitmap_values(Global.current_project, false)
temp_bitmap = project.selection_map
temp_rect = big_bounding_rectangle
is_moving_content = true
is_pasting = true
original_preview_image = clipboard.image
preview_image.copy_from(original_preview_image)
preview_image_texture.create_from_image(preview_image, 0)
self.big_bounding_rectangle = big_bounding_rectangle
temp_bitmap = project.selection_map
temp_rect = big_bounding_rectangle
is_moving_content = true
is_pasting = true
original_preview_image = clipboard.image
preview_image.copy_from(original_preview_image)
preview_image_texture.create_from_image(preview_image, 0)
project.selection_map_changed()
project.selection_map_changed()
func delete(selected_cels := true) -> void:

View file

@ -89,7 +89,15 @@ func update_recent_projects_submenu() -> void:
func _setup_edit_menu() -> void:
# Order as in Global.EditMenu enum
var edit_menu_items := [
"Undo", "Redo", "Copy", "Cut", "Paste", "Delete", "New Brush", "Preferences"
"Undo",
"Redo",
"Copy",
"Cut",
"Paste",
"Paste in Place",
"Delete",
"New Brush",
"Preferences"
]
var edit_menu: PopupMenu = edit_menu_button.get_popup()
var i := 0
@ -401,6 +409,8 @@ func edit_menu_id_pressed(id: int) -> void:
Global.canvas.selection.cut()
Global.EditMenu.PASTE:
Global.canvas.selection.paste()
Global.EditMenu.PASTE_IN_PLACE:
Global.canvas.selection.paste(true)
Global.EditMenu.DELETE:
Global.canvas.selection.delete()
Global.EditMenu.NEW_BRUSH: