extends Panel enum FileMenuId {NEW, OPEN, OPEN_LAST_PROJECT, SAVE, SAVE_AS, EXPORT, EXPORT_AS, QUIT} enum EditMenuId {UNDO, REDO, COPY, CUT, PASTE, DELETE, CLEAR_SELECTION, PREFERENCES} enum ViewMenuId {TILE_MODE, WINDOW_TRANSPARENCY, MIRROR_VIEW, SHOW_GRID, SHOW_PIXEL_GRID, SHOW_RULERS, SHOW_GUIDES, SHOW_ANIMATION_TIMELINE, ZEN_MODE, FULLSCREEN_MODE} enum ImageMenuId {SCALE_IMAGE,CENTRALIZE_IMAGE, CROP_IMAGE, RESIZE_CANVAS, FLIP, ROTATE, INVERT_COLORS, DESATURATION, OUTLINE, HSV, GRADIENT, SHADER} enum HelpMenuId {VIEW_SPLASH_SCREEN, ONLINE_DOCS, ISSUE_TRACKER, CHANGELOG, ABOUT_PIXELORAMA} var file_menu : PopupMenu var view_menu : PopupMenu var zen_mode := false func _ready() -> void: setup_file_menu() setup_edit_menu() setup_view_menu() setup_image_menu() setup_help_menu() func setup_file_menu() -> void: var file_menu_items := { # order as in FileMenuId enum "New..." : InputMap.get_action_list("new_file")[0].get_scancode_with_modifiers(), "Open..." : InputMap.get_action_list("open_file")[0].get_scancode_with_modifiers(), 'Open last project...' : 0, "Recent projects": 0, "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(), "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(), } file_menu = Global.file_menu.get_popup() var i := 0 for item in file_menu_items.keys(): if item == "Recent projects": setup_recent_projects_submenu(item) else: file_menu.add_item(item, i, file_menu_items[item]) i += 1 file_menu.connect("id_pressed", self, "file_menu_id_pressed") if OS.get_name() == "HTML5": file_menu.set_item_disabled(FileMenuId.OPEN_LAST_PROJECT, true) file_menu.set_item_disabled(FileMenuId.SAVE, true) func setup_recent_projects_submenu(item : String) -> void: Global.recent_projects_submenu.connect("id_pressed", self, "on_recent_projects_submenu_id_pressed") Global.update_recent_projects_submenu() file_menu.add_child(Global.recent_projects_submenu) file_menu.add_submenu_item(item, Global.recent_projects_submenu.get_name()) func setup_edit_menu() -> void: var edit_menu_items := { # order as in EditMenuId enum "Undo" : InputMap.get_action_list("undo")[0].get_scancode_with_modifiers(), "Redo" : InputMap.get_action_list("redo")[0].get_scancode_with_modifiers(), "Copy" : InputMap.get_action_list("copy")[0].get_scancode_with_modifiers(), "Cut" : InputMap.get_action_list("cut")[0].get_scancode_with_modifiers(), "Paste" : InputMap.get_action_list("paste")[0].get_scancode_with_modifiers(), "Delete" : InputMap.get_action_list("delete")[0].get_scancode_with_modifiers(), "Clear Selection" : InputMap.get_action_list("clear_selection")[0].get_scancode_with_modifiers(), "Preferences" : 0 } var edit_menu : PopupMenu = Global.edit_menu.get_popup() var i := 0 for item in edit_menu_items.keys(): edit_menu.add_item(item, i, edit_menu_items[item]) i += 1 edit_menu.connect("id_pressed", self, "edit_menu_id_pressed") func setup_view_menu() -> void: var view_menu_items := { # order as in ViewMenuId enum "Tile Mode" : 0, "Window Transparency" : 0, "Mirror View" : InputMap.get_action_list("mirror_view")[0].get_scancode_with_modifiers(), "Show Grid" : InputMap.get_action_list("show_grid")[0].get_scancode_with_modifiers(), "Show Pixel Grid" : InputMap.get_action_list("show_pixel_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, "Zen Mode" : InputMap.get_action_list("zen_mode")[0].get_scancode_with_modifiers(), "Fullscreen Mode" : InputMap.get_action_list("toggle_fullscreen")[0].get_scancode_with_modifiers(), } view_menu = Global.view_menu.get_popup() var i := 0 for item in view_menu_items.keys(): if item == "Tile Mode": setup_tile_mode_submenu(item) elif item == "Window Transparency": setup_window_transparency_submenu(item) else: view_menu.add_check_item(item, i, view_menu_items[item]) i += 1 view_menu.set_item_checked(ViewMenuId.SHOW_RULERS, true) view_menu.set_item_checked(ViewMenuId.SHOW_GUIDES, true) view_menu.set_item_checked(ViewMenuId.SHOW_ANIMATION_TIMELINE, true) view_menu.hide_on_checkable_item_selection = false view_menu.connect("id_pressed", self, "view_menu_id_pressed") if OS.get_name() == "HTML5": view_menu.set_item_disabled(ViewMenuId.WINDOW_TRANSPARENCY, true) func setup_tile_mode_submenu(item : String): Global.tile_mode_submenu.connect("id_pressed", self, "tile_mode_submenu_id_pressed") view_menu.add_child(Global.tile_mode_submenu) view_menu.add_submenu_item(item, Global.tile_mode_submenu.get_name()) func setup_window_transparency_submenu(item : String): Global.window_transparency_submenu.connect("id_pressed", self, "window_transparency_submenu_id_pressed") view_menu.add_child(Global.window_transparency_submenu) view_menu.add_submenu_item(item, Global.window_transparency_submenu.get_name()) func setup_image_menu() -> void: var image_menu_items := { # order as in ImageMenuId enum "Scale Image" : 0, "Centralize Image" : 0, "Crop Image" : 0, "Resize Canvas" : 0, "Flip" : 0, "Rotate Image" : 0, "Invert Colors" : 0, "Desaturation" : 0, "Outline" : 0, "Adjust Hue/Saturation/Value" : 0, "Gradient" : 0, # "Shader" : 0 } var image_menu : PopupMenu = Global.image_menu.get_popup() var i := 0 for item in image_menu_items.keys(): image_menu.add_item(item, i, image_menu_items[item]) if i == ImageMenuId.RESIZE_CANVAS: image_menu.add_separator() i += 1 image_menu.connect("id_pressed", self, "image_menu_id_pressed") func setup_help_menu() -> void: var help_menu_items := { # order as in HelpMenuId enum "View Splash Screen" : 0, "Online Docs" : InputMap.get_action_list("open_docs")[0].get_scancode_with_modifiers(), "Issue Tracker" : 0, "Changelog" : 0, "About Pixelorama" : 0 } var help_menu : PopupMenu = Global.help_menu.get_popup() var i := 0 for item in help_menu_items.keys(): help_menu.add_item(item, i, help_menu_items[item]) i += 1 help_menu.connect("id_pressed", self, "help_menu_id_pressed") func file_menu_id_pressed(id : int) -> void: match id: FileMenuId.NEW: on_new_project_file_menu_option_pressed() FileMenuId.OPEN: open_project_file() FileMenuId.OPEN_LAST_PROJECT: on_open_last_project_file_menu_option_pressed() FileMenuId.SAVE: save_project_file() FileMenuId.SAVE_AS: save_project_file_as() FileMenuId.EXPORT: export_file() FileMenuId.EXPORT_AS: Global.export_dialog.popup_centered() Global.dialog_open(true) FileMenuId.QUIT: Global.control.show_quit_dialog() func on_new_project_file_menu_option_pressed() -> void: Global.new_image_dialog.popup_centered() Global.dialog_open(true) func open_project_file() -> void: if OS.get_name() == "HTML5": Html5FileExchange.load_image() else: Global.open_sprites_dialog.popup_centered() Global.dialog_open(true) Global.control.opensprite_file_selected = false func on_open_last_project_file_menu_option_pressed() -> void: # Check if last project path is set and if yes then open if Global.config_cache.has_section_key("preferences", "last_project_path"): Global.control.load_last_project() else: # if not then warn user that he didn't edit any project yet Global.error_dialog.set_text("You haven't saved or opened any project in Pixelorama yet!") Global.error_dialog.popup_centered() Global.dialog_open(true) func save_project_file() -> void: Global.control.is_quitting_on_save = false var path = OpenSave.current_save_paths[Global.current_project_index] if path == "": if OS.get_name() == "HTML5": Global.save_sprites_html5_dialog.popup_centered() else: Global.save_sprites_dialog.popup_centered() Global.dialog_open(true) else: Global.control._on_SaveSprite_file_selected(path) func save_project_file_as() -> void: Global.control.is_quitting_on_save = false if OS.get_name() == "HTML5": Global.save_sprites_html5_dialog.popup_centered() else: Global.save_sprites_dialog.popup_centered() Global.dialog_open(true) func export_file() -> void: if Export.was_exported == false: Global.export_dialog.popup_centered() Global.dialog_open(true) else: Export.external_export() func on_recent_projects_submenu_id_pressed(id : int) -> void: Global.control.load_recent_project_file(Global.recent_projects[id]) func edit_menu_id_pressed(id : int) -> void: match id: EditMenuId.UNDO: Global.current_project.undo_redo.undo() EditMenuId.REDO: Global.control.redone = true Global.current_project.undo_redo.redo() Global.control.redone = false EditMenuId.COPY: Global.selection_rectangle.copy() EditMenuId.CUT: Global.selection_rectangle.cut() EditMenuId.PASTE: Global.selection_rectangle.paste() EditMenuId.DELETE: Global.selection_rectangle.delete() EditMenuId.CLEAR_SELECTION: Global.selection_rectangle.set_rect(Rect2(0, 0, 0, 0)) Global.selection_rectangle.select_rect() EditMenuId.PREFERENCES: Global.preferences_dialog.popup_centered(Vector2(400, 280)) Global.dialog_open(true) func view_menu_id_pressed(id : int) -> void: match id: ViewMenuId.MIRROR_VIEW: toggle_mirror_view() ViewMenuId.SHOW_GRID: toggle_show_grid() ViewMenuId.SHOW_PIXEL_GRID: toggle_show_pixel_grid() ViewMenuId.SHOW_RULERS: toggle_show_rulers() ViewMenuId.SHOW_GUIDES: toggle_show_guides() ViewMenuId.SHOW_ANIMATION_TIMELINE: toggle_show_anim_timeline() ViewMenuId.ZEN_MODE: toggle_zen_mode() ViewMenuId.FULLSCREEN_MODE: toggle_fullscreen() Global.canvas.update() func tile_mode_submenu_id_pressed(id : int) -> void: Global.current_project.tile_mode = id Global.transparent_checker.fit_rect(Global.current_project.get_tile_mode_rect()) for i in Global.TileMode.values(): Global.tile_mode_submenu.set_item_checked(i, i == id) Global.canvas.tile_mode.update() Global.canvas.pixel_grid.update() Global.canvas.grid.update() func window_transparency_submenu_id_pressed(id : float) -> void: if OS.window_fullscreen: for i in 11: Global.window_transparency_submenu.set_item_checked(i, i == 10) window_transparency(1) else: for i in 11: Global.window_transparency_submenu.set_item_checked(i, i == id) window_transparency(id/10) func window_transparency(value :float) -> void: if value == 1: get_node("../../AlternateTransparentBackground").visible = false else: get_node("../../AlternateTransparentBackground").visible = true var checker :ColorRect = get_parent().get_node("UI/CanvasAndTimeline/ViewportAndRulers/HSplitContainer/ViewportandVerticalRuler/ViewportContainer/Viewport/TransparentChecker") var color :Color = Global.control.theme.get_stylebox("panel", "PanelContainer").bg_color color.a = value get_node("../../AlternateTransparentBackground").color = color checker.transparency(value) func toggle_mirror_view() -> void: Global.mirror_view = !Global.mirror_view view_menu.set_item_checked(ViewMenuId.MIRROR_VIEW, Global.mirror_view) func toggle_show_grid() -> void: Global.draw_grid = !Global.draw_grid view_menu.set_item_checked(ViewMenuId.SHOW_GRID, Global.draw_grid) Global.canvas.grid.update() func toggle_show_pixel_grid() -> void: Global.draw_pixel_grid = !Global.draw_pixel_grid view_menu.set_item_checked(ViewMenuId.SHOW_PIXEL_GRID, Global.draw_pixel_grid) Global.canvas.pixel_grid.update() func toggle_show_rulers() -> void: Global.show_rulers = !Global.show_rulers view_menu.set_item_checked(ViewMenuId.SHOW_RULERS, Global.show_rulers) Global.horizontal_ruler.visible = Global.show_rulers Global.vertical_ruler.visible = Global.show_rulers func toggle_show_guides() -> void: Global.show_guides = !Global.show_guides view_menu.set_item_checked(ViewMenuId.SHOW_GUIDES, Global.show_guides) for guide in Global.canvas.get_children(): if guide is Guide and guide in Global.current_project.guides: guide.visible = Global.show_guides if guide is SymmetryGuide: if guide.type == Guide.Types.HORIZONTAL: guide.visible = Global.show_x_symmetry_axis and Global.show_guides else: guide.visible = Global.show_y_symmetry_axis and Global.show_guides func toggle_show_anim_timeline() -> void: if zen_mode: return Global.show_animation_timeline = !Global.show_animation_timeline view_menu.set_item_checked(ViewMenuId.SHOW_ANIMATION_TIMELINE, Global.show_animation_timeline) Global.animation_timeline.visible = Global.show_animation_timeline func toggle_zen_mode() -> void: if Global.show_animation_timeline: Global.animation_timeline.visible = zen_mode Global.control.get_node("MenuAndUI/UI/ToolPanel").visible = zen_mode Global.control.get_node("MenuAndUI/UI/RightPanel").visible = zen_mode Global.control.get_node("MenuAndUI/UI/CanvasAndTimeline/ViewportAndRulers/TabsContainer").visible = zen_mode zen_mode = !zen_mode view_menu.set_item_checked(ViewMenuId.ZEN_MODE, zen_mode) func toggle_fullscreen() -> void: OS.window_fullscreen = !OS.window_fullscreen view_menu.set_item_checked(ViewMenuId.FULLSCREEN_MODE, OS.window_fullscreen) # if window is fullscreen then reset transparency if OS.window_fullscreen: window_transparency_submenu_id_pressed(10) func image_menu_id_pressed(id : int) -> void: if Global.current_project.layers[Global.current_project.current_layer].locked: # No changes if the layer is locked return var image : Image = Global.current_project.frames[Global.current_project.current_frame].cels[Global.current_project.current_layer].image match id: ImageMenuId.SCALE_IMAGE: show_scale_image_popup() ImageMenuId.CENTRALIZE_IMAGE: DrawingAlgos.centralize() ImageMenuId.CROP_IMAGE: DrawingAlgos.crop_image(image) ImageMenuId.RESIZE_CANVAS: show_resize_canvas_popup() ImageMenuId.FLIP: Global.control.get_node("Dialogs/ImageEffects/FlipImageDialog").popup_centered() Global.dialog_open(true) ImageMenuId.ROTATE: show_rotate_image_popup() ImageMenuId.INVERT_COLORS: Global.control.get_node("Dialogs/ImageEffects/InvertColorsDialog").popup_centered() Global.dialog_open(true) ImageMenuId.DESATURATION: Global.control.get_node("Dialogs/ImageEffects/DesaturateDialog").popup_centered() Global.dialog_open(true) ImageMenuId.OUTLINE: show_add_outline_popup() ImageMenuId.HSV: show_hsv_configuration_popup() ImageMenuId.GRADIENT: Global.control.get_node("Dialogs/ImageEffects/GradientDialog").popup_centered() Global.dialog_open(true) ImageMenuId.SHADER: Global.control.get_node("Dialogs/ImageEffects/ShaderEffect").popup_centered() Global.dialog_open(true) func show_scale_image_popup() -> void: Global.control.get_node("Dialogs/ImageEffects/ScaleImage").popup_centered() Global.dialog_open(true) func show_resize_canvas_popup() -> void: Global.control.get_node("Dialogs/ImageEffects/ResizeCanvas").popup_centered() Global.dialog_open(true) func show_rotate_image_popup() -> void: Global.control.get_node("Dialogs/ImageEffects/RotateImage").popup_centered() Global.dialog_open(true) func show_add_outline_popup() -> void: Global.control.get_node("Dialogs/ImageEffects/OutlineDialog").popup_centered() Global.dialog_open(true) func show_hsv_configuration_popup() -> void: Global.control.get_node("Dialogs/ImageEffects/HSVDialog").popup_centered() Global.dialog_open(true) func help_menu_id_pressed(id : int) -> void: match id: HelpMenuId.VIEW_SPLASH_SCREEN: Global.control.get_node("Dialogs/SplashDialog").popup_centered() Global.dialog_open(true) HelpMenuId.ONLINE_DOCS: OS.shell_open("https://orama-interactive.github.io/Pixelorama-Docs/") HelpMenuId.ISSUE_TRACKER: OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/issues") HelpMenuId.CHANGELOG: if OS.get_name() == "OSX": # Issue #275 - remove when macOS builds use Godot 3.2.3 OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/blob/master/CHANGELOG.md") else: OS.shell_open("https://github.com/Orama-Interactive/Pixelorama/blob/master/CHANGELOG.md#v082---2020-12-12") HelpMenuId.ABOUT_PIXELORAMA: Global.control.get_node("Dialogs/AboutDialog").popup_centered() Global.dialog_open(true)