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

Revert back to an OptionButton in the Bucket tool options and add "Whole Selection" option in the fill area

Still WIP, "Whole selection" isn't working with patterns yet.
This commit is contained in:
Emmanouil Papadeas 2022-09-18 18:43:50 +03:00
parent 0e4804342a
commit cac9b67335
2 changed files with 84 additions and 42 deletions

View file

@ -1,12 +1,15 @@
extends BaseTool extends BaseTool
enum FillArea { AREA, COLORS, SELECTION }
enum FillWith { COLOR, PATTERN }
const COLOR_REPLACE_SHADER := preload("res://src/Shaders/ColorReplace.shader") const COLOR_REPLACE_SHADER := preload("res://src/Shaders/ColorReplace.shader")
var _prev_mode := 0 var _prev_mode := 0
var _pattern: Patterns.Pattern var _pattern: Patterns.Pattern
var _similarity := 100 var _similarity := 100
var _fill_area := true var _fill_area: int = FillArea.AREA
var _fill_with := 0 var _fill_with: int = FillWith.COLOR
var _offset_x := 0 var _offset_x := 0
var _offset_y := 0 var _offset_y := 0
# working array used as buffer for segments while flooding # working array used as buffer for segments while flooding
@ -14,26 +17,36 @@ var _allegro_flood_segments: Array
# results array per image while flooding # results array per image while flooding
var _allegro_image_segments: Array var _allegro_image_segments: Array
onready var fill_check_box: CheckBox = $FillCheckBox
func _ready() -> void: func _ready() -> void:
update_pattern() update_pattern()
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event.is_action_pressed("change_tool_mode") or event.is_action_released("change_tool_mode"): if event.is_action_pressed("change_tool_mode"):
fill_check_box.pressed = not fill_check_box.pressed _prev_mode = _fill_area
_fill_area = fill_check_box.pressed if event.is_action("change_tool_mode"):
$Similarity.visible = not _fill_area if _fill_area == FillArea.SELECTION:
_fill_area = FillArea.AREA
else:
_fill_area = _prev_mode ^ 1
_select_fill_area_optionbutton()
if event.is_action_released("change_tool_mode"):
_fill_area = _prev_mode
_select_fill_area_optionbutton()
func _on_FillCheckBox_toggled(button_pressed: bool) -> void: func _on_FillAreaOptions_item_selected(index: int) -> void:
_fill_area = button_pressed _fill_area = index
update_config() update_config()
save_config() save_config()
func _select_fill_area_optionbutton() -> void:
$FillAreaOptions.selected = _fill_area
$Similarity.visible = (_fill_area == FillArea.COLORS)
func _on_FillWithOptions_item_selected(index: int) -> void: func _on_FillWithOptions_item_selected(index: int) -> void:
_fill_with = index _fill_with = index
$Similarity/Value.value = _similarity $Similarity/Value.value = _similarity
@ -105,12 +118,11 @@ func set_config(config: Dictionary) -> void:
func update_config() -> void: func update_config() -> void:
$FillCheckBox.pressed = _fill_area _select_fill_area_optionbutton()
$FillWithOptions.selected = _fill_with $FillWithOptions.selected = _fill_with
$Similarity.visible = not _fill_area
$Similarity/Value.value = _similarity $Similarity/Value.value = _similarity
$Similarity/Slider.value = _similarity $Similarity/Slider.value = _similarity
$FillPattern.visible = _fill_with == 1 $FillPattern.visible = _fill_with == FillWith.PATTERN
$FillPattern/XOffset/OffsetX.value = _offset_x $FillPattern/XOffset/OffsetX.value = _offset_x
$FillPattern/YOffset/OffsetY.value = _offset_y $FillPattern/YOffset/OffsetY.value = _offset_y
@ -147,11 +159,14 @@ func draw_start(position: Vector2) -> void:
and not Global.current_project.can_pixel_get_drawn(position) and not Global.current_project.can_pixel_get_drawn(position)
): ):
return return
var undo_data = _get_undo_data() var undo_data := _get_undo_data()
if _fill_area: match _fill_area:
fill_in_area(position) FillArea.AREA:
else: fill_in_area(position)
fill_in_color(position) FillArea.COLORS:
fill_in_color(position)
FillArea.SELECTION:
fill_in_selection()
commit_undo("Draw", undo_data) commit_undo("Draw", undo_data)
@ -169,7 +184,7 @@ func fill_in_color(position: Vector2) -> void:
var images := _get_selected_draw_images() var images := _get_selected_draw_images()
for image in images: for image in images:
var pattern_image: Image var pattern_image: Image
if _fill_with == 0 or _pattern == null: if _fill_with == FillWith.COLOR or _pattern == null:
if tool_slot.color.is_equal_approx(color): if tool_slot.color.is_equal_approx(color):
return return
else: else:
@ -205,7 +220,7 @@ func fill_in_color(position: Vector2) -> void:
# pixel offset converted to pattern uv offset # pixel offset converted to pattern uv offset
"pattern_uv_offset": "pattern_uv_offset":
Vector2.ONE / pattern_tex.get_size() * Vector2(_offset_x, _offset_y), Vector2.ONE / pattern_tex.get_size() * Vector2(_offset_x, _offset_y),
"has_pattern": true if _fill_with == 1 else false "has_pattern": true if _fill_with == FillWith.PATTERN else false
} }
var gen := ShaderImageEffect.new() var gen := ShaderImageEffect.new()
gen.generate_image(image, COLOR_REPLACE_SHADER, params, project.size) gen.generate_image(image, COLOR_REPLACE_SHADER, params, project.size)
@ -232,6 +247,25 @@ func fill_in_area(position: Vector2) -> void:
_flood_fill(Vector2(position.x, mirror_y)) _flood_fill(Vector2(position.x, mirror_y))
func fill_in_selection() -> void:
var project: Project = Global.current_project
var images := _get_selected_draw_images()
if project.has_selection:
var filler := Image.new()
filler.create(project.size.x, project.size.y, false, Image.FORMAT_RGBA8)
filler.fill(tool_slot.color)
var rect: Rect2 = Global.canvas.selection.big_bounding_rectangle
var selection_map_copy := SelectionMap.new()
selection_map_copy.copy_from(project.selection_map)
# In case the selection map is bigger than the canvas
selection_map_copy.crop(project.size.x, project.size.y)
for image in images:
image.blit_rect_mask(filler, selection_map_copy, rect, rect.position)
else:
for image in images:
image.fill(tool_slot.color)
# Add a new segment to the array # Add a new segment to the array
func _add_new_segment(y: int = 0) -> void: func _add_new_segment(y: int = 0) -> void:
var segment = {} var segment = {}
@ -337,7 +371,7 @@ func _flood_fill(position: Vector2) -> void:
var images := _get_selected_draw_images() var images := _get_selected_draw_images()
for image in images: for image in images:
var color: Color = image.get_pixelv(position) var color: Color = image.get_pixelv(position)
if _fill_with == 0 or _pattern == null: if _fill_with == FillWith.COLOR or _pattern == null:
# end early if we are filling with the same color # end early if we are filling with the same color
if tool_slot.color.is_equal_approx(color): if tool_slot.color.is_equal_approx(color):
return return
@ -385,7 +419,7 @@ func _compute_segments_for_image(
func _color_segments(image: Image) -> void: func _color_segments(image: Image) -> void:
if _fill_with == 0 or _pattern == null: if _fill_with == FillWith.COLOR or _pattern == null:
var color_str = tool_slot.color.to_html() var color_str = tool_slot.color.to_html()
# short circuit for flat colors # short circuit for flat colors
for c in _allegro_image_segments.size(): for c in _allegro_image_segments.size():

View file

@ -27,21 +27,29 @@ margin_bottom = 105.0
script = ExtResource( 3 ) script = ExtResource( 3 )
[node name="Label" parent="." index="0"] [node name="Label" parent="." index="0"]
margin_right = 132.0 margin_right = 131.0
[node name="FillCheckBox" type="CheckBox" parent="." index="1"] [node name="FillArea" type="Label" parent="." index="1"]
margin_left = 38.0
margin_top = 18.0 margin_top = 18.0
margin_right = 132.0 margin_right = 92.0
margin_bottom = 42.0 margin_bottom = 32.0
hint_tooltip = "If enabled, it fills the contiguous area with the selected color.
If disabled, it replaces all pixels of the same color with the selected color."
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
pressed = true text = "Fill area:"
text = "Fill contiguously"
align = 1
[node name="Similarity" type="VBoxContainer" parent="." index="2"] [node name="FillAreaOptions" type="OptionButton" parent="." index="2"]
margin_left = 13.0
margin_top = 36.0
margin_right = 117.0
margin_bottom = 56.0
mouse_default_cursor_shape = 2
size_flags_horizontal = 4
text = "Similar area"
items = [ "Similar area", null, false, 0, null, "Similar colors", null, false, 1, null, "Whole selection", null, false, 2, null ]
selected = 0
[node name="Similarity" type="VBoxContainer" parent="." index="3"]
visible = false visible = false
margin_top = 60.0 margin_top = 60.0
margin_right = 131.0 margin_right = 131.0
@ -89,26 +97,26 @@ __meta__ = {
"_editor_description_": "" "_editor_description_": ""
} }
[node name="FillWith" type="Label" parent="." index="3"] [node name="FillWith" type="Label" parent="." index="4"]
margin_left = 39.0 margin_left = 38.0
margin_top = 46.0 margin_top = 60.0
margin_right = 93.0 margin_right = 92.0
margin_bottom = 60.0 margin_bottom = 74.0
size_flags_horizontal = 4 size_flags_horizontal = 4
text = "Fill with:" text = "Fill with:"
[node name="FillWithOptions" type="OptionButton" parent="." index="4"] [node name="FillWithOptions" type="OptionButton" parent="." index="5"]
margin_left = 5.0 margin_left = 5.0
margin_top = 64.0 margin_top = 78.0
margin_right = 126.0 margin_right = 126.0
margin_bottom = 84.0 margin_bottom = 98.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
size_flags_horizontal = 4 size_flags_horizontal = 4
text = "Selected Color" text = "Selected Color"
items = [ "Selected Color", null, false, 0, null, "Pattern", null, false, 1, null ] items = [ "Selected Color", null, false, 0, null, "Pattern", null, false, 1, null ]
selected = 0 selected = 0
[node name="FillPattern" type="VBoxContainer" parent="." index="5"] [node name="FillPattern" type="VBoxContainer" parent="." index="6"]
visible = false visible = false
margin_left = 22.0 margin_left = 22.0
margin_top = 102.0 margin_top = 102.0
@ -180,7 +188,7 @@ margin_right = 85.0
margin_bottom = 24.0 margin_bottom = 24.0
mouse_default_cursor_shape = 2 mouse_default_cursor_shape = 2
[connection signal="toggled" from="FillCheckBox" to="." method="_on_FillCheckBox_toggled"] [connection signal="item_selected" from="FillAreaOptions" to="." method="_on_FillAreaOptions_item_selected"]
[connection signal="value_changed" from="Similarity/Value" to="." method="_on_Value_value_changed"] [connection signal="value_changed" from="Similarity/Value" to="." method="_on_Value_value_changed"]
[connection signal="value_changed" from="Similarity/Slider" to="." method="_on_Slider_value_changed"] [connection signal="value_changed" from="Similarity/Slider" to="." method="_on_Slider_value_changed"]
[connection signal="item_selected" from="FillWithOptions" to="." method="_on_FillWithOptions_item_selected"] [connection signal="item_selected" from="FillWithOptions" to="." method="_on_FillWithOptions_item_selected"]