From 94e920a80fb80e3f97376b3430acaf5cba00b2c6 Mon Sep 17 00:00:00 2001 From: 2ManyProjects Date: Sun, 2 Mar 2025 19:21:56 -0600 Subject: [PATCH] Started DeckManager UI --- Systems/Cards/CardBankItem.gd | 44 ++++++ Systems/Cards/CardSlot.gd | 86 ++++++++++++ Systems/FairyStockfish/StockfishClient.gd | 2 +- Systems/Game/DeckManagerScreen.gd | 164 ++++++++++++++++++++++ Systems/Game/Menu/MenuContainer.gd | 62 ++++---- board.tscn | 7 +- card_bank_item.tscn | 57 ++++++++ card_slot.tscn | 124 ++++++++++++++++ deck_manager_screen.tscn | 105 ++++++++++++++ 9 files changed, 611 insertions(+), 40 deletions(-) create mode 100644 Systems/Cards/CardBankItem.gd create mode 100644 Systems/Cards/CardSlot.gd create mode 100644 Systems/Game/DeckManagerScreen.gd create mode 100644 card_bank_item.tscn create mode 100644 card_slot.tscn create mode 100644 deck_manager_screen.tscn diff --git a/Systems/Cards/CardBankItem.gd b/Systems/Cards/CardBankItem.gd new file mode 100644 index 0000000..9b00dd0 --- /dev/null +++ b/Systems/Cards/CardBankItem.gd @@ -0,0 +1,44 @@ +extends Control +class_name CardBankItem + +signal card_selected(card_item, card) + +var current_card = null + +@onready var rank_label = $RankLabel +@onready var card_name_label = $CardNameLabel +@onready var card_frame = $CardFrame + +# Card rank colors (matching CardSlot colors) +var rank_colors = { + Card.Rank.RANK_0: Color(0.9, 0.1, 0.1, 1.0), # Red + Card.Rank.RANK_1: Color(0.9, 0.6, 0.1, 1.0), # Orange + Card.Rank.RANK_2: Color(0.1, 0.7, 0.1, 1.0), # Green + Card.Rank.RANK_3: Color(0.1, 0.7, 0.9, 1.0) # Blue +} + +func _ready(): + # Connect signals for interaction + mouse_filter = Control.MOUSE_FILTER_STOP + gui_input.connect(_on_gui_input) + +func set_card(card): + current_card = card + update_appearance() + +func update_appearance(): + if current_card: + # Update card details + card_name_label.text = current_card.cardName + rank_label.text = str(current_card.rank) + + # Set color based on rank + if current_card.rank in rank_colors: + rank_label.modulate = rank_colors[current_card.rank] + card_frame.modulate = rank_colors[current_card.rank] + +func _on_gui_input(event): + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + if current_card: + emit_signal("card_selected", self, current_card) \ No newline at end of file diff --git a/Systems/Cards/CardSlot.gd b/Systems/Cards/CardSlot.gd new file mode 100644 index 0000000..8777c33 --- /dev/null +++ b/Systems/Cards/CardSlot.gd @@ -0,0 +1,86 @@ +extends Panel +class_name CardSlot + +signal card_selected(card_slot, card) + +var current_card = null +var dragging = false +var drag_offset = Vector2() + +@onready var card_name_label = $CardNameLabel +@onready var card_rank_label = $RankLabel +@onready var card_border = $CardBorder +@onready var card_bg = $CardBackground + +# Card rank colors +var rank_colors = { + Card.Rank.RANK_0: Color(0.9, 0.1, 0.1, 1.0), # Red + Card.Rank.RANK_1: Color(0.9, 0.6, 0.1, 1.0), # Orange + Card.Rank.RANK_2: Color(0.1, 0.7, 0.1, 1.0), # Green + Card.Rank.RANK_3: Color(0.1, 0.7, 0.9, 1.0) # Blue +} + +func _ready(): + # Set up card appearance + update_appearance() + + # Connect signals for interaction + mouse_filter = Control.MOUSE_FILTER_STOP + gui_input.connect(_on_gui_input) + +func set_card(card): + current_card = card + update_appearance() + +func clear(): + current_card = null + update_appearance() + +func has_card(): + return current_card != null + +func update_appearance(): + if current_card: + # Show card details + card_name_label.text = current_card.cardName + card_name_label.visible = true + + # Set rank display + card_rank_label.text = str(current_card.rank) + card_rank_label.visible = true + + # Set color based on rank + if current_card.rank in rank_colors: + card_rank_label.add_theme_color_override("font_color", rank_colors[current_card.rank]) + card_border.modulate = rank_colors[current_card.rank] + + # Show card background + card_bg.modulate = Color(0.2, 0.2, 0.25, 1.0) + else: + # Empty slot + card_name_label.visible = false + card_rank_label.visible = false + card_border.modulate = Color(0.4, 0.4, 0.4, 0.5) + card_bg.modulate = Color(0.15, 0.15, 0.15, 0.8) + +func _on_gui_input(event): + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_LEFT: + if event.pressed: + # Start drag + if current_card: + dragging = true + drag_offset = get_global_mouse_position() - global_position + else: + # End drag + if dragging: + dragging = false + emit_signal("card_selected", self, current_card) + elif current_card: + # Just a click, still select the card + emit_signal("card_selected", self, current_card) + +func _process(delta): + if dragging: + # Update position while dragging + global_position = get_global_mouse_position() - drag_offset \ No newline at end of file diff --git a/Systems/FairyStockfish/StockfishClient.gd b/Systems/FairyStockfish/StockfishClient.gd index 126de30..a1fb693 100644 --- a/Systems/FairyStockfish/StockfishClient.gd +++ b/Systems/FairyStockfish/StockfishClient.gd @@ -34,7 +34,7 @@ func connect_to_engine(_path: String, g: ChessGame) -> bool: if ServerManager.is_server_running(): print("**************SERVER RUNNING ****************") running = true - start_game(1350) + start_game(2100) return true await get_tree().create_timer(delay).timeout diff --git a/Systems/Game/DeckManagerScreen.gd b/Systems/Game/DeckManagerScreen.gd new file mode 100644 index 0000000..a3442e7 --- /dev/null +++ b/Systems/Game/DeckManagerScreen.gd @@ -0,0 +1,164 @@ +extends Control +class_name DeckManagerScreen + +signal back_pressed + +# Node references +@onready var deck_grid = $MainContainer/GridContainer +@onready var bank_container = $MainContainer/BankContainer/ScrollContainer/VBoxContainer +@onready var back_button = $BackButton + +# Default deck size (can be overridden via options) +var max_deck_size = 40 +var deck_manager = null +var bank_cards = [] # Cards available but not in deck + +# The current deck +var current_deck = [] + +func _ready(): + # Connect back button + if back_button: + back_button.connect("pressed", Callable(self, "_on_back_button_pressed")) + + # Find the DeckManager instance + deck_manager = get_node_or_null("/root/Board").deckManager + +func initialize(options = null): + # Process options if provided + if options: + if options.has("max_deck_size") and options.max_deck_size is int: + max_deck_size = options.max_deck_size + + # Load cards from deck and bank + load_cards() + + # Set up the grid with empty card containers + setup_deck_grid() + + # Populate the bank with available cards + populate_bank() + +func load_cards(): + if deck_manager: + # Clone the deck to work with + current_deck = deck_manager.deck.duplicate() + + # For testing, we'll create a bank of all card types + # In a real implementation, you'd get this from a saved player state + bank_cards = create_card_bank() + else: + # Fallback with empty collections if deck manager not found + current_deck = [] + bank_cards = [] + print("Warning: DeckManager not found") + +func create_card_bank(): + # This is a placeholder - in a real implementation you'd load this from saved state + var bank = [] + + # Add some sample cards + bank.append(HopscotchCard.new()) + bank.append(FieryCapeCard.new()) + bank.append(FieryTrailCard.new()) + bank.append(ExplosiveBootsCard.new()) + bank.append(DoubleTimeCard.new()) + bank.append(DrunkDrivingCard.new()) + bank.append(SupernovaCard.new()) + + # Add some duplicates for testing + for i in range(3): + bank.append(HopscotchCard.new()) + bank.append(FieryCapeCard.new()) + + return bank + +func setup_deck_grid(): + # Clear existing children + for child in deck_grid.get_children(): + child.queue_free() + + # Calculate grid dimensions + var rows = 4 # You might want to make this responsive or configurable + var cols = max_deck_size / rows + deck_grid.columns = cols + + # Create card slots + for i in range(max_deck_size): + var card_slot = preload("res://card_slot.tscn").instantiate() + deck_grid.add_child(card_slot) + + # Connect signals + card_slot.connect("card_selected", Callable(self, "_on_deck_card_selected")) + + # Set card if available + if i < current_deck.size(): + card_slot.set_card(current_deck[i]) + else: + card_slot.clear() + +func populate_bank(): + # Clear existing children + for child in bank_container.get_children(): + child.queue_free() + + # Add each bank card to the list + for card in bank_cards: + var card_item = preload("res://card_bank_item.tscn").instantiate() + bank_container.add_child(card_item) + card_item.set_card(card) + card_item.connect("card_selected", Callable(self, "_on_bank_card_selected")) + +func _on_deck_card_selected(card_slot, card): + if card: + # Remove card from deck + var index = current_deck.find(card) + if index >= 0: + current_deck.remove_at(index) + + # Add to bank + bank_cards.append(card) + + # Update UI + card_slot.clear() + populate_bank() + +func _on_bank_card_selected(card_item, card): + # Find first empty slot in deck + var empty_slot_index = -1 + for i in range(deck_grid.get_child_count()): + var slot = deck_grid.get_child(i) + if !slot.has_card(): + empty_slot_index = i + break + + if empty_slot_index >= 0 and current_deck.size() < max_deck_size: + # Remove from bank + var bank_index = bank_cards.find(card) + if bank_index >= 0: + bank_cards.remove_at(bank_index) + + # Add to deck + current_deck.append(card) + + # Update UI + deck_grid.get_child(empty_slot_index).set_card(card) + populate_bank() + +func save_deck(): + if deck_manager: + # Save the current deck to the deck manager + deck_manager.deck = current_deck.duplicate() + + # If we implement persistence, we'd save the bank state as well + print("Deck saved with ", current_deck.size(), " cards") + +func _on_back_button_pressed(): + # Save changes before returning + save_deck() + + # Emit signal to go back + emit_signal("back_pressed") + + # Hide this screen + visible = false \ No newline at end of file diff --git a/Systems/Game/Menu/MenuContainer.gd b/Systems/Game/Menu/MenuContainer.gd index 89e8448..bd8db97 100644 --- a/Systems/Game/Menu/MenuContainer.gd +++ b/Systems/Game/Menu/MenuContainer.gd @@ -1,9 +1,6 @@ extends Control class_name MenuContainer - -# Path to the game scene or initialization script -const ChessGame = preload("res://Systems/Game/ChessGame.gd") - + const VERSION_FILE_PATH = "res://Game.json" # Signal to notify parent when a new game is requested # signal new_game_requested @@ -18,6 +15,7 @@ signal map_open_requested(options) @onready var titleText = $HBoxContainer/VBoxContainer/TitleText @onready var developerText = $HBoxContainer/VBoxContainer/DeveloperText @onready var gameMenuScreen = get_node("/root/Board/GameMenuScreen") +@onready var deckManagerScreen = get_node("/root/Board/DeckManagerScreen") @onready var stateMachine = get_node("/root/Board/StateMachine") func _ready(): @@ -32,6 +30,10 @@ func _ready(): gameMenuScreen.connect("map_open_requested", Callable(self, "_on_map_open_requested")) gameMenuScreen.connect("new_game_requested", Callable(self, "_on_start_game_pressed")) gameMenuScreen.visible = false + + if deckManagerScreen: + deckManagerScreen.connect("back_pressed", Callable(self, "_on_deck_manager_back_pressed")) + deckManagerScreen.visible = false load_version() @@ -102,49 +104,33 @@ func _on_shop_open_requested(options): func _on_deckmanager_open_requested(options): print("Deck Manager requested with options:", options) + + # Hide game menu + gameMenuScreen.visible = false + + # Show and initialize deck manager + if deckManagerScreen: + deckManagerScreen.visible = true + deckManagerScreen.initialize(options) + + # Also emit signal for other systems that might need to know emit_signal("deckmanager_open_requested", options) +func _on_deck_manager_back_pressed(): + # Return to game menu screen + deckManagerScreen.visible = false + gameMenuScreen.visible = true + + func _on_map_open_requested(options): print("Map requested with options:", options) emit_signal("map_open_requested", options) func _on_start_game_pressed(options): print("Starting game with options:", options) - - # Find the ChessGame instance - # var chess_game = _find_chess_game() - - # if chess_game: - # # Reset the game board if it exists - # chess_game.resetBoard() - - # # Start state machine - # if stateMachine: - # stateMachine.transitionToNextState(Constants.WHITE_TURN) - # else: - # print("Warning: StateMachine not found") - # else: - # print("Error: ChessGame not found") - - # Emit signal for parent to handle with options + emit_signal("new_game_requested", options) - - -# Find the ChessGame node -func _find_chess_game(): - # Try to find existing ChessGame node - var chess_game = get_node_or_null("/root/Game/ChessGame") - - # If not found, check if we're a child of ChessGame - if not chess_game: - var parent = get_parent() - while parent and not chess_game: - if parent.get_class() == "ChessGame" or parent is ChessGame: - chess_game = parent - parent = parent.get_parent() - - return chess_game - + # Public method to show the menu func show_menu(): self.visible = true diff --git a/board.tscn b/board.tscn index 9f6a73c..9244387 100644 --- a/board.tscn +++ b/board.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=28 format=3 uid="uid://d0qyk6v20uief"] +[gd_scene load_steps=29 format=3 uid="uid://d0qyk6v20uief"] [ext_resource type="Script" path="res://Systems/Game/ChessGame.gd" id="1_fkb2r"] [ext_resource type="Script" path="res://Systems/StateMachine/GameStates/WhiteTurn.gd" id="3_276ip"] @@ -27,6 +27,7 @@ [ext_resource type="Script" path="res://Systems/Game/Menu/MenuTextOption.gd" id="24_aslgu"] [ext_resource type="Script" path="res://Systems/Game/GameMenuScreen.gd" id="26_pb4ja"] [ext_resource type="Script" path="res://Systems/Game/GameMenuButton.gd" id="26_t2e38"] +[ext_resource type="PackedScene" uid="uid://c7uqbcxdjoais" path="res://deck_manager_screen.tscn" id="28_4nyv8"] [node name="Board" type="Control"] layout_mode = 3 @@ -382,3 +383,7 @@ size_flags_horizontal = 3 [node name="GameImage" type="TextureRect" parent="GameMenuScreen/HBoxContainer/CenterContainer"] layout_mode = 2 texture = ExtResource("23_vmvai") + +[node name="DeckManagerScreen" parent="." instance=ExtResource("28_4nyv8")] +visible = false +layout_mode = 1 diff --git a/card_bank_item.tscn b/card_bank_item.tscn new file mode 100644 index 0000000..412912d --- /dev/null +++ b/card_bank_item.tscn @@ -0,0 +1,57 @@ +[gd_scene load_steps=3 format=3 uid="uid://cqg23tpbanwv4"] + +[ext_resource type="Script" path="res://Systems/Cards/CardBankItem.gd" id="1_gu47gh"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_asdfvfa"] +bg_color = Color(0.15, 0.15, 0.15, 1) +border_width_left = 1 +border_width_top = 1 +border_width_right = 1 +border_width_bottom = 1 +border_color = Color(0.4, 0.4, 0.4, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[node name="CardBankItem" type="Control"] +custom_minimum_size = Vector2(0, 40) +layout_mode = 3 +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +script = ExtResource("1_gu47gh") + +[node name="CardFrame" type="Panel" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_asdfvfa") + +[node name="RankLabel" type="Label" parent="."] +layout_mode = 0 +offset_left = 10.0 +offset_top = 8.0 +offset_right = 32.0 +offset_bottom = 32.0 +theme_override_colors/font_color = Color(0.1, 0.7, 0.9, 1) +theme_override_font_sizes/font_size = 20 +text = "3" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="CardNameLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 40.0 +offset_right = -10.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_font_sizes/font_size = 16 +text = "Card Name" +vertical_alignment = 1 diff --git a/card_slot.tscn b/card_slot.tscn new file mode 100644 index 0000000..9f19d26 --- /dev/null +++ b/card_slot.tscn @@ -0,0 +1,124 @@ +[gd_scene load_steps=3 format=3 uid="uid://b13w87rkhvwcv"] + +[ext_resource type="Script" path="res://Systems/Cards/CardSlot.gd" id="1_asdwda"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_asdawdf"] +bg_color = Color(0.15, 0.15, 0.15, 1) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.4, 0.4, 0.4, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[node name="CardSlot" type="Panel"] +custom_minimum_size = Vector2(120, 160) +theme_override_styles/panel = SubResource("StyleBoxFlat_asdawdf") +script = ExtResource("1_asdwda") + +[node name="CardBackground" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 2.0 +offset_top = 2.0 +offset_right = -2.0 +offset_bottom = -2.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.15, 0.15, 0.15, 1) + +[node name="CardBorder" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 0) + +[node name="RankLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -35.0 +offset_top = 5.0 +offset_right = -5.0 +offset_bottom = 35.0 +grow_horizontal = 0 +theme_override_colors/font_color = Color(0.1, 0.7, 0.9, 1) +theme_override_font_sizes/font_size = 24 +text = "3" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="TopLeftRank" type="Label" parent="."] +layout_mode = 1 +offset_left = 5.0 +offset_top = 5.0 +offset_right = 35.0 +offset_bottom = 35.0 +theme_override_colors/font_color = Color(0.1, 0.7, 0.9, 1) +theme_override_font_sizes/font_size = 24 +text = "3" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="CardNameLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 14 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = 10.0 +offset_top = -15.0 +offset_right = -10.0 +offset_bottom = 15.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_font_sizes/font_size = 16 +text = "Card Name" +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 3 + +[node name="BottomLeftRank" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 5.0 +offset_top = -35.0 +offset_right = 35.0 +offset_bottom = -5.0 +grow_vertical = 0 +theme_override_colors/font_color = Color(0.1, 0.7, 0.9, 1) +theme_override_font_sizes/font_size = 24 +text = "3" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="BottomRightRank" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -35.0 +offset_top = -35.0 +offset_right = -5.0 +offset_bottom = -5.0 +grow_horizontal = 0 +grow_vertical = 0 +theme_override_colors/font_color = Color(0.1, 0.7, 0.9, 1) +theme_override_font_sizes/font_size = 24 +text = "3" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/deck_manager_screen.tscn b/deck_manager_screen.tscn new file mode 100644 index 0000000..5303424 --- /dev/null +++ b/deck_manager_screen.tscn @@ -0,0 +1,105 @@ +[gd_scene load_steps=3 format=3 uid="uid://c7uqbcxdjoais"] + +[ext_resource type="Script" path="res://Systems/Game/DeckManagerScreen.gd" id="1_gokg4"] +[ext_resource type="Script" path="res://Systems/Game/GameMenuButton.gd" id="4_gokg4"] + +[node name="DeckManagerScreen" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_gokg4") + +[node name="Background" type="ColorRect" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.08, 0.08, 0.12, 1) + +[node name="TitleLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_top = 20.0 +offset_bottom = 72.0 +grow_horizontal = 2 +theme_override_font_sizes/font_size = 36 +text = "DECK MANAGER" +horizontal_alignment = 1 + +[node name="MainContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 20.0 +offset_top = 80.0 +offset_right = -20.0 +offset_bottom = -80.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="GridContainer" type="GridContainer" parent="MainContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +size_flags_stretch_ratio = 3.0 +theme_override_constants/h_separation = 10 +theme_override_constants/v_separation = 10 +columns = 5 + +[node name="BankContainer" type="VBoxContainer" parent="MainContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="MainContainer/BankContainer"] +layout_mode = 2 +text = "AVAILABLE CARDS" +horizontal_alignment = 1 + +[node name="HSeparator" type="HSeparator" parent="MainContainer/BankContainer"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="MainContainer/BankContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="MainContainer/BankContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +theme_override_constants/separation = 5 + +[node name="BackButton" type="RichTextLabel" parent="."] +layout_mode = 1 +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 20.0 +offset_top = -50.0 +offset_right = 155.0 +offset_bottom = -20.0 +grow_vertical = 0 +text = "BACK" +script = ExtResource("4_gokg4") + +[node name="SaveLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -223.0 +offset_top = -40.0 +offset_right = -20.0 +offset_bottom = -15.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "Changes will be saved automatically" +horizontal_alignment = 2