1
0
Fork 0
mirror of https://github.com/Orama-Interactive/Pixelorama.git synced 2025-02-20 12:33:14 +00:00

TileMode for selection, (plus some other fixes) (#834)

* Tilemode selections

* Selection TileMode

* Fixed some bugs with the ORIGINAL tile mode

Image brushes needed to be adjusted

* remove behaviour checkbutton

* fixed remaining things

* formating

* formatting

* formatting

* formatting

* fix crash on rotating image

* Fix Color getting transparent on double chicking

same swatch twice

* typo

* typo

* Update RotateImage.gd

* Use sheckbox instead of option button

* make checkbox directly under select menu
This commit is contained in:
Variable 2023-04-27 14:22:32 +05:00 committed by GitHub
parent 7c14af7129
commit 7b189cc45e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 141 additions and 50 deletions

View file

@ -13,6 +13,61 @@ func is_pixel_selected(pixel: Vector2) -> bool:
return selected
func get_nearest_position(pixel: Vector2) -> Vector2:
if Global.canvas.selection.flag_tilemode:
# functions more or less the same way as the tilemode
var size = Global.current_project.size
var selection_rect = get_used_rect()
var start_x = selection_rect.position.x - selection_rect.size.x
var end_x = selection_rect.position.x + 2 * selection_rect.size.x
var start_y = selection_rect.position.y - selection_rect.size.y
var end_y = selection_rect.position.y + 2 * selection_rect.size.y
for x in range(start_x, end_x, selection_rect.size.x):
for y in range(start_y, end_y, selection_rect.size.y):
var test_image = Image.new()
test_image.create(size.x, size.y, false, Image.FORMAT_LA8)
test_image.blit_rect(self, selection_rect, Vector2(x, y))
test_image.lock()
if (
pixel.x < 0
or pixel.y < 0
or pixel.x >= test_image.get_width()
or pixel.y >= test_image.get_height()
):
continue
var selected: bool = test_image.get_pixelv(pixel).a > 0
test_image.unlock()
if selected:
var offset = Vector2(x, y) - selection_rect.position
return offset
return Vector2.ZERO
else:
return Vector2.ZERO
func get_point_in_tile_mode(pixel: Vector2) -> Array:
var result = []
if Global.canvas.selection.flag_tilemode:
var selection_rect = get_used_rect()
var start_x = selection_rect.position.x - selection_rect.size.x
var end_x = selection_rect.position.x + 2 * selection_rect.size.x
var start_y = selection_rect.position.y - selection_rect.size.y
var end_y = selection_rect.position.y + 2 * selection_rect.size.y
for x in range(start_x, end_x, selection_rect.size.x):
for y in range(start_y, end_y, selection_rect.size.y):
result.append(Vector2(x, y) + pixel - selection_rect.position)
else:
result.append(pixel)
return result
func get_canon_position(position) -> Vector2:
if Global.canvas.selection.flag_tilemode:
return position - get_nearest_position(position)
else:
return position
func select_pixel(pixel: Vector2, select := true) -> void:
lock()
if select:

View file

@ -86,6 +86,15 @@ func get_canon_position(position: Vector2) -> Vector2:
return position
func get_point_in_tiles(pixel: Vector2) -> Array:
var positions = Global.canvas.tile_mode.get_tile_positions()
positions.append(Vector2.ZERO)
var result = []
for pos in positions:
result.append(pos + pixel)
return result
func has_point(point: Vector2) -> bool:
var positions = Global.canvas.tile_mode.get_tile_positions()
positions.append(Vector2.ZERO) # The central tile is included manually

View file

@ -374,38 +374,44 @@ func _draw_tool_circle_from_map(position: Vector2) -> PoolVector2Array:
return result
func draw_tool_brush(position: Vector2) -> void:
func draw_tool_brush(brush_position: Vector2) -> void:
var project: Project = Global.current_project
position = project.tiles.get_canon_position(position)
# image brushes work differently, (we have to consider all 8 surrounding points)
var central_point = project.tiles.get_canon_position(brush_position)
var positions = project.tiles.get_point_in_tiles(central_point)
if Global.current_project.has_selection and project.tiles.mode == Tiles.MODE.NONE:
positions = Global.current_project.selection_map.get_point_in_tile_mode(central_point)
var size := _brush_image.get_size()
var dst := position - (size / 2).floor()
var dst_rect := Rect2(dst, size)
var draw_rect := _get_draw_rect()
dst_rect = dst_rect.clip(draw_rect)
if dst_rect.size == Vector2.ZERO:
return
var src_rect := Rect2(dst_rect.position - dst, dst_rect.size)
var brush_image: Image = remove_unselected_parts_of_brush(_brush_image, dst)
dst = dst_rect.position
_draw_brush_image(brush_image, src_rect, dst)
for i in positions.size():
var position: Vector2 = positions[i]
var dst: Vector2 = position - (size / 2).floor()
var dst_rect := Rect2(dst, size)
var draw_rect := _get_draw_rect()
dst_rect = dst_rect.clip(draw_rect)
if dst_rect.size == Vector2.ZERO:
continue
var src_rect := Rect2(dst_rect.position - dst, dst_rect.size)
var brush_image: Image = remove_unselected_parts_of_brush(_brush_image, dst)
dst = dst_rect.position
_draw_brush_image(brush_image, src_rect, dst)
# Handle Mirroring
var mirror_x = (project.x_symmetry_point + 1) - dst.x - src_rect.size.x
var mirror_y = (project.y_symmetry_point + 1) - dst.y - src_rect.size.y
# Handle Mirroring
var mirror_x = (project.x_symmetry_point + 1) - dst.x - src_rect.size.x
var mirror_y = (project.y_symmetry_point + 1) - dst.y - src_rect.size.y
if Tools.horizontal_mirror:
var x_dst := Vector2(mirror_x, dst.y)
var mirror_brush_x: Image = remove_unselected_parts_of_brush(_mirror_brushes.x, x_dst)
_draw_brush_image(mirror_brush_x, _flip_rect(src_rect, size, true, false), x_dst)
if Tools.horizontal_mirror:
var x_dst := Vector2(mirror_x, dst.y)
var mirror_brush_x: Image = remove_unselected_parts_of_brush(_mirror_brushes.x, x_dst)
_draw_brush_image(mirror_brush_x, _flip_rect(src_rect, size, true, false), x_dst)
if Tools.vertical_mirror:
var xy_dst := Vector2(mirror_x, mirror_y)
var mirror_brush_xy := remove_unselected_parts_of_brush(_mirror_brushes.xy, xy_dst)
_draw_brush_image(mirror_brush_xy, _flip_rect(src_rect, size, true, true), xy_dst)
if Tools.vertical_mirror:
var xy_dst := Vector2(mirror_x, mirror_y)
var mirror_brush_xy := remove_unselected_parts_of_brush(_mirror_brushes.xy, xy_dst)
_draw_brush_image(mirror_brush_xy, _flip_rect(src_rect, size, true, true), xy_dst)
if Tools.vertical_mirror:
var y_dst := Vector2(dst.x, mirror_y)
var mirror_brush_y: Image = remove_unselected_parts_of_brush(_mirror_brushes.y, y_dst)
_draw_brush_image(mirror_brush_y, _flip_rect(src_rect, size, false, true), y_dst)
var y_dst := Vector2(dst.x, mirror_y)
var mirror_brush_y: Image = remove_unselected_parts_of_brush(_mirror_brushes.y, y_dst)
_draw_brush_image(mirror_brush_y, _flip_rect(src_rect, size, false, true), y_dst)
func remove_unselected_parts_of_brush(brush: Image, dst: Vector2) -> Image:
@ -429,6 +435,17 @@ func remove_unselected_parts_of_brush(brush: Image, dst: Vector2) -> Image:
func draw_indicator(left: bool) -> void:
var color := Global.left_tool_color if left else Global.right_tool_color
draw_indicator_at(snap_position(_cursor), Vector2.ZERO, color)
if (
Global.current_project.has_selection
and Global.current_project.tiles.mode == Tiles.MODE.NONE
):
var position := _line_start if _draw_line else _cursor
var nearest_pos := Global.current_project.selection_map.get_nearest_position(position)
if nearest_pos != Vector2.ZERO:
var offset := nearest_pos
draw_indicator_at(snap_position(_cursor), offset, Color.green)
return
if Global.current_project.tiles.mode and Global.current_project.tiles.has_point(_cursor):
var position := _line_start if _draw_line else _cursor
var nearest_tile := Global.current_project.tiles.get_nearest_tile(position)
@ -470,6 +487,8 @@ func _set_pixel(position: Vector2, ignore_mirroring := false) -> void:
func _set_pixel_no_cache(position: Vector2, ignore_mirroring := false) -> void:
position = _stroke_project.tiles.get_canon_position(position)
if Global.current_project.has_selection:
position = Global.current_project.selection_map.get_canon_position(position)
if !_stroke_project.can_pixel_get_drawn(position):
return

View file

@ -1,10 +1,13 @@
extends Node2D
enum SelectionOperation { ADD, SUBTRACT, INTERSECT }
enum SelectionFlags { TILE_MODE }
const KEY_MOVE_ACTION_NAMES := ["ui_up", "ui_down", "ui_left", "ui_right"]
const CLIPBOARD_FILE_PATH := "user://clipboard.txt"
# flags (additional properties of selection that can be toggled)
var flag_tilemode = false
var is_moving_content := false
var arrow_key_move := false
var is_pasting := false

View file

@ -299,13 +299,14 @@ func _setup_image_menu() -> void:
func _setup_select_menu() -> void:
# Order as in Global.SelectMenu enum
var select_menu_items := ["All", "Clear", "Invert"]
var select_menu_items := ["All", "Clear", "Invert", "Tile Mode"]
var select_menu: PopupMenu = select_menu_button.get_popup()
var i := 0
for item in select_menu_items:
select_menu.add_item(item, i)
i += 1
for i in select_menu_items.size():
var item: String = select_menu_items[i]
if item == "Tile Mode":
select_menu.add_check_item(item, i)
else:
select_menu.add_item(item, i)
select_menu.connect("id_pressed", self, "select_menu_id_pressed")
@ -474,6 +475,23 @@ func view_menu_id_pressed(id: int) -> void:
Global.canvas.update()
func window_menu_id_pressed(id: int) -> void:
if not Global.can_draw:
return
match id:
Global.WindowMenu.WINDOW_OPACITY:
_popup_dialog(window_opacity_dialog)
Global.WindowMenu.MOVABLE_PANELS:
ui.tabs_visible = !ui.tabs_visible
window_menu.set_item_checked(id, ui.tabs_visible)
Global.WindowMenu.ZEN_MODE:
_toggle_zen_mode()
Global.WindowMenu.FULLSCREEN_MODE:
_toggle_fullscreen()
_:
_handle_metadata(id, window_menu_button)
func _tile_mode_submenu_id_pressed(id: int) -> void:
Global.current_project.tiles.mode = id
Global.transparent_checker.fit_rect(Global.current_project.tiles.get_bounding_rect())
@ -497,23 +515,6 @@ func _snap_to_submenu_id_pressed(id: int) -> void:
snap_to_submenu.set_item_checked(id, Global.snap_to_perspective_guides)
func window_menu_id_pressed(id: int) -> void:
if not Global.can_draw:
return
match id:
Global.WindowMenu.WINDOW_OPACITY:
_popup_dialog(window_opacity_dialog)
Global.WindowMenu.MOVABLE_PANELS:
ui.tabs_visible = !ui.tabs_visible
window_menu.set_item_checked(id, ui.tabs_visible)
Global.WindowMenu.ZEN_MODE:
_toggle_zen_mode()
Global.WindowMenu.FULLSCREEN_MODE:
_toggle_fullscreen()
_:
_handle_metadata(id, window_menu_button)
func _panels_submenu_id_pressed(id: int) -> void:
if zen_mode:
return
@ -699,6 +700,10 @@ func select_menu_id_pressed(id: int) -> void:
Global.canvas.selection.clear_selection(true)
Global.SelectMenu.INVERT:
Global.canvas.selection.invert()
Global.SelectMenu.TILE_MODE:
var state = select_menu_button.get_popup().is_item_checked(id)
Global.canvas.selection.flag_tilemode = !state
select_menu_button.get_popup().set_item_checked(id, !state)
_:
_handle_metadata(id, select_menu_button)