From de164ea9de501d3afb8c201ddd95886da3e0bdfc Mon Sep 17 00:00:00 2001 From: ballerburg9005 <50874674+ballerburg9005@users.noreply.github.com> Date: Sat, 6 Mar 2021 14:59:26 +0100 Subject: [PATCH] full support for auto tallscreen/widescreen panel layout (#458) * full support for auto tallscreen/widescreen panel layout * Update Main.tscn * Update CanvasPreviewContainer.tscn * Update UI.tscn * tallscreen support - better display scale * tallscreen support - better display scale * Update UI.tscn * Update Main.gd * tallscreen support - better display scale * tallscreen support - better display scale * tallscreen support - alternate panel placement comment-784228607 * tallscreen support - code cleanup * tallscreen support - color picker swap: comment-785032683 * prettier border * tallscreen support - color picker * tallscreen support - pullrequestreview-601156079 * tallscreen support - bugfix & review Co-authored-by: ballerburg9005 --- src/Autoload/Global.gd | 22 +++++++ src/Classes/Project.gd | 1 - src/Main.gd | 95 ++++++++++++++++++++++++++++++ src/UI/CanvasPreviewContainer.tscn | 1 + src/UI/TopMenuContainer.gd | 25 ++++++-- src/UI/UI.tscn | 17 +++++- 6 files changed, 154 insertions(+), 7 deletions(-) diff --git a/src/Autoload/Global.gd b/src/Autoload/Global.gd index cf808fe97..e0b74c4d7 100644 --- a/src/Autoload/Global.gd +++ b/src/Autoload/Global.gd @@ -6,6 +6,7 @@ enum PressureSensitivity {NONE, ALPHA, SIZE, ALPHA_AND_SIZE} enum Direction {UP, DOWN, LEFT, RIGHT} enum ThemeTypes {DARK, BLUE, CARAMEL, LIGHT} enum TileMode {NONE, BOTH, X_AXIS, Y_AXIS} +enum PanelLayout {AUTO, WIDESCREEN, TALLSCREEN} # Stuff for arrowkey-based canvas movements nyaa ^.^ const low_speed_move_rate := 150.0 const medium_speed_move_rate := 750.0 @@ -22,6 +23,7 @@ var current_project : Project var current_project_index := 0 setget project_changed var recent_projects := [] +var panel_layout = PanelLayout.AUTO # Indices are as in the Direction enum # This is the total time the key for @@ -124,9 +126,14 @@ var help_menu : MenuButton var cursor_position_label : Label var zoom_level_label : Label +var tool_panel : Panel +var right_panel : Panel +var tabs_container : PanelContainer + var recent_projects_submenu : PopupMenu var tile_mode_submenu : PopupMenu var window_transparency_submenu : PopupMenu +var panel_layout_submenu : PopupMenu var new_image_dialog : ConfirmationDialog var open_sprites_dialog : FileDialog @@ -194,6 +201,7 @@ func _ready() -> void: config_cache.load("user://cache.ini") recent_projects = config_cache.get_value("data", "recent_projects", []) + panel_layout = config_cache.get_value("window", "panel_layout", PanelLayout.AUTO) # The fact that root_dir is set earlier than this is important # XDGDataDirs depends on it nyaa @@ -203,6 +211,7 @@ func _ready() -> void: var root = get_tree().get_root() control = find_node_by_name(root, "Control") + top_menu_container = find_node_by_name(control, "TopMenuContainer") left_cursor = find_node_by_name(root, "LeftCursor") right_cursor = find_node_by_name(root, "RightCursor") @@ -228,6 +237,10 @@ func _ready() -> void: cursor_position_label = find_node_by_name(root, "CursorPosition") zoom_level_label = find_node_by_name(root, "ZoomLevel") + tool_panel = control.get_node("MenuAndUI/UI/ToolPanel") + right_panel = control.get_node("MenuAndUI/UI/RightPanel") + tabs_container = control.get_node("MenuAndUI/UI/CanvasAndTimeline/ViewportAndRulers/TabsContainer") + recent_projects_submenu = PopupMenu.new() recent_projects_submenu.set_name("recent_projects_submenu") @@ -256,6 +269,14 @@ func _ready() -> void: window_transparency_submenu.set_item_checked(10, true) window_transparency_submenu.hide_on_checkable_item_selection = false + panel_layout_submenu = PopupMenu.new() + panel_layout_submenu.set_name("panel_layout_submenu") + panel_layout_submenu.add_radio_check_item("Auto", PanelLayout.AUTO) + panel_layout_submenu.add_radio_check_item("Widescreen", PanelLayout.WIDESCREEN) + panel_layout_submenu.add_radio_check_item("Tallscreen", PanelLayout.TALLSCREEN) + panel_layout_submenu.hide_on_checkable_item_selection = false + panel_layout_submenu.set_item_checked(panel_layout, true) + new_image_dialog = find_node_by_name(root, "CreateNewImage") open_sprites_dialog = find_node_by_name(root, "OpenSprite") save_sprites_dialog = find_node_by_name(root, "SaveSprite") @@ -557,6 +578,7 @@ func is_cjk(locale : String) -> bool: func _exit_tree() -> void: + config_cache.set_value("window", "panel_layout", panel_layout) config_cache.set_value("window", "screen", OS.current_screen) config_cache.set_value("window", "maximized", OS.window_maximized || OS.window_fullscreen) config_cache.set_value("window", "position", OS.window_position) diff --git a/src/Classes/Project.gd b/src/Classes/Project.gd index 4d7a57e78..f62219cb0 100644 --- a/src/Classes/Project.gd +++ b/src/Classes/Project.gd @@ -210,7 +210,6 @@ func change_project() -> void: Global.tile_mode_submenu.set_item_checked(j, j == tile_mode) - func serialize() -> Dictionary: var layer_data := [] for layer in layers: diff --git a/src/Main.gd b/src/Main.gd index 646c59b7e..64c96f0a4 100644 --- a/src/Main.gd +++ b/src/Main.gd @@ -4,6 +4,15 @@ var opensprite_file_selected := false var redone := false var is_quitting_on_save := false +var tallscreen_is_active = false +onready var ui := $MenuAndUI/UI +onready var bottom_panel := $MenuAndUI/UI/CanvasAndTimeline/HBoxContainer/BottomPanel +onready var right_panel := $MenuAndUI/UI/RightPanel +onready var tool_and_palette_vsplit := $MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit +onready var color_and_tool_options := $MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions +onready var canvas_preview_container := $MenuAndUI/UI/RightPanel/PreviewAndPalettes/CanvasPreviewContainer +onready var tool_panel := $MenuAndUI/UI/ToolPanel +onready var scroll_container := $MenuAndUI/UI/RightPanel/PreviewAndPalettes/ToolAndPaletteVSplit/ColorAndToolOptions/ScrollContainer # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -19,6 +28,9 @@ func _ready() -> void: get_tree().set_auto_accept_quit(false) setup_application_window_size() + handle_resize() + get_tree().get_root().connect("size_changed", self, "handle_resize") + Global.window_title = tr("untitled") + " - Pixelorama " + Global.current_version @@ -55,6 +67,89 @@ func _ready() -> void: get_tree().connect("files_dropped", self, "_on_files_dropped") +func handle_resize() -> void: + var aspect_ratio = get_viewport_rect().size.x/(0.00001 if get_viewport_rect().size.y == 0 else get_viewport_rect().size.y) + if ( (aspect_ratio <= 3.0/4.0 and Global.panel_layout != Global.PanelLayout.WIDESCREEN) + or Global.panel_layout == Global.PanelLayout.TALLSCREEN): + change_ui_layout("tallscreen") + else: + change_ui_layout("widescreen") + + +func change_ui_layout(mode : String) -> void: + var colorpicker_is_switched = true if tool_and_palette_vsplit.has_node("ScrollContainer") else false + + if mode == "tallscreen" and not tallscreen_is_active: + tallscreen_is_active = true + reparent_node_to(right_panel, bottom_panel, 0) + right_panel.rect_min_size.y = 300 + reparent_node_to(canvas_preview_container, tool_and_palette_vsplit, 1) + tool_and_palette_vsplit = replace_node_with(tool_and_palette_vsplit, HBoxContainer.new()) + color_and_tool_options.rect_min_size.x = 280 + reparent_node_to(tool_panel, ui.get_node("CanvasAndTimeline/HBoxContainer"), 0) + elif mode == "widescreen" and tallscreen_is_active: + tallscreen_is_active = false + reparent_node_to(right_panel, ui, -1) + right_panel.rect_min_size.y = 0 + reparent_node_to(canvas_preview_container, right_panel.get_node("PreviewAndPalettes"), 0) + tool_and_palette_vsplit = replace_node_with(tool_and_palette_vsplit, VSplitContainer.new()) + color_and_tool_options.rect_min_size.x = 0 + canvas_preview_container.visible = true + reparent_node_to(tool_panel, ui, 0) + + if get_viewport_rect().size.x < 908 and mode == "tallscreen": + canvas_preview_container.visible = false + else: + canvas_preview_container.visible = true + + if not colorpicker_is_switched and canvas_preview_container.visible and mode == "tallscreen": + reparent_node_to(scroll_container, tool_and_palette_vsplit, 0) + scroll_container.rect_min_size = Vector2(268, 196) + color_and_tool_options.set("custom_constants/separation", 20) + reparent_node_to(canvas_preview_container, color_and_tool_options, -1) + elif colorpicker_is_switched and (not canvas_preview_container.visible or mode != "tallscreen"): + reparent_node_to(scroll_container, color_and_tool_options, -1) + scroll_container.rect_min_size = Vector2(0, 0) + color_and_tool_options.set("custom_constants/separation", 8) + if mode == "widescreen": + reparent_node_to(canvas_preview_container, right_panel.get_node("PreviewAndPalettes"), 0) + else: + reparent_node_to(canvas_preview_container, tool_and_palette_vsplit, 1) + + +# helper function (change_ui_layout) +# warning: this doesn't really copy any sort of attributes, except a few that were needed in my particular case +func replace_node_with(old : Node, new : Node) -> Node: + var tempname = old.name + old.name = "old" + new.name = tempname + new.size_flags_vertical = old.size_flags_horizontal + new.size_flags_vertical = old.size_flags_vertical + # new.set("custom_constants/autohide", old.get("custom_constants/autohide")) + if new is HBoxContainer: + new.set_alignment(HBoxContainer.ALIGN_CENTER) + new.set("custom_constants/separation", 20) + old.get_parent().add_child(new) + for n in old.get_children(): + reparent_node_to(n, new, -1) + old.get_parent().remove_child(old) + old.queue_free() + return new + + +# helper function (change_ui_layout) +func reparent_node_to(node : Node, dest : Node, pos : int) -> bool: + if dest is Node and node is Node: + node.get_parent().remove_child(node) + dest.add_child(node) + node.set_owner(dest) + if pos >= 0: + dest.move_child(node, pos) + return true + else: + return false + + 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 diff --git a/src/UI/CanvasPreviewContainer.tscn b/src/UI/CanvasPreviewContainer.tscn index a56e7fed7..eedb86024 100644 --- a/src/UI/CanvasPreviewContainer.tscn +++ b/src/UI/CanvasPreviewContainer.tscn @@ -23,6 +23,7 @@ margin_right = 278.0 margin_bottom = 164.0 rect_min_size = Vector2( 300, 0 ) size_flags_horizontal = 4 +size_flags_vertical = 0 script = ExtResource( 3 ) __meta__ = { "_edit_use_anchors_": false diff --git a/src/UI/TopMenuContainer.gd b/src/UI/TopMenuContainer.gd index 21a4c114e..9607478f2 100644 --- a/src/UI/TopMenuContainer.gd +++ b/src/UI/TopMenuContainer.gd @@ -3,11 +3,10 @@ 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 ViewMenuId {TILE_MODE, WINDOW_TRANSPARENCY, PANEL_LAYOUT, 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 @@ -83,6 +82,7 @@ func setup_view_menu() -> void: var view_menu_items := { # order as in ViewMenuId enum "Tile Mode" : 0, "Window Transparency" : 0, + "Panel Layout" : 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(), @@ -100,6 +100,8 @@ func setup_view_menu() -> void: setup_tile_mode_submenu(item) elif item == "Window Transparency": setup_window_transparency_submenu(item) + elif item == "Panel Layout": + setup_panel_layout_submenu(item) else: view_menu.add_check_item(item, i, view_menu_items[item]) i += 1 @@ -124,6 +126,12 @@ func setup_window_transparency_submenu(item : String): view_menu.add_submenu_item(item, Global.window_transparency_submenu.get_name()) +func setup_panel_layout_submenu(item : String): + Global.panel_layout_submenu.connect("id_pressed", self, "panel_layout_submenu_id_pressed") + view_menu.add_child(Global.panel_layout_submenu) + view_menu.add_submenu_item(item, Global.panel_layout_submenu.get_name()) + + func setup_image_menu() -> void: var image_menu_items := { # order as in ImageMenuId enum "Scale Image" : 0, @@ -314,6 +322,13 @@ func window_transparency_submenu_id_pressed(id : float) -> void: window_transparency(id/10) +func panel_layout_submenu_id_pressed(id : int) -> void: + Global.panel_layout = id + for i in Global.PanelLayout.values(): + Global.panel_layout_submenu.set_item_checked(i, i == id) + get_tree().get_root().get_node("Control").handle_resize() + + func window_transparency(value :float) -> void: if value == 1: get_node("../../AlternateTransparentBackground").visible = false @@ -374,9 +389,9 @@ func toggle_show_anim_timeline() -> void: 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 + Global.tool_panel.visible = zen_mode + Global.right_panel.visible = zen_mode + Global.tabs_container.visible = zen_mode zen_mode = !zen_mode view_menu.set_item_checked(ViewMenuId.ZEN_MODE, zen_mode) diff --git a/src/UI/UI.tscn b/src/UI/UI.tscn index 2f137297a..acb296748 100644 --- a/src/UI/UI.tscn +++ b/src/UI/UI.tscn @@ -359,9 +359,23 @@ current = true zoom = Vector2( 0.15, 0.15 ) script = ExtResource( 7 ) -[node name="AnimationTimeline" parent="CanvasAndTimeline" instance=ExtResource( 18 )] +[node name="HBoxContainer" type="HBoxContainer" parent="CanvasAndTimeline"] margin_top = 492.0 +margin_right = 902.0 margin_bottom = 692.0 +size_flags_horizontal = 3 + +[node name="BottomPanel" type="VSplitContainer" parent="CanvasAndTimeline/HBoxContainer"] +margin_right = 902.0 +margin_bottom = 200.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +custom_constants/autohide = 0 + +[node name="AnimationTimeline" parent="CanvasAndTimeline/HBoxContainer/BottomPanel" instance=ExtResource( 18 )] +margin_top = 0.0 +margin_bottom = 200.0 +size_flags_vertical = 3 custom_styles/panel = SubResource( 3 ) [node name="RightPanel" type="Panel" parent="."] @@ -388,6 +402,7 @@ margin_right = 315.0 margin_top = 168.0 margin_right = 330.0 margin_bottom = 676.0 +size_flags_horizontal = 3 size_flags_vertical = 3 custom_constants/autohide = 0