diff --git a/.gitignore b/.gitignore index 227d7e8..41e7b5c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ export_presets.cfg data_*/ # Godot 4+ specific ignores .godot/ +Bibles/* diff --git a/BibleViwer.gd b/BibleViwer.gd index d5c36b7..0f05067 100644 --- a/BibleViwer.gd +++ b/BibleViwer.gd @@ -4,12 +4,11 @@ const SAVE_FORMAT_VERSION:= 0 @export var chapter_tab:PackedScene +var bible_version:= "nkjv" ## An [Array] of the books of the bible. -var books:= [] +var books:= load_book_names() as Array ## The currently selected chater tab. var current_tab:int = -1 -var to_book:String = "Genesis" -var to_chapter:int = 1 var fuzzy_books:Array = [] var font_size:= 16: set(v): @@ -57,25 +56,18 @@ func _ready() -> void: %PageResolutionY.value ) - # Get books of bible - var outputs:= [] - OS.execute("python3", ["Py/get_books.py"], outputs) - books = outputs[0].split(", ") - books.pop_back() - books = books.map(func(book:String): - book = book.strip_escapes() - return book.substr(0,book.length()-1) - ) - load_settings() + if %ChapterTabs.get_child_count() == 0: + add_tab("Genesis", 1) + func add_tab(book:String, chapter:int) -> CanvasItem: var new_tab:Node = chapter_tab.instantiate() %ChapterTabs.add_child(new_tab) new_tab.book = book new_tab.chapter = chapter - new_tab.text = get_chapter_text(to_book, to_chapter) + new_tab.text = get_chapter_text(book, chapter) new_tab.visible = false new_tab.font_size = font_size %ChapterTabBar.add_tab("%s %d" % [book, chapter]) @@ -104,19 +96,22 @@ func book_fuzzy_search(search_by:String) -> Array: return closest_matches +func load_book_names() -> Array: + var file:= FileAccess.open("res://bibles.txt", FileAccess.READ) + var arr:= file.get_as_text().split("\n") as Array + arr.erase("") + return arr + + func get_chapter_text(book:String, chapter:int) -> String: - var outputs:= [] - OS.execute( - "python3", - [ - "Py/nkjv_scraper.py", - "--site", - "https://www.biblegateway.com/passage/?search=%s+%d&version=%s" - % [book, chapter, "NKJV"] - ], - outputs - ) - return outputs[0] + var path:= "Bibles/%s/%s_%s.txt" \ + % [bible_version, book.replace(" ", "_"), int(chapter)] + var file:= FileAccess.open(path, FileAccess.READ) + + if file == null: + return "" + + return file.get_as_text() func get_saving_properties() -> Dictionary: @@ -130,11 +125,19 @@ func get_saving_properties() -> Dictionary: func goto_chapter(book:String, chapter:int) -> void: + var chapter_text:= get_chapter_text(book, chapter) + if chapter_text == "": + book = books[wrapi(books.find(book)+1, 0, books.size())] + chapter = 1 + goto_chapter(book, chapter) + %SearchBook.text = book + %SearchChapter.value = chapter + var curr_chapter_tab:= %ChapterTabs.get_child(current_tab) curr_chapter_tab.book = book curr_chapter_tab.chapter = chapter - curr_chapter_tab.text = get_chapter_text(to_book, to_chapter) + curr_chapter_tab.text = get_chapter_text(book, chapter) curr_chapter_tab.font_size = font_size %ChapterTabBar.set_tab_title(current_tab, "%s %d" % [book, chapter]) @@ -152,7 +155,8 @@ func load_settings() -> void: for prop in obj_meta.params: var config_property:= "%s.%s"%[obj_meta.name, prop] if config.has_section_key("data", config_property): - obj.set(prop, config.get_value("data", config_property)) + var val = config.get_value("data", config_property) + obj.set(prop, val) func remove_tab(tab_index:int) -> void: @@ -168,7 +172,6 @@ func remove_tab(tab_index:int) -> void: func save_settings() -> void: var config:= ConfigFile.new() config.set_value("meta", "format", SAVE_FORMAT_VERSION) - prints("_tabs", self._tabs) var to_save:= get_saving_properties() for obj in to_save: var obj_meta:Dictionary = to_save[obj] @@ -195,11 +198,9 @@ func switch_tab(tab_index:int) -> void: func _on_fuzzy_book_pressed(button:Button) -> void: - to_book = button.text - %SearchBook.text = to_book - _on_search_book_text_changed(to_book) + _on_search_book_text_changed(button.text) %SearchBook.grab_focus() - goto_chapter(to_book, to_chapter) + goto_chapter(button.text, %SearchChapter.value) func _on_search_book_text_changed(new_text:String) -> void: @@ -212,7 +213,6 @@ func _on_search_book_text_changed(new_text:String) -> void: return %FuzzyBooks.visible = true - to_book = str(fuzzy_books[0][0]) %FuzzyBook1.text = str(fuzzy_books[0][0]) %FuzzyBook2.text = str(fuzzy_books[1][0]) %FuzzyBook3.text = str(fuzzy_books[2][0]) @@ -220,12 +220,11 @@ func _on_search_book_text_changed(new_text:String) -> void: func _on_search_chapter_text_changed(value:int) -> void: - to_chapter = value - goto_chapter(to_book, to_chapter) + goto_chapter(%SearchBook.text, value) func _on_search_enter(_p=null) -> void: - goto_chapter(to_book, to_chapter) + goto_chapter(%SearchBook.text, %SearchChapter.value) func _on_tab_bar_tab_close_pressed(tab:int) -> void: @@ -233,7 +232,7 @@ func _on_tab_bar_tab_close_pressed(tab:int) -> void: func _on_new_tab_pressed() -> void: - add_tab(to_book, to_chapter) + add_tab(%SearchBook.text, %SearchChapter.value) func _on_chapter_tab_bar_tab_changed(tab: int) -> void: @@ -258,3 +257,8 @@ func _on_page_resiazable_toggled(button_pressed: bool) -> void: func _on_font_size_value_changed(value: float) -> void: self.font_size = value save_settings() + + +func _on_scroll_value_changed(value: float) -> void: + var scroll_cont:= %ChapterTabs.get_child(current_tab).get_node(^"%TextScroll") + scroll_cont.scroll_vertical = value * scroll_cont.get_child(0).get_rect().size.y diff --git a/BibleViwer.tscn b/BibleViwer.tscn index e5a1247..647c7fe 100644 --- a/BibleViwer.tscn +++ b/BibleViwer.tscn @@ -39,6 +39,7 @@ chapter_tab = ExtResource("2_rn5h4") [node name="ChapterTabs" type="MarginContainer" parent="."] unique_name_in_owner = true +layout_mode = 2 offset_left = 5.0 offset_top = 5.0 offset_right = 1147.0 @@ -47,7 +48,7 @@ offset_bottom = 643.0 [node name="Window" type="Window" parent="."] title = "Bible Reader Controls" position = Vector2i(2000, 60) -size = Vector2i(334, 240) +size = Vector2i(334, 241) current_screen = 1 wrap_controls = true @@ -63,16 +64,19 @@ theme_override_constants/margin_right = 5 theme_override_constants/margin_bottom = 5 [node name="VBoxContainer" type="VBoxContainer" parent="Window/MarginContainer"] +layout_mode = 2 offset_left = 5.0 offset_top = 5.0 offset_right = 1147.0 offset_bottom = 643.0 [node name="TabControls" type="HBoxContainer" parent="Window/MarginContainer/VBoxContainer"] +layout_mode = 2 offset_right = 1142.0 offset_bottom = 31.0 [node name="ScrollContainer" type="ScrollContainer" parent="Window/MarginContainer/VBoxContainer/TabControls"] +layout_mode = 2 offset_right = 1049.0 offset_bottom = 31.0 size_flags_horizontal = 3 @@ -81,12 +85,14 @@ vertical_scroll_mode = 0 [node name="ChapterTabBar" type="TabBar" parent="Window/MarginContainer/VBoxContainer/TabControls/ScrollContainer"] unique_name_in_owner = true +layout_mode = 2 offset_right = 1049.0 size_flags_horizontal = 3 clip_tabs = false tab_close_display_policy = 2 [node name="NewTab" type="Button" parent="Window/MarginContainer/VBoxContainer/TabControls"] +layout_mode = 2 offset_left = 1053.0 offset_right = 1142.0 offset_bottom = 31.0 @@ -94,39 +100,46 @@ size_flags_vertical = 0 text = "+ New Tab" [node name="BookSearchContainer" type="HBoxContainer" parent="Window/MarginContainer/VBoxContainer"] +layout_mode = 2 offset_top = 35.0 offset_right = 1142.0 offset_bottom = 66.0 [node name="VBoxContainer" type="VBoxContainer" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer"] +layout_mode = 2 offset_right = 569.0 offset_bottom = 31.0 size_flags_horizontal = 3 [node name="SearchBook" type="LineEdit" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer"] unique_name_in_owner = true +layout_mode = 2 offset_right = 569.0 offset_bottom = 31.0 focus_neighbor_right = NodePath("../../SearchChapter") focus_neighbor_bottom = NodePath("../FuzzyBooks/VBoxContainer/FuzzyBook1") focus_next = NodePath("../../SearchChapter") +text = "Genesis" placeholder_text = "Book" script = SubResource("GDScript_jd8xs") [node name="FuzzyBooks" type="PanelContainer" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer"] unique_name_in_owner = true visible = false +layout_mode = 2 offset_top = 35.0 offset_right = 569.0 offset_bottom = 67.0 [node name="VBoxContainer" type="VBoxContainer" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer/FuzzyBooks"] +layout_mode = 2 offset_right = 569.0 offset_bottom = 32.0 theme_override_constants/separation = 0 [node name="FuzzyBook1" type="Button" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer/FuzzyBooks/VBoxContainer" node_paths=PackedStringArray("shortcut_context")] unique_name_in_owner = true +layout_mode = 2 offset_right = 569.0 offset_bottom = 8.0 shortcut = SubResource("Shortcut_apwqq") @@ -136,6 +149,7 @@ alignment = 0 [node name="FuzzyBook2" type="Button" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer/FuzzyBooks/VBoxContainer" node_paths=PackedStringArray("shortcut_context")] unique_name_in_owner = true +layout_mode = 2 offset_top = 8.0 offset_right = 569.0 offset_bottom = 16.0 @@ -145,6 +159,7 @@ alignment = 0 [node name="FuzzyBook3" type="Button" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer/FuzzyBooks/VBoxContainer" node_paths=PackedStringArray("shortcut_context")] unique_name_in_owner = true +layout_mode = 2 offset_top = 16.0 offset_right = 569.0 offset_bottom = 24.0 @@ -154,6 +169,7 @@ alignment = 0 [node name="FuzzyBook4" type="Button" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer/VBoxContainer/FuzzyBooks/VBoxContainer" node_paths=PackedStringArray("shortcut_context")] unique_name_in_owner = true +layout_mode = 2 offset_top = 24.0 offset_right = 569.0 offset_bottom = 32.0 @@ -164,17 +180,20 @@ alignment = 0 [node name="SearchChapter" type="SpinBox" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer"] unique_name_in_owner = true +layout_mode = 2 offset_left = 573.0 offset_right = 1142.0 offset_bottom = 31.0 size_flags_horizontal = 3 size_flags_vertical = 0 min_value = 1.0 +max_value = 1000.0 value = 1.0 [node name="SearchVerse" type="SpinBox" parent="Window/MarginContainer/VBoxContainer/BookSearchContainer"] unique_name_in_owner = true visible = false +layout_mode = 2 offset_left = 764.0 offset_right = 1142.0 offset_bottom = 31.0 @@ -185,18 +204,21 @@ max_value = 200.0 value = 1.0 [node name="PageLabel" type="Label" parent="Window/MarginContainer/VBoxContainer"] +layout_mode = 2 offset_top = 70.0 offset_right = 1142.0 offset_bottom = 96.0 text = "Page Resolution" [node name="PageResolutionControls" type="HBoxContainer" parent="Window/MarginContainer/VBoxContainer"] +layout_mode = 2 offset_top = 100.0 offset_right = 1142.0 offset_bottom = 131.0 [node name="PageResolutionX" type="SpinBox" parent="Window/MarginContainer/VBoxContainer/PageResolutionControls"] unique_name_in_owner = true +layout_mode = 2 offset_right = 516.0 offset_bottom = 31.0 size_flags_horizontal = 3 @@ -207,6 +229,7 @@ suffix = "px" [node name="PageResolutionY" type="SpinBox" parent="Window/MarginContainer/VBoxContainer/PageResolutionControls"] unique_name_in_owner = true +layout_mode = 2 offset_left = 520.0 offset_right = 1037.0 offset_bottom = 31.0 @@ -218,6 +241,7 @@ suffix = "px" [node name="PageResiazable" type="CheckBox" parent="Window/MarginContainer/VBoxContainer/PageResolutionControls"] unique_name_in_owner = true +layout_mode = 2 offset_left = 1041.0 offset_right = 1142.0 offset_bottom = 31.0 @@ -225,18 +249,21 @@ button_pressed = true text = "Resizable" [node name="FontLabel" type="Label" parent="Window/MarginContainer/VBoxContainer"] +layout_mode = 2 offset_top = 135.0 offset_right = 1142.0 offset_bottom = 161.0 text = "Font" [node name="FontControls" type="HBoxContainer" parent="Window/MarginContainer/VBoxContainer"] +layout_mode = 2 offset_top = 165.0 offset_right = 1142.0 offset_bottom = 196.0 [node name="FontSizeLabel" type="Label" parent="Window/MarginContainer/VBoxContainer/FontControls"] self_modulate = Color(0.678431, 0.678431, 0.678431, 1) +layout_mode = 2 offset_top = 2.0 offset_right = 70.0 offset_bottom = 28.0 @@ -244,6 +271,7 @@ text = "Font Size" [node name="FontSize" type="SpinBox" parent="Window/MarginContainer/VBoxContainer/FontControls"] unique_name_in_owner = true +layout_mode = 2 offset_left = 74.0 offset_right = 157.0 offset_bottom = 31.0 @@ -254,6 +282,7 @@ suffix = "px" [node name="PanelContainer" type="PanelContainer" parent="Window/MarginContainer/VBoxContainer"] visible = false self_modulate = Color(1, 1, 1, 0) +layout_mode = 2 offset_top = 200.0 offset_right = 1142.0 offset_bottom = 638.0 diff --git a/Scenes/ChapterTab.tscn b/Scenes/ChapterTab.tscn index eb1c861..c8907b3 100644 --- a/Scenes/ChapterTab.tscn +++ b/Scenes/ChapterTab.tscn @@ -1,6 +1,41 @@ -[gd_scene load_steps=2 format=3 uid="uid://dmfev8bm6xoo4"] +[gd_scene load_steps=8 format=3 uid="uid://dmfev8bm6xoo4"] [ext_resource type="Script" path="res://Scenes/ChapterTab.gd" id="1_qo15t"] +[ext_resource type="Script" path="res://addons/SmoothScroll/SmoothScrollContainer.gd" id="2_h6cu7"] +[ext_resource type="RichTextEffect" uid="uid://c40yw3vkrmlb" path="res://TextEffects/woj.texteffect.tres" id="3_i2cr3"] + +[sub_resource type="Texture2D" id="Texture2D_yp8u2"] +resource_local_to_scene = false +resource_name = "" + +[sub_resource type="StyleBox" id="StyleBox_h2uv4"] +resource_local_to_scene = false +resource_name = "" +content_margin_left = -1.0 +content_margin_top = -1.0 +content_margin_right = -1.0 +content_margin_bottom = -1.0 + +[sub_resource type="Theme" id="Theme_d175w"] +VScrollBar/icons/decrement = SubResource("Texture2D_yp8u2") +VScrollBar/icons/decrement_highlight = SubResource("Texture2D_yp8u2") +VScrollBar/icons/decrement_pressed = SubResource("Texture2D_yp8u2") +VScrollBar/icons/increment = SubResource("Texture2D_yp8u2") +VScrollBar/icons/increment_highlight = SubResource("Texture2D_yp8u2") +VScrollBar/icons/increment_pressed = SubResource("Texture2D_yp8u2") +VScrollBar/styles/grabber = SubResource("StyleBox_h2uv4") +VScrollBar/styles/grabber_highlight = SubResource("StyleBox_h2uv4") +VScrollBar/styles/grabber_pressed = SubResource("StyleBox_h2uv4") +VScrollBar/styles/scroll = SubResource("StyleBox_h2uv4") +VScrollBar/styles/scroll_focus = SubResource("StyleBox_h2uv4") + +[sub_resource type="StyleBox" id="StyleBox_6uujh"] +resource_local_to_scene = false +resource_name = "" +content_margin_left = -1.0 +content_margin_top = -1.0 +content_margin_right = -1.0 +content_margin_bottom = -1.0 [node name="ChapterTab" type="VBoxContainer"] anchors_preset = 15 @@ -11,34 +46,48 @@ grow_vertical = 2 script = ExtResource("1_qo15t") [node name="PanelContainer2" type="PanelContainer" parent="."] -layout_mode = 2 offset_right = 1152.0 -offset_bottom = 26.0 +offset_bottom = 46.0 -[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer2"] -layout_mode = 2 +[node name="MarginContainer" type="MarginContainer" parent="PanelContainer2"] offset_right = 1152.0 -offset_bottom = 26.0 +offset_bottom = 46.0 +theme_override_constants/margin_left = 10 +theme_override_constants/margin_top = 10 +theme_override_constants/margin_right = 10 +theme_override_constants/margin_bottom = 10 + +[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer2/MarginContainer"] +offset_left = 10.0 +offset_top = 10.0 +offset_right = 1142.0 +offset_bottom = 36.0 theme_override_constants/separation = 0 -[node name="BookTitle" type="Label" parent="PanelContainer2/HBoxContainer"] +[node name="BookTitle" type="Label" parent="PanelContainer2/MarginContainer/HBoxContainer"] unique_name_in_owner = true -layout_mode = 2 offset_right = 38.0 offset_bottom = 26.0 text = "Luke" +[node name="TextScroll" type="ScrollContainer" parent="."] +visible = false +offset_top = 50.0 +offset_right = 1152.0 +offset_bottom = 347.0 +size_flags_vertical = 3 +theme = SubResource("Theme_d175w") +horizontal_scroll_mode = 0 + [node name="PanelContainer" type="PanelContainer" parent="."] -layout_mode = 2 -offset_top = 30.0 +offset_top = 50.0 offset_right = 1152.0 offset_bottom = 648.0 size_flags_vertical = 3 [node name="MarginContainer" type="MarginContainer" parent="PanelContainer"] -layout_mode = 2 offset_right = 1152.0 -offset_bottom = 618.0 +offset_bottom = 598.0 theme_override_constants/margin_left = 10 theme_override_constants/margin_top = 10 theme_override_constants/margin_right = 10 @@ -46,24 +95,25 @@ theme_override_constants/margin_bottom = 10 [node name="TextScroll" type="ScrollContainer" parent="PanelContainer/MarginContainer"] unique_name_in_owner = true -layout_mode = 2 offset_left = 10.0 offset_top = 10.0 offset_right = 1142.0 -offset_bottom = 608.0 -size_flags_vertical = 3 -horizontal_scroll_mode = 0 +offset_bottom = 588.0 +theme = SubResource("Theme_d175w") +script = ExtResource("2_h6cu7") +speed = 1.0 +damping = 0.05 [node name="BibleText" type="RichTextLabel" parent="PanelContainer/MarginContainer/TextScroll"] unique_name_in_owner = true -layout_mode = 2 -offset_right = 1124.0 -offset_bottom = 966.0 +offset_right = 1132.0 +offset_bottom = 920.0 size_flags_horizontal = 3 size_flags_vertical = 3 focus_mode = 2 +theme_override_styles/focus = SubResource("StyleBox_6uujh") bbcode_enabled = true -text = " [h1]31[/color] But that the world may know that I love the Father; and as the Father gave me commandment, even so I do. Arise, let us go hence. +text = " [woj]31[/woj] that the world may know that I love the Father; and as the Father gave me commandment, even so I do. Arise, let us go hence. Chapter 15 CHAPTER 15. @@ -99,6 +149,7 @@ Chapter 16 1 These things have I spoken unto you, that ye should not be offended." fit_content_height = true scroll_active = false -threaded = true +context_menu_enabled = true +custom_effects = [ExtResource("3_i2cr3")] progress_bar_delay = 0 selection_enabled = true diff --git a/TextEffects/WojTextEffect.gd b/TextEffects/WojTextEffect.gd new file mode 100644 index 0000000..d12b921 --- /dev/null +++ b/TextEffects/WojTextEffect.gd @@ -0,0 +1,9 @@ + +@tool +extends RichTextEffect + +var bbcode = "woj" + +func _process_custom_fx(char_fx:CharFXTransform) -> bool: + char_fx.color = Color("ff7777") + return true diff --git a/TextEffects/woj.texteffect.tres b/TextEffects/woj.texteffect.tres new file mode 100644 index 0000000..fef6944 --- /dev/null +++ b/TextEffects/woj.texteffect.tres @@ -0,0 +1,6 @@ +[gd_resource type="RichTextEffect" load_steps=2 format=3 uid="uid://c40yw3vkrmlb"] + +[ext_resource type="Script" path="res://TextEffects/WojTextEffect.gd" id="1_ekvne"] + +[resource] +script = ExtResource("1_ekvne") diff --git a/addons/SmoothScroll/SmoothScrollContainer.gd b/addons/SmoothScroll/SmoothScrollContainer.gd new file mode 100644 index 0000000..11b2c97 --- /dev/null +++ b/addons/SmoothScroll/SmoothScrollContainer.gd @@ -0,0 +1,181 @@ +## Smooth scroll functionality for ScrollContainer +## +## Applies velocity based momentum and "overdrag" +## functionality to a ScrollContainer +extends ScrollContainer + +# Drag impact for one scroll input +@export_range(10, 1) +var speed := 2 +# Softness of damping when "overdragging" +@export_range(0, 1) +var damping := 0.1 +# Follows the focus smoothly +@export +var follow_focus_ := true + +@export_range(0, 1) +var friction_scroll := 0.9 +@export_range(0, 1) +var friction_drag := 0.97 + +# Current velocity of the `content_node` +var velocity := Vector2(0,0) +# Below this value, velocity is set to `0` +var just_stop_under := 0.01 +# Current counterforce for "overdragging" on the top +var over_drag_multiplicator_top := 1 +# Current counterforce for "overdragging" on the bottom +var over_drag_multiplicator_bottom := 1 +# Control node to move when scrolling +var content_node : Control +# Current position of `content_node` +var pos := Vector2(0, 0) +# When true, `content_node`'s position is only set by dragging the scroll bar +var scrolling := false +# Current friction +var friction := 0.9 + + +func _ready() -> void: + get_v_scroll_bar().connect("scrolling", _on_VScrollBar_scrolling) + get_viewport().connect("gui_focus_changed", _on_focus_changed) + for c in get_children(): + if not c is ScrollBar: content_node = c + + +func _process(delta: float) -> void: + # If no scroll needed, don't apply forces + if content_node.size.y - self.size.y < 1: + return + + var d := delta + # Distance between content_node's bottom and bottom of the scroll box + var bottom_distance : float = content_node.position.y + content_node.size.y - self.size.y + # Distance between content_node and top of the scroll box + var top_distance : float = content_node.position.y + + # If overdragged on bottom: + if bottom_distance< 0 : + over_drag_multiplicator_bottom = 1/abs(bottom_distance)*10 + else: + over_drag_multiplicator_bottom = 1 + + # If overdragged on top: + if top_distance> 0: + over_drag_multiplicator_top = 1/abs(top_distance)*10 + else: + over_drag_multiplicator_top = 1 + + # Simulate friction + velocity *= friction + + # If velocity is too low, just set it to 0 + if velocity.length() <= just_stop_under: + velocity = Vector2(0,0) + + # Applies counterforces when overdragging + if bottom_distance< 0 : + velocity.y = lerp(velocity.y, -bottom_distance/8, damping) + if top_distance> 0: + velocity.y = lerp(velocity.y, -top_distance/8, damping) + + # If using scroll bar dragging, set the content_node's + # position by using the scrollbar position + if scrolling: + pos = content_node.position + return + + # Move content node by applying velocity + pos += velocity + content_node.position = pos + + # Update vertical scroll bar + set_v_scroll(-pos.y) + + +func _gui_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + if not event.pressed: + scrolling = false + + var scrolled = true + + match event.button_index: + MOUSE_BUTTON_WHEEL_DOWN: velocity.y -= speed + MOUSE_BUTTON_WHEEL_UP: velocity.y += speed + _: scrolled = false + + if scrolled: friction = friction_scroll + + elif event is InputEventScreenDrag: + friction = friction_drag + if scroll_horizontal: velocity.x = event.relative.x + if scroll_vertically: velocity.y = event.relative.y + +# Scroll to new focused element +func _on_focus_changed(control: Control) -> void: + var is_child := false + for child in content_node.get_children(): + if child == control: + is_child = true + if not is_child: + return + if not follow_focus_: + return + + var focus_size = control.size.y + var focus_top = control.position.y + + var scroll_size = size.y + var scroll_top = get_v_scroll() + var scroll_bottom = scroll_top + scroll_size - focus_size + + if focus_top < scroll_top: + scroll_to(focus_top) + + if focus_top > scroll_bottom: + var scroll_offset = scroll_top + focus_top - scroll_bottom + scroll_to(scroll_offset) + +func _on_VScrollBar_scrolling() -> void: + scrolling = true + +# Scrolls to specific position +func scroll_to(y_pos: float) -> void: + velocity.y = -(y_pos + content_node.position.y) / 8 + +# Scrolls up a page +func scroll_page_up() -> void: + velocity.y += self.size.y / 10 + + +# Scrolls down a page +func scroll_page_down() -> void: + velocity.y -= self.size.y / 10 + + +# Adds velocity to the vertical scroll +func scroll_vertically(amount: float) -> void: + velocity.y -= amount + +# Scrolls to top +func scroll_to_top() -> void: + # Reset velocity + velocity.y = 0 + # Move content node to top + pos.y = 0 + content_node.position = pos + # Update vertical scroll bar + set_v_scroll(-pos.y) + + +# Scrolls to bottom +func scroll_to_bottom() -> void: + # Reset velocity + velocity.y = 0 + # Move content node to bottom + pos.y = -content_node.size.y + self.size.y + content_node.position = pos + # Update vertical scroll bar + set_v_scroll(-pos.y) diff --git a/addons/SmoothScroll/class-icon.svg b/addons/SmoothScroll/class-icon.svg new file mode 100644 index 0000000..30862c1 --- /dev/null +++ b/addons/SmoothScroll/class-icon.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/addons/SmoothScroll/class-icon.svg.import b/addons/SmoothScroll/class-icon.svg.import new file mode 100644 index 0000000..a7f8a52 --- /dev/null +++ b/addons/SmoothScroll/class-icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dorhyoghxkay6" +path="res://.godot/imported/class-icon.svg-c17de51589a7d30572bf401526524f64.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/SmoothScroll/class-icon.svg" +dest_files=["res://.godot/imported/class-icon.svg-c17de51589a7d30572bf401526524f64.ctex"] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/bptc_ldr=0 +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 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/addons/SmoothScroll/icon.afdesign b/addons/SmoothScroll/icon.afdesign new file mode 100644 index 0000000..1b54598 Binary files /dev/null and b/addons/SmoothScroll/icon.afdesign differ diff --git a/addons/SmoothScroll/plugin.cfg b/addons/SmoothScroll/plugin.cfg new file mode 100644 index 0000000..ef5baa9 --- /dev/null +++ b/addons/SmoothScroll/plugin.cfg @@ -0,0 +1,8 @@ +[plugin] + +name="SmoothScroll" +description="""This plugin adds a new scroll container class +with additional smooth scroll options.""" +author="Fabian Keßler (SpyrexDE)" +version="1.1" +script="plugin.gd" \ No newline at end of file diff --git a/addons/SmoothScroll/plugin.gd b/addons/SmoothScroll/plugin.gd new file mode 100644 index 0000000..e487e52 --- /dev/null +++ b/addons/SmoothScroll/plugin.gd @@ -0,0 +1,10 @@ +@tool +extends EditorPlugin + + +func _enter_tree(): + add_custom_type("SmoothScrollContainer", "ScrollContainer", preload("SmoothScrollContainer.gd"), preload("class-icon.svg")) + + +func _exit_tree(): + remove_custom_type("SmoothScrollContainer") diff --git a/bibles.txt b/bibles.txt new file mode 100644 index 0000000..d2000ae --- /dev/null +++ b/bibles.txt @@ -0,0 +1,66 @@ +Genesis +Exodus +Leviticus +Numbers +Deuteronomy +Joshua +Judges +Ruth +1 Samuel +2 Samuel +1 Kings +2 Kings +1 Chronicles +2 Chronicles +Ezra +Nehemiah +Esther +Job +Psalm +Proverbs +Ecclesiastes +Song of Solomon +Isaiah +Jeremiah +Lamentations +Ezekiel +Daniel +Hosea +Joel +Amos +Obadiah +Jonah +Micah +Nahum +Habakkuk +Zephaniah +Haggai +Zechariah +Malachi +Matthew +Mark +Luke +John +Acts +Romans +1 Corinthians +2 Corinthians +Galatians +Ephesians +Philippians +Colossians +1 Thessalonians +2 Thessalonians +1 Timothy +2 Timothy +Titus +Philemon +Hebrews +James +1 Peter +2 Peter +1 John +2 John +3 John +Jude +Revelation diff --git a/project.godot b/project.godot index 59b610e..60ba340 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,10 @@ config/icon="res://icon.svg" window/subwindows/embed_subwindows=false +[editor_plugins] + +enabled=PackedStringArray("res://addons/SmoothScroll/plugin.cfg") + [rendering] renderer/rendering_method="mobile"