diff --git a/app/addons/max_size_container/icon.png b/app/addons/max_size_container/icon.png
new file mode 100644
index 0000000..2727079
Binary files /dev/null and b/app/addons/max_size_container/icon.png differ
diff --git a/app/addons/max_size_container/icon.png.import b/app/addons/max_size_container/icon.png.import
new file mode 100644
index 0000000..1e218a7
--- /dev/null
+++ b/app/addons/max_size_container/icon.png.import
@@ -0,0 +1,36 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d34gqxl8s8vne"
+path.s3tc="res://.godot/imported/icon.png-a7092b8839b5f5cb0339bb8ff99972fb.s3tc.ctex"
+path.etc2="res://.godot/imported/icon.png-a7092b8839b5f5cb0339bb8ff99972fb.etc2.ctex"
+metadata={
+"imported_formats": ["s3tc_bptc", "etc2_astc"],
+"vram_texture": true
+}
+
+[deps]
+
+source_file="res://addons/max_size_container/icon.png"
+dest_files=["res://.godot/imported/icon.png-a7092b8839b5f5cb0339bb8ff99972fb.s3tc.ctex", "res://.godot/imported/icon.png-a7092b8839b5f5cb0339bb8ff99972fb.etc2.ctex"]
+
+[params]
+
+compress/mode=2
+compress/high_quality=false
+compress/lossy_quality=0.7
+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/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/app/addons/max_size_container/max_size_container.gd b/app/addons/max_size_container/max_size_container.gd
new file mode 100644
index 0000000..ee5c991
--- /dev/null
+++ b/app/addons/max_size_container/max_size_container.gd
@@ -0,0 +1,301 @@
+# Made by Matthieu Huvé
+# Ported for Godot 4 Beta 10 by Benedikt Wicklein
+# Updated for Godot 4.x by Brom Bresenham (tested on Godot 4.2-dev2)
+
+## Limits the size of its single child node to arbitrary dimensions.
+@tool
+@icon("res://addons/max_size_container/icon.png")
+class_name MaxSizeContainer
+extends MarginContainer
+
+# Enums
+enum MODE
+{
+ PIXEL_SIZE, ## Limits the child to a specific pixel size.
+ ASPECT_FIT, ## Constrains the child to a specific aspect ratio. [member limit] is used as a ratio; (4,3) is equivalent to (8,6).
+ ASPECT_OR_WIDER, ## [member limit] specifies the narrowest allowed aspect ratio.
+ ASPECT_OR_TALLER ## [member limit] specifies the shortest allowed aspect ratio.
+}
+
+enum {LEFT, RIGHT, TOP, BOTTOM}
+
+enum VERTICAL_ALIGN
+{
+ TOP, ## Align with the top side of this MaxSizeContainer.
+ CENTER, ## Center vertically within this MaxSizeContainer.
+ BOTTOM ## Align with the bottom side of this MaxSizeContainer.
+}
+
+enum HORIZONTAL_ALIGN
+{
+ LEFT, ## Align with the left side of this MaxSizeContainer.
+ CENTER, ## Center horizontally within this MaxSizeContainer.
+ RIGHT ## Align with the right side of this MaxSizeContainer.
+}
+
+# Parameters
+## The constraint mode of this container.
+@export var mode := MODE.PIXEL_SIZE:
+ set(value):
+ if value == mode: return
+ mode = value
+
+ if value == MODE.PIXEL_SIZE:
+ limit = pixel_limit
+ else:
+ limit = aspect_limit
+
+## In Pixel Size mode, the maximum size the child node is allowed to be, or '-1' for no limit. In other modes, an aspect ratio, where (4,3) is equivalent to (8,6), and so on.
+@export var limit := Vector2(-1, -1):
+ set(value):
+ if mode == MODE.PIXEL_SIZE:
+ if value.x < 0: value.x = -1
+ if value.y < 0: value.y = -1
+
+ limit = value
+ pixel_limit = value
+ max_size = value
+
+ else:
+ if value.x <= 0: value.x = 1
+ if value.y <= 0: value.y = 1
+ limit = value
+ aspect_limit = value
+
+ if is_initialized:
+ _adapt_margins()
+
+## How the child node is vertically aligned within the excess space once it has reached its maximum height.
+@export var valign := VERTICAL_ALIGN.CENTER:
+ set(value):
+ valign = value
+ if is_initialized:
+ _adapt_margins()
+
+## How the child node is horizontally aligned within the excess space once it has reached its maximum width.
+@export var halign := HORIZONTAL_ALIGN.CENTER:
+ set(value):
+ halign = value
+
+ if is_initialized:
+ _adapt_margins()
+
+var max_size := Vector2(-1,-1)
+var pixel_limit := Vector2(-1,-1)
+var aspect_limit := Vector2(1,1)
+
+# child node of the container
+var child : Node
+
+# Intern var
+var minimum_child_size : Vector2
+var is_size_valid := {"x": false, "y": false}
+var is_initialized := false
+
+var is_resizing := false # infinite recursion guard
+
+func _ready() -> void:
+ # Reset custom margins if modified from the editor
+ _set_custom_margin(LEFT, 0)
+ _set_custom_margin(RIGHT, 0)
+ _set_custom_margin(TOP, 0)
+ _set_custom_margin(BOTTOM, 0)
+
+ # Sets up the Container
+ resized.connect(_on_self_resized)
+
+ child_entered_tree.connect( _on_child_entered_tree )
+ child_exiting_tree.connect( _on_child_exiting_tree )
+
+ if get_child_count() > 0:
+ _initialize(get_child(0))
+
+func _initialize(p_child: Node) -> void:
+ # Sets the child node
+ if not p_child: return
+ child = p_child
+ minimum_child_size = p_child.get_combined_minimum_size()
+ p_child.minimum_size_changed.connect( _on_child_minimum_size_changed )
+
+ _adapt_margins()
+
+ # Tells other parts that the child node is ready
+ # important to avoid early calculations that give wrong minimum child size
+ is_initialized = true
+
+func _update_maximum_size():
+ if mode != MODE.PIXEL_SIZE:
+ var fit_w = size.y * (aspect_limit.x / aspect_limit.y) # aspect pixel width given current height
+ var fit_h = size.x * (aspect_limit.y / aspect_limit.x) # aspect pixel height given current width
+
+ match mode:
+ MODE.ASPECT_FIT:
+ if fit_w <= size.x:
+ max_size.x = fit_w
+ max_size.y = size.y
+ else:
+ max_size.x = size.x
+ max_size.y = fit_h
+
+ MODE.ASPECT_OR_WIDER:
+ if fit_w <= size.x:
+ max_size.x = -1
+ max_size.y = size.y
+ else:
+ max_size.x = -1
+ max_size.y = fit_h
+
+ MODE.ASPECT_OR_TALLER:
+ if fit_w <= size.x:
+ max_size.x = fit_w
+ max_size.y = -1
+ else:
+ max_size.x = size.x
+ max_size.y = -1
+
+ _validate_maximum_size()
+
+
+func _validate_maximum_size() -> void:
+ # This function checks if the child is smaller than max_size.
+ # Otherwise there would be a risk of infinite margins
+ if child == null:
+ return
+
+ if max_size.x < 0:
+ is_size_valid.x = false
+ elif minimum_child_size.x > max_size.x:
+ is_size_valid.x = false
+ push_warning(str("max_size ( ", max_size, " ) ignored on x axis: too small.",
+ "The minimum possible size is: ", minimum_child_size))
+ else:
+ is_size_valid.x = true
+
+ if max_size.y < 0:
+ is_size_valid.y = false
+ elif minimum_child_size.y > max_size.y:
+ is_size_valid.y = false
+ push_warning(str("max_size ( ", max_size, " ) ignored on y axis: too small.",
+ "The minimum possible size is: ", minimum_child_size))
+ else:
+ is_size_valid.y = true
+
+
+func _adapt_margins() -> void:
+ # Adapts the margin to keep the child size below max_size
+ _update_maximum_size() # adjusts & validates max size for aspect modes
+
+ var rect_size := size
+ # If the container size is smaller than the max size, no margins are necessary
+ if rect_size.x < max_size.x:
+ _set_custom_margin(LEFT, 0)
+ _set_custom_margin(RIGHT, 0)
+ if rect_size.y < max_size.y:
+ _set_custom_margin(TOP, 0)
+ _set_custom_margin(BOTTOM, 0)
+
+ ### x ###
+ # If the max_size is smaller than the child's size: ignore it
+ if not is_size_valid.x:
+ _set_custom_margin(LEFT, 0)
+ _set_custom_margin(RIGHT, 0)
+
+ # Else, adds margins to keep the child's rect_size below the max_size
+ elif rect_size.x >= max_size.x:
+ var new_margin_left : int
+ var new_margin_right : int
+
+ match halign:
+ HORIZONTAL_ALIGN.LEFT:
+ new_margin_left = 0
+ new_margin_right = int(rect_size.x - max_size.x)
+ HORIZONTAL_ALIGN.CENTER:
+ new_margin_left = int((rect_size.x - max_size.x) / 2)
+ new_margin_right = int((rect_size.x - max_size.x) / 2)
+ HORIZONTAL_ALIGN.RIGHT:
+ new_margin_left = int(rect_size.x - max_size.x)
+ new_margin_right = 0
+
+ _set_custom_margin(LEFT, new_margin_left)
+ _set_custom_margin(RIGHT, new_margin_right)
+
+ ### y ###
+ # If the max_size is smaller than the child's size: ignore it
+ if not is_size_valid.y:
+ _set_custom_margin(TOP, 0)
+ _set_custom_margin(BOTTOM, 0)
+
+ # Else, adds margins to keep the child's rect_size below the max_size
+ elif rect_size.y >= max_size.y:
+ var new_margin_top : int
+ var new_margin_bottom : int
+
+ match valign:
+ VERTICAL_ALIGN.TOP:
+ new_margin_top = 0
+ new_margin_bottom = int(rect_size.y - max_size.y)
+ VERTICAL_ALIGN.CENTER:
+ new_margin_top = int((rect_size.y - max_size.y) / 2)
+ new_margin_bottom = int((rect_size.y - max_size.y) / 2)
+ VERTICAL_ALIGN.BOTTOM:
+ new_margin_top = int(rect_size.y - max_size.y)
+ new_margin_bottom = 0
+
+ _set_custom_margin(TOP, new_margin_top)
+ _set_custom_margin(BOTTOM, new_margin_bottom)
+
+
+func _set_custom_margin(side : int, value : int) -> void:
+# This function makes custom constants modifications easier
+ match side:
+ LEFT: add_theme_constant_override("margin_left", value)
+ RIGHT: add_theme_constant_override("margin_right", value)
+ TOP: add_theme_constant_override("margin_top", value)
+ BOTTOM: add_theme_constant_override("margin_bottom", value)
+
+
+func _on_self_resized() -> void:
+ # To avoid errors in tool mode and setup, the container must be fully ready
+ if is_initialized and not is_resizing:
+ is_resizing = true
+ _adapt_margins()
+ is_resizing = false
+
+
+func _on_child_entered_tree( p_child:Node ) -> void:
+ if get_child_count() == 1:
+ _initialize( p_child )
+ else:
+ push_warning(str("MaxSizeContainer can only handle one child. ", p_child.name,
+ " will be ignored because ", get_child(0).name, " is the first child."))
+
+func _on_child_exiting_tree( p_child:Node ) -> void:
+ if not p_child == child:
+ # Some other child that we're not paying attention to is being removed
+ return
+
+ # Stops margin calculations
+ is_initialized = false
+
+ # Disconnect signals
+ p_child.minimum_size_changed.disconnect( _on_child_minimum_size_changed )
+ child = null
+
+ # Reset custom margins
+ _set_custom_margin(LEFT, 0)
+ _set_custom_margin(RIGHT, 0)
+ _set_custom_margin(TOP, 0)
+ _set_custom_margin(BOTTOM, 0)
+
+ if get_child_count() > 1:
+ # There will still be at least one node remaining. Reinitialize and manage it.
+ for i in range( get_child_count() ):
+ var cur = get_child(i)
+ if cur != p_child:
+ _initialize( cur )
+ break
+
+
+func _on_child_minimum_size_changed() -> void:
+ minimum_child_size = child.get_combined_minimum_size()
+ _validate_maximum_size()
diff --git a/app/addons/max_size_container/plugin.cfg b/app/addons/max_size_container/plugin.cfg
new file mode 100644
index 0000000..8366ee7
--- /dev/null
+++ b/app/addons/max_size_container/plugin.cfg
@@ -0,0 +1,13 @@
+[plugin]
+
+name="Max Size Container"
+description="This is a custom container that limits its child maximum size.
+
+1. Add a Control node as a child
+2. Set its maximum width and height
+3. Choose how to align the child node when the maximum size is reached
+
+Note that the container can only accept 1 child."
+author="Brom Bresenham"
+version="1.3"
+script="plugin.gd"
diff --git a/app/addons/max_size_container/plugin.gd b/app/addons/max_size_container/plugin.gd
new file mode 100644
index 0000000..ee4f46a
--- /dev/null
+++ b/app/addons/max_size_container/plugin.gd
@@ -0,0 +1,12 @@
+@tool
+extends EditorPlugin
+
+func _enter_tree():
+ # Initialization of the plugin goes here.
+ # Add the new type with a name, a parent type, a script and an icon.
+ add_custom_type("MaxSizeContainer", "MarginContainer", preload("max_size_container.gd"), preload("icon.png"))
+
+func _exit_tree():
+ # Clean-up of the plugin goes here.
+ # Always remember to remove it from the engine when deactivated.
+ remove_custom_type("MaxSizeContainer")
diff --git a/app/assets/textures/icon-round.svg b/app/assets/textures/icon-round.svg
index 8ca81ce..c00cfb9 100644
--- a/app/assets/textures/icon-round.svg
+++ b/app/assets/textures/icon-round.svg
@@ -7,47 +7,13 @@
viewBox="0 0 67.733334 67.733337"
version="1.1"
id="svg5"
- inkscape:export-filename="icon_256.png"
- inkscape:export-xdpi="25.4"
- inkscape:export-ydpi="25.4"
- inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
- sodipodi:docname="icon-round-2.svg"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
-
+ id="linearGradient1">
+
+
+
+
+
+
+ gradientTransform="matrix(0.91069626,0,0,0.91069626,2.83401,3.0361791)" />
+
+
-
-
+ r="29.999853" />
+ style="display:inline;fill:none;stroke:#ffffff;stroke-width:1.228;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:40.2195;stroke-opacity:1"
+ d="m 29.089536,36.972782 c 0,0 0,-4.138992 0,-4.793899 0,-0.654908 0.199007,-2.996188 2.646631,-2.996188 2.458039,0 2.646632,2.340781 2.646632,2.996188 v 4.793899"
+ id="path2550" />
+ style="display:inline;fill:none;stroke:#ffffff;stroke-width:2.676;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:40.2195;stroke-opacity:1"
+ d="m 24.750141,43.768465 c 0,0 0,-10.925247 0,-12.653935 0,-1.728689 0.525295,-7.90871 6.986026,-7.90871 6.488214,0 6.986026,6.178703 6.986026,7.90871 v 12.653935"
+ id="path2547" />
+ style="display:inline;fill:none;stroke:#ffffff;stroke-width:5.2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:40.2195;stroke-opacity:1"
+ d="m 17.746746,54.736312 c 0,0 0,-21.877798 0,-25.3395 0,-3.461699 1.051899,-15.837186 13.98942,-15.837186 12.99255,0 13.989417,12.37285 13.989417,15.837186 v 25.3395"
+ id="path1246" />
diff --git a/app/assets/textures/icon-round.svg.import b/app/assets/textures/icon-round.svg.import
index abd4803..6de7a93 100644
--- a/app/assets/textures/icon-round.svg.import
+++ b/app/assets/textures/icon-round.svg.import
@@ -3,8 +3,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bw1cffhlt112i"
-path.bptc="res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.bptc.ctex"
-path.astc="res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.astc.ctex"
+path.s3tc="res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.s3tc.ctex"
+path.etc2="res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
@@ -13,12 +13,12 @@ metadata={
[deps]
source_file="res://assets/textures/icon-round.svg"
-dest_files=["res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.bptc.ctex", "res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.astc.ctex"]
+dest_files=["res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.s3tc.ctex", "res://.godot/imported/icon-round.svg-960dde2a3cd6f3751096cc6c33335de2.etc2.ctex"]
[params]
compress/mode=2
-compress/high_quality=true
+compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
@@ -34,6 +34,6 @@ process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
-svg/scale=0.5
+svg/scale=0.75
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
diff --git a/app/project.godot b/app/project.godot
index 5cc1459..adec843 100644
--- a/app/project.godot
+++ b/app/project.godot
@@ -29,7 +29,7 @@ driver/enable_input=true
DataSaver="*res://scripts/data_saver.gd"
FileDownloader="*res://scripts/loading/file_downloader.gd"
-Debug="*res://scripts/debug-log/debug.gd"
+Debug="*res://scripts/debug_log/debug.gd"
AnalyticsEvents="*res://scripts/api/analytics/analytics_events.gd"
Backend="*res://scripts/api/backend.gd"
@@ -53,6 +53,10 @@ window/per_pixel_transparency/allowed=true
naming/script_name_casing=2
+[editor_plugins]
+
+enabled=PackedStringArray("res://addons/max_size_container/plugin.cfg")
+
[gui]
theme/custom_font="res://assets/fonts/Inter-Regular.otf"
diff --git a/app/scenes/app.tscn b/app/scenes/app.tscn
index 6a840af..72fa964 100644
--- a/app/scenes/app.tscn
+++ b/app/scenes/app.tscn
@@ -2,7 +2,7 @@
[ext_resource type="Script" path="res://scripts/app.gd" id="1_skc7d"]
[ext_resource type="Resource" uid="uid://b1xvdym0qh6td" path="res://resources/gate_events.res" id="2_cdryv"]
-[ext_resource type="PackedScene" uid="uid://pgl3w7q5w84m" path="res://scenes/menu_body/bookmarks.tscn" id="3_l8glb"]
+[ext_resource type="PackedScene" uid="uid://ca647gp63bshc" path="res://scenes/menu_body/home.tscn" id="3_i66gl"]
[ext_resource type="PackedScene" uid="uid://5btb7nvgmfhl" path="res://scenes/menu.tscn" id="3_o1f7b"]
[ext_resource type="PackedScene" uid="uid://kywrsqro3d5i" path="res://scenes/menu_body/world.tscn" id="4_p75rl"]
[ext_resource type="PackedScene" uid="uid://dh3owgirapji5" path="res://scenes/menu_body/search_results.tscn" id="4_phjpd"]
@@ -21,7 +21,7 @@
[node name="App" type="Node" node_paths=PackedStringArray("scenes_root")]
script = ExtResource("1_skc7d")
gate_events = ExtResource("2_cdryv")
-bookmarks = ExtResource("3_l8glb")
+home = ExtResource("3_i66gl")
search_results = ExtResource("4_phjpd")
world_scene = ExtResource("4_p75rl")
scenes_root = NodePath("Menu/VBoxContainer/Body")
diff --git a/app/scenes/components/bookmark.tscn b/app/scenes/components/bookmark.tscn
index cab6a05..9ad4a5c 100644
--- a/app/scenes/components/bookmark.tscn
+++ b/app/scenes/components/bookmark.tscn
@@ -91,6 +91,8 @@ process_mode = 0
process_priority = 0
process_physics_priority = 0
process_thread_group = 0
+physics_interpolation_mode = 2
+auto_translate_mode = 1
editor_description = ""
visible = true
modulate = Color(1, 1, 1, 1)
@@ -128,7 +130,6 @@ pivot_offset = Vector2(0, 0)
size_flags_horizontal = 1
size_flags_vertical = 1
size_flags_stretch_ratio = 1.0
-auto_translate = true
localize_numeral_system = true
tooltip_text = ""
focus_neighbor_left = NodePath("")
diff --git a/app/scenes/components/tab.tscn b/app/scenes/components/tab.tscn
index 9d5cce8..2195c7a 100644
--- a/app/scenes/components/tab.tscn
+++ b/app/scenes/components/tab.tscn
@@ -71,13 +71,7 @@ texture = ExtResource("1_jc4ra")
expand_mode = 1
stretch_mode = 4
-[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/HBoxContainer"]
-layout_mode = 2
-size_flags_horizontal = 3
-size_flags_vertical = 4
-theme_override_constants/margin_top = 2
-
-[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/MarginContainer"]
+[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "New Tab"
diff --git a/app/scenes/debug.tscn b/app/scenes/debug.tscn
index 956a071..60563c5 100644
--- a/app/scenes/debug.tscn
+++ b/app/scenes/debug.tscn
@@ -1,8 +1,8 @@
[gd_scene load_steps=9 format=3 uid="uid://byrcbqat0n2px"]
-[ext_resource type="Script" path="res://scripts/debug-log/debug_window.gd" id="1_j4w8w"]
+[ext_resource type="Script" path="res://scripts/debug_log/debug_window.gd" id="1_j4w8w"]
[ext_resource type="FontFile" uid="uid://do40418waa8w3" path="res://assets/fonts/Inter-Regular.otf" id="2_da5xc"]
-[ext_resource type="Script" path="res://scripts/debug-log/debug_log.gd" id="2_lgt6s"]
+[ext_resource type="Script" path="res://scripts/debug_log/debug_log.gd" id="2_lgt6s"]
[ext_resource type="FontFile" uid="uid://c14w1y1r54wgi" path="res://assets/fonts/Inter-Bold.otf" id="3_w27g3"]
[ext_resource type="FontFile" uid="uid://b3xb1fpllhnf4" path="res://assets/fonts/Inter-Italic.otf" id="4_jcerd"]
[ext_resource type="FontFile" uid="uid://tfj3o1e1wytn" path="res://assets/fonts/Inter-BoldItalic.otf" id="5_jgvml"]
diff --git a/app/scenes/menu.tscn b/app/scenes/menu.tscn
index 174d4df..5dbae4f 100644
--- a/app/scenes/menu.tscn
+++ b/app/scenes/menu.tscn
@@ -34,7 +34,6 @@ content_margin_bottom = 0.0
color = Color(0.12549, 0.133333, 0.172549, 1)
grow_begin = 0.0
grow_end = 0.0
-thickness = 2
[sub_resource type="Animation" id="Animation_ydijj"]
length = 0.001
diff --git a/app/scenes/menu_body/bookmarks.tscn b/app/scenes/menu_body/bookmarks.tscn
deleted file mode 100644
index 32209d6..0000000
--- a/app/scenes/menu_body/bookmarks.tscn
+++ /dev/null
@@ -1,30 +0,0 @@
-[gd_scene load_steps=4 format=3 uid="uid://pgl3w7q5w84m"]
-
-[ext_resource type="Script" path="res://scripts/ui/menu/bookmark_container.gd" id="1_vspm3"]
-[ext_resource type="Resource" uid="uid://bewhdj6jugt6q" path="res://resources/bookmarks.tres" id="2_g2k3b"]
-[ext_resource type="PackedScene" uid="uid://82ca8so31njy" path="res://scenes/components/bookmark.tscn" id="3_dyxu5"]
-
-[node name="Bookmarks" type="ScrollContainer"]
-custom_minimum_size = Vector2(1200, 400)
-anchors_preset = 8
-anchor_left = 0.5
-anchor_top = 0.5
-anchor_right = 0.5
-anchor_bottom = 0.5
-offset_top = -100.0
-offset_bottom = 100.0
-grow_horizontal = 2
-grow_vertical = 2
-follow_focus = true
-horizontal_scroll_mode = 0
-
-[node name="GridContainer" type="GridContainer" parent="."]
-layout_mode = 2
-size_flags_horizontal = 3
-size_flags_vertical = 3
-theme_override_constants/h_separation = 70
-theme_override_constants/v_separation = 40
-columns = 6
-script = ExtResource("1_vspm3")
-bookmarks = ExtResource("2_g2k3b")
-bookmark_scene = ExtResource("3_dyxu5")
diff --git a/app/scenes/menu_body/home.tscn b/app/scenes/menu_body/home.tscn
new file mode 100644
index 0000000..147c506
--- /dev/null
+++ b/app/scenes/menu_body/home.tscn
@@ -0,0 +1,97 @@
+[gd_scene load_steps=6 format=3 uid="uid://ca647gp63bshc"]
+
+[ext_resource type="Texture2D" uid="uid://bw1cffhlt112i" path="res://assets/textures/icon-round.svg" id="1_dh3vr"]
+[ext_resource type="Script" path="res://scripts/ui/menu/bookmark_container.gd" id="1_g38mt"]
+[ext_resource type="Resource" uid="uid://bewhdj6jugt6q" path="res://resources/bookmarks.tres" id="2_2igc6"]
+[ext_resource type="Script" path="res://addons/max_size_container/max_size_container.gd" id="2_ceb6w"]
+[ext_resource type="PackedScene" uid="uid://82ca8so31njy" path="res://scenes/components/bookmark.tscn" id="3_isdis"]
+
+[node name="Home" type="Control"]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="ScrollContainer" type="ScrollContainer" parent="."]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+size_flags_horizontal = 3
+follow_focus = true
+horizontal_scroll_mode = 0
+
+[node name="VBoxContainer" type="VBoxContainer" parent="ScrollContainer"]
+clip_contents = true
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+
+[node name="SpaceTop" type="Control" parent="ScrollContainer/VBoxContainer"]
+custom_minimum_size = Vector2(0, 240)
+layout_mode = 2
+size_flags_vertical = 3
+
+[node name="TextureRect" type="TextureRect" parent="ScrollContainer/VBoxContainer/SpaceTop"]
+layout_mode = 1
+anchors_preset = 7
+anchor_left = 0.5
+anchor_top = 1.0
+anchor_right = 0.5
+anchor_bottom = 1.0
+offset_left = -40.0
+offset_top = -180.0
+offset_right = 40.0
+offset_bottom = -100.0
+grow_horizontal = 2
+grow_vertical = 0
+texture = ExtResource("1_dh3vr")
+expand_mode = 1
+
+[node name="HBoxContainer" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+
+[node name="SpaceLeft" type="Control" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
+custom_minimum_size = Vector2(200, 0)
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="MaxSizeContainer" type="MarginContainer" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
+custom_minimum_size = Vector2(200, 400)
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_stretch_ratio = 3.0
+theme_override_constants/margin_left = 0
+theme_override_constants/margin_top = 0
+theme_override_constants/margin_right = 0
+theme_override_constants/margin_bottom = 0
+script = ExtResource("2_ceb6w")
+limit = Vector2(1200, -1)
+valign = 0
+
+[node name="Bookmarks" type="HFlowContainer" parent="ScrollContainer/VBoxContainer/HBoxContainer/MaxSizeContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+theme_override_constants/h_separation = 70
+theme_override_constants/v_separation = 40
+alignment = 1
+last_wrap_alignment = 1
+script = ExtResource("1_g38mt")
+bookmarks = ExtResource("2_2igc6")
+bookmark_scene = ExtResource("3_isdis")
+
+[node name="SpaceRight" type="Control" parent="ScrollContainer/VBoxContainer/HBoxContainer"]
+custom_minimum_size = Vector2(200, 0)
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="SpaceBottom" type="Control" parent="ScrollContainer/VBoxContainer"]
+custom_minimum_size = Vector2(0, 120)
+layout_mode = 2
+size_flags_vertical = 3
diff --git a/app/scripts/app.gd b/app/scripts/app.gd
index 6b2f714..e162817 100644
--- a/app/scripts/app.gd
+++ b/app/scripts/app.gd
@@ -1,7 +1,7 @@
extends Node
@export var gate_events: GateEvents
-@export var bookmarks: PackedScene
+@export var home: PackedScene
@export var search_results: PackedScene
@export var world_scene: PackedScene
@export var scenes_root: Node
@@ -10,9 +10,9 @@ extends Node
func _ready() -> void:
gate_events.search.connect(func(_query): switch_scene(search_results))
gate_events.open_gate.connect(func(_url): switch_scene(world_scene))
- gate_events.exit_gate.connect(func(): switch_scene(bookmarks))
+ gate_events.exit_gate.connect(func(): switch_scene(home))
- switch_scene(bookmarks)
+ switch_scene(home)
func switch_scene(scene: PackedScene) -> void:
diff --git a/app/scripts/debug-log/debug.gd b/app/scripts/debug_log/debug.gd
similarity index 100%
rename from app/scripts/debug-log/debug.gd
rename to app/scripts/debug_log/debug.gd
diff --git a/app/scripts/debug-log/debug_log.gd b/app/scripts/debug_log/debug_log.gd
similarity index 100%
rename from app/scripts/debug-log/debug_log.gd
rename to app/scripts/debug_log/debug_log.gd
diff --git a/app/scripts/debug-log/debug_window.gd b/app/scripts/debug_log/debug_window.gd
similarity index 100%
rename from app/scripts/debug-log/debug_window.gd
rename to app/scripts/debug_log/debug_window.gd
diff --git a/app/scripts/ui/menu/bookmark_container.gd b/app/scripts/ui/menu/bookmark_container.gd
index 5d2b32a..df405f6 100644
--- a/app/scripts/ui/menu/bookmark_container.gd
+++ b/app/scripts/ui/menu/bookmark_container.gd
@@ -1,4 +1,4 @@
-extends GridContainer
+extends HFlowContainer
@export var bookmarks: Bookmarks
@export var bookmark_scene: PackedScene
diff --git a/app/scripts/ui/menu/menu.gd b/app/scripts/ui/menu/menu.gd
index 96559bd..4eb7d81 100644
--- a/app/scripts/ui/menu/menu.gd
+++ b/app/scripts/ui/menu/menu.gd
@@ -2,10 +2,17 @@ extends Control
@export var ui_events: UiEvents
+var window: Window
+
func _ready() -> void:
+ window = get_window()
+
+ window.dpi_changed.connect(scale_content)
resized.connect(on_resized)
+
set_initial_screen()
+ scale_content()
on_resized()
@@ -14,6 +21,13 @@ func on_resized() -> void:
ui_events.ui_size_changed_emit(size)
+func scale_content() -> void:
+ # TODO: support other platforms FEATURE_HIDPI
+ var screen_scale = DisplayServer.screen_get_scale()
+ get_window().content_scale_factor = screen_scale
+ Debug.logclr("Content scale factor: %.2f" % [screen_scale], Debug.SILENT_CLR)
+
+
func set_initial_screen() -> void:
var last_screen = DataSaver.get_value("settings", "last_screen")
if last_screen == null: last_screen = 0
@@ -24,12 +38,8 @@ func set_initial_screen() -> void:
if Platform.is_macos():
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
Debug.logclr("Setting fullscreen mode", Debug.SILENT_CLR)
-
- var screen_scale = DisplayServer.screen_get_scale()
- get_window().content_scale_factor = screen_scale
- Debug.logclr("Content scale factor: %.2f" % [screen_scale], Debug.SILENT_CLR)
func _exit_tree() -> void:
- var last_screen = DisplayServer.window_get_current_screen()
- DataSaver.set_value("settings", "last_screen", last_screen)
+ var last_screen = DisplayServer.window_get_current_screen()
+ DataSaver.set_value("settings", "last_screen", last_screen)