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

When picking color, ensure that the correct index is selected in palette (#1144)

* When picking color, ensure that the correct index is selected

* if drawing over same color in index mode, check and update index as well

* revert an optimization (croping indices image before display)

* typo
This commit is contained in:
Variable 2024-12-02 22:44:52 +05:00 committed by GitHub
parent 55f83a3367
commit ff5713ae91
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 76 additions and 45 deletions

View file

@ -896,7 +896,7 @@ class SignalsAPI:
# TOOL RELATED SIGNALS
## Connects/disconnects a signal to [param callable], that emits
## whenever a tool changes color.[br]
## [b]Binds: [/b] It has two bind of type [Color] (indicating new color)
## [b]Binds: [/b] It has two bind of type [Color] (a dictionary with keys "color" and "index")
## and [int] (Indicating button that tool is assigned to, see [enum @GlobalScope.MouseButton])
func signal_tool_color_changed(callable: Callable, is_disconnecting := false) -> void:
_connect_disconnect(Tools.color_changed, callable, is_disconnecting)

View file

@ -300,9 +300,9 @@ func current_palette_select_color(mouse_button: int, index: int) -> void:
match mouse_button:
MOUSE_BUTTON_LEFT:
Tools.assign_color(color, mouse_button)
Tools.assign_color(color, mouse_button, true, left_selected_color)
MOUSE_BUTTON_RIGHT:
Tools.assign_color(color, mouse_button)
Tools.assign_color(color, mouse_button, true, right_selected_color)
func _select_color(mouse_button: int, index: int) -> void:

View file

@ -1,7 +1,7 @@
# gdlint: ignore=max-public-methods
extends Node
signal color_changed(color: Color, button: int)
signal color_changed(color_info: Dictionary, button: int)
signal config_changed(slot_idx: int, config: Dictionary)
@warning_ignore("unused_signal")
signal flip_rotated(flip_x, flip_y, rotate_90, rotate_180, rotate_270)
@ -509,7 +509,7 @@ func swap_color() -> void:
assign_color(left, MOUSE_BUTTON_RIGHT, false)
func assign_color(color: Color, button: int, change_alpha := true) -> void:
func assign_color(color: Color, button: int, change_alpha := true, index: int = -1) -> void:
var c: Color = _slots[button].color
# This was requested by Issue #54 on GitHub
if color.a == 0 and change_alpha:
@ -517,7 +517,8 @@ func assign_color(color: Color, button: int, change_alpha := true) -> void:
color.a = 1
_slots[button].color = color
Global.config_cache.set_value(_slots[button].kname, "color", color)
color_changed.emit(color, button)
var color_info := {"color": color, "index": index}
color_changed.emit(color_info, button)
func get_assigned_color(button: int) -> Color:

View file

@ -30,6 +30,8 @@ class SimpleDrawer:
var color_new := op.process(Color(color_str), color_old)
if not color_new.is_equal_approx(color_old):
image.set_pixelv_custom(position, color_new)
else:
image.set_pixelv_custom(position, color_new, image.is_indexed)
class PixelPerfectDrawer:

View file

@ -139,7 +139,7 @@ func set_pixel_custom(x: int, y: int, color: Color) -> void:
## Equivalent of [method Image.set_pixelv],
## but also handles the logic necessary for indexed mode.
func set_pixelv_custom(point: Vector2i, color: Color) -> void:
func set_pixelv_custom(point: Vector2i, color: Color, index_image_only := false) -> void:
var new_color := color
if is_indexed:
var color_to_fill := TRANSPARENT
@ -164,13 +164,15 @@ func set_pixelv_custom(point: Vector2i, color: Color) -> void:
if dist < smaller_distance:
smaller_distance = dist
color_index = i
indices_image.set_pixelv(point, Color((color_index + 1) / 255.0, 0, 0, 0))
if not indices_image.get_pixelv(point).r8 == color_index + 1:
indices_image.set_pixelv(point, Color((color_index + 1) / 255.0, 0, 0, 0))
color_to_fill = palette[color_index]
new_color = color_to_fill
else:
indices_image.set_pixelv(point, TRANSPARENT)
new_color = TRANSPARENT
set_pixelv(point, new_color)
if not index_image_only:
set_pixelv(point, new_color)
## Finds the distance between colors [param c1] and [param c2].

View file

@ -83,25 +83,38 @@ func scroll_palette(origin: Vector2i) -> void:
## Called when the color changes, either the left or the right, determined by [param mouse_button].
## If current palette has [param target_color] as a [Color], then select it.
## This is helpful when we select color indirectly (e.g through colorpicker)
func find_and_select_color(target_color: Color, mouse_button: int) -> void:
func find_and_select_color(color_info: Dictionary, mouse_button: int) -> void:
var target_color: Color = color_info.get("color", Color(0, 0, 0, 0))
var palette_color_index: int = color_info.get("index", -1)
if not is_instance_valid(current_palette):
return
var selected_index := Palettes.current_palette_get_selected_color_index(mouse_button)
if get_swatch_color(selected_index) == target_color: # Color already selected
return
for color_ind in swatches.size():
if (
target_color.is_equal_approx(swatches[color_ind].color)
or target_color.to_html() == swatches[color_ind].color.to_html()
):
var index := convert_grid_index_to_palette_index(color_ind)
select_swatch(mouse_button, index, selected_index)
match mouse_button:
MOUSE_BUTTON_LEFT:
Palettes.left_selected_color = index
MOUSE_BUTTON_RIGHT:
Palettes.right_selected_color = index
if palette_color_index != -1: # If color has a defined index in palette then priortize index
if selected_index == palette_color_index: # Index already selected
return
select_swatch(mouse_button, palette_color_index, selected_index)
match mouse_button:
MOUSE_BUTTON_LEFT:
Palettes.left_selected_color = palette_color_index
MOUSE_BUTTON_RIGHT:
Palettes.right_selected_color = palette_color_index
return
else: # If it doesn't then select the first match in the palette
if get_swatch_color(selected_index) == target_color: # Color already selected
return
for color_ind in swatches.size():
if (
target_color.is_equal_approx(swatches[color_ind].color)
or target_color.to_html() == swatches[color_ind].color.to_html()
):
var index := convert_grid_index_to_palette_index(color_ind)
select_swatch(mouse_button, index, selected_index)
match mouse_button:
MOUSE_BUTTON_LEFT:
Palettes.left_selected_color = index
MOUSE_BUTTON_RIGHT:
Palettes.right_selected_color = index
return
# Unselect swatches when tools color is changed
var swatch_to_unselect := -1
if mouse_button == MOUSE_BUTTON_LEFT:

View file

@ -104,7 +104,7 @@ func _on_InterpolateFactor_value_changed(value: float) -> void:
save_config()
func _on_Color_changed(_color: Color, _button: int) -> void:
func _on_Color_changed(_color_info: Dictionary, _button: int) -> void:
update_brush()

View file

@ -347,15 +347,21 @@ func _pick_color(pos: Vector2i) -> void:
return
var color := Color(0, 0, 0, 0)
var palette_index = -1
var curr_frame: Frame = project.frames[project.current_frame]
for layer in project.layers.size():
var idx := (project.layers.size() - 1) - layer
if project.layers[idx].is_visible_in_hierarchy():
image = curr_frame.cels[idx].get_image()
var cel := curr_frame.cels[idx]
image = cel.get_image()
color = image.get_pixelv(pos)
if not is_zero_approx(color.a):
# If image is indexed then get index as well
if cel is PixelCel:
if cel.image.is_indexed:
palette_index = cel.image.indices_image.get_pixel(pos.x, pos.y).r8 - 1
if not is_zero_approx(color.a) or palette_index > -1:
break
Tools.assign_color(color, tool_slot.button, false)
Tools.assign_color(color, tool_slot.button, false, palette_index)
func _flip_rect(rect: Rect2, rect_size: Vector2, horiz: bool, vert: bool) -> Rect2:

View file

@ -324,8 +324,8 @@ func update_brush() -> void:
$ColorInterpolation.visible = false
## this function is also used by a signal, this is why there is _color = Color.TRANSPARENT in here.
func _refresh_colors_array(_color = Color.TRANSPARENT, mouse_button := tool_slot.button) -> void:
## this function is also used by a signal, this is why there is _color_info = {} in here.
func _refresh_colors_array(_color_info = {}, mouse_button := tool_slot.button) -> void:
if mouse_button != tool_slot.button:
return
if _shading_mode == ShadingMode.COLOR_REPLACE:

View file

@ -67,22 +67,33 @@ func _pick_color(pos: Vector2i) -> void:
if pos.x < 0 or pos.y < 0:
return
var color := Color(0, 0, 0, 0)
var image := Image.new()
image.copy_from(_get_draw_image())
if pos.x > image.get_width() - 1 or pos.y > image.get_height() - 1:
return
var color := Color(0, 0, 0, 0)
var palette_index = -1
match _mode:
TOP_COLOR:
var curr_frame := project.frames[project.current_frame]
for layer in project.layers.size():
var idx := (project.layers.size() - 1) - layer
if project.layers[idx].is_visible_in_hierarchy():
image = curr_frame.cels[idx].get_image()
var cel := curr_frame.cels[idx]
image = cel.get_image()
color = image.get_pixelv(pos)
# If image is indexed then get index as well
if cel is PixelCel:
if cel.image.is_indexed:
palette_index = cel.image.indices_image.get_pixel(pos.x, pos.y).r8 - 1
if not is_zero_approx(color.a):
break
CURRENT_LAYER:
color = image.get_pixelv(pos)
var current_cel = Global.current_project.get_current_cel()
if current_cel is PixelCel:
if current_cel.image.is_indexed:
palette_index = current_cel.image.index_image.get_pixel(pos.x, pos.y).r8 - 1
var button := MOUSE_BUTTON_LEFT if _color_slot == 0 else MOUSE_BUTTON_RIGHT
Tools.assign_color(color, button, false)
Tools.assign_color(color, button, false, palette_index)

View file

@ -204,7 +204,7 @@ func _textedit_text_changed() -> void:
text_edit._on_text_changed()
func _on_color_changed(_color: Color, _button: int) -> void:
func _on_color_changed(_color_info: Dictionary, _button: int) -> void:
if is_instance_valid(text_edit):
text_edit.add_theme_color_override(&"font_color", tool_slot.color)

View file

@ -23,23 +23,18 @@ func _draw() -> void:
if zoom_percentage < Global.pixel_grid_show_at_zoom:
return
var project = ExtensionsApi.project.current_project
var size: Vector2i = project.size
var cel: BaseCel = project.frames[project.current_frame].cels[project.current_layer]
if not cel is PixelCel:
return
var index_image: Image = cel.image.indices_image
if index_image.get_size() != project.size or not cel.image.is_indexed:
if index_image.get_size() != size or not cel.image.is_indexed:
return
var used_rect: Rect2i = cel.image.get_used_rect()
if used_rect.size != Vector2i.ZERO:
# use smaller image for optimization
index_image = index_image.get_region(used_rect)
var font: Font = ExtensionsApi.theme.get_theme().default_font
var offset = position + Vector2(used_rect.position)
draw_set_transform(offset, rotation, Vector2(0.05, 0.05))
for x in range(index_image.get_size().x):
for y in range(index_image.get_size().y):
draw_set_transform(position, rotation, Vector2(0.05, 0.05))
for x in range(size.x):
for y in range(size.y):
var index := index_image.get_pixel(x, y).r8
if index == 0:
continue

View file

@ -128,7 +128,8 @@ func reset_options() -> void:
expand_button.button_pressed = false
func update_color(color: Color, button: int) -> void:
func update_color(color_info: Dictionary, button: int) -> void:
var color = color_info.get("color", Color.WHITE)
if Tools.picking_color_for == button:
color_picker.color = color
if button == MOUSE_BUTTON_RIGHT: