mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-20 12:33: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:
parent
0e4804342a
commit
cac9b67335
2 changed files with 84 additions and 42 deletions
|
@ -1,12 +1,15 @@
|
|||
extends BaseTool
|
||||
|
||||
enum FillArea { AREA, COLORS, SELECTION }
|
||||
enum FillWith { COLOR, PATTERN }
|
||||
|
||||
const COLOR_REPLACE_SHADER := preload("res://src/Shaders/ColorReplace.shader")
|
||||
|
||||
var _prev_mode := 0
|
||||
var _pattern: Patterns.Pattern
|
||||
var _similarity := 100
|
||||
var _fill_area := true
|
||||
var _fill_with := 0
|
||||
var _fill_area: int = FillArea.AREA
|
||||
var _fill_with: int = FillWith.COLOR
|
||||
var _offset_x := 0
|
||||
var _offset_y := 0
|
||||
# working array used as buffer for segments while flooding
|
||||
|
@ -14,26 +17,36 @@ var _allegro_flood_segments: Array
|
|||
# results array per image while flooding
|
||||
var _allegro_image_segments: Array
|
||||
|
||||
onready var fill_check_box: CheckBox = $FillCheckBox
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
update_pattern()
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("change_tool_mode") or event.is_action_released("change_tool_mode"):
|
||||
fill_check_box.pressed = not fill_check_box.pressed
|
||||
_fill_area = fill_check_box.pressed
|
||||
$Similarity.visible = not _fill_area
|
||||
if event.is_action_pressed("change_tool_mode"):
|
||||
_prev_mode = _fill_area
|
||||
if event.is_action("change_tool_mode"):
|
||||
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:
|
||||
_fill_area = button_pressed
|
||||
func _on_FillAreaOptions_item_selected(index: int) -> void:
|
||||
_fill_area = index
|
||||
update_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:
|
||||
_fill_with = index
|
||||
$Similarity/Value.value = _similarity
|
||||
|
@ -105,12 +118,11 @@ func set_config(config: Dictionary) -> void:
|
|||
|
||||
|
||||
func update_config() -> void:
|
||||
$FillCheckBox.pressed = _fill_area
|
||||
_select_fill_area_optionbutton()
|
||||
$FillWithOptions.selected = _fill_with
|
||||
$Similarity.visible = not _fill_area
|
||||
$Similarity/Value.value = _similarity
|
||||
$Similarity/Slider.value = _similarity
|
||||
$FillPattern.visible = _fill_with == 1
|
||||
$FillPattern.visible = _fill_with == FillWith.PATTERN
|
||||
$FillPattern/XOffset/OffsetX.value = _offset_x
|
||||
$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)
|
||||
):
|
||||
return
|
||||
var undo_data = _get_undo_data()
|
||||
if _fill_area:
|
||||
fill_in_area(position)
|
||||
else:
|
||||
fill_in_color(position)
|
||||
var undo_data := _get_undo_data()
|
||||
match _fill_area:
|
||||
FillArea.AREA:
|
||||
fill_in_area(position)
|
||||
FillArea.COLORS:
|
||||
fill_in_color(position)
|
||||
FillArea.SELECTION:
|
||||
fill_in_selection()
|
||||
commit_undo("Draw", undo_data)
|
||||
|
||||
|
||||
|
@ -169,7 +184,7 @@ func fill_in_color(position: Vector2) -> void:
|
|||
var images := _get_selected_draw_images()
|
||||
for image in images:
|
||||
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):
|
||||
return
|
||||
else:
|
||||
|
@ -205,7 +220,7 @@ func fill_in_color(position: Vector2) -> void:
|
|||
# pixel offset converted to pattern uv offset
|
||||
"pattern_uv_offset":
|
||||
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()
|
||||
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))
|
||||
|
||||
|
||||
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
|
||||
func _add_new_segment(y: int = 0) -> void:
|
||||
var segment = {}
|
||||
|
@ -337,7 +371,7 @@ func _flood_fill(position: Vector2) -> void:
|
|||
var images := _get_selected_draw_images()
|
||||
for image in images:
|
||||
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
|
||||
if tool_slot.color.is_equal_approx(color):
|
||||
return
|
||||
|
@ -385,7 +419,7 @@ func _compute_segments_for_image(
|
|||
|
||||
|
||||
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()
|
||||
# short circuit for flat colors
|
||||
for c in _allegro_image_segments.size():
|
||||
|
|
|
@ -27,21 +27,29 @@ margin_bottom = 105.0
|
|||
script = ExtResource( 3 )
|
||||
|
||||
[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_right = 132.0
|
||||
margin_bottom = 42.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."
|
||||
margin_right = 92.0
|
||||
margin_bottom = 32.0
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 4
|
||||
pressed = true
|
||||
text = "Fill contiguously"
|
||||
align = 1
|
||||
text = "Fill area:"
|
||||
|
||||
[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
|
||||
margin_top = 60.0
|
||||
margin_right = 131.0
|
||||
|
@ -89,26 +97,26 @@ __meta__ = {
|
|||
"_editor_description_": ""
|
||||
}
|
||||
|
||||
[node name="FillWith" type="Label" parent="." index="3"]
|
||||
margin_left = 39.0
|
||||
margin_top = 46.0
|
||||
margin_right = 93.0
|
||||
margin_bottom = 60.0
|
||||
[node name="FillWith" type="Label" parent="." index="4"]
|
||||
margin_left = 38.0
|
||||
margin_top = 60.0
|
||||
margin_right = 92.0
|
||||
margin_bottom = 74.0
|
||||
size_flags_horizontal = 4
|
||||
text = "Fill with:"
|
||||
|
||||
[node name="FillWithOptions" type="OptionButton" parent="." index="4"]
|
||||
[node name="FillWithOptions" type="OptionButton" parent="." index="5"]
|
||||
margin_left = 5.0
|
||||
margin_top = 64.0
|
||||
margin_top = 78.0
|
||||
margin_right = 126.0
|
||||
margin_bottom = 84.0
|
||||
margin_bottom = 98.0
|
||||
mouse_default_cursor_shape = 2
|
||||
size_flags_horizontal = 4
|
||||
text = "Selected Color"
|
||||
items = [ "Selected Color", null, false, 0, null, "Pattern", null, false, 1, null ]
|
||||
selected = 0
|
||||
|
||||
[node name="FillPattern" type="VBoxContainer" parent="." index="5"]
|
||||
[node name="FillPattern" type="VBoxContainer" parent="." index="6"]
|
||||
visible = false
|
||||
margin_left = 22.0
|
||||
margin_top = 102.0
|
||||
|
@ -180,7 +188,7 @@ margin_right = 85.0
|
|||
margin_bottom = 24.0
|
||||
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/Slider" to="." method="_on_Slider_value_changed"]
|
||||
[connection signal="item_selected" from="FillWithOptions" to="." method="_on_FillWithOptions_item_selected"]
|
||||
|
|
Loading…
Add table
Reference in a new issue