mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-01-19 01:29:49 +00:00
bdd3cdf45e
The resulting camera zoom now depends on the window size. More specifically, the main viewport's x size. This formula is purely trial-and-error, and it may not work perfectly, or properly for some screen sizes. If anyone wants to improve it, feel free to do so!
708 lines
27 KiB
GDScript
708 lines
27 KiB
GDScript
extends Control
|
|
|
|
var opensprite_file_selected := false
|
|
var file_menu : PopupMenu
|
|
var view_menu : PopupMenu
|
|
var tools := []
|
|
var redone := false
|
|
var is_quitting_on_save := false
|
|
var previous_left_color := Color.black
|
|
var previous_right_color := Color.white
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready() -> void:
|
|
get_tree().set_auto_accept_quit(false)
|
|
# Set a minimum window size to prevent UI elements from collapsing on each other.
|
|
# This property is only available in 3.2alpha or later, so use `set()` to fail gracefully if it doesn't exist.
|
|
OS.set("min_window_size", Vector2(1024, 576))
|
|
|
|
# `TranslationServer.get_loaded_locales()` was added in 3.2beta and in 3.1.2
|
|
# The `has_method()` check and the `else` branch can be removed once 3.2 is released.
|
|
if TranslationServer.has_method("get_loaded_locales"):
|
|
Global.loaded_locales = TranslationServer.get_loaded_locales()
|
|
else:
|
|
# Hardcoded list of locales
|
|
Global.loaded_locales = ["de_DE", "el_GR", "en_US", "eo_UY", "es_ES", "fr_FR", "it_IT", "lv_LV", "pl_PL", "pt_BR", "ru_RU", "zh_CN","zh_TW"]
|
|
|
|
# Make sure locales are always sorted, in the same order
|
|
Global.loaded_locales.sort()
|
|
|
|
# Restore the window position/size if values are present in the configuration cache
|
|
if Global.config_cache.has_section_key("window", "screen"):
|
|
OS.current_screen = Global.config_cache.get_value("window", "screen")
|
|
if Global.config_cache.has_section_key("window", "maximized"):
|
|
OS.window_maximized = Global.config_cache.get_value("window", "maximized")
|
|
|
|
if !OS.window_maximized:
|
|
if Global.config_cache.has_section_key("window", "position"):
|
|
OS.window_position = Global.config_cache.get_value("window", "position")
|
|
if Global.config_cache.has_section_key("window", "size"):
|
|
OS.window_size = Global.config_cache.get_value("window", "size")
|
|
|
|
var file_menu_items := {
|
|
"New..." : InputMap.get_action_list("new_file")[0].get_scancode_with_modifiers(),
|
|
"Open..." : InputMap.get_action_list("open_file")[0].get_scancode_with_modifiers(),
|
|
"Save..." : InputMap.get_action_list("save_file")[0].get_scancode_with_modifiers(),
|
|
"Save as..." : InputMap.get_action_list("save_file_as")[0].get_scancode_with_modifiers(),
|
|
"Import..." : InputMap.get_action_list("import_file")[0].get_scancode_with_modifiers(),
|
|
"Export..." : InputMap.get_action_list("export_file")[0].get_scancode_with_modifiers(),
|
|
"Export as..." : InputMap.get_action_list("export_file_as")[0].get_scancode_with_modifiers(),
|
|
"Quit" : InputMap.get_action_list("quit")[0].get_scancode_with_modifiers(),
|
|
}
|
|
var edit_menu_items := {
|
|
"Undo" : InputMap.get_action_list("undo")[0].get_scancode_with_modifiers(),
|
|
"Redo" : InputMap.get_action_list("redo")[0].get_scancode_with_modifiers(),
|
|
"Clear Selection" : 0,
|
|
"Preferences" : 0
|
|
}
|
|
var view_menu_items := {
|
|
"Tile Mode" : InputMap.get_action_list("tile_mode")[0].get_scancode_with_modifiers(),
|
|
"Show Grid" : InputMap.get_action_list("show_grid")[0].get_scancode_with_modifiers(),
|
|
"Show Rulers" : InputMap.get_action_list("show_rulers")[0].get_scancode_with_modifiers(),
|
|
"Show Guides" : InputMap.get_action_list("show_guides")[0].get_scancode_with_modifiers(),
|
|
"Show Animation Timeline" : 0
|
|
}
|
|
var image_menu_items := {
|
|
"Scale Image" : 0,
|
|
"Crop Image" : 0,
|
|
"Flip Horizontal" : InputMap.get_action_list("image_flip_horizontal")[0].get_scancode_with_modifiers(),
|
|
"Flip Vertical" : InputMap.get_action_list("image_flip_vertical")[0].get_scancode_with_modifiers(),
|
|
"Rotate Image" : 0,
|
|
"Invert colors" : 0,
|
|
"Desaturation" : 0,
|
|
"Outline" : 0
|
|
}
|
|
var help_menu_items := {
|
|
"View Splash Screen" : 0,
|
|
"Issue Tracker" : 0,
|
|
"Changelog" : 0,
|
|
"About Pixelorama" : 0
|
|
}
|
|
|
|
# Load language
|
|
if Global.config_cache.has_section_key("preferences", "locale"):
|
|
var saved_locale : String = Global.config_cache.get_value("preferences", "locale")
|
|
TranslationServer.set_locale(saved_locale)
|
|
|
|
# Set the language option menu's default selected option to the loaded locale
|
|
var locale_index: int = Global.loaded_locales.find(saved_locale)
|
|
$PreferencesDialog.languages.get_child(1).pressed = false
|
|
$PreferencesDialog.languages.get_child(locale_index + 2).pressed = true
|
|
else: # If the user doesn't have a language preference, set it to their OS' locale
|
|
TranslationServer.set_locale(OS.get_locale())
|
|
|
|
if "zh" in TranslationServer.get_locale():
|
|
theme.default_font = preload("res://Assets/Fonts/CJK/NotoSansCJKtc-Regular.tres")
|
|
else:
|
|
theme.default_font = preload("res://Assets/Fonts/Roboto-Regular.tres")
|
|
|
|
|
|
file_menu = 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 i = 0
|
|
for item in file_menu_items.keys():
|
|
file_menu.add_item(item, i, file_menu_items[item])
|
|
i += 1
|
|
i = 0
|
|
for item in edit_menu_items.keys():
|
|
edit_menu.add_item(item, i, edit_menu_items[item])
|
|
i += 1
|
|
i = 0
|
|
for item in view_menu_items.keys():
|
|
view_menu.add_check_item(item, i, view_menu_items[item])
|
|
i += 1
|
|
view_menu.set_item_checked(2, true) # Show Rulers
|
|
view_menu.set_item_checked(3, true) # Show Guides
|
|
view_menu.set_item_checked(4, true) # Show Animation Timeline
|
|
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])
|
|
if i == 4:
|
|
image_menu.add_separator()
|
|
i += 1
|
|
i = 0
|
|
for item in help_menu_items.keys():
|
|
help_menu.add_item(item, i, help_menu_items[item])
|
|
i += 1
|
|
|
|
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")
|
|
|
|
var root = get_tree().get_root()
|
|
# 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"])
|
|
tools.append([Global.find_node_by_name(root, "LightenDarken"), "left_lightdark_tool", "right_lightdark_tool"])
|
|
tools.append([Global.find_node_by_name(root, "RectSelect"), "left_rectangle_select_tool", "right_rectangle_select_tool"])
|
|
tools.append([Global.find_node_by_name(root, "ColorPicker"), "left_colorpicker_tool", "right_colorpicker_tool"])
|
|
tools.append([Global.find_node_by_name(root, "Zoom"), "left_zoom_tool", "right_zoom_tool"])
|
|
|
|
for t in tools:
|
|
t[0].connect("pressed", self, "_on_Tool_pressed", [t[0]])
|
|
|
|
Global.update_hint_tooltips()
|
|
|
|
# Checks to see if it's 3.1.x
|
|
if Engine.get_version_info().major == 3 and Engine.get_version_info().minor < 2:
|
|
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)
|
|
|
|
if OS.get_cmdline_args():
|
|
for arg in OS.get_cmdline_args():
|
|
if arg.get_extension().to_lower() == "pxo":
|
|
_on_OpenSprite_file_selected(arg)
|
|
else:
|
|
$ImportSprites._on_ImportSprites_files_selected([arg])
|
|
|
|
Global.window_title = "(" + tr("untitled") + ") - Pixelorama"
|
|
|
|
Global.layers[0][0] = tr("Layer") + " 0"
|
|
Global.layers_container.get_child(0).label.text = Global.layers[0][0]
|
|
Global.layers_container.get_child(0).line_edit.text = Global.layers[0][0]
|
|
|
|
Import.import_brushes(Global.directory_module.get_brushes_search_path_in_order())
|
|
|
|
Global.left_color_picker.get_picker().presets_visible = false
|
|
Global.right_color_picker.get_picker().presets_visible = false
|
|
$QuitAndSaveDialog.add_button("Save & Exit", false, "Save")
|
|
$QuitAndSaveDialog.get_ok().text = "Exit without saving"
|
|
|
|
|
|
if not Global.config_cache.has_section_key("preferences", "startup"):
|
|
Global.config_cache.set_value("preferences", "startup", true)
|
|
if Global.config_cache.get_value("preferences", "startup"):
|
|
# Wait for the window to adjust itself, so the popup is correctly centered
|
|
yield(get_tree().create_timer(0.01), "timeout")
|
|
$SplashDialog.popup_centered() # Splash screen
|
|
else:
|
|
Global.can_draw = true
|
|
|
|
func _input(event : InputEvent) -> void:
|
|
Global.left_cursor.position = get_global_mouse_position() + Vector2(-32, 32)
|
|
Global.left_cursor.texture = Global.left_cursor_tool_texture
|
|
Global.right_cursor.position = get_global_mouse_position() + Vector2(32, 32)
|
|
Global.right_cursor.texture = Global.right_cursor_tool_texture
|
|
|
|
if event is InputEventKey and (event.scancode == KEY_ENTER or event.scancode == KEY_KP_ENTER):
|
|
if get_focus_owner() is LineEdit:
|
|
get_focus_owner().release_focus()
|
|
|
|
if event.is_action_pressed("toggle_fullscreen"):
|
|
OS.window_fullscreen = !OS.window_fullscreen
|
|
|
|
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)
|
|
_on_Tool_pressed(t[0], false, false)
|
|
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
|
|
show_quit_dialog()
|
|
|
|
func file_menu_id_pressed(id : int) -> void:
|
|
match id:
|
|
0: # New
|
|
if(!Global.saved):
|
|
$UnsavedCanvasDialog.popup_centered()
|
|
else:
|
|
$CreateNewImage.popup_centered()
|
|
Global.can_draw = false
|
|
1: # Open
|
|
$OpenSprite.popup_centered()
|
|
Global.can_draw = false
|
|
opensprite_file_selected = false
|
|
2: # Save
|
|
is_quitting_on_save = false
|
|
if OpenSave.current_save_path == "":
|
|
$SaveSprite.popup_centered()
|
|
Global.can_draw = false
|
|
else:
|
|
_on_SaveSprite_file_selected(OpenSave.current_save_path)
|
|
3: # Save as
|
|
is_quitting_on_save = false
|
|
$SaveSprite.popup_centered()
|
|
Global.can_draw = false
|
|
4: # Import
|
|
$ImportSprites.popup_centered()
|
|
Global.can_draw = false
|
|
opensprite_file_selected = false
|
|
5: # Export
|
|
if $ExportDialog.was_exported == false:
|
|
$ExportDialog.popup_centered()
|
|
Global.can_draw = false
|
|
else:
|
|
$ExportDialog.external_export()
|
|
6: # Export as
|
|
$ExportDialog.popup_centered()
|
|
Global.can_draw = false
|
|
7: # Quit
|
|
show_quit_dialog()
|
|
|
|
func edit_menu_id_pressed(id : int) -> void:
|
|
match id:
|
|
0: # Undo
|
|
Global.undo_redo.undo()
|
|
1: # Redo
|
|
redone = true
|
|
Global.undo_redo.redo()
|
|
redone = false
|
|
2: # Clear selection
|
|
Global.canvas.handle_undo("Rectangle Select")
|
|
Global.selection_rectangle.polygon[0] = Vector2.ZERO
|
|
Global.selection_rectangle.polygon[1] = Vector2.ZERO
|
|
Global.selection_rectangle.polygon[2] = Vector2.ZERO
|
|
Global.selection_rectangle.polygon[3] = Vector2.ZERO
|
|
Global.selected_pixels.clear()
|
|
Global.canvas.handle_redo("Rectangle Select")
|
|
3: # Preferences
|
|
$PreferencesDialog.popup_centered(Vector2(400, 280))
|
|
Global.can_draw = false
|
|
|
|
func view_menu_id_pressed(id : int) -> void:
|
|
match id:
|
|
0: # Tile mode
|
|
Global.tile_mode = !Global.tile_mode
|
|
view_menu.set_item_checked(0, Global.tile_mode)
|
|
1: # Show grid
|
|
Global.draw_grid = !Global.draw_grid
|
|
view_menu.set_item_checked(1, Global.draw_grid)
|
|
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
|
|
Global.show_guides = !Global.show_guides
|
|
view_menu.set_item_checked(3, Global.show_guides)
|
|
for canvas in Global.canvases:
|
|
for guide in canvas.get_children():
|
|
if guide is Guide:
|
|
guide.visible = Global.show_guides
|
|
4: # Show animation timeline
|
|
Global.show_animation_timeline = !Global.show_animation_timeline
|
|
view_menu.set_item_checked(4, Global.show_animation_timeline)
|
|
Global.animation_timeline.visible = Global.show_animation_timeline
|
|
|
|
Global.canvas.update()
|
|
|
|
func image_menu_id_pressed(id : int) -> void:
|
|
if Global.layers[Global.current_layer][2]: # No changes if the layer is locked
|
|
return
|
|
match id:
|
|
0: # Scale Image
|
|
$ScaleImage.popup_centered()
|
|
Global.can_draw = false
|
|
1: # 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
|
|
var i := 0
|
|
while(i < Global.canvas.layers.size() - 1 and 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
|
|
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 used_rect == Rect2(0, 0, 0, 0):
|
|
return
|
|
|
|
var width := used_rect.size.x
|
|
var height := used_rect.size.y
|
|
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
|
|
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)
|
|
Global.undo_redo.add_undo_property(Global.canvas.layers[j][0], "data", Global.canvas.layers[j][0].data)
|
|
|
|
Global.undo_redo.add_undo_property(Global.canvas, "size", Global.canvas.size)
|
|
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()
|
|
2: # Flip Horizontal
|
|
var canvas : Canvas = Global.canvas
|
|
canvas.handle_undo("Draw")
|
|
canvas.layers[Global.current_layer][0].unlock()
|
|
canvas.layers[Global.current_layer][0].flip_x()
|
|
canvas.layers[Global.current_layer][0].lock()
|
|
canvas.handle_redo("Draw")
|
|
3: # Flip Vertical
|
|
var canvas : Canvas = Global.canvas
|
|
canvas.handle_undo("Draw")
|
|
canvas.layers[Global.current_layer][0].unlock()
|
|
canvas.layers[Global.current_layer][0].flip_y()
|
|
canvas.layers[Global.current_layer][0].lock()
|
|
canvas.handle_redo("Draw")
|
|
4: # Rotate
|
|
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
|
$RotateImage.set_sprite(image)
|
|
$RotateImage.popup_centered()
|
|
Global.can_draw = false
|
|
5: # Invert Colors
|
|
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
|
Global.canvas.handle_undo("Draw")
|
|
for xx in image.get_size().x:
|
|
for yy in image.get_size().y:
|
|
var px_color = image.get_pixel(xx, yy).inverted()
|
|
if px_color.a == 0:
|
|
continue
|
|
image.set_pixel(xx, yy, px_color)
|
|
Global.canvas.handle_redo("Draw")
|
|
6: # Desaturation
|
|
var image : Image = Global.canvas.layers[Global.current_layer][0]
|
|
Global.canvas.handle_undo("Draw")
|
|
for xx in image.get_size().x:
|
|
for yy in image.get_size().y:
|
|
var px_color = image.get_pixel(xx, yy)
|
|
if px_color.a == 0:
|
|
continue
|
|
var gray = image.get_pixel(xx, yy).v
|
|
px_color = Color(gray, gray, gray, px_color.a)
|
|
image.set_pixel(xx, yy, px_color)
|
|
Global.canvas.handle_redo("Draw")
|
|
7: # Outline
|
|
$OutlineDialog.popup_centered()
|
|
Global.can_draw = false
|
|
|
|
func help_menu_id_pressed(id : int) -> void:
|
|
match id:
|
|
0: # Splash Screen
|
|
$SplashDialog.popup_centered()
|
|
Global.can_draw = false
|
|
1: # Issue Tracker
|
|
OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/issues")
|
|
2: # Changelog
|
|
OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/blob/master/Changelog.md#v062---17-02-2020")
|
|
3: # About Pixelorama
|
|
$AboutDialog.popup_centered()
|
|
Global.can_draw = false
|
|
|
|
|
|
func _on_UnsavedCanvasDialog_confirmed() -> void:
|
|
$CreateNewImage.popup_centered()
|
|
|
|
|
|
func _on_OpenSprite_file_selected(path : String) -> void:
|
|
OpenSave.open_pxo_file(path)
|
|
|
|
$SaveSprite.current_path = path
|
|
$ExportDialog.file_name = path.get_file().trim_suffix(".pxo")
|
|
$ExportDialog.directory_path = path.get_base_dir()
|
|
$ExportDialog.was_exported = false
|
|
file_menu.set_item_text(2, tr("Save") + " %s" % path.get_file())
|
|
file_menu.set_item_text(5, tr("Export"))
|
|
|
|
|
|
func _on_SaveSprite_file_selected(path : String) -> void:
|
|
OpenSave.save_pxo_file(path)
|
|
|
|
$ExportDialog.file_name = path.get_file().trim_suffix(".pxo")
|
|
$ExportDialog.directory_path = path.get_base_dir()
|
|
$ExportDialog.was_exported = false
|
|
file_menu.set_item_text(2, tr("Save") + " %s" % path.get_file())
|
|
|
|
if is_quitting_on_save:
|
|
_on_QuitDialog_confirmed()
|
|
|
|
|
|
func _on_ImportSprites_popup_hide() -> void:
|
|
if !opensprite_file_selected:
|
|
Global.can_draw = true
|
|
|
|
func _on_ViewportContainer_mouse_entered() -> void:
|
|
Global.has_focus = true
|
|
|
|
func _on_ViewportContainer_mouse_exited() -> void:
|
|
Global.has_focus = false
|
|
|
|
func _can_draw_true() -> void:
|
|
Global.can_draw = true
|
|
func _can_draw_false() -> void:
|
|
Global.can_draw = false
|
|
|
|
func _on_Tool_pressed(tool_pressed : BaseButton, mouse_press := true, key_for_left := true) -> void:
|
|
var current_action := tool_pressed.name
|
|
if (mouse_press and Input.is_action_just_released("left_mouse")) or (!mouse_press and key_for_left):
|
|
Global.current_left_tool = current_action
|
|
|
|
# Start from 1, so the label won't get invisible
|
|
for i in range(1, Global.left_tool_options_container.get_child_count()):
|
|
Global.left_tool_options_container.get_child(i).visible = false
|
|
|
|
Global.left_tool_options_container.get_node("EmptySpacer").visible = true
|
|
|
|
# Tool options visible depending on the selected tool
|
|
if current_action == "Pencil":
|
|
Global.left_brush_type_container.visible = true
|
|
Global.left_brush_size_slider.visible = true
|
|
Global.left_mirror_container.visible = true
|
|
if Global.current_left_brush_type == Global.Brush_Types.FILE or Global.current_left_brush_type == Global.Brush_Types.CUSTOM or Global.current_left_brush_type == Global.Brush_Types.RANDOM_FILE:
|
|
Global.left_color_interpolation_container.visible = true
|
|
elif current_action == "Eraser":
|
|
Global.left_brush_type_container.visible = true
|
|
Global.left_brush_size_slider.visible = true
|
|
Global.left_mirror_container.visible = true
|
|
elif current_action == "Bucket":
|
|
Global.left_brush_type_container.visible = true
|
|
Global.left_brush_size_slider.visible = true
|
|
Global.left_fill_area_container.visible = true
|
|
Global.left_mirror_container.visible = true
|
|
if Global.current_left_brush_type == Global.Brush_Types.FILE or Global.current_left_brush_type == Global.Brush_Types.CUSTOM or Global.current_left_brush_type == Global.Brush_Types.RANDOM_FILE:
|
|
Global.left_color_interpolation_container.visible = true
|
|
elif current_action == "LightenDarken":
|
|
Global.left_brush_type_container.visible = true
|
|
Global.left_brush_size_slider.visible = true
|
|
Global.left_ld_container.visible = true
|
|
Global.left_mirror_container.visible = true
|
|
elif current_action == "ColorPicker":
|
|
Global.left_colorpicker_container.visible = true
|
|
elif current_action == "Zoom":
|
|
Global.left_zoom_container.visible = true
|
|
|
|
elif (mouse_press and Input.is_action_just_released("right_mouse")) or (!mouse_press and !key_for_left):
|
|
Global.current_right_tool = current_action
|
|
# Start from 1, so the label won't get invisible
|
|
for i in range(1, Global.right_tool_options_container.get_child_count()):
|
|
Global.right_tool_options_container.get_child(i).visible = false
|
|
|
|
Global.right_tool_options_container.get_node("EmptySpacer").visible = true
|
|
|
|
# Tool options visible depending on the selected tool
|
|
if current_action == "Pencil":
|
|
Global.right_brush_type_container.visible = true
|
|
Global.right_brush_size_slider.visible = true
|
|
Global.right_mirror_container.visible = true
|
|
if Global.current_right_brush_type == Global.Brush_Types.FILE or Global.current_right_brush_type == Global.Brush_Types.CUSTOM or Global.current_right_brush_type == Global.Brush_Types.RANDOM_FILE:
|
|
Global.right_color_interpolation_container.visible = true
|
|
elif current_action == "Eraser":
|
|
Global.right_brush_type_container.visible = true
|
|
Global.right_brush_size_slider.visible = true
|
|
Global.right_mirror_container.visible = true
|
|
elif current_action == "Bucket":
|
|
Global.right_brush_type_container.visible = true
|
|
Global.right_brush_size_slider.visible = true
|
|
Global.right_fill_area_container.visible = true
|
|
Global.right_mirror_container.visible = true
|
|
if Global.current_right_brush_type == Global.Brush_Types.FILE or Global.current_right_brush_type == Global.Brush_Types.CUSTOM or Global.current_right_brush_type == Global.Brush_Types.RANDOM_FILE:
|
|
Global.right_color_interpolation_container.visible = true
|
|
elif current_action == "LightenDarken":
|
|
Global.right_brush_type_container.visible = true
|
|
Global.right_brush_size_slider.visible = true
|
|
Global.right_ld_container.visible = true
|
|
Global.right_mirror_container.visible = true
|
|
elif current_action == "ColorPicker":
|
|
Global.right_colorpicker_container.visible = true
|
|
elif current_action == "Zoom":
|
|
Global.right_zoom_container.visible = true
|
|
|
|
for t in tools:
|
|
var tool_name : String = t[0].name
|
|
if tool_name == Global.current_left_tool and tool_name == Global.current_right_tool:
|
|
t[0].texture_normal = load("res://Assets/Graphics/%s Themes/Tools/%s_l_r.png" % [Global.theme_type, tool_name])
|
|
elif tool_name == Global.current_left_tool:
|
|
t[0].texture_normal = load("res://Assets/Graphics/%s Themes/Tools/%s_l.png" % [Global.theme_type, tool_name])
|
|
elif tool_name == Global.current_right_tool:
|
|
t[0].texture_normal = load("res://Assets/Graphics/%s Themes/Tools/%s_r.png" % [Global.theme_type, tool_name])
|
|
else:
|
|
t[0].texture_normal = load("res://Assets/Graphics/%s Themes/Tools/%s.png" % [Global.theme_type, tool_name])
|
|
|
|
Global.left_cursor_tool_texture.create_from_image(load("res://Assets/Graphics/Tool Cursors/%s_Cursor.png" % Global.current_left_tool), 0)
|
|
Global.right_cursor_tool_texture.create_from_image(load("res://Assets/Graphics/Tool Cursors/%s_Cursor.png" % Global.current_right_tool), 0)
|
|
|
|
|
|
func _on_LeftBrushTypeButton_pressed() -> void:
|
|
Global.brushes_popup.popup(Rect2(Global.left_brush_type_button.rect_global_position, Vector2(226, 72)))
|
|
Global.brush_type_window_position = "left"
|
|
|
|
func _on_RightBrushTypeButton_pressed() -> void:
|
|
Global.brushes_popup.popup(Rect2(Global.right_brush_type_button.rect_global_position, Vector2(226, 72)))
|
|
Global.brush_type_window_position = "right"
|
|
|
|
func _on_LeftBrushSizeEdit_value_changed(value) -> void:
|
|
Global.left_brush_size_edit.value = value
|
|
Global.left_brush_size_slider.value = value
|
|
var new_size = int(value)
|
|
Global.left_brush_size = new_size
|
|
update_left_custom_brush()
|
|
|
|
func _on_RightBrushSizeEdit_value_changed(value) -> void:
|
|
Global.right_brush_size_edit.value = value
|
|
Global.right_brush_size_slider.value = value
|
|
var new_size = int(value)
|
|
Global.right_brush_size = new_size
|
|
update_right_custom_brush()
|
|
|
|
|
|
func _on_ColorSwitch_pressed() -> void:
|
|
var temp: Color = Global.left_color_picker.color
|
|
Global.left_color_picker.color = Global.right_color_picker.color
|
|
Global.right_color_picker.color = temp
|
|
update_left_custom_brush()
|
|
update_right_custom_brush()
|
|
|
|
|
|
func _on_ColorDefaults_pressed() -> void:
|
|
Global.left_color_picker.color = Color.black
|
|
Global.right_color_picker.color = Color.white
|
|
update_left_custom_brush()
|
|
update_right_custom_brush()
|
|
|
|
|
|
func _on_LeftColorPickerButton_color_changed(color : Color) -> void:
|
|
# If the color changed while it's on full transparency, make it opaque (GH issue #54)
|
|
if color.a == 0:
|
|
if previous_left_color.r != color.r or previous_left_color.g != color.g or previous_left_color.b != color.b:
|
|
Global.left_color_picker.color.a = 1
|
|
update_left_custom_brush()
|
|
previous_left_color = color
|
|
|
|
|
|
func _on_RightColorPickerButton_color_changed(color : Color) -> void:
|
|
# If the color changed while it's on full transparency, make it opaque (GH issue #54)
|
|
if color.a == 0:
|
|
if previous_right_color.r != color.r or previous_right_color.g != color.g or previous_right_color.b != color.b:
|
|
Global.right_color_picker.color.a = 1
|
|
update_right_custom_brush()
|
|
previous_right_color = color
|
|
|
|
|
|
func _on_LeftInterpolateFactor_value_changed(value : float) -> void:
|
|
Global.left_interpolate_spinbox.value = value
|
|
Global.left_interpolate_slider.value = value
|
|
update_left_custom_brush()
|
|
|
|
|
|
func _on_RightInterpolateFactor_value_changed(value : float) -> void:
|
|
Global.right_interpolate_spinbox.value = value
|
|
Global.right_interpolate_slider.value = value
|
|
update_right_custom_brush()
|
|
|
|
|
|
func update_left_custom_brush() -> void:
|
|
Global.update_left_custom_brush()
|
|
|
|
|
|
func update_right_custom_brush() -> void:
|
|
Global.update_right_custom_brush()
|
|
|
|
|
|
func _on_LeftFillAreaOptions_item_selected(ID : int) -> void:
|
|
Global.left_fill_area = ID
|
|
|
|
|
|
func _on_RightFillAreaOptions_item_selected(ID : int) -> void:
|
|
Global.right_fill_area = ID
|
|
|
|
|
|
func _on_LeftLightenDarken_item_selected(ID : int) -> void:
|
|
Global.left_ld = ID
|
|
|
|
|
|
func _on_LeftLDAmountSpinbox_value_changed(value : float) -> void:
|
|
Global.left_ld_amount = value / 100
|
|
Global.left_ld_amount_slider.value = value
|
|
Global.left_ld_amount_spinbox.value = value
|
|
|
|
|
|
func _on_RightLightenDarken_item_selected(ID : int) -> void:
|
|
Global.right_ld = ID
|
|
|
|
|
|
func _on_RightLDAmountSpinbox_value_changed(value : float) -> void:
|
|
Global.right_ld_amount = value / 100
|
|
Global.right_ld_amount_slider.value = value
|
|
Global.right_ld_amount_spinbox.value = value
|
|
|
|
|
|
func _on_LeftForColorOptions_item_selected(ID : int) -> void:
|
|
Global.left_color_picker_for = ID
|
|
|
|
|
|
func _on_RightForColorOptions_item_selected(ID : int) -> void:
|
|
Global.right_color_picker_for = ID
|
|
|
|
|
|
func _on_LeftZoomModeOptions_item_selected(ID : int) -> void:
|
|
Global.left_zoom_mode = ID
|
|
|
|
|
|
func _on_RightZoomModeOptions_item_selected(ID : int) -> void:
|
|
Global.right_zoom_mode = ID
|
|
|
|
|
|
func _on_FitToFrameButton_pressed() -> void:
|
|
var bigger = max(Global.canvas.size.x, Global.canvas.size.y)
|
|
Global.camera.zoom = (Vector2(bigger, bigger) * 0.004) / (Global.main_viewport.rect_size.x * 0.002)
|
|
Global.camera.offset = Global.canvas.size / 2
|
|
Global.zoom_level_label.text = str(round(100 / Global.camera.zoom.x)) + " %"
|
|
|
|
|
|
func _on_100ZoomButton_pressed() -> void:
|
|
Global.camera.zoom = Vector2.ONE
|
|
Global.camera.offset = Global.canvas.size / 2
|
|
Global.zoom_level_label.text = str(round(100 / Global.camera.zoom.x)) + " %"
|
|
|
|
|
|
func _on_LeftHorizontalMirroring_toggled(button_pressed) -> void:
|
|
Global.left_horizontal_mirror = button_pressed
|
|
|
|
|
|
func _on_LeftVerticalMirroring_toggled(button_pressed) -> void:
|
|
Global.left_vertical_mirror = button_pressed
|
|
|
|
|
|
func _on_RightHorizontalMirroring_toggled(button_pressed) -> void:
|
|
Global.right_horizontal_mirror = button_pressed
|
|
|
|
|
|
func _on_RightVerticalMirroring_toggled(button_pressed) -> void:
|
|
Global.right_vertical_mirror = button_pressed
|
|
|
|
|
|
func show_quit_dialog() -> void:
|
|
if !$QuitDialog.visible:
|
|
if Global.saved:
|
|
$QuitDialog.call_deferred("popup_centered")
|
|
else:
|
|
$QuitAndSaveDialog.call_deferred("popup_centered")
|
|
|
|
Global.can_draw = false
|
|
|
|
|
|
func _on_QuitAndSaveDialog_custom_action(action : String) -> void:
|
|
if action == "Save":
|
|
is_quitting_on_save = true
|
|
$SaveSprite.popup_centered()
|
|
$QuitDialog.hide()
|
|
Global.can_draw = false
|
|
|
|
|
|
func _on_QuitDialog_confirmed() -> void:
|
|
# Darken the UI to denote that the application is currently exiting
|
|
# (it won't respond to user input in this state).
|
|
modulate = Color(0.5, 0.5, 0.5)
|
|
|
|
get_tree().quit()
|