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

Added outline generation, under new "Image" menu

You can currently change outline color & thickness
This commit is contained in:
OverloadedOrama 2019-12-24 16:48:07 +02:00
parent a127b71aaa
commit ea97ec85f8
3 changed files with 153 additions and 36 deletions

View file

@ -158,14 +158,12 @@ anchor_bottom = 1.0
custom_constants/separation = 0
[node name="TopMenuContainer" type="Panel" parent="MenuAndUI"]
editor/display_folded = true
margin_right = 1152.0
margin_bottom = 28.0
rect_min_size = Vector2( 0, 28 )
custom_styles/panel = ExtResource( 3 )
[node name="MenuItems" type="HBoxContainer" parent="MenuAndUI/TopMenuContainer"]
editor/display_folded = true
margin_left = 2.0
margin_top = 4.0
margin_right = 1010.0
@ -193,9 +191,17 @@ mouse_default_cursor_shape = 2
text = "View"
switch_on_hover = true
[node name="HelpMenu" type="MenuButton" parent="MenuAndUI/TopMenuContainer/MenuItems"]
[node name="ImageMenu" type="MenuButton" parent="MenuAndUI/TopMenuContainer/MenuItems"]
margin_left = 102.0
margin_right = 135.0
margin_right = 144.0
margin_bottom = 23.0
mouse_default_cursor_shape = 2
text = "Image"
switch_on_hover = true
[node name="HelpMenu" type="MenuButton" parent="MenuAndUI/TopMenuContainer/MenuItems"]
margin_left = 148.0
margin_right = 181.0
margin_bottom = 23.0
mouse_default_cursor_shape = 2
text = "Help"
@ -1671,6 +1677,53 @@ selected = 0
[node name="PreferencesDialog" parent="." instance=ExtResource( 61 )]
[node name="OutlineDialog" type="ConfirmationDialog" parent="."]
editor/display_folded = true
margin_right = 200.0
margin_bottom = 70.0
[node name="OptionsContainer" type="GridContainer" parent="OutlineDialog"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -92.0
margin_top = -36.0
margin_right = 92.0
margin_bottom = 5.0
custom_constants/vseparation = 4
custom_constants/hseparation = 4
columns = 2
[node name="ThickLabel" type="Label" parent="OutlineDialog/OptionsContainer"]
margin_top = 1.0
margin_right = 75.0
margin_bottom = 16.0
text = "Thickness:"
[node name="ThickValue" type="SpinBox" parent="OutlineDialog/OptionsContainer"]
margin_left = 79.0
margin_right = 143.0
margin_bottom = 17.0
min_value = 1.0
max_value = 16384.0
value = 1.0
suffix = "px"
[node name="OutlineColorLabel" type="Label" parent="OutlineDialog/OptionsContainer"]
margin_top = 23.0
margin_right = 75.0
margin_bottom = 38.0
text = "Fill with color:"
[node name="OutlineColor" type="ColorPickerButton" parent="OutlineDialog/OptionsContainer"]
margin_left = 79.0
margin_top = 21.0
margin_right = 143.0
margin_bottom = 41.0
rect_min_size = Vector2( 64, 20 )
color = Color( 1, 0, 0, 1 )
[node name="AboutDialog" type="AcceptDialog" parent="."]
editor/display_folded = true
margin_right = 284.0
@ -1832,6 +1885,8 @@ visible = false
[connection signal="confirmed" from="ScaleImage" to="." method="_on_ScaleImage_confirmed"]
[connection signal="popup_hide" from="ScaleImage" to="." method="_can_draw_true"]
[connection signal="popup_hide" from="PreferencesDialog" to="." method="_can_draw_true"]
[connection signal="confirmed" from="OutlineDialog" to="." method="_on_OutlineDialog_confirmed"]
[connection signal="popup_hide" from="OutlineDialog" to="." method="_can_draw_true"]
[connection signal="popup_hide" from="AboutDialog" to="." method="_can_draw_true"]
[connection signal="pressed" from="AboutDialog/AboutUI/Links/LinkButtons/Website" to="AboutDialog" method="_on_Website_pressed"]
[connection signal="pressed" from="AboutDialog/AboutUI/Links/LinkButtons/GitHub" to="AboutDialog" method="_on_GitHub_pressed"]

View file

@ -136,6 +136,7 @@ var vertical_ruler : BaseButton
var file_menu : MenuButton
var edit_menu : MenuButton
var view_menu : MenuButton
var image_menu : MenuButton
var help_menu : MenuButton
var cursor_position_label : Label
var zoom_level_label : Label
@ -236,6 +237,7 @@ func _ready() -> void:
file_menu = find_node_by_name(root, "FileMenu")
edit_menu = find_node_by_name(root, "EditMenu")
view_menu = find_node_by_name(root, "ViewMenu")
image_menu = find_node_by_name(root, "ImageMenu")
help_menu = find_node_by_name(root, "HelpMenu")
cursor_position_label = find_node_by_name(root, "CursorPosition")
zoom_level_label = find_node_by_name(root, "ZoomLevel")

View file

@ -71,6 +71,9 @@ func _ready() -> void:
"Show Rulers" : KEY_MASK_CMD + KEY_R,
"Show Guides" : KEY_MASK_CMD + KEY_F
}
var image_menu_items := {
"Outline" : 0
}
var help_menu_items := {
"About Pixelorama" : 0
}
@ -95,6 +98,7 @@ func _ready() -> void:
var file_menu : PopupMenu = Global.file_menu.get_popup()
var edit_menu : PopupMenu = Global.edit_menu.get_popup()
view_menu = Global.view_menu.get_popup()
var image_menu : PopupMenu = Global.image_menu.get_popup()
var help_menu : PopupMenu = Global.help_menu.get_popup()
var add_palette_menu : PopupMenu = Global.add_palette_button.get_child(0)
@ -114,6 +118,10 @@ func _ready() -> void:
view_menu.set_item_checked(3, true) #Show Guides
view_menu.hide_on_checkable_item_selection = false
i = 0
for item in image_menu_items.keys():
image_menu.add_item(item, i, image_menu_items[item])
i += 1
i = 0
for item in help_menu_items.keys():
help_menu.add_item(item, i, help_menu_items[item])
i += 1
@ -121,11 +129,12 @@ func _ready() -> void:
file_menu.connect("id_pressed", self, "file_menu_id_pressed")
edit_menu.connect("id_pressed", self, "edit_menu_id_pressed")
view_menu.connect("id_pressed", self, "view_menu_id_pressed")
image_menu.connect("id_pressed", self, "image_menu_id_pressed")
help_menu.connect("id_pressed", self, "help_menu_id_pressed")
add_palette_menu.connect("id_pressed", self, "add_palette_menu_id_pressed")
var root = get_tree().get_root()
#Node, left mouse shortcut, right mouse shortcut
# Node, left mouse shortcut, right mouse shortcut
tools.append([Global.find_node_by_name(root, "Pencil"), "left_pencil_tool", "right_pencil_tool"])
tools.append([Global.find_node_by_name(root, "Eraser"), "left_eraser_tool", "right_eraser_tool"])
tools.append([Global.find_node_by_name(root, "Bucket"), "left_fill_tool", "right_fill_tool"])
@ -139,12 +148,12 @@ func _ready() -> void:
Global.left_color_picker.get_picker().move_child(Global.left_color_picker.get_picker().get_child(0), 1)
Global.right_color_picker.get_picker().move_child(Global.right_color_picker.get_picker().get_child(0), 1)
#Options for Import
# Options for Import
import_as_new_frame = CheckBox.new()
import_as_new_frame.text = tr("IMPORT_FILE_LABEL")
$ImportSprites.get_vbox().add_child(import_as_new_frame)
#Options for Export
# Options for Export
var export_project_hbox := HBoxContainer.new()
export_all_frames = CheckBox.new()
export_all_frames.text = tr("EXPORT_ALLFRAMES_LABEL")
@ -185,84 +194,84 @@ func _input(event : InputEvent) -> void:
if event.is_action_pressed("toggle_fullscreen"):
OS.window_fullscreen = !OS.window_fullscreen
if event.is_action_pressed("redo_secondary"): #Shift + Ctrl + Z
if event.is_action_pressed("redo_secondary"): # Shift + Ctrl + Z
redone = true
Global.undo_redo.redo()
redone = false
if Global.has_focus:
for t in tools: #Handle tool shortcuts
if event.is_action_pressed(t[2]): #Shortcut for right button (with Alt)
for t in tools: # Handle tool shortcuts
if event.is_action_pressed(t[2]): # Shortcut for right button (with Alt)
_on_Tool_pressed(t[0], false, false)
elif event.is_action_pressed(t[1]): #Shortcut for left button
elif event.is_action_pressed(t[1]): # Shortcut for left button
_on_Tool_pressed(t[0], false, true)
func _notification(what : int) -> void:
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: #Handle exit
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: # Handle exit
$QuitDialog.call_deferred("popup_centered")
Global.can_draw = false
func file_menu_id_pressed(id : int) -> void:
match id:
0: #New
0: # New
$CreateNewImage.popup_centered()
Global.can_draw = false
1: #Open
1: # Open
$OpenSprite.popup_centered()
Global.can_draw = false
opensprite_file_selected = false
2: #Save
2: # Save
if current_save_path == "":
$SaveSprite.popup_centered()
Global.can_draw = false
else:
_on_SaveSprite_file_selected(current_save_path)
3: #Save as
3: # Save as
$SaveSprite.popup_centered()
Global.can_draw = false
4: #Import
4: # Import
$ImportSprites.popup_centered()
Global.can_draw = false
opensprite_file_selected = false
5: #Export
5: # Export
if current_export_path == "":
$ExportSprites.popup_centered()
Global.can_draw = false
else:
export_project()
6: #Export as
6: # Export as
$ExportSprites.popup_centered()
Global.can_draw = false
7: #Quit
7: # Quit
$QuitDialog.popup_centered()
Global.can_draw = false
func edit_menu_id_pressed(id : int) -> void:
match id:
0: #Undo
0: # Undo
Global.undo_redo.undo()
1: #Redo
1: # Redo
redone = true
Global.undo_redo.redo()
redone = false
2: #Scale Image
2: # Scale Image
$ScaleImage.popup_centered()
Global.can_draw = false
3: #Crop Image
#Use first layer as a starting rectangle
3: # Crop Image
# Use first layer as a starting rectangle
var used_rect : Rect2 = Global.canvas.layers[0][0].get_used_rect()
#However, if first layer is empty, loop through all layers until we find one that isn't
# However, if first layer is empty, loop through all layers until we find one that isn't
var i := 0
while(i < Global.canvas.layers.size() - 1 && Global.canvas.layers[i][0].get_used_rect() == Rect2(0, 0, 0, 0)):
i += 1
used_rect = Global.canvas.layers[i][0].get_used_rect()
#Merge all layers with content
# Merge all layers with content
for j in range(Global.canvas.layers.size() - 1, i, -1):
if Global.canvas.layers[j][0].get_used_rect() != Rect2(0, 0, 0, 0):
used_rect = used_rect.merge(Global.canvas.layers[j][0].get_used_rect())
#If no layer has any content, just return
# If no layer has any content, just return
if used_rect == Rect2(0, 0, 0, 0):
return
@ -271,7 +280,7 @@ func edit_menu_id_pressed(id : int) -> void:
Global.undos += 1
Global.undo_redo.create_action("Scale")
Global.undo_redo.add_do_property(Global.canvas, "size", Vector2(width, height).floor())
#Loop through all the layers to crop them
# Loop through all the layers to crop them
for j in range(Global.canvas.layers.size() - 1, -1, -1):
var sprite : Image = Global.canvas.layers[j][0].get_rect(used_rect)
Global.undo_redo.add_do_property(Global.canvas.layers[j][0], "data", sprite.data)
@ -281,7 +290,7 @@ func edit_menu_id_pressed(id : int) -> void:
Global.undo_redo.add_undo_method(Global, "undo", [Global.canvas])
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
4: #Clear selection
4: # Clear selection
Global.canvas.handle_undo("Rectangle Select")
Global.selection_rectangle.polygon[0] = Vector2.ZERO
Global.selection_rectangle.polygon[1] = Vector2.ZERO
@ -303,24 +312,24 @@ func edit_menu_id_pressed(id : int) -> void:
canvas.layers[canvas.current_layer_index][0].flip_y()
canvas.layers[canvas.current_layer_index][0].lock()
canvas.handle_redo("Draw")
7: #Preferences
7: # Preferences
$PreferencesDialog.popup_centered()
Global.can_draw = false
func view_menu_id_pressed(id : int) -> void:
match id:
0: #Tile mode
0: # Tile mode
Global.tile_mode = !Global.tile_mode
view_menu.set_item_checked(0, Global.tile_mode)
1: #Show grid
1: # Show grid
Global.draw_grid = !Global.draw_grid
view_menu.set_item_checked(1, Global.draw_grid)
2: #Show rulers
2: # Show rulers
Global.show_rulers = !Global.show_rulers
view_menu.set_item_checked(2, Global.show_rulers)
Global.horizontal_ruler.visible = Global.show_rulers
Global.vertical_ruler.visible = Global.show_rulers
3: #Show guides
3: # Show guides
Global.show_guides = !Global.show_guides
view_menu.set_item_checked(3, Global.show_guides)
for canvas in Global.canvases:
@ -328,9 +337,14 @@ func view_menu_id_pressed(id : int) -> void:
if guide is Guide:
guide.visible = Global.show_guides
func image_menu_id_pressed(id : int) -> void:
match id:
0: # Outline
$OutlineDialog.popup_centered()
func help_menu_id_pressed(id : int) -> void:
match id:
0: #About Pixelorama
0: # About Pixelorama
$AboutDialog.popup_centered()
Global.can_draw = false
@ -638,6 +652,52 @@ func _on_ScaleImage_confirmed() -> void:
Global.undo_redo.add_do_method(Global, "redo", [Global.canvas])
Global.undo_redo.commit_action()
func _on_OutlineDialog_confirmed() -> void:
var outline_color : Color = $OutlineDialog/OptionsContainer/OutlineColor.color
var thickness : int = $OutlineDialog/OptionsContainer/ThickValue.value
var image : Image = Global.canvas.layers[Global.canvas.current_layer_index][0]
if image.is_invisible():
return
var new_image := Image.new()
new_image.copy_from(image)
new_image.lock()
Global.canvas.handle_undo("Draw")
for xx in image.get_size().x:
for yy in image.get_size().y:
var pos = Vector2(xx, yy)
var current_pixel := image.get_pixelv(pos)
if current_pixel.a == 0:
continue
for i in range(1, thickness + 1):
var new_pos : Vector2 = pos + Vector2.LEFT * i
if new_pos.x > 0:
var new_pixel = image.get_pixelv(new_pos)
if new_pixel.a == 0:
new_image.set_pixelv(new_pos, outline_color)
new_pos = pos + Vector2.RIGHT * i
if new_pos.x < Global.canvas.size.x - 1:
var new_pixel = image.get_pixelv(new_pos)
if new_pixel.a == 0:
new_image.set_pixelv(new_pos, outline_color)
new_pos = pos + Vector2.UP * i
if yy > 0:
var new_pixel = image.get_pixelv(new_pos)
if new_pixel.a == 0:
new_image.set_pixelv(new_pos, outline_color)
new_pos = pos + Vector2.DOWN * i
if yy < Global.canvas.size.y - 1:
var new_pixel = image.get_pixelv(new_pos)
if new_pixel.a == 0:
new_image.set_pixelv(new_pos, outline_color)
image.copy_from(new_image)
Global.canvas.handle_redo("Draw")
func _on_ImportSprites_popup_hide() -> void:
if !opensprite_file_selected:
Global.can_draw = true