diff --git a/misc/multiple_windows/README.md b/misc/multiple_windows/README.md new file mode 100644 index 00000000000..e8d682edc7f --- /dev/null +++ b/misc/multiple_windows/README.md @@ -0,0 +1,20 @@ +# Window Management + +A demo showing all [`Window`](https://docs.godotengine.org/en/stable/classes/class_window.html) classes and their use within the main window. + +It includes: +- Embedding/unembedding subwindows. +- Using a transparent window. +- Adding physical objects to new windows. +- Showcase of all Dialog Windows. +- Showcase of all Popup Windows. +- Adding elements to a Popup Menu. +- Adding an icon to the system tray. + +Language: GDScript + +Renderer: Compatbility + +## Screenshots + +![Screenshot](screenshots/screenshot.webp) diff --git a/misc/multiple_windows/icon.webp b/misc/multiple_windows/icon.webp new file mode 100644 index 00000000000..e36bd12ef02 Binary files /dev/null and b/misc/multiple_windows/icon.webp differ diff --git a/misc/multiple_windows/icon.webp.import b/misc/multiple_windows/icon.webp.import new file mode 100644 index 00000000000..670cfc50d10 --- /dev/null +++ b/misc/multiple_windows/icon.webp.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cehd300ehf1vw" +path="res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.webp" +dest_files=["res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/misc/multiple_windows/project.godot b/misc/multiple_windows/project.godot new file mode 100644 index 00000000000..c10e1a8dcac --- /dev/null +++ b/misc/multiple_windows/project.godot @@ -0,0 +1,31 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Multiple Windows Demo" +config/description="A demo showing all Window classes and their use within the main window." +run/main_scene="res://scenes/main_scene.tscn" +config/features=PackedStringArray("4.5", "GL Compatibility") +run/low_processor_mode=true +config/icon="res://icon.webp" + +[display] + +window/size/viewport_width=650 +window/size/viewport_height=650 +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" +window/per_pixel_transparency/allowed=true + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/misc/multiple_windows/scenes/accept_dialogue/accept_dialog.tscn b/misc/multiple_windows/scenes/accept_dialogue/accept_dialog.tscn new file mode 100644 index 00000000000..cb6498c3e48 --- /dev/null +++ b/misc/multiple_windows/scenes/accept_dialogue/accept_dialog.tscn @@ -0,0 +1,7 @@ +[gd_scene format=3 uid="uid://cudrukovmha7p"] + +[node name="AcceptDialog" type="AcceptDialog"] +initial_position = 2 +size = Vector2i(277, 100) +visible = true +dialog_text = "This is an AcceptDialog window" diff --git a/misc/multiple_windows/scenes/confimation_dialogue/confirmation_dialog.tscn b/misc/multiple_windows/scenes/confimation_dialogue/confirmation_dialog.tscn new file mode 100644 index 00000000000..4cd56fc86ab --- /dev/null +++ b/misc/multiple_windows/scenes/confimation_dialogue/confirmation_dialog.tscn @@ -0,0 +1,7 @@ +[gd_scene format=3 uid="uid://1nswovajdv3n"] + +[node name="ConfirmationDialog" type="ConfirmationDialog"] +initial_position = 2 +size = Vector2i(310, 100) +visible = true +dialog_text = "This is a ConfimationDialog window" diff --git a/misc/multiple_windows/scenes/disable_other.gd b/misc/multiple_windows/scenes/disable_other.gd new file mode 100644 index 00000000000..b1c93898a80 --- /dev/null +++ b/misc/multiple_windows/scenes/disable_other.gd @@ -0,0 +1,29 @@ +extends BaseButton + + +enum Behavior { + ENABLE_OTHERS_WHEN_ENABLED, + ENABLE_OTHERS_WHEN_DISABLED, +} + +@export var behavior: Behavior = Behavior.ENABLE_OTHERS_WHEN_ENABLED +@export var others: Array[BaseButton] = [] + + +func _ready() -> void: + var others_disabled: bool + if behavior == Behavior.ENABLE_OTHERS_WHEN_ENABLED: + others_disabled = not button_pressed + else: + others_disabled = button_pressed + for other in others: + other.disabled = others_disabled + + +func _toggled(toggled_on: bool) -> void: + if behavior == Behavior.ENABLE_OTHERS_WHEN_ENABLED: + for other in others: + other.disabled = not toggled_on + else: + for other in others: + other.disabled = toggled_on diff --git a/misc/multiple_windows/scenes/disable_other.gd.uid b/misc/multiple_windows/scenes/disable_other.gd.uid new file mode 100644 index 00000000000..812aa2ae928 --- /dev/null +++ b/misc/multiple_windows/scenes/disable_other.gd.uid @@ -0,0 +1 @@ +uid://b4ngyw7e2c75u diff --git a/misc/multiple_windows/scenes/draggable_window/draggable_region.gd b/misc/multiple_windows/scenes/draggable_window/draggable_region.gd new file mode 100644 index 00000000000..b8dd6c2877a --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/draggable_region.gd @@ -0,0 +1,6 @@ +extends Area2D + +func _input_event(_viewport: Viewport, event: InputEvent, _shape_index: int) -> void: + if event is InputEventMouseButton: + if event.pressed: + get_window().start_drag() diff --git a/misc/multiple_windows/scenes/draggable_window/draggable_region.gd.uid b/misc/multiple_windows/scenes/draggable_window/draggable_region.gd.uid new file mode 100644 index 00000000000..cfce1cd533e --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/draggable_region.gd.uid @@ -0,0 +1 @@ +uid://d1nq2ipicit18 diff --git a/misc/multiple_windows/scenes/draggable_window/draggable_window.tscn b/misc/multiple_windows/scenes/draggable_window/draggable_window.tscn new file mode 100644 index 00000000000..5544f944f69 --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/draggable_window.tscn @@ -0,0 +1,40 @@ +[gd_scene load_steps=6 format=3 uid="uid://ek1fmwy87san"] + +[ext_resource type="Texture2D" uid="uid://pgdemhy0xqog" path="res://scenes/draggable_window/hand.svg" id="1_y4nm8"] +[ext_resource type="Script" uid="uid://d1nq2ipicit18" path="res://scenes/draggable_window/draggable_region.gd" id="2_pflw3"] +[ext_resource type="Script" uid="uid://djnd1kuhucddh" path="res://scenes/draggable_window/sprite_polygon_passthrough.gd" id="3_20753"] + +[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_ghj85"] +size = Vector2(256, 256) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_cvhp1"] +size = Vector2(128, 128) + +[node name="DraggableWindow" type="Window"] +transparent_bg = true +physics_object_picking = true +oversampling_override = 1.0 +size = Vector2i(128, 128) +unresizable = true +borderless = true +always_on_top = true +transparent = true + +[node name="BG" type="Sprite2D" parent="."] +visible = false +texture = SubResource("PlaceholderTexture2D_ghj85") +centered = false + +[node name="Icon" type="Sprite2D" parent="."] +position = Vector2(64, 64) +texture = ExtResource("1_y4nm8") + +[node name="Area2D" type="Area2D" parent="Icon"] +script = ExtResource("2_pflw3") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Icon/Area2D"] +shape = SubResource("RectangleShape2D_cvhp1") + +[node name="PassthroughGenerator" type="Node" parent="." node_paths=PackedStringArray("sprite")] +script = ExtResource("3_20753") +sprite = NodePath("../Icon") diff --git a/misc/multiple_windows/scenes/draggable_window/hand.svg b/misc/multiple_windows/scenes/draggable_window/hand.svg new file mode 100644 index 00000000000..320920a7f4b --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/hand.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/misc/multiple_windows/scenes/draggable_window/hand.svg.import b/misc/multiple_windows/scenes/draggable_window/hand.svg.import new file mode 100644 index 00000000000..ef27b617880 --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/hand.svg.import @@ -0,0 +1,43 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://pgdemhy0xqog" +path="res://.godot/imported/hand.svg-b2d702bcd7ae140c6ed485fe3d5b4a36.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://scenes/draggable_window/hand.svg" +dest_files=["res://.godot/imported/hand.svg-b2d702bcd7ae140c6ed485fe3d5b4a36.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/misc/multiple_windows/scenes/draggable_window/sprite_polygon_passthrough.gd b/misc/multiple_windows/scenes/draggable_window/sprite_polygon_passthrough.gd new file mode 100644 index 00000000000..cb3ed80e186 --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/sprite_polygon_passthrough.gd @@ -0,0 +1,34 @@ +extends Node + +@export var sprite: Sprite2D + +func generate_polygon(): + # Make a bitmap out of a sprite. + var bitmap := BitMap.new() + bitmap.create_from_image_alpha(sprite.texture.get_image()) + # Cell size in case sprite cell is used for animation. + var cell_size_x := float(bitmap.get_size().x) / sprite.hframes + var cell_size_y := float(bitmap.get_size().y) / sprite.vframes + var cell_rect: Rect2 = Rect2(cell_size_x * sprite.frame_coords.x, cell_size_y * sprite.frame_coords.y, cell_size_x, cell_size_y) + # Grow bitmap to make sure every pixel will be captured. + bitmap.grow_mask(1, cell_rect) + # Generate array of polygons from bitmap. + var bitmap_polygons: Array[PackedVector2Array] = bitmap.opaque_to_polygons(cell_rect, 1.0) + var polygon = PackedVector2Array() + # Offset to position polygon correctly in relation of sprite to a window. + var offset: Vector2 = sprite.position + sprite.offset + if sprite.centered: + offset -= Vector2(cell_size_x, cell_size_y) / 2 + + # First point is used to connect multiple polygons into one big polygon. + var first_point: Vector2 = bitmap_polygons[0][0] + # Uniting all polygons into polygon for window to use. + for bitmap_polygon: PackedVector2Array in bitmap_polygons: + for point: Vector2 in bitmap_polygon: + polygon.append(point + offset) + + polygon.append(first_point) + polygon.append(first_point) + + # Apply passthrough mask to the window. + get_window().mouse_passthrough_polygon = polygon diff --git a/misc/multiple_windows/scenes/draggable_window/sprite_polygon_passthrough.gd.uid b/misc/multiple_windows/scenes/draggable_window/sprite_polygon_passthrough.gd.uid new file mode 100644 index 00000000000..687e975f93d --- /dev/null +++ b/misc/multiple_windows/scenes/draggable_window/sprite_polygon_passthrough.gd.uid @@ -0,0 +1 @@ +uid://djnd1kuhucddh diff --git a/misc/multiple_windows/scenes/file_dialogue/file_dialog.tscn b/misc/multiple_windows/scenes/file_dialogue/file_dialog.tscn new file mode 100644 index 00000000000..39390d42e82 --- /dev/null +++ b/misc/multiple_windows/scenes/file_dialogue/file_dialog.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://dx84v67isxyjv"] + +[node name="FileDialog" type="FileDialog"] +initial_position = 2 +size = Vector2i(700, 400) +visible = true diff --git a/misc/multiple_windows/scenes/main_scene.gd b/misc/multiple_windows/scenes/main_scene.gd new file mode 100644 index 00000000000..fa4f093b486 --- /dev/null +++ b/misc/multiple_windows/scenes/main_scene.gd @@ -0,0 +1,187 @@ +extends Control + + +@onready var window: Window = $Window +@onready var draggable_window: Window = $DraggableWindow +@onready var file_dialog: FileDialog = $FileDialog +@onready var file_dialog_output: TextEdit = $HBoxContainer/VBoxContainer2/FileDialogOutput +@onready var accept_dialog: AcceptDialog = $AcceptDialog +@onready var accept_dialog_output: TextEdit = $HBoxContainer/VBoxContainer2/AcceptOutput +@onready var confirmation_dialog: ConfirmationDialog = $ConfirmationDialog +@onready var confirmation_dialog_output: TextEdit = $HBoxContainer/VBoxContainer2/ConfirmationOutput +@onready var popup: Popup = $Popup +@onready var popup_menu: PopupMenu = $PopupMenu +@onready var popup_menu_output: TextEdit = $HBoxContainer/VBoxContainer3/PopupMenuOutput +@onready var popup_panel: PopupPanel = $PopupPanel +@onready var status_indicator: StatusIndicator = $StatusIndicator + + +func _on_embed_subwindows_toggled(toggled_on: bool) -> void: + var hidden_windows: Array[Window] = [] + for child in get_children(): + if child is Window and child.is_visible(): + child.hide() + hidden_windows.append(child) + + embed_subwindows(toggled_on) + for _window in hidden_windows: + _window.show() + + +func embed_subwindows(state: bool) -> void: + get_viewport().gui_embed_subwindows = state + + +func _on_window_button_pressed() -> void: + window.show() + window.grab_focus() + + +func _on_transient_window_toggled(toggled_on: bool) -> void: + window.transient = toggled_on + + +func _on_exclusive_window_toggled(toggled_on: bool) -> void: + window.exclusive = toggled_on + + +func _on_unresizable_window_toggled(toggled_on: bool) -> void: + window.unresizable = toggled_on + + +func _on_borderless_window_toggled(toggled_on: bool) -> void: + window.borderless = toggled_on + + +func _on_always_on_top_window_toggled(toggled_on: bool) -> void: + window.always_on_top = toggled_on + + +func _on_transparent_window_toggled(toggled_on: bool) -> void: + window.transparent = toggled_on + + +func _on_window_title_edit_text_changed(new_text: String) -> void: + window.title = new_text + + +func _on_draggable_window_button_pressed() -> void: + draggable_window.show() + draggable_window.grab_focus() + + +func _on_draggable_window_close_pressed() -> void: + draggable_window.hide() + + +func _on_bg_draggable_window_toggled(toggled_on: bool) -> void: + draggable_window.get_node("BG").visible = toggled_on + + +func _on_passthrough_polygon_item_selected(index: int) -> void: + match index: + 0: + draggable_window.mouse_passthrough_polygon = [] + 1: + draggable_window.get_node("PassthroughGenerator").generate_polygon() + 2: + draggable_window.mouse_passthrough_polygon = [ + Vector2(16, 0), Vector2(16, 128), + Vector2(116, 128), Vector2(116, 0)] + + +func _on_file_dialog_button_pressed() -> void: + file_dialog.show() + + +func _on_file_dialog_dir_selected(dir: String) -> void: + file_dialog_output.text = "Directory Path: " + dir + + +func _on_file_dialog_file_selected(path: String) -> void: + file_dialog_output.text = "File Path: " + path + + +func _on_file_dialog_files_selected(paths: PackedStringArray) -> void: + file_dialog_output.text = "Chosen Paths: " + str(paths) + + +func _on_file_dialog_options_item_selected(index: int) -> void: + match index: + 0: + file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE + 1: + file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILES + 2: + file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_DIR + 3: + file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_ANY + 4: + file_dialog.file_mode = FileDialog.FILE_MODE_SAVE_FILE + +func _on_native_dialog_toggled(toggled_on: bool) -> void: + file_dialog.use_native_dialog = toggled_on + + +func _on_accept_button_text_submitted(new_text: String) -> void: + if not new_text.is_empty(): + accept_dialog.add_button(new_text, false, new_text) + + +func _on_accept_dialog_canceled() -> void: + accept_dialog_output.text = "Cancelled" + + +func _on_accept_dialog_confirmed() -> void: + accept_dialog_output.text = "Accepted" + + +func _on_accept_dialog_custom_action(action: StringName) -> void: + accept_dialog_output.text = "Custom Action: " + action + accept_dialog.hide() + + +func _on_accept_button_pressed() -> void: + accept_dialog.show() + + +func _on_confirmation_button_pressed() -> void: + confirmation_dialog.show() + + +func _on_confirmation_dialog_canceled() -> void: + confirmation_dialog_output.text = "Cancelled" + + +func _on_confirmation_dialog_confirmed() -> void: + confirmation_dialog_output.text = "Accepted" + + +func show_popup(_popup: Popup): + var mouse_position + if get_viewport().gui_embed_subwindows: + mouse_position = get_global_mouse_position() + else: + mouse_position = DisplayServer.mouse_get_position() + + _popup.popup(Rect2(mouse_position, _popup.size)) + + +func _on_popup_button_pressed() -> void: + show_popup(popup) + + +func _on_popup_menu_button_pressed() -> void: + show_popup(popup_menu) + + +func _on_popup_panel_button_pressed() -> void: + show_popup(popup_panel) + + +func _on_popup_menu_option_pressed(option: String) -> void: + popup_menu_output.text = option + " was pressed." + + +func _on_status_indicator_visible_toggled(toggled_on: bool) -> void: + status_indicator.visible = toggled_on diff --git a/misc/multiple_windows/scenes/main_scene.gd.uid b/misc/multiple_windows/scenes/main_scene.gd.uid new file mode 100644 index 00000000000..c3ad87de3a8 --- /dev/null +++ b/misc/multiple_windows/scenes/main_scene.gd.uid @@ -0,0 +1 @@ +uid://brqixlpt4am24 diff --git a/misc/multiple_windows/scenes/main_scene.tscn b/misc/multiple_windows/scenes/main_scene.tscn new file mode 100644 index 00000000000..fa663559e5d --- /dev/null +++ b/misc/multiple_windows/scenes/main_scene.tscn @@ -0,0 +1,368 @@ +[gd_scene load_steps=13 format=3 uid="uid://8nmbmlqd6df6"] + +[ext_resource type="Script" uid="uid://brqixlpt4am24" path="res://scenes/main_scene.gd" id="1_nwc20"] +[ext_resource type="PackedScene" uid="uid://blbehgenpldb" path="res://scenes/window/window.tscn" id="2_ldw47"] +[ext_resource type="Script" uid="uid://b4ngyw7e2c75u" path="res://scenes/disable_other.gd" id="2_psh0l"] +[ext_resource type="Script" uid="uid://evvrji8vwf5l" path="res://scenes/text_field.gd" id="3_bgndp"] +[ext_resource type="PackedScene" uid="uid://ek1fmwy87san" path="res://scenes/draggable_window/draggable_window.tscn" id="4_diw6b"] +[ext_resource type="PackedScene" uid="uid://dx84v67isxyjv" path="res://scenes/file_dialogue/file_dialog.tscn" id="5_f4o8g"] +[ext_resource type="PackedScene" uid="uid://cudrukovmha7p" path="res://scenes/accept_dialogue/accept_dialog.tscn" id="6_st8be"] +[ext_resource type="PackedScene" uid="uid://1nswovajdv3n" path="res://scenes/confimation_dialogue/confirmation_dialog.tscn" id="7_wii4q"] +[ext_resource type="PackedScene" uid="uid://p7lgllpnc8h8" path="res://scenes/popup/popup.tscn" id="8_vohc5"] +[ext_resource type="PackedScene" uid="uid://j7j6fe7plvmt" path="res://scenes/popup_menu/popup_menu.tscn" id="9_b1y32"] +[ext_resource type="PackedScene" uid="uid://dj15to28g17lb" path="res://scenes/popup_panel/popup_panel.tscn" id="10_rn47v"] +[ext_resource type="PackedScene" uid="uid://bfsfek8h27vha" path="res://scenes/status_indicator/status_indicator.tscn" id="12_cb4u3"] + +[node name="MainScene" 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_nwc20") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/separation = 32 +alignment = 1 + +[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] +layout_mode = 2 + +[node name="EmbedSubwindows" type="CheckButton" parent="HBoxContainer/VBoxContainer" node_paths=PackedStringArray("others")] +layout_mode = 2 +button_pressed = true +text = "Embed Subwindows" +script = ExtResource("2_psh0l") +others = [NodePath("../TransparentWindow"), NodePath("../PassthroughPolygon")] +behavior = 1 + +[node name="HSeparator" type="HSeparator" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 + +[node name="WindowLabel" type="Label" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Window" +horizontal_alignment = 1 + +[node name="WindowButton" type="Button" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Show window" + +[node name="WindowTitleEdit" type="LineEdit" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +placeholder_text = "Window's Title" + +[node name="TransientWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer" node_paths=PackedStringArray("others")] +layout_mode = 2 +text = "Transient" +script = ExtResource("2_psh0l") +others = [NodePath("../ExclusiveWindow")] + +[node name="ExclusiveWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +tooltip_text = "Needs transient enabled to work." +disabled = true +text = "Exclusive +" + +[node name="UnresizableWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Unresizable +" + +[node name="BorderlessWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Borderless" + +[node name="AlwaysOnTopWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Always on Top" + +[node name="TransparentWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +tooltip_text = "Needs embed_subwindows disabled to work." +text = "Transparent +" + +[node name="HSeparator2" type="HSeparator" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 + +[node name="WindowArea2D" type="Label" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Window with Area2D" +horizontal_alignment = 1 + +[node name="HBoxContainerDW" type="HBoxContainer" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 + +[node name="DraggableWindowButton" type="Button" parent="HBoxContainer/VBoxContainer/HBoxContainerDW"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Draggable window" + +[node name="Close" type="Button" parent="HBoxContainer/VBoxContainer/HBoxContainerDW"] +layout_mode = 2 +text = "X" + +[node name="DraggableWindowExplanation" type="RichTextLabel" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 12 +text = "This window uses Area2D to detect if user clicked inside of it. +Since it's Area2D, you can change it's CollisionShape2D. +But since Area2D is a Physics Object, \"Physics Object Picking\" inside of Window's properties hard to be enabled. +" +fit_content = true + +[node name="BGDraggableWindow" type="CheckButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +tooltip_text = "Needs embed_subwindows disabled to work." +text = "Add Background" + +[node name="PassthroughLabel" type="Label" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Passthrough Polygon:" + +[node name="PassthroughPolygon" type="OptionButton" parent="HBoxContainer/VBoxContainer"] +layout_mode = 2 +tooltip_text = "Needs embed_subwindows disabled to work." +selected = 0 +item_count = 3 +popup/item_0/text = "Empty" +popup/item_0/id = 0 +popup/item_1/text = "Calculate via BitMap" +popup/item_1/id = 1 +popup/item_2/text = "Rectangle" +popup/item_2/id = 2 + +[node name="VBoxContainer2" type="VBoxContainer" parent="HBoxContainer"] +layout_mode = 2 + +[node name="FileDialogLabel" type="Label" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "File Dialog" +horizontal_alignment = 1 + +[node name="FileDialogButton" type="Button" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "Show File Dialog" + +[node name="FileDialogOptions" type="OptionButton" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +selected = 4 +item_count = 5 +popup/item_0/text = "Open File" +popup/item_0/id = 0 +popup/item_1/text = "Open Files" +popup/item_1/id = 1 +popup/item_2/text = "Open Folder" +popup/item_2/id = 2 +popup/item_3/text = "Open Any" +popup/item_3/id = 3 +popup/item_4/text = "Save" +popup/item_4/id = 4 + +[node name="NativeDialog" type="CheckButton" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "Use Native +Dialog" + +[node name="FileDialogOutput" type="TextEdit" parent="HBoxContainer/VBoxContainer2"] +custom_minimum_size = Vector2(200, 150) +layout_mode = 2 +placeholder_text = "Chosen path will show up here." +editable = false +wrap_mode = 1 + +[node name="HSeparator" type="HSeparator" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 + +[node name="AcceptLabel" type="Label" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "Accept Dialog" +horizontal_alignment = 1 + +[node name="AcceptButton" type="Button" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "Show Accept Dialog" + +[node name="NewButtonField" type="HBoxContainer" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 + +[node name="LineEdit" type="LineEdit" parent="HBoxContainer/VBoxContainer2/NewButtonField" node_paths=PackedStringArray("submit_button")] +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "New button field" +script = ExtResource("3_bgndp") +submit_button = NodePath("../Submit") + +[node name="Submit" type="Button" parent="HBoxContainer/VBoxContainer2/NewButtonField"] +layout_mode = 2 +text = "Enter" + +[node name="AcceptOutput" type="TextEdit" parent="HBoxContainer/VBoxContainer2"] +custom_minimum_size = Vector2(200, 70) +layout_mode = 2 +placeholder_text = "Dialogue result will show up here." +editable = false +wrap_mode = 1 + +[node name="HSeparator2" type="HSeparator" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 + +[node name="ConfirmationLabel" type="Label" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "Confirmation Dialog" +horizontal_alignment = 1 + +[node name="ConfirmationButton" type="Button" parent="HBoxContainer/VBoxContainer2"] +layout_mode = 2 +text = "Show Dialogue" + +[node name="ConfirmationOutput" type="TextEdit" parent="HBoxContainer/VBoxContainer2"] +custom_minimum_size = Vector2(200, 35) +layout_mode = 2 +placeholder_text = "Confirmation Result" +editable = false +wrap_mode = 1 + +[node name="VBoxContainer3" type="VBoxContainer" parent="HBoxContainer"] +layout_mode = 2 + +[node name="PopupLabel" type="Label" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +text = "Popup" +horizontal_alignment = 1 + +[node name="PopupButton" type="Button" parent="HBoxContainer/VBoxContainer3"] +custom_minimum_size = Vector2(150, 85) +layout_mode = 2 +text = "Show Popup" + +[node name="PopupDescription" type="RichTextLabel" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 12 +theme_override_font_sizes/mono_font_size = 12 +bbcode_enabled = true +text = "Popup hiding on mouse exit is handled by via [code]mouse_exited[/code] signal" +fit_content = true + +[node name="HSeparator" type="HSeparator" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 + +[node name="PopupMenuLabel" type="Label" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +text = "Popup" +horizontal_alignment = 1 + +[node name="PopupMenuButton" type="Button" parent="HBoxContainer/VBoxContainer3"] +custom_minimum_size = Vector2(150, 85) +layout_mode = 2 +text = "Show Popup" + +[node name="PopupMenuOutput" type="TextEdit" parent="HBoxContainer/VBoxContainer3"] +custom_minimum_size = Vector2(0, 100) +layout_mode = 2 +placeholder_text = "Pressed option will show up here." +editable = false +wrap_mode = 1 + +[node name="HSeparator2" type="HSeparator" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 + +[node name="PopupPanelLabel" type="Label" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +text = "Popup" +horizontal_alignment = 1 + +[node name="PopupPanelButton" type="Button" parent="HBoxContainer/VBoxContainer3"] +custom_minimum_size = Vector2(150, 85) +layout_mode = 2 +text = "Show Popup" + +[node name="HSeparator3" type="HSeparator" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 + +[node name="StatusIndicatorLabel" type="Label" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +text = "Status Indicator" +horizontal_alignment = 1 + +[node name="StatusIndicatorVisible" type="CheckButton" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +button_pressed = true +text = "Visible Tray Icon" + +[node name="OSLimitation" type="RichTextLabel" parent="HBoxContainer/VBoxContainer3"] +layout_mode = 2 +theme_override_font_sizes/normal_font_size = 12 +text = "Only works on Windows and macOS" +fit_content = true + +[node name="Window" parent="." instance=ExtResource("2_ldw47")] +visible = false + +[node name="DraggableWindow" parent="." instance=ExtResource("4_diw6b")] +visible = false + +[node name="FileDialog" parent="." instance=ExtResource("5_f4o8g")] +visible = false +access = 2 + +[node name="AcceptDialog" parent="." instance=ExtResource("6_st8be")] +visible = false + +[node name="ConfirmationDialog" parent="." instance=ExtResource("7_wii4q")] +visible = false + +[node name="Popup" parent="." instance=ExtResource("8_vohc5")] +visible = false + +[node name="PopupMenu" parent="." instance=ExtResource("9_b1y32")] +visible = false +unfocusable = false + +[node name="PopupPanel" parent="." instance=ExtResource("10_rn47v")] +visible = false + +[node name="StatusIndicator" parent="." instance=ExtResource("12_cb4u3")] +tooltip = "Multiple Windows Demo" + +[connection signal="toggled" from="HBoxContainer/VBoxContainer/EmbedSubwindows" to="." method="_on_embed_subwindows_toggled"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer/WindowButton" to="." method="_on_window_button_pressed"] +[connection signal="text_changed" from="HBoxContainer/VBoxContainer/WindowTitleEdit" to="." method="_on_window_title_edit_text_changed"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/TransientWindow" to="." method="_on_transient_window_toggled"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/ExclusiveWindow" to="." method="_on_exclusive_window_toggled"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/UnresizableWindow" to="." method="_on_unresizable_window_toggled"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/BorderlessWindow" to="." method="_on_borderless_window_toggled"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/AlwaysOnTopWindow" to="." method="_on_always_on_top_window_toggled"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/TransparentWindow" to="." method="_on_transparent_window_toggled"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer/HBoxContainerDW/DraggableWindowButton" to="." method="_on_draggable_window_button_pressed"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer/HBoxContainerDW/Close" to="." method="_on_draggable_window_close_pressed"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer/BGDraggableWindow" to="." method="_on_bg_draggable_window_toggled"] +[connection signal="item_selected" from="HBoxContainer/VBoxContainer/PassthroughPolygon" to="." method="_on_passthrough_polygon_item_selected"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer2/FileDialogButton" to="." method="_on_file_dialog_button_pressed"] +[connection signal="item_selected" from="HBoxContainer/VBoxContainer2/FileDialogOptions" to="." method="_on_file_dialog_options_item_selected"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer2/NativeDialog" to="." method="_on_native_dialog_toggled"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer2/AcceptButton" to="." method="_on_accept_button_pressed"] +[connection signal="text_submitted" from="HBoxContainer/VBoxContainer2/NewButtonField/LineEdit" to="." method="_on_accept_button_text_submitted"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer2/ConfirmationButton" to="." method="_on_confirmation_button_pressed"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer3/PopupButton" to="." method="_on_popup_button_pressed"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer3/PopupMenuButton" to="." method="_on_popup_menu_button_pressed"] +[connection signal="pressed" from="HBoxContainer/VBoxContainer3/PopupPanelButton" to="." method="_on_popup_panel_button_pressed"] +[connection signal="toggled" from="HBoxContainer/VBoxContainer3/StatusIndicatorVisible" to="." method="_on_status_indicator_visible_toggled"] +[connection signal="dir_selected" from="FileDialog" to="." method="_on_file_dialog_dir_selected"] +[connection signal="file_selected" from="FileDialog" to="." method="_on_file_dialog_file_selected"] +[connection signal="files_selected" from="FileDialog" to="." method="_on_file_dialog_files_selected"] +[connection signal="canceled" from="AcceptDialog" to="." method="_on_accept_dialog_canceled"] +[connection signal="confirmed" from="AcceptDialog" to="." method="_on_accept_dialog_confirmed"] +[connection signal="custom_action" from="AcceptDialog" to="." method="_on_accept_dialog_custom_action"] +[connection signal="canceled" from="ConfirmationDialog" to="." method="_on_confirmation_dialog_canceled"] +[connection signal="confirmed" from="ConfirmationDialog" to="." method="_on_confirmation_dialog_confirmed"] +[connection signal="option_pressed" from="PopupMenu" to="." method="_on_popup_menu_option_pressed"] diff --git a/misc/multiple_windows/scenes/popup/hide_on_mouse_exit.gd b/misc/multiple_windows/scenes/popup/hide_on_mouse_exit.gd new file mode 100644 index 00000000000..6afecd11b4d --- /dev/null +++ b/misc/multiple_windows/scenes/popup/hide_on_mouse_exit.gd @@ -0,0 +1,9 @@ +extends Popup + + +func _ready() -> void: + mouse_exited.connect(_on_mouse_exited) + + +func _on_mouse_exited(): + hide() diff --git a/misc/multiple_windows/scenes/popup/hide_on_mouse_exit.gd.uid b/misc/multiple_windows/scenes/popup/hide_on_mouse_exit.gd.uid new file mode 100644 index 00000000000..f090a059412 --- /dev/null +++ b/misc/multiple_windows/scenes/popup/hide_on_mouse_exit.gd.uid @@ -0,0 +1 @@ +uid://vyfoelflu5ca diff --git a/misc/multiple_windows/scenes/popup/popup.tscn b/misc/multiple_windows/scenes/popup/popup.tscn new file mode 100644 index 00000000000..4c79788f497 --- /dev/null +++ b/misc/multiple_windows/scenes/popup/popup.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=3 format=3 uid="uid://p7lgllpnc8h8"] + +[ext_resource type="Script" path="res://scenes/popup/hide_on_mouse_exit.gd" id="1_8lp3w"] +[ext_resource type="Texture2D" uid="uid://cehd300ehf1vw" path="res://icon.webp" id="2_yl4m2"] + +[node name="Popup" type="Popup"] +size = Vector2i(128, 128) +visible = true +script = ExtResource("1_8lp3w") + +[node name="TextureRect" type="TextureRect" parent="."] +offset_right = 40.0 +offset_bottom = 40.0 +texture = ExtResource("2_yl4m2") diff --git a/misc/multiple_windows/scenes/popup_menu/popup_menu.gd b/misc/multiple_windows/scenes/popup_menu/popup_menu.gd new file mode 100644 index 00000000000..ee651609ab5 --- /dev/null +++ b/misc/multiple_windows/scenes/popup_menu/popup_menu.gd @@ -0,0 +1,34 @@ +extends PopupMenu + + +signal option_pressed(option: String) + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + add_item("Normal Item") + add_multistate_item("Multistate Item", 3, 0) + add_radio_check_item("Radio Check Item 1") + add_radio_check_item("Radio Check Item 2") + add_check_item("Check Item") + add_separator("Separator") + add_submenu_item("Submenu", "SubPopupMenu") + var submenu: PopupMenu = $SubPopupMenu + submenu.transparent = true + submenu.add_item("Submenu Item 1") + submenu.add_item("Submenu Item 2") + submenu.index_pressed.connect(func(index): option_pressed.emit(submenu.get_item_text(index))) + index_pressed.connect(_on_index_pressed) + + +func _on_index_pressed(index: int) -> void: + if is_item_checkable(index): + set_item_checked(index, not is_item_checked(index)) + + match index: + 2: + set_item_checked(3, false) + 3: + set_item_checked(2, false) + + option_pressed.emit(get_item_text(index)) diff --git a/misc/multiple_windows/scenes/popup_menu/popup_menu.gd.uid b/misc/multiple_windows/scenes/popup_menu/popup_menu.gd.uid new file mode 100644 index 00000000000..351aedd7a04 --- /dev/null +++ b/misc/multiple_windows/scenes/popup_menu/popup_menu.gd.uid @@ -0,0 +1 @@ +uid://dmqie5oywulfi diff --git a/misc/multiple_windows/scenes/popup_menu/popup_menu.tscn b/misc/multiple_windows/scenes/popup_menu/popup_menu.tscn new file mode 100644 index 00000000000..3068abd7f90 --- /dev/null +++ b/misc/multiple_windows/scenes/popup_menu/popup_menu.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=2 format=3 uid="uid://j7j6fe7plvmt"] + +[ext_resource type="Script" path="res://scenes/popup_menu/popup_menu.gd" id="1_hi4jw"] + +[node name="PopupMenu" type="PopupMenu"] +transparent_bg = true +visible = true +transparent = true +unfocusable = true +script = ExtResource("1_hi4jw") + +[node name="SubPopupMenu" type="PopupMenu" parent="."] +transparent_bg = true +transparent = true diff --git a/misc/multiple_windows/scenes/popup_panel/popup_panel.tscn b/misc/multiple_windows/scenes/popup_panel/popup_panel.tscn new file mode 100644 index 00000000000..9765618901b --- /dev/null +++ b/misc/multiple_windows/scenes/popup_panel/popup_panel.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=2 format=3 uid="uid://dj15to28g17lb"] + +[sub_resource type="GDScript" id="GDScript_aqitk"] +script/source = "extends ProgressBar + +func _on_h_slider_value_changed(_value: float) -> void: + value = _value +" + +[node name="PopupPanel" type="PopupPanel"] +visible = true + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +offset_left = 4.0 +offset_top = 4.0 +offset_right = 96.0 +offset_bottom = 96.0 + +[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer"] +layout_mode = 2 +script = SubResource("GDScript_aqitk") + +[node name="HSlider" type="HSlider" parent="VBoxContainer"] +layout_mode = 2 + +[connection signal="value_changed" from="VBoxContainer/HSlider" to="VBoxContainer/ProgressBar" method="_on_h_slider_value_changed"] diff --git a/misc/multiple_windows/scenes/status_indicator/status_indicator.gd b/misc/multiple_windows/scenes/status_indicator/status_indicator.gd new file mode 100644 index 00000000000..7933f25eb0f --- /dev/null +++ b/misc/multiple_windows/scenes/status_indicator/status_indicator.gd @@ -0,0 +1,27 @@ +extends StatusIndicator + + +@onready var popup_menu: PopupMenu = get_node(menu) + + +func _ready() -> void: + popup_menu.prefer_native_menu = true + popup_menu.add_item("Quit") + popup_menu.index_pressed.connect(_on_popup_menu_index_pressed) + pressed.connect(_on_pressed) + + +# Isn't being called on right mouse button because menu is set. +func _on_pressed(mouse_button: int, _mouse_position: Vector2i) -> void: + if mouse_button == MOUSE_BUTTON_LEFT: + var window: Window = get_window() + if window.mode == Window.Mode.MODE_MINIMIZED: + window.mode = Window.Mode.MODE_WINDOWED + window.grab_focus() + + +func _on_popup_menu_index_pressed(index: int) -> void: + match index: + 0: + get_tree().root.propagate_notification(NOTIFICATION_WM_CLOSE_REQUEST) + get_tree().quit() diff --git a/misc/multiple_windows/scenes/status_indicator/status_indicator.gd.uid b/misc/multiple_windows/scenes/status_indicator/status_indicator.gd.uid new file mode 100644 index 00000000000..03257846372 --- /dev/null +++ b/misc/multiple_windows/scenes/status_indicator/status_indicator.gd.uid @@ -0,0 +1 @@ +uid://b3ccfgjmssfm3 diff --git a/misc/multiple_windows/scenes/status_indicator/status_indicator.tscn b/misc/multiple_windows/scenes/status_indicator/status_indicator.tscn new file mode 100644 index 00000000000..2d869458c79 --- /dev/null +++ b/misc/multiple_windows/scenes/status_indicator/status_indicator.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=3 format=3 uid="uid://bfsfek8h27vha"] + +[ext_resource type="Texture2D" uid="uid://cehd300ehf1vw" path="res://icon.webp" id="1_ryu0x"] +[ext_resource type="Script" path="res://scenes/status_indicator/status_indicator.gd" id="2_oe45l"] + +[node name="StatusIndicator" type="StatusIndicator"] +icon = ExtResource("1_ryu0x") +menu = NodePath("PopupMenu") +script = ExtResource("2_oe45l") + +[node name="PopupMenu" type="PopupMenu" parent="."] +prefer_native_menu = true diff --git a/misc/multiple_windows/scenes/text_field.gd b/misc/multiple_windows/scenes/text_field.gd new file mode 100644 index 00000000000..31a96f4d1b4 --- /dev/null +++ b/misc/multiple_windows/scenes/text_field.gd @@ -0,0 +1,10 @@ +extends LineEdit + + +@export var submit_button: Button + + +func _ready() -> void: + text_submitted.connect(func(_s): clear(), ConnectFlags.CONNECT_DEFERRED) + if submit_button: + submit_button.pressed.connect(func(): text_submitted.emit(text)) diff --git a/misc/multiple_windows/scenes/text_field.gd.uid b/misc/multiple_windows/scenes/text_field.gd.uid new file mode 100644 index 00000000000..c88cd66cd2c --- /dev/null +++ b/misc/multiple_windows/scenes/text_field.gd.uid @@ -0,0 +1 @@ +uid://evvrji8vwf5l diff --git a/misc/multiple_windows/scenes/window/url_opener.gd b/misc/multiple_windows/scenes/window/url_opener.gd new file mode 100644 index 00000000000..f148ad1ab05 --- /dev/null +++ b/misc/multiple_windows/scenes/window/url_opener.gd @@ -0,0 +1,10 @@ +extends RichTextLabel + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + meta_clicked.connect(_on_meta_clicked) + + +func _on_meta_clicked(meta: Variant) -> void: + OS.shell_open(str(meta)) diff --git a/misc/multiple_windows/scenes/window/url_opener.gd.uid b/misc/multiple_windows/scenes/window/url_opener.gd.uid new file mode 100644 index 00000000000..d242fd830bd --- /dev/null +++ b/misc/multiple_windows/scenes/window/url_opener.gd.uid @@ -0,0 +1 @@ +uid://bkauiff2v11ga diff --git a/misc/multiple_windows/scenes/window/window.gd b/misc/multiple_windows/scenes/window/window.gd new file mode 100644 index 00000000000..ceaee472e7e --- /dev/null +++ b/misc/multiple_windows/scenes/window/window.gd @@ -0,0 +1,11 @@ +extends Window + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + close_requested.connect(_on_close_requested) + + +func _on_close_requested() -> void: + print("%s %s was hidden." % [str(self.get_class()), name]) + hide() diff --git a/misc/multiple_windows/scenes/window/window.gd.uid b/misc/multiple_windows/scenes/window/window.gd.uid new file mode 100644 index 00000000000..2f45468363b --- /dev/null +++ b/misc/multiple_windows/scenes/window/window.gd.uid @@ -0,0 +1 @@ +uid://op5na21b0cg3 diff --git a/misc/multiple_windows/scenes/window/window.tscn b/misc/multiple_windows/scenes/window/window.tscn new file mode 100644 index 00000000000..fab15e3e443 --- /dev/null +++ b/misc/multiple_windows/scenes/window/window.tscn @@ -0,0 +1,30 @@ +[gd_scene load_steps=3 format=3 uid="uid://blbehgenpldb"] + +[ext_resource type="Script" path="res://scenes/window/url_opener.gd" id="1_cqmq3"] +[ext_resource type="Script" path="res://scenes/window/window.gd" id="1_yx1y1"] + +[node name="Window" type="Window"] +initial_position = 2 +size = Vector2i(500, 150) +script = ExtResource("1_yx1y1") + +[node name="Control" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="RichTextLabel" type="RichTextLabel" parent="Control"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +bbcode_enabled = true +text = "[url=https://docs.godotengine.org/en/stable/classes/class_window.html]Window, Godot Docs[/url]: + +At runtime, [b]Windows[/b] will not close automatically when requested. You need to handle it manually using the [url=https://docs.godotengine.org/en/stable/classes/class_window.html#class-window-signal-close-requested]close_requested[/url] signal (this applies both to pressing the close button and clicking outside of a popup)." +script = ExtResource("1_cqmq3") diff --git a/misc/multiple_windows/screenshots/.gdignore b/misc/multiple_windows/screenshots/.gdignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/misc/multiple_windows/screenshots/screenshot.webp b/misc/multiple_windows/screenshots/screenshot.webp new file mode 100644 index 00000000000..c0424a03568 Binary files /dev/null and b/misc/multiple_windows/screenshots/screenshot.webp differ