diff --git a/flumi/Scenes/BrowserMenus/history.tscn b/flumi/Scenes/BrowserMenus/history.tscn index 67fc4c5..e182a5d 100644 --- a/flumi/Scenes/BrowserMenus/history.tscn +++ b/flumi/Scenes/BrowserMenus/history.tscn @@ -1,11 +1,43 @@ [gd_scene load_steps=15 format=3 uid="uid://cn24pafwdpb1q"] -[ext_resource type="Texture2D" uid="uid://ctpe0lbehepen" path="res://Assets/gurted.svg" id="1_occ3h"] [ext_resource type="Script" uid="uid://ektopbvnhfga" path="res://Scripts/history.gd" id="1_yn8i4"] [ext_resource type="PackedScene" uid="uid://3smiker6ni50" path="res://Scenes/BrowserMenus/history_entry.tscn" id="2_a5287"] [ext_resource type="Texture2D" uid="uid://gq8g7t4s3ryg" path="res://Assets/Icons/x.svg" id="2_ijpe2"] [ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="3_yoadi"] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yoadi"] +content_margin_left = 15.0 +content_margin_top = 15.0 +content_margin_right = 15.0 +content_margin_bottom = 15.0 +bg_color = Color(0.105882, 0.105882, 0.105882, 1) +corner_radius_top_left = 30 +corner_radius_top_right = 30 +corner_radius_bottom_right = 30 +corner_radius_bottom_left = 30 + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8gbba"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8gbba"] +bg_color = Color(0.168627, 0.168627, 0.168627, 1) +corner_radius_top_left = 15 +corner_radius_top_right = 15 +corner_radius_bottom_right = 15 +corner_radius_bottom_left = 15 +expand_margin_left = 40.0 + +[sub_resource type="Theme" id="Theme_ijpe2"] +LineEdit/styles/focus = SubResource("StyleBoxEmpty_8gbba") +LineEdit/styles/normal = SubResource("StyleBoxFlat_8gbba") + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a5287"] +content_margin_left = 10.0 +bg_color = Color(0.219501, 0.219501, 0.219501, 1) +corner_radius_top_left = 15 +corner_radius_top_right = 15 +corner_radius_bottom_right = 15 +corner_radius_bottom_left = 15 + [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ijpe2"] content_margin_left = 15.0 content_margin_top = 5.0 @@ -43,78 +75,42 @@ corner_radius_top_right = 25 corner_radius_bottom_right = 25 corner_radius_bottom_left = 25 -[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8gbba"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8gbba"] -bg_color = Color(0.168627, 0.168627, 0.168627, 1) -corner_radius_top_left = 15 -corner_radius_top_right = 15 -corner_radius_bottom_right = 15 -corner_radius_bottom_left = 15 -expand_margin_left = 40.0 - -[sub_resource type="Theme" id="Theme_ijpe2"] -LineEdit/styles/focus = SubResource("StyleBoxEmpty_8gbba") -LineEdit/styles/normal = SubResource("StyleBoxFlat_8gbba") - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a5287"] -content_margin_left = 10.0 -bg_color = Color(0.219501, 0.219501, 0.219501, 1) -corner_radius_top_left = 15 -corner_radius_top_right = 15 -corner_radius_bottom_right = 15 -corner_radius_bottom_left = 15 - [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yn8i4"] content_margin_left = 15.0 content_margin_top = 15.0 content_margin_right = 15.0 content_margin_bottom = 5.0 -bg_color = Color(0.105882, 0.105882, 0.105882, 1) +bg_color = Color(0.154876, 0.154876, 0.154876, 1) corner_radius_top_left = 15 corner_radius_top_right = 15 corner_radius_bottom_right = 15 corner_radius_bottom_left = 15 -[node name="History" type="MarginContainer"] -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 20 -theme_override_constants/margin_top = 20 -theme_override_constants/margin_right = 20 +[node name="PopupPanel" type="PopupPanel"] +initial_position = 1 +size = Vector2i(760, 710) +visible = true +theme_override_styles/panel = SubResource("StyleBoxFlat_yoadi") script = ExtResource("1_yn8i4") -[node name="Control" type="Control" parent="."] -custom_minimum_size = Vector2(400, 100) -layout_mode = 2 - -[node name="TextureRect" type="TextureRect" parent="Control"] -layout_mode = 1 -offset_right = 417.0 -offset_bottom = 417.0 -scale = Vector2(0.105, 0.105) -texture = ExtResource("1_occ3h") -stretch_mode = 2 - -[node name="RichTextLabel" type="RichTextLabel" parent="Control"] -layout_mode = 0 -offset_left = 50.0 -offset_top = 9.0 -offset_right = 339.0 -offset_bottom = 85.0 -theme_override_font_sizes/bold_font_size = 26 -bbcode_enabled = true -text = "[b]History[/b]" - [node name="Main" type="VBoxContainer" parent="."] custom_minimum_size = Vector2(600, 0) -layout_mode = 2 +offset_left = 15.0 +offset_top = 15.0 +offset_right = 745.0 +offset_bottom = 695.0 size_flags_horizontal = 4 theme_override_constants/separation = 15 +[node name="LineEdit" type="LineEdit" parent="Main"] +custom_minimum_size = Vector2(0, 45) +layout_mode = 2 +size_flags_horizontal = 3 +theme = SubResource("Theme_ijpe2") +theme_override_styles/normal = SubResource("StyleBoxFlat_a5287") +placeholder_text = "Search history..." +caret_blink = true + [node name="DeleteMenu" type="PanelContainer" parent="Main"] visible = false layout_mode = 2 @@ -149,24 +145,13 @@ theme_override_styles/hover = SubResource("StyleBoxFlat_a8gu8") theme_override_styles/normal = SubResource("StyleBoxFlat_31fx5") text = "Delete" -[node name="LineEdit" type="LineEdit" parent="Main"] -custom_minimum_size = Vector2(0, 45) -layout_mode = 2 -size_flags_horizontal = 3 -theme = SubResource("Theme_ijpe2") -theme_override_styles/normal = SubResource("StyleBoxFlat_a5287") -placeholder_text = "Search history..." -caret_blink = true - -[node name="HSeparator" type="HSeparator" parent="Main"] -layout_mode = 2 - [node name="PanelContainer2" type="PanelContainer" parent="Main"] layout_mode = 2 size_flags_vertical = 3 theme_override_styles/panel = SubResource("StyleBoxFlat_yn8i4") [node name="ScrollContainer" type="ScrollContainer" parent="Main/PanelContainer2"] +custom_minimum_size = Vector2(700, 500) layout_mode = 2 size_flags_vertical = 3 @@ -174,7 +159,6 @@ size_flags_vertical = 3 layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 -alignment = 1 [node name="HistoryEntry" parent="Main/PanelContainer2/ScrollContainer/HistoryEntryContainer" instance=ExtResource("2_a5287")] layout_mode = 2 @@ -322,5 +306,3 @@ layout_mode = 2 [node name="HistoryEntry49" parent="Main/PanelContainer2/ScrollContainer/HistoryEntryContainer" instance=ExtResource("2_a5287")] layout_mode = 2 - -[connection signal="pressed" from="Main/DeleteMenu/HBoxContainer/CancelButton" to="." method="_on_cancel_button_pressed"] diff --git a/flumi/Scenes/BrowserMenus/history_entry.tscn b/flumi/Scenes/BrowserMenus/history_entry.tscn index 6cc6f91..b970660 100644 --- a/flumi/Scenes/BrowserMenus/history_entry.tscn +++ b/flumi/Scenes/BrowserMenus/history_entry.tscn @@ -30,13 +30,23 @@ layout_mode = 2 [node name="TextureRect" type="TextureRect" parent="."] custom_minimum_size = Vector2(24, 24) layout_mode = 2 +size_flags_horizontal = 0 +size_flags_vertical = 4 texture = ExtResource("2_k4hqm") -stretch_mode = 3 +expand_mode = 1 +stretch_mode = 5 [node name="RichTextLabel2" type="RichTextLabel" parent="."] -custom_minimum_size = Vector2(350, 0) +custom_minimum_size = Vector2(300, 0) layout_mode = 2 text = "Selection - Google Fonts" vertical_alignment = 1 +[node name="DomainLabel" type="RichTextLabel" parent="."] +custom_minimum_size = Vector2(150, 0) +layout_mode = 2 +theme_override_colors/default_color = Color(0.817521, 0.817521, 0.817521, 1) +text = "example.com" +vertical_alignment = 1 + [connection signal="toggled" from="CheckBox" to="." method="_on_check_box_toggled"] diff --git a/flumi/Scenes/DevTools.tscn b/flumi/Scenes/DevTools.tscn index 5027a85..5e03c7e 100644 --- a/flumi/Scenes/DevTools.tscn +++ b/flumi/Scenes/DevTools.tscn @@ -1,11 +1,13 @@ -[gd_scene load_steps=26 format=3 uid="uid://cgav3xl2xgupb"] +[gd_scene load_steps=31 format=3 uid="uid://cgav3xl2xgupb"] [ext_resource type="Script" uid="uid://vrobqac6makc" path="res://Scripts/DevToolsConsole.gd" id="2_3m6n9"] +[ext_resource type="Texture2D" uid="uid://gq8g7t4s3ryg" path="res://Assets/Icons/x.svg" id="2_pqhy6"] [ext_resource type="Texture2D" uid="uid://custohlvwclqs" path="res://Assets/Icons/eraser.svg" id="3_6hj4c"] [ext_resource type="Texture2D" uid="uid://cqg4eny0nyojd" path="res://Assets/Icons/funnel.svg" id="4_ynqb1"] [ext_resource type="SyntaxHighlighter" uid="uid://d0aeuvwp0545i" path="res://Resources/LuaSyntaxHighlighter.tres" id="5_xkykt"] [ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="6_8muo7"] [ext_resource type="Script" uid="uid://dh3jdrot4r7m3" path="res://Scripts/NetworkTab.gd" id="7_network"] +[ext_resource type="Script" uid="uid://21a6ds271vmb" path="res://Scripts/DevTools.gd" id="25_devtools"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6hj4c"] @@ -172,11 +174,38 @@ corner_radius_bottom_left = 8 content_margin_top = 5.0 bg_color = Color(0.105882, 0.105882, 0.105882, 1) -[node name="DevTools" type="VBoxContainer"] -custom_minimum_size = Vector2(495, 400) -size_flags_vertical = 3 +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_apu5o"] -[node name="TabContainer" type="TabContainer" parent="."] +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dbrn0"] +bg_color = Color(0.168627, 0.168627, 0.168627, 1) +corner_radius_top_left = 50 +corner_radius_top_right = 50 +corner_radius_bottom_right = 50 +corner_radius_bottom_left = 50 + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_heash"] +bg_color = Color(0.6, 0.6, 0.6, 0) +draw_center = false + +[node name="Control" type="Control"] +custom_minimum_size = Vector2(495, 400) +layout_mode = 3 +anchors_preset = 0 +size_flags_vertical = 3 +script = ExtResource("25_devtools") + +[node name="DevTools" type="VBoxContainer" parent="."] +custom_minimum_size = Vector2(495, 400) +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_vertical = 3 +theme_override_constants/separation = 0 + +[node name="TabContainer" type="TabContainer" parent="DevTools"] custom_minimum_size = Vector2(300, 0) layout_mode = 2 size_flags_vertical = 3 @@ -191,7 +220,7 @@ tab_alignment = 1 current_tab = 1 drag_to_rearrange_enabled = true -[node name="Elements" type="Label" parent="TabContainer"] +[node name="Elements" type="Label" parent="DevTools/TabContainer"] visible = false layout_mode = 2 text = "Elements tab - Coming soon" @@ -199,16 +228,16 @@ horizontal_alignment = 1 vertical_alignment = 1 metadata/_tab_index = 0 -[node name="Console" type="VBoxContainer" parent="TabContainer"] +[node name="Console" type="VBoxContainer" parent="DevTools/TabContainer"] layout_mode = 2 script = ExtResource("2_3m6n9") metadata/_tab_index = 1 -[node name="Toolbar" type="HBoxContainer" parent="TabContainer/Console"] +[node name="Toolbar" type="HBoxContainer" parent="DevTools/TabContainer/Console"] layout_mode = 2 theme_override_constants/separation = 8 -[node name="ClearButton" type="Button" parent="TabContainer/Console/Toolbar"] +[node name="ClearButton" type="Button" parent="DevTools/TabContainer/Console/Toolbar"] custom_minimum_size = Vector2(32, 32) layout_mode = 2 theme_override_constants/icon_max_width = 20 @@ -219,7 +248,7 @@ theme_override_styles/normal = SubResource("StyleBoxFlat_dderp") icon = ExtResource("3_6hj4c") icon_alignment = 1 -[node name="LineEdit" type="LineEdit" parent="TabContainer/Console/Toolbar"] +[node name="LineEdit" type="LineEdit" parent="DevTools/TabContainer/Console/Toolbar"] layout_mode = 2 size_flags_horizontal = 3 theme_override_styles/focus = SubResource("StyleBoxFlat_ko37l") @@ -227,29 +256,29 @@ theme_override_styles/normal = SubResource("StyleBoxFlat_65n6c") placeholder_text = "Filter" right_icon = ExtResource("4_ynqb1") -[node name="Spacer2" type="Control" parent="TabContainer/Console"] +[node name="Spacer2" type="Control" parent="DevTools/TabContainer/Console"] custom_minimum_size = Vector2(0, 15) layout_mode = 2 -[node name="ScrollContainer" type="ScrollContainer" parent="TabContainer/Console"] +[node name="ScrollContainer" type="ScrollContainer" parent="DevTools/TabContainer/Console"] custom_minimum_size = Vector2(0, 200) layout_mode = 2 size_flags_vertical = 3 -[node name="LogContainer" type="VBoxContainer" parent="TabContainer/Console/ScrollContainer"] +[node name="LogContainer" type="VBoxContainer" parent="DevTools/TabContainer/Console/ScrollContainer"] layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 -[node name="Spacer" type="Control" parent="TabContainer/Console"] +[node name="Spacer" type="Control" parent="DevTools/TabContainer/Console"] custom_minimum_size = Vector2(0, 15) layout_mode = 2 -[node name="InputContainer" type="HBoxContainer" parent="TabContainer/Console"] +[node name="InputContainer" type="HBoxContainer" parent="DevTools/TabContainer/Console"] layout_mode = 2 theme_override_constants/separation = 4 -[node name="InputLine" type="CodeEdit" parent="TabContainer/Console/InputContainer"] +[node name="InputLine" type="CodeEdit" parent="DevTools/TabContainer/Console/InputContainer"] clip_contents = false custom_minimum_size = Vector2(0, 35) layout_mode = 2 @@ -267,9 +296,9 @@ gutters_draw_line_numbers = true auto_brace_completion_enabled = true auto_brace_completion_highlight_matching = true -[node name="PositioningTimer" type="Timer" parent="TabContainer/Console/InputContainer"] +[node name="PositioningTimer" type="Timer" parent="DevTools/TabContainer/Console/InputContainer"] -[node name="Sources" type="Label" parent="TabContainer"] +[node name="Sources" type="Label" parent="DevTools/TabContainer"] visible = false layout_mode = 2 text = "Sources tab - Coming soon" @@ -277,36 +306,36 @@ horizontal_alignment = 1 vertical_alignment = 1 metadata/_tab_index = 2 -[node name="Network" type="VBoxContainer" parent="TabContainer"] +[node name="Network" type="VBoxContainer" parent="DevTools/TabContainer"] visible = false layout_mode = 2 script = ExtResource("7_network") metadata/_tab_index = 3 -[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Network"] +[node name="HBoxContainer" type="HBoxContainer" parent="DevTools/TabContainer/Network"] layout_mode = 2 -[node name="StatusBar" type="HBoxContainer" parent="TabContainer/Network/HBoxContainer"] +[node name="StatusBar" type="HBoxContainer" parent="DevTools/TabContainer/Network/HBoxContainer"] layout_mode = 2 theme_override_constants/separation = 16 -[node name="RequestCount" type="Label" parent="TabContainer/Network/HBoxContainer/StatusBar"] +[node name="RequestCount" type="Label" parent="DevTools/TabContainer/Network/HBoxContainer/StatusBar"] layout_mode = 2 text = "0 requests" -[node name="Transfer" type="Label" parent="TabContainer/Network/HBoxContainer/StatusBar"] +[node name="Transfer" type="Label" parent="DevTools/TabContainer/Network/HBoxContainer/StatusBar"] layout_mode = 2 text = "0 B transferred" -[node name="Loaded" type="Label" parent="TabContainer/Network/HBoxContainer/StatusBar"] +[node name="Loaded" type="Label" parent="DevTools/TabContainer/Network/HBoxContainer/StatusBar"] layout_mode = 2 text = "0 resources loaded" -[node name="Control" type="Control" parent="TabContainer/Network/HBoxContainer"] +[node name="Control" type="Control" parent="DevTools/TabContainer/Network/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 -[node name="FilterDropdown" type="OptionButton" parent="TabContainer/Network/HBoxContainer"] +[node name="FilterDropdown" type="OptionButton" parent="DevTools/TabContainer/Network/HBoxContainer"] unique_name_in_owner = true layout_mode = 2 theme = ExtResource("6_8muo7") @@ -339,34 +368,34 @@ popup/item_7/id = 7 popup/item_8/text = "Other" popup/item_8/id = 8 -[node name="HSeparator2" type="HSeparator" parent="TabContainer/Network"] +[node name="HSeparator2" type="HSeparator" parent="DevTools/TabContainer/Network"] layout_mode = 2 theme_override_constants/separation = 14 -[node name="MainContainer" type="HSplitContainer" parent="TabContainer/Network"] +[node name="MainContainer" type="HSplitContainer" parent="DevTools/TabContainer/Network"] layout_mode = 2 size_flags_vertical = 3 -[node name="LeftPanel" type="VBoxContainer" parent="TabContainer/Network/MainContainer"] +[node name="LeftPanel" type="VBoxContainer" parent="DevTools/TabContainer/Network/MainContainer"] layout_mode = 2 -[node name="HeaderRow" type="HBoxContainer" parent="TabContainer/Network/MainContainer/LeftPanel"] +[node name="HeaderRow" type="HBoxContainer" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel"] custom_minimum_size = Vector2(0, 28) layout_mode = 2 theme_override_constants/separation = 8 -[node name="IconHeader" type="Control" parent="TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] +[node name="IconHeader" type="Control" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] custom_minimum_size = Vector2(25, 20) layout_mode = 2 -[node name="NameHeader" type="Label" parent="TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] +[node name="NameHeader" type="Label" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] custom_minimum_size = Vector2(120, 0) layout_mode = 2 size_flags_horizontal = 3 text = "Name" vertical_alignment = 1 -[node name="StatusHeader" type="Label" parent="TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] +[node name="StatusHeader" type="Label" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] unique_name_in_owner = true custom_minimum_size = Vector2(60, 0) layout_mode = 2 @@ -374,7 +403,7 @@ text = "Status" horizontal_alignment = 1 vertical_alignment = 1 -[node name="TypeHeader" type="Label" parent="TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] +[node name="TypeHeader" type="Label" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] unique_name_in_owner = true custom_minimum_size = Vector2(60, 0) layout_mode = 2 @@ -382,7 +411,7 @@ text = "Type" horizontal_alignment = 1 vertical_alignment = 1 -[node name="SizeHeader" type="Label" parent="TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] +[node name="SizeHeader" type="Label" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] unique_name_in_owner = true custom_minimum_size = Vector2(50, 0) layout_mode = 2 @@ -390,7 +419,7 @@ text = "Size" horizontal_alignment = 2 vertical_alignment = 1 -[node name="TimeHeader" type="Label" parent="TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] +[node name="TimeHeader" type="Label" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/HeaderRow"] unique_name_in_owner = true custom_minimum_size = Vector2(80, 0) layout_mode = 2 @@ -398,31 +427,31 @@ text = "Time" horizontal_alignment = 2 vertical_alignment = 1 -[node name="ScrollContainer" type="ScrollContainer" parent="TabContainer/Network/MainContainer/LeftPanel"] +[node name="ScrollContainer" type="ScrollContainer" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel"] layout_mode = 2 size_flags_vertical = 3 -[node name="RequestList" type="VBoxContainer" parent="TabContainer/Network/MainContainer/LeftPanel/ScrollContainer"] +[node name="RequestList" type="VBoxContainer" parent="DevTools/TabContainer/Network/MainContainer/LeftPanel/ScrollContainer"] layout_mode = 2 size_flags_horizontal = 3 -[node name="RightPanel" type="VBoxContainer" parent="TabContainer/Network/MainContainer"] +[node name="RightPanel" type="VBoxContainer" parent="DevTools/TabContainer/Network/MainContainer"] visible = false custom_minimum_size = Vector2(300, 0) layout_mode = 2 size_flags_horizontal = 3 -[node name="PanelContainer" type="PanelContainer" parent="TabContainer/Network/MainContainer/RightPanel"] +[node name="PanelContainer" type="PanelContainer" parent="DevTools/TabContainer/Network/MainContainer/RightPanel"] layout_mode = 2 size_flags_vertical = 3 theme_override_styles/panel = SubResource("StyleBoxFlat_6hj4c") -[node name="HBoxContainer" type="HBoxContainer" parent="TabContainer/Network/MainContainer/RightPanel/PanelContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer"] layout_mode = 2 size_flags_vertical = 3 theme_override_constants/separation = 0 -[node name="CloseButton" type="Button" parent="TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer"] +[node name="CloseButton" type="Button" parent="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(32, 32) layout_mode = 2 @@ -432,7 +461,7 @@ theme_override_styles/focus = SubResource("StyleBoxEmpty_xkykt") text = "✕" flat = true -[node name="TabContainer" type="TabContainer" parent="TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer"] +[node name="TabContainer" type="TabContainer" parent="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 @@ -445,21 +474,21 @@ theme_override_styles/tab_hovered = SubResource("StyleBoxFlat_8muo7") theme_override_styles/tab_unselected = SubResource("StyleBoxFlat_xkykt") current_tab = 0 -[node name="Headers" type="VBoxContainer" parent="TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/TabContainer"] +[node name="Headers" type="VBoxContainer" parent="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/TabContainer"] layout_mode = 2 metadata/_tab_index = 0 -[node name="Preview" type="VBoxContainer" parent="TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/TabContainer"] +[node name="Preview" type="VBoxContainer" parent="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/TabContainer"] visible = false layout_mode = 2 metadata/_tab_index = 1 -[node name="Response" type="VBoxContainer" parent="TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/TabContainer"] +[node name="Response" type="VBoxContainer" parent="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/TabContainer"] visible = false layout_mode = 2 metadata/_tab_index = 2 -[node name="Application" type="Label" parent="TabContainer"] +[node name="Application" type="Label" parent="DevTools/TabContainer"] visible = false layout_mode = 2 text = "Application tab - Coming soon" @@ -467,5 +496,20 @@ horizontal_alignment = 1 vertical_alignment = 1 metadata/_tab_index = 4 -[connection signal="item_selected" from="TabContainer/Network/HBoxContainer/FilterDropdown" to="TabContainer/Network" method="_on_filter_selected"] -[connection signal="pressed" from="TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/CloseButton" to="TabContainer/Network" method="hide_details_panel"] +[node name="CloseButton" type="Button" parent="."] +layout_mode = 2 +offset_left = 9.0 +offset_top = 2.0 +offset_right = 33.0 +offset_bottom = 26.0 +theme_override_styles/focus = SubResource("StyleBoxEmpty_apu5o") +theme_override_styles/hover = SubResource("StyleBoxFlat_dbrn0") +theme_override_styles/pressed = SubResource("StyleBoxFlat_heash") +theme_override_styles/normal = SubResource("StyleBoxFlat_heash") +icon = ExtResource("2_pqhy6") +flat = true +icon_alignment = 1 + +[connection signal="item_selected" from="DevTools/TabContainer/Network/HBoxContainer/FilterDropdown" to="DevTools/TabContainer/Network" method="_on_filter_selected"] +[connection signal="pressed" from="DevTools/TabContainer/Network/MainContainer/RightPanel/PanelContainer/HBoxContainer/CloseButton" to="DevTools/TabContainer/Network" method="hide_details_panel"] +[connection signal="pressed" from="CloseButton" to="." method="_on_close_button_pressed"] diff --git a/flumi/Scenes/main.tscn b/flumi/Scenes/main.tscn index 448f2ee..8169427 100644 --- a/flumi/Scenes/main.tscn +++ b/flumi/Scenes/main.tscn @@ -251,6 +251,7 @@ item_5/id = 5 item_6/text = "Bookmarks (CTRL SHIFT B)" item_6/icon = ExtResource("17_ueoa1") item_6/id = 7 +item_6/disabled = true item_7/id = 7 item_7/separator = true item_8/text = "Help" @@ -283,9 +284,6 @@ theme_override_constants/separation = 22 [node name="HistoryContainer" parent="VBoxContainer/ScrollContainer" instance=ExtResource("24_3pmx8")] visible = false -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 [node name="Panel" type="Panel" parent="."] z_index = -5 @@ -311,6 +309,9 @@ mouse_filter = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_21xkr") [connection signal="pressed" from="VBoxContainer/TabContainer/NewTabButton" to="VBoxContainer/TabContainer" method="_on_new_tab_button_pressed"] +[connection signal="pressed" from="VBoxContainer/HBoxContainer/BackButton" to="." method="_on_back_button_pressed"] +[connection signal="pressed" from="VBoxContainer/HBoxContainer/ForwardButton" to="." method="_on_forward_button_pressed"] +[connection signal="pressed" from="VBoxContainer/HBoxContainer/RefreshButton" to="." method="_on_refresh_button_pressed"] [connection signal="focus_entered" from="VBoxContainer/HBoxContainer/LineEdit" to="." method="_on_search_focus_entered"] [connection signal="focus_exited" from="VBoxContainer/HBoxContainer/LineEdit" to="." method="_on_search_focus_exited"] [connection signal="text_submitted" from="VBoxContainer/HBoxContainer/LineEdit" to="." method="_on_search_submitted"] diff --git a/flumi/Scripts/BrowserHistory.gd b/flumi/Scripts/BrowserHistory.gd new file mode 100644 index 0000000..19788e2 --- /dev/null +++ b/flumi/Scripts/BrowserHistory.gd @@ -0,0 +1,91 @@ +extends Node + +const HISTORY_FILE_PATH = "user://browser_history.json" +const MAX_HISTORY_ENTRIES = 1000 + +func get_history_data() -> Array: + var history_file = FileAccess.open(HISTORY_FILE_PATH, FileAccess.READ) + if not history_file: + return [] + + var json_string = history_file.get_as_text() + history_file.close() + + var json = JSON.new() + var parse_result = json.parse(json_string) + + if parse_result != OK: + return [] + + var history_data = json.data + if not history_data is Array: + return [] + + return history_data + +func save_history_data(history_data: Array): + var history_file = FileAccess.open(HISTORY_FILE_PATH, FileAccess.WRITE) + if not history_file: + push_error("Failed to open history file for writing") + return + + var json_string = JSON.stringify(history_data) + history_file.store_string(json_string) + history_file.close() + +func add_entry(url: String, title: String, icon_url: String = ""): + if url.is_empty(): + return + + var history_data = get_history_data() + var timestamp = Time.get_datetime_string_from_system() + + var existing_index = -1 + for i in range(history_data.size()): + if history_data[i].url == url: + existing_index = i + break + + var entry = { + "url": url, + "title": title, + "timestamp": timestamp, + "icon_url": icon_url + } + + if existing_index >= 0: + history_data.remove_at(existing_index) + + history_data.insert(0, entry) + + if history_data.size() > MAX_HISTORY_ENTRIES: + history_data = history_data.slice(0, MAX_HISTORY_ENTRIES) + + save_history_data(history_data) + +func remove_entry(url: String): + var history_data = get_history_data() + + for i in range(history_data.size() - 1, -1, -1): + if history_data[i].url == url: + history_data.remove_at(i) + + save_history_data(history_data) + +func clear_all(): + save_history_data([]) + +func search_history(query: String) -> Array: + var history_data = get_history_data() + var results = [] + + query = query.to_lower() + + for entry in history_data: + var title = entry.get("title", "").to_lower() + var url = entry.get("url", "").to_lower() + + if title.contains(query) or url.contains(query): + results.append(entry) + + return results diff --git a/flumi/Scripts/BrowserHistory.gd.uid b/flumi/Scripts/BrowserHistory.gd.uid new file mode 100644 index 0000000..ece646f --- /dev/null +++ b/flumi/Scripts/BrowserHistory.gd.uid @@ -0,0 +1 @@ +uid://c8wiwde042pkx diff --git a/flumi/Scripts/DevTools.gd b/flumi/Scripts/DevTools.gd new file mode 100644 index 0000000..191d408 --- /dev/null +++ b/flumi/Scripts/DevTools.gd @@ -0,0 +1,4 @@ +extends Control + +func _on_close_button_pressed(): + Engine.get_main_loop().current_scene._toggle_dev_tools() diff --git a/flumi/Scripts/DevTools.gd.uid b/flumi/Scripts/DevTools.gd.uid new file mode 100644 index 0000000..6e9a6dd --- /dev/null +++ b/flumi/Scripts/DevTools.gd.uid @@ -0,0 +1 @@ +uid://21a6ds271vmb diff --git a/flumi/Scripts/OptionButton.gd b/flumi/Scripts/OptionButton.gd index 10e2a0b..13e6ed5 100644 --- a/flumi/Scripts/OptionButton.gd +++ b/flumi/Scripts/OptionButton.gd @@ -1,10 +1,31 @@ extends Button +const HISTORY = preload("res://Scenes/BrowserMenus/history.tscn") + @onready var tab_container: TabManager = $"../../TabContainer" +@onready var main: Main = $"../../../" + +var history_scene: PopupPanel = null func _on_pressed() -> void: %OptionsMenu.show() +func _input(_event: InputEvent) -> void: + if _event is InputEventKey and _event.pressed and _event.ctrl_pressed: + if _event.keycode == KEY_N: + if _event.shift_pressed: + # CTRL+SHIFT+N - New incognito window + _on_options_menu_id_pressed(2) + get_viewport().set_input_as_handled() + else: + # CTRL+N - New window + _on_options_menu_id_pressed(1) + get_viewport().set_input_as_handled() + elif _event.keycode == KEY_H: + # CTRL+H - History + _on_options_menu_id_pressed(4) + get_viewport().set_input_as_handled() + func _on_options_menu_id_pressed(id: int) -> void: if id == 0: # new tab tab_container.create_tab() @@ -14,4 +35,21 @@ func _on_options_menu_id_pressed(id: int) -> void: # TODO: handle incognito OS.create_process(OS.get_executable_path(), ["--incognito"]) if id == 4: # history - modulate = Constants.SECONDARY_COLOR + show_history() + if id == 10: # exit + get_tree().quit() + +func show_history() -> void: + if history_scene == null: + history_scene = HISTORY.instantiate() + history_scene.navigate_to_url.connect(main.navigate_to_url) + main.add_child(history_scene) + + history_scene.connect("popup_hide", _on_history_closed) + else: + history_scene.load_history() + history_scene.show() + +func _on_history_closed() -> void: + if history_scene: + history_scene.hide() diff --git a/flumi/Scripts/Tab.gd b/flumi/Scripts/Tab.gd index 893da56..2a58f02 100644 --- a/flumi/Scripts/Tab.gd +++ b/flumi/Scripts/Tab.gd @@ -41,6 +41,8 @@ var dev_tools_visible: bool = false var lua_apis: Array[LuaAPI] = [] var current_url: String = "" var has_content: bool = false +var navigation_history: Array[String] = [] +var history_index: int = -1 func _ready(): add_to_group("tabs") @@ -70,8 +72,11 @@ func update_icon_from_url(icon_url: String) -> void: if icon_url.is_empty(): const GLOBE_ICON = preload("res://Assets/Icons/globe.svg") set_icon(GLOBE_ICON) + remove_meta("original_icon_url") return + set_meta("original_icon_url", icon_url) + var icon_resource = await Network.fetch_image(icon_url) if is_instance_valid(self) and icon_resource: @@ -252,3 +257,39 @@ func get_dev_tools_console() -> DevToolsConsole: if dev_tools and dev_tools.has_method("get_console"): return dev_tools.get_console() return null + +func add_to_navigation_history(url: String) -> void: + if url.is_empty(): + return + + # If we're not at the end of history, remove everything after current position + if history_index < navigation_history.size() - 1: + navigation_history = navigation_history.slice(0, history_index + 1) + + # Don't add duplicate consecutive entries + if navigation_history.is_empty() or navigation_history[-1] != url: + navigation_history.append(url) + history_index = navigation_history.size() - 1 + +func can_go_back() -> bool: + return history_index > 0 + +func can_go_forward() -> bool: + return history_index < navigation_history.size() - 1 + +func go_back() -> String: + if can_go_back(): + history_index -= 1 + return navigation_history[history_index] + return "" + +func go_forward() -> String: + if can_go_forward(): + history_index += 1 + return navigation_history[history_index] + return "" + +func get_current_history_url() -> String: + if history_index >= 0 and history_index < navigation_history.size(): + return navigation_history[history_index] + return "" diff --git a/flumi/Scripts/TabContainer.gd b/flumi/Scripts/TabContainer.gd index c647d80..65881d7 100644 --- a/flumi/Scripts/TabContainer.gd +++ b/flumi/Scripts/TabContainer.gd @@ -205,6 +205,8 @@ func set_active_tab(index: int) -> void: main.current_domain = "" main.search_bar.text = "" main.search_bar.grab_focus() + + main.update_navigation_buttons() func create_tab() -> void: var index = tabs.size(); diff --git a/flumi/Scripts/Utils/URLUtils.gd b/flumi/Scripts/Utils/URLUtils.gd index 9a15dcc..cb3f9f5 100644 --- a/flumi/Scripts/Utils/URLUtils.gd +++ b/flumi/Scripts/Utils/URLUtils.gd @@ -65,3 +65,21 @@ static func resolve_url(base_url: String, relative_url: String) -> String: result += "/" + "/".join(final_path_parts) return result + +static func extract_domain(url: String) -> String: + if url.is_empty(): + return "" + + var clean_url = url + if clean_url.begins_with("gurt://"): + clean_url = clean_url.substr(7) + elif clean_url.begins_with("https://"): + clean_url = clean_url.substr(8) + elif clean_url.begins_with("http://"): + clean_url = clean_url.substr(7) + + var slash_pos = clean_url.find("/") + if slash_pos != -1: + clean_url = clean_url.substr(0, slash_pos) + + return clean_url diff --git a/flumi/Scripts/history.gd b/flumi/Scripts/history.gd index d45676c..d112008 100644 --- a/flumi/Scripts/history.gd +++ b/flumi/Scripts/history.gd @@ -1,16 +1,20 @@ -extends MarginContainer +extends PopupPanel +signal navigate_to_url(url: String) @onready var history_entry_container: VBoxContainer = $Main/PanelContainer2/ScrollContainer/HistoryEntryContainer @onready var delete_menu: PanelContainer = $Main/DeleteMenu @onready var line_edit: LineEdit = $Main/LineEdit @onready var entries_label: RichTextLabel = $Main/DeleteMenu/HBoxContainer/RichTextLabel @onready var cancel_button: Button = $Main/DeleteMenu/HBoxContainer/CancelButton +@onready var delete_button: Button = $Main/DeleteMenu/HBoxContainer/DeleteButton var toggled_entries = [] +var history_entry_scene = preload("res://Scenes/BrowserMenus/history_entry.tscn") func _ready(): - for entry in history_entry_container.get_children(): - entry.connect("checkbox_toggle", history_toggle.bind(entry)) + delete_button.pressed.connect(_on_delete_button_pressed) + line_edit.text_changed.connect(_on_search_text_changed) + load_history() func history_toggle(toggled: bool, entry) -> void: print('toggling ', entry, ' to :', toggled) @@ -37,3 +41,80 @@ func _on_cancel_button_pressed() -> void: delete_menu.hide() line_edit.show() + +func _on_delete_button_pressed() -> void: + var urls_to_delete = [] + for entry in toggled_entries: + if entry.has_meta("history_url"): + urls_to_delete.append(entry.get_meta("history_url")) + + for url in urls_to_delete: + remove_history_entry(url) + + var entries_to_remove = toggled_entries.duplicate() + toggled_entries.clear() + + for entry in entries_to_remove: + history_entry_container.remove_child(entry) + entry.queue_free() + + delete_menu.hide() + line_edit.show() + +func _on_search_text_changed(search_text: String) -> void: + filter_history_entries(search_text) + +func load_history(): + var history_data = BrowserHistory.get_history_data() + var existing_entries = history_entry_container.get_children() + + var needs_update = existing_entries.size() != history_data.size() + + if not needs_update and history_data.size() > 0 and existing_entries.size() > 0: + var first_entry = existing_entries[0] + if first_entry.has_meta("history_url"): + var stored_url = first_entry.get_meta("history_url") + if stored_url != history_data[0].url: + needs_update = true + + if needs_update: + clear_displayed_entries() + for entry in history_data: + add_history_entry_to_display(entry.url, entry.title, entry.timestamp, entry.icon_url) + + show() + +func clear_displayed_entries(): + for child in history_entry_container.get_children(): + child.queue_free() + +func add_history_entry_to_display(url: String, title_: String, timestamp: String, icon_url: String = ""): + var entry_instance = history_entry_scene.instantiate() + history_entry_container.add_child(entry_instance) + entry_instance.setup_entry(url, title_, timestamp, icon_url) + entry_instance.connect("checkbox_toggle", history_toggle.bind(entry_instance)) + entry_instance.connect("entry_clicked", _on_entry_clicked) + entry_instance.set_meta("history_url", url) + +func filter_history_entries(search_text: String): + if search_text.is_empty(): + # Show all entries + for child in history_entry_container.get_children(): + child.visible = true + return + + # Filter existing entries by showing/hiding them + var query = search_text.to_lower() + for child in history_entry_container.get_children(): + if child.has_method("get_title") and child.has_method("get_url"): + var title_ = child.get_title().to_lower() + var url = child.get_url().to_lower() + child.visible = title_.contains(query) or url.contains(query) + else: + child.visible = false + +func remove_history_entry(url: String): + BrowserHistory.remove_entry(url) + +func _on_entry_clicked(url: String): + navigate_to_url.emit(url) diff --git a/flumi/Scripts/history_entry.gd b/flumi/Scripts/history_entry.gd index 3d5631c..69e5861 100644 --- a/flumi/Scripts/history_entry.gd +++ b/flumi/Scripts/history_entry.gd @@ -1,10 +1,84 @@ extends HBoxContainer signal checkbox_toggle +signal entry_clicked(url: String) @onready var check_box: CheckBox = $CheckBox +@onready var time_label: RichTextLabel = $RichTextLabel +@onready var icon: TextureRect = $TextureRect +@onready var title_label: RichTextLabel = $RichTextLabel2 +@onready var domain_label: RichTextLabel = $DomainLabel + +var entry_url: String = "" +var entry_title: String = "" func reset() -> void: check_box.set_pressed_no_signal(false) func _on_check_box_toggled(toggled_on: bool) -> void: checkbox_toggle.emit(toggled_on) + +func setup_entry(url: String, title: String, timestamp: String, icon_url: String = ""): + entry_url = url + entry_title = title + + title_label.text = title if not title.is_empty() else url + + var domain = URLUtils.extract_domain(url) + if domain.is_empty(): + domain = url + domain_label.text = domain + + var datetime_dict = Time.get_datetime_dict_from_datetime_string(timestamp, false) + if datetime_dict.has("hour") and datetime_dict.has("minute"): + var hour = datetime_dict.hour + var minute = datetime_dict.minute + var am_pm = "AM" + + if hour == 0: + hour = 12 + elif hour > 12: + hour -= 12 + am_pm = "PM" + elif hour == 12: + am_pm = "PM" + + time_label.text = "%d:%02d%s" % [hour, minute, am_pm] + else: + time_label.text = "" + + if not icon_url.is_empty(): + _load_icon(icon_url) + else: + const GLOBE_ICON = preload("res://Assets/Icons/globe.svg") + icon.texture = GLOBE_ICON + +func _load_icon(icon_url: String): + if icon_url.is_empty(): + const GLOBE_ICON = preload("res://Assets/Icons/globe.svg") + icon.texture = GLOBE_ICON + return + + icon.texture = null + + var icon_resource = await Network.fetch_image(icon_url) + + if is_instance_valid(self) and icon_resource: + icon.texture = icon_resource + elif is_instance_valid(self): + const GLOBE_ICON = preload("res://Assets/Icons/globe.svg") + icon.texture = GLOBE_ICON + +func get_title() -> String: + return entry_title + +func get_url() -> String: + return entry_url + +func _ready(): + title_label.gui_input.connect(_on_title_clicked) + domain_label.gui_input.connect(_on_title_clicked) + +func _on_title_clicked(event: InputEvent): + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + entry_clicked.emit(entry_url) diff --git a/flumi/Scripts/main.gd b/flumi/Scripts/main.gd index 7ab96d4..ff53d7f 100644 --- a/flumi/Scripts/main.gd +++ b/flumi/Scripts/main.gd @@ -4,6 +4,9 @@ extends Control @onready var website_container: Control = %WebsiteContainer @onready var tab_container: TabManager = $VBoxContainer/TabContainer @onready var search_bar: LineEdit = $VBoxContainer/HBoxContainer/LineEdit +@onready var back_button: Button = $VBoxContainer/HBoxContainer/BackButton +@onready var forward_button: Button = $VBoxContainer/HBoxContainer/ForwardButton +@onready var refresh_button: Button = $VBoxContainer/HBoxContainer/RefreshButton const LOADER_CIRCLE = preload("res://Assets/Icons/loader-circle.svg") const AUTO_SIZING_FLEX_CONTAINER = preload("res://Scripts/AutoSizingFlexContainer.gd") @@ -63,6 +66,7 @@ func _ready(): original_scroll.visible = false call_deferred("render") + call_deferred("update_navigation_buttons") func _input(_event: InputEvent) -> void: if Input.is_action_just_pressed("DevTools"): @@ -87,7 +91,7 @@ func handle_link_click(meta: Variant) -> void: else: OS.shell_open(resolved_url) -func _on_search_submitted(url: String) -> void: +func _on_search_submitted(url: String, add_to_history: bool = true) -> void: print("Search submitted: ", url) search_bar.release_focus() @@ -102,11 +106,11 @@ func _on_search_submitted(url: String) -> void: if not gurt_url.begins_with("gurt://"): gurt_url = "gurt://" + gurt_url - await fetch_gurt_content_async(gurt_url, tab, url) + await fetch_gurt_content_async(gurt_url, tab, url, add_to_history) else: print("Non-GURT URL entered: ", url) -func fetch_gurt_content_async(gurt_url: String, tab: Tab, original_url: String) -> void: +func fetch_gurt_content_async(gurt_url: String, tab: Tab, original_url: String, add_to_history: bool = true) -> void: main_navigation_request = NetworkManager.start_request(gurt_url, "GET", false) main_navigation_request.type = NetworkRequest.RequestType.DOC network_start_time = Time.get_ticks_msec() @@ -121,7 +125,7 @@ func fetch_gurt_content_async(gurt_url: String, tab: Tab, original_url: String) var result = thread.wait_to_finish() - _handle_gurt_result(result, tab, original_url, gurt_url) + _handle_gurt_result(result, tab, original_url, gurt_url, add_to_history) func _perform_gurt_request_threaded(request_data: Dictionary) -> Dictionary: var gurt_url: String = request_data.gurt_url @@ -149,7 +153,7 @@ func _perform_gurt_request_threaded(request_data: Dictionary) -> Dictionary: return {"success": true, "html_bytes": response.body} -func _handle_gurt_result(result: Dictionary, tab: Tab, original_url: String, gurt_url: String) -> void: +func _handle_gurt_result(result: Dictionary, tab: Tab, original_url: String, gurt_url: String, add_to_history: bool = true) -> void: if not result.success: print("GURT request failed: ", result.error) handle_gurt_error(result.error, tab) @@ -173,6 +177,11 @@ func _handle_gurt_result(result: Dictionary, tab: Tab, original_url: String, gur main_navigation_request = null tab.stop_loading() + + if add_to_history: + add_to_history(gurt_url, tab) + else: + update_navigation_buttons() func handle_gurt_error(error_message: String, tab: Tab) -> void: var error_html = GurtProtocol.create_error_page(error_message) @@ -301,6 +310,9 @@ func render_content(html_bytes: PackedByteArray) -> void: var icon = parser.get_icon() tab.update_icon_from_url(icon) + if not icon.is_empty(): + tab.set_meta("parsed_icon_url", icon) + var body = parser.find_first("body") if body: @@ -719,9 +731,12 @@ func reload_current_page() -> void: if not current_domain.is_empty(): _on_search_submitted(current_domain) -func navigate_to_url(url: String) -> void: - var resolved_url = resolve_url(url) - _on_search_submitted(resolved_url) +func navigate_to_url(url: String, add_to_history: bool = true) -> void: + if url.begins_with("gurt://"): + _on_search_submitted(url, add_to_history) + else: + var resolved_url = resolve_url(url) + _on_search_submitted(resolved_url, add_to_history) func update_search_bar_from_current_domain() -> void: if not search_bar.has_focus() and not current_domain.is_empty(): @@ -746,3 +761,54 @@ func get_dev_tools_console() -> DevToolsConsole: if active_tab: return active_tab.get_dev_tools_console() return null + +func add_to_history(url: String, tab: Tab, add_to_navigation: bool = true): + if url.is_empty(): + return + + var title = "New Tab" + var icon_url = "" + + if tab: + if add_to_navigation: + tab.add_to_navigation_history(url) + + if tab.button and tab.button.text: + title = tab.button.text + + if tab.has_meta("parsed_icon_url"): + icon_url = tab.get_meta("parsed_icon_url") + + var clean_url = url + if clean_url.begins_with("gurt://"): + clean_url = clean_url.substr(7) + + BrowserHistory.add_entry(clean_url, title, icon_url) + update_navigation_buttons() + +func _on_back_button_pressed() -> void: + var active_tab = get_active_tab() + if active_tab and active_tab.can_go_back(): + var url = active_tab.go_back() + if not url.is_empty(): + navigate_to_url(url, false) + +func _on_forward_button_pressed() -> void: + var active_tab = get_active_tab() + if active_tab and active_tab.can_go_forward(): + var url = active_tab.go_forward() + if not url.is_empty(): + navigate_to_url(url, false) + +func _on_refresh_button_pressed() -> void: + reload_current_page() + +func update_navigation_buttons() -> void: + var active_tab = get_active_tab() + if active_tab: + back_button.disabled = not active_tab.can_go_back() + forward_button.disabled = not active_tab.can_go_forward() + else: + back_button.disabled = true + forward_button.disabled = true + diff --git a/flumi/project.godot b/flumi/project.godot index 69bfd56..ca5fa3b 100644 --- a/flumi/project.godot +++ b/flumi/project.godot @@ -23,6 +23,7 @@ config/icon="uid://ctpe0lbehepen" Constants="*res://Scripts/Constants.gd" Network="*res://Scripts/Network.gd" NetworkManager="*res://Scripts/NetworkManager.gd" +BrowserHistory="*res://Scripts/BrowserHistory.gd" [display]