Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a way to see index of color (plus bugfixes) #1143

Merged
merged 10 commits into from
Nov 29, 2024
4 changes: 4 additions & 0 deletions project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,10 @@ right_text_tool={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
show_pixel_indices={
"deadzone": 0.5,
"events": []
}

[input_devices]

Expand Down
8 changes: 8 additions & 0 deletions src/Autoload/Global.gd
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum ViewMenu {
MIRROR_VIEW,
SHOW_GRID,
SHOW_PIXEL_GRID,
SHOW_PIXEL_INDICES,
SHOW_RULERS,
SHOW_GUIDES,
SHOW_MOUSE_GUIDES,
Expand Down Expand Up @@ -555,6 +556,12 @@ var show_rulers := true:
var show_guides := true
## If [code]true[/code], the mouse guides are visible.
var show_mouse_guides := false
## If [code]true[/code], the indices of color are shown.
var show_pixel_indices := false:
set(value):
show_pixel_indices = value
if is_instance_valid(canvas.color_index):
canvas.color_index.enabled = value
var display_layer_effects := true:
set(value):
if value == display_layer_effects:
Expand Down Expand Up @@ -749,6 +756,7 @@ func _ready() -> void:
Global.use_native_file_dialogs = true
await get_tree().process_frame
project_switched.emit()
canvas.color_index.enabled = show_pixel_indices # Initialize color index preview


func update_grids(grids_data: Dictionary):
Expand Down
4 changes: 2 additions & 2 deletions src/Autoload/Palettes.gd
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,14 @@ func current_palette_select_color(mouse_button: int, index: int) -> void:
if color == null:
return

_select_color(mouse_button, index)

match mouse_button:
MOUSE_BUTTON_LEFT:
Tools.assign_color(color, mouse_button)
MOUSE_BUTTON_RIGHT:
Tools.assign_color(color, mouse_button)

_select_color(mouse_button, index)


func _select_color(mouse_button: int, index: int) -> void:
match mouse_button:
Expand Down
38 changes: 17 additions & 21 deletions src/Autoload/Tools.gd
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum Dynamics { NONE, PRESSURE, VELOCITY }
const XY_LINE := Vector2(-0.707107, 0.707107)
const X_MINUS_Y_LINE := Vector2(0.707107, 0.707107)

var active_button := -1
var picking_color_for := MOUSE_BUTTON_LEFT
var horizontal_mirror := false
var vertical_mirror := false
Expand Down Expand Up @@ -238,7 +239,6 @@ var _right_tools_per_layer_type := {
Global.LayerTypes.THREE_D: "Pan",
}
var _tool_buttons: Node
var _active_button := -1
var _last_position := Vector2i(Vector2.INF)


Expand Down Expand Up @@ -627,32 +627,28 @@ func handle_draw(position: Vector2i, event: InputEvent) -> void:
change_layer_automatically(draw_pos)
return

if event.is_action_pressed(&"activate_left_tool") and _active_button == -1 and not pen_inverted:
_active_button = MOUSE_BUTTON_LEFT
_slots[_active_button].tool_node.draw_start(draw_pos)
elif event.is_action_released(&"activate_left_tool") and _active_button == MOUSE_BUTTON_LEFT:
_slots[_active_button].tool_node.draw_end(draw_pos)
_active_button = -1
if event.is_action_pressed(&"activate_left_tool") and active_button == -1 and not pen_inverted:
active_button = MOUSE_BUTTON_LEFT
_slots[active_button].tool_node.draw_start(draw_pos)
elif event.is_action_released(&"activate_left_tool") and active_button == MOUSE_BUTTON_LEFT:
_slots[active_button].tool_node.draw_end(draw_pos)
active_button = -1
elif (
(
event.is_action_pressed(&"activate_right_tool")
and _active_button == -1
and active_button == -1
and not pen_inverted
)
or (
event.is_action_pressed(&"activate_left_tool") and _active_button == -1 and pen_inverted
)
or event.is_action_pressed(&"activate_left_tool") and active_button == -1 and pen_inverted
):
_active_button = MOUSE_BUTTON_RIGHT
_slots[_active_button].tool_node.draw_start(draw_pos)
active_button = MOUSE_BUTTON_RIGHT
_slots[active_button].tool_node.draw_start(draw_pos)
elif (
(event.is_action_released(&"activate_right_tool") and _active_button == MOUSE_BUTTON_RIGHT)
or (
event.is_action_released(&"activate_left_tool") and _active_button == MOUSE_BUTTON_RIGHT
)
(event.is_action_released(&"activate_right_tool") and active_button == MOUSE_BUTTON_RIGHT)
or event.is_action_released(&"activate_left_tool") and active_button == MOUSE_BUTTON_RIGHT
):
_slots[_active_button].tool_node.draw_end(draw_pos)
_active_button = -1
_slots[active_button].tool_node.draw_end(draw_pos)
active_button = -1

if event is InputEventMouseMotion:
pen_pressure = event.pressure
Expand Down Expand Up @@ -683,8 +679,8 @@ func handle_draw(position: Vector2i, event: InputEvent) -> void:
_last_position = position
_slots[MOUSE_BUTTON_LEFT].tool_node.cursor_move(position)
_slots[MOUSE_BUTTON_RIGHT].tool_node.cursor_move(position)
if _active_button != -1:
_slots[_active_button].tool_node.draw_move(draw_pos)
if active_button != -1:
_slots[active_button].tool_node.draw_move(draw_pos)

var project := Global.current_project
var text := "[%s×%s]" % [project.size.x, project.size.y]
Expand Down
16 changes: 14 additions & 2 deletions src/Classes/ImageExtended.gd
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,14 @@ func update_palette() -> void:
return
if palette.size() != current_palette.colors_max:
palette.resize(current_palette.colors_max)
palette.fill(TRANSPARENT)
palette.fill(TRANSPARENT)
for i in current_palette.colors:
palette[i] = current_palette.colors[i].color
# Due to the decimal nature of the color values, some values get rounded off
# unintentionally.
# Even though the decimal values change, the HTML code remains the same after the change.
# So we're using this trick to convert the values back to how they are shown in
# the palette.
palette[i] = Color(current_palette.colors[i].color.to_html())


## Displays the actual RGBA values of each pixel in the image from indexed mode.
Expand Down Expand Up @@ -142,6 +147,13 @@ func set_pixelv_custom(point: Vector2i, color: Color) -> void:
if not color.is_equal_approx(TRANSPARENT):
if palette.has(color):
color_index = palette.find(color)
# If the color selected in the palette is the same then it should take prioity.
var selected_index = Palettes.current_palette_get_selected_color_index(
Tools.active_button
)
if selected_index != -1:
if palette[selected_index].is_equal_approx(color):
color_index = selected_index
else: # Find the most similar color
var smaller_distance := color_distance(color, palette[0])
for i in palette.size():
Expand Down
1 change: 1 addition & 0 deletions src/Classes/Project.gd
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var color_mode: int = Image.FORMAT_RGBA8:
image.resize_indices()
image.select_palette("", false)
image.convert_rgb_to_indexed()
Global.canvas.color_index.queue_redraw()
var fill_color := Color(0)
var has_changed := false:
set(value):
Expand Down
1 change: 1 addition & 0 deletions src/Main.gd
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ func _exit_tree() -> void:
Global.config_cache.set_value("window", "size", get_window().size)
Global.config_cache.set_value("view_menu", "draw_grid", Global.draw_grid)
Global.config_cache.set_value("view_menu", "draw_pixel_grid", Global.draw_pixel_grid)
Global.config_cache.set_value("view_menu", "show_pixel_indices", Global.show_pixel_indices)
Global.config_cache.set_value("view_menu", "show_rulers", Global.show_rulers)
Global.config_cache.set_value("view_menu", "show_guides", Global.show_guides)
Global.config_cache.set_value("view_menu", "show_mouse_guides", Global.show_mouse_guides)
Expand Down
7 changes: 5 additions & 2 deletions src/Palette/PaletteGrid.gd
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,20 @@ 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:
if not is_instance_valid(current_palette):
return
var old_index := Palettes.current_palette_get_selected_color_index(mouse_button)
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, old_index)
select_swatch(mouse_button, index, selected_index)
match mouse_button:
MOUSE_BUTTON_LEFT:
Palettes.left_selected_color = index
Expand Down
2 changes: 2 additions & 0 deletions src/UI/Canvas/Canvas.gd
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var layer_metadata_texture := ImageTexture.new()
@onready var currently_visible_frame := $CurrentlyVisibleFrame as SubViewport
@onready var current_frame_drawer := $CurrentlyVisibleFrame/CurrentFrameDrawer as Node2D
@onready var tile_mode := $TileMode as Node2D
@onready var color_index := $ColorIndex as Node2D
@onready var pixel_grid := $PixelGrid as Node2D
@onready var grid := $Grid as Node2D
@onready var selection := $Selection as SelectionNode
Expand Down Expand Up @@ -67,6 +68,7 @@ func _draw() -> void:
current_frame_drawer.queue_redraw()
tile_mode.queue_redraw()
draw_set_transform(position, rotation, scale)
color_index.queue_redraw()


func _input(event: InputEvent) -> void:
Expand Down
12 changes: 11 additions & 1 deletion src/UI/Canvas/Canvas.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=22 format=3 uid="uid://ba24iuv55m4l3"]
[gd_scene load_steps=24 format=3 uid="uid://ba24iuv55m4l3"]

[ext_resource type="Script" path="res://src/UI/Canvas/Canvas.gd" id="1"]
[ext_resource type="Shader" path="res://src/Shaders/BlendLayers.gdshader" id="1_253dh"]
Expand All @@ -17,6 +17,7 @@
[ext_resource type="Script" path="res://src/UI/Canvas/Measurements.gd" id="16_nxilb"]
[ext_resource type="Shader" path="res://src/Shaders/AutoInvertColors.gdshader" id="17_lowhf"]
[ext_resource type="Script" path="res://src/UI/Canvas/ReferenceImages.gd" id="17_qfjb4"]
[ext_resource type="Script" path="res://src/UI/Canvas/color_index.gd" id="18_o3xx2"]

[sub_resource type="ShaderMaterial" id="ShaderMaterial_6b0ox"]
shader = ExtResource("1_253dh")
Expand All @@ -26,6 +27,11 @@ shader_parameter/origin_y_positive = true
[sub_resource type="CanvasItemMaterial" id="1"]
blend_mode = 4

[sub_resource type="ShaderMaterial" id="ShaderMaterial_ascg6"]
shader = ExtResource("17_lowhf")
shader_parameter/width = 0.05
shader_parameter/hollow_shapes = false

[sub_resource type="ShaderMaterial" id="2"]
shader = ExtResource("9")
shader_parameter/width = 0.05
Expand Down Expand Up @@ -59,6 +65,10 @@ show_behind_parent = true
material = SubResource("1")
script = ExtResource("4")

[node name="ColorIndex" type="Node2D" parent="."]
material = SubResource("ShaderMaterial_ascg6")
script = ExtResource("18_o3xx2")

[node name="PixelGrid" type="Node2D" parent="."]
script = ExtResource("6")

Expand Down
54 changes: 54 additions & 0 deletions src/UI/Canvas/color_index.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
extends Node2D

const FONT_SIZE = 16

var users := 1
var enabled: bool = false:
set(value):
enabled = value
queue_redraw()


func _ready() -> void:
Global.camera.zoom_changed.connect(queue_redraw)


func _draw() -> void:
if not enabled:
return
# when we zoom out there is a visual issue that inverts the text
# (kind of how you look through a magnifying glass)
# so we should restrict the rendering distance of this preview.
var zoom_percentage := 100.0 * Global.camera.zoom.x
if zoom_percentage < Global.pixel_grid_show_at_zoom:
return
var project = ExtensionsApi.project.current_project
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:
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):
var index := index_image.get_pixel(x, y).r8
if index == 0:
continue
draw_string(
font,
Vector2(x, y) * 20 + Vector2.DOWN * 16,
str(index),
HORIZONTAL_ALIGNMENT_LEFT,
-1,
FONT_SIZE if (index < 100) else int(FONT_SIZE / 1.5)
)
draw_set_transform(position, rotation, scale)
13 changes: 13 additions & 0 deletions src/UI/TopMenuContainer/TopMenuContainer.gd
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ func _setup_view_menu() -> void:
"Mirror View": "mirror_view",
"Show Grid": "show_grid",
"Show Pixel Grid": "show_pixel_grid",
"Show Pixel Indices": "show_pixel_indices",
"Show Rulers": "show_rulers",
"Show Guides": "show_guides",
"Show Mouse Guides": "",
Expand Down Expand Up @@ -261,6 +262,9 @@ func _setup_view_menu() -> void:
var draw_pixel_grid: bool = Global.config_cache.get_value(
"view_menu", "draw_pixel_grid", Global.draw_pixel_grid
)
var show_pixel_indices: bool = Global.config_cache.get_value(
"view_menu", "show_pixel_indices", Global.show_pixel_indices
)
var show_rulers: bool = Global.config_cache.get_value(
"view_menu", "show_rulers", Global.show_rulers
)
Expand Down Expand Up @@ -295,6 +299,8 @@ func _setup_view_menu() -> void:
_toggle_show_guides()
if show_mouse_guides != Global.show_mouse_guides:
_toggle_show_mouse_guides()
if show_pixel_indices != Global.show_pixel_indices:
_toggle_show_pixel_indices()
if display_layer_effects != Global.display_layer_effects:
Global.display_layer_effects = display_layer_effects
if snap_to_rectangular_grid_boundary != Global.snap_to_rectangular_grid_boundary:
Expand Down Expand Up @@ -666,6 +672,8 @@ func view_menu_id_pressed(id: int) -> void:
_toggle_show_guides()
Global.ViewMenu.SHOW_MOUSE_GUIDES:
_toggle_show_mouse_guides()
Global.ViewMenu.SHOW_PIXEL_INDICES:
_toggle_show_pixel_indices()
Global.ViewMenu.DISPLAY_LAYER_EFFECTS:
Global.display_layer_effects = not Global.display_layer_effects
_:
Expand Down Expand Up @@ -820,6 +828,11 @@ func _toggle_show_pixel_grid() -> void:
view_menu.set_item_checked(Global.ViewMenu.SHOW_PIXEL_GRID, Global.draw_pixel_grid)


func _toggle_show_pixel_indices() -> void:
Global.show_pixel_indices = !Global.show_pixel_indices
view_menu.set_item_checked(Global.ViewMenu.SHOW_PIXEL_INDICES, Global.show_pixel_indices)


func _toggle_show_rulers() -> void:
Global.show_rulers = !Global.show_rulers
view_menu.set_item_checked(Global.ViewMenu.SHOW_RULERS, Global.show_rulers)
Expand Down