From 605bfb516f9d2d7452bac534b7d619599ed6d643 Mon Sep 17 00:00:00 2001 From: Face <69168154+face-hh@users.noreply.github.com> Date: Fri, 15 Aug 2025 14:44:22 +0300 Subject: [PATCH] swap smoothscrollcontainer with scrollcontainer --- flumi/Scenes/main.tscn | 22 +- flumi/addons/DatePicker/YearView.tscn | 28 +- .../SmoothScroll/SmoothScrollContainer.gd | 916 ------------------ .../SmoothScroll/SmoothScrollContainer.gd.uid | 1 - flumi/addons/SmoothScroll/class-icon.svg | 19 - .../addons/SmoothScroll/class-icon.svg.import | 37 - flumi/addons/SmoothScroll/debug_font.tres | 3 - flumi/addons/SmoothScroll/icon.afdesign | Bin 49347 -> 0 bytes flumi/addons/SmoothScroll/plugin.cfg | 8 - flumi/addons/SmoothScroll/plugin.gd | 12 - flumi/addons/SmoothScroll/plugin.gd.uid | 1 - .../scroll_damper/cubic_scroll_damper.gd | 33 - .../scroll_damper/cubic_scroll_damper.gd.uid | 1 - .../scroll_damper/expo_scroll_damper.gd | 47 - .../scroll_damper/expo_scroll_damper.gd.uid | 1 - .../SmoothScroll/scroll_damper/icon.afdesign | Bin 36905 -> 0 bytes .../SmoothScroll/scroll_damper/icon.svg | 29 - .../scroll_damper/icon.svg.import | 37 - .../scroll_damper/linear_scroll_damper.gd | 33 - .../scroll_damper/linear_scroll_damper.gd.uid | 1 - .../scroll_damper/quad_scroll_damper.gd | 33 - .../scroll_damper/quad_scroll_damper.gd.uid | 1 - .../scroll_damper/scroll_damper.gd | 74 -- .../scroll_damper/scroll_damper.gd.uid | 1 - flumi/icon.svg.import | 2 +- 25 files changed, 6 insertions(+), 1334 deletions(-) delete mode 100644 flumi/addons/SmoothScroll/SmoothScrollContainer.gd delete mode 100644 flumi/addons/SmoothScroll/SmoothScrollContainer.gd.uid delete mode 100644 flumi/addons/SmoothScroll/class-icon.svg delete mode 100644 flumi/addons/SmoothScroll/class-icon.svg.import delete mode 100644 flumi/addons/SmoothScroll/debug_font.tres delete mode 100644 flumi/addons/SmoothScroll/icon.afdesign delete mode 100644 flumi/addons/SmoothScroll/plugin.cfg delete mode 100644 flumi/addons/SmoothScroll/plugin.gd delete mode 100644 flumi/addons/SmoothScroll/plugin.gd.uid delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/cubic_scroll_damper.gd delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/cubic_scroll_damper.gd.uid delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd.uid delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/icon.afdesign delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/icon.svg delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/icon.svg.import delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd.uid delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd.uid delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd delete mode 100644 flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd.uid diff --git a/flumi/Scenes/main.tscn b/flumi/Scenes/main.tscn index 1e0c479..23bd2bf 100644 --- a/flumi/Scenes/main.tscn +++ b/flumi/Scenes/main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=40 format=3 uid="uid://bytm7bt2s4ak8"] +[gd_scene load_steps=36 format=3 uid="uid://bytm7bt2s4ak8"] [ext_resource type="Script" uid="uid://bg5iqnwic1rio" path="res://Scripts/main.gd" id="1_8q3xr"] [ext_resource type="Texture2D" uid="uid://df1m4j7uxi63v" path="res://Assets/Icons/chevron-down.svg" id="2_6bp64"] @@ -10,8 +10,6 @@ [ext_resource type="Texture2D" uid="uid://cu4hjoba6etf" path="res://Assets/Icons/rotate-cw.svg" id="5_344ge"] [ext_resource type="Texture2D" uid="uid://cehbtwq6gq0cn" path="res://Assets/Icons/plus.svg" id="5_ynf5e"] [ext_resource type="Texture2D" uid="uid://cklatjc4m38dy" path="res://Assets/Icons/ellipsis-vertical.svg" id="10_6iyac"] -[ext_resource type="Script" uid="uid://bgqglerkcylxx" path="res://addons/SmoothScroll/SmoothScrollContainer.gd" id="10_d1ilt"] -[ext_resource type="Script" uid="uid://b7h0k2h2qwlqv" path="res://addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd" id="11_6iyac"] [ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="11_ee4r6"] [ext_resource type="Script" uid="uid://vjjhljlftlbk" path="res://Scripts/OptionButton.gd" id="11_gt3je"] [ext_resource type="Texture2D" uid="uid://du24f6em2nqwq" path="res://Assets/Icons/external-link.svg" id="12_gt3je"] @@ -76,18 +74,6 @@ expand_margin_left = 40.0 LineEdit/styles/focus = SubResource("StyleBoxEmpty_u50mg") LineEdit/styles/normal = SubResource("StyleBoxFlat_cbgmd") -[sub_resource type="Resource" id="Resource_fdnlq"] -script = ExtResource("11_6iyac") -friction = 4.0 -minimum_velocity = 0.4 -rebound_strength = 7.0 - -[sub_resource type="Resource" id="Resource_jkdf5"] -script = ExtResource("11_6iyac") -friction = 4.0 -minimum_velocity = 0.4 -rebound_strength = 7.0 - [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_white"] bg_color = Color(1, 1, 1, 1) @@ -273,12 +259,6 @@ layout_mode = 2 [node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer"] layout_mode = 2 size_flags_vertical = 3 -script = ExtResource("10_d1ilt") -wheel_scroll_damper = SubResource("Resource_fdnlq") -dragging_scroll_damper = SubResource("Resource_jkdf5") -drag_with_mouse = false -allow_overdragging = false -metadata/_custom_type_script = "uid://bgqglerkcylxx" [node name="WebsiteContainer" type="VBoxContainer" parent="VBoxContainer/ScrollContainer"] unique_name_in_owner = true diff --git a/flumi/addons/DatePicker/YearView.tscn b/flumi/addons/DatePicker/YearView.tscn index 35810a1..3b39692 100644 --- a/flumi/addons/DatePicker/YearView.tscn +++ b/flumi/addons/DatePicker/YearView.tscn @@ -1,21 +1,7 @@ -[gd_scene load_steps=11 format=3 uid="uid://n5ra5w5aupx7"] +[gd_scene load_steps=7 format=3 uid="uid://n5ra5w5aupx7"] [ext_resource type="Script" uid="uid://c8nfr825g08sy" path="res://addons/DatePicker/YearView.gd" id="1_hiiks"] -[ext_resource type="Script" uid="uid://bgqglerkcylxx" path="res://addons/SmoothScroll/SmoothScrollContainer.gd" id="1_sw7yn"] [ext_resource type="ButtonGroup" uid="uid://bqxxq56yxl44h" path="res://addons/DatePicker/CalendarGroup.tres" id="2_2qddy"] -[ext_resource type="Script" uid="uid://b7h0k2h2qwlqv" path="res://addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd" id="2_iofl3"] - -[sub_resource type="Resource" id="Resource_wpifq"] -script = ExtResource("2_iofl3") -friction = 4.0 -minimum_velocity = 0.4 -rebound_strength = 7.0 - -[sub_resource type="Resource" id="Resource_kdl71"] -script = ExtResource("2_iofl3") -friction = 4.0 -minimum_velocity = 0.4 -rebound_strength = 7.0 [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_iofl3"] @@ -46,24 +32,18 @@ corner_radius_bottom_left = 4 [node name="YearView" type="HBoxContainer"] script = ExtResource("1_hiiks") -[node name="SmoothScrollContainer" type="ScrollContainer" parent="."] +[node name="ScrollContainer" type="ScrollContainer" parent="."] custom_minimum_size = Vector2(234, 240) layout_mode = 2 -script = ExtResource("1_sw7yn") -wheel_scroll_damper = SubResource("Resource_wpifq") -dragging_scroll_damper = SubResource("Resource_kdl71") -drag_with_mouse = false -allow_overdragging = false -metadata/_custom_type_script = "uid://bgqglerkcylxx" -[node name="YearContainer" type="VBoxContainer" parent="SmoothScrollContainer"] +[node name="YearContainer" type="VBoxContainer" parent="ScrollContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(234, 240) layout_mode = 2 size_flags_horizontal = 4 size_flags_vertical = 4 -[node name="Button" type="Button" parent="SmoothScrollContainer/YearContainer"] +[node name="Button" type="Button" parent="ScrollContainer/YearContainer"] unique_name_in_owner = true custom_minimum_size = Vector2(34, 5) layout_mode = 2 diff --git a/flumi/addons/SmoothScroll/SmoothScrollContainer.gd b/flumi/addons/SmoothScroll/SmoothScrollContainer.gd deleted file mode 100644 index 4c3c9ce..0000000 --- a/flumi/addons/SmoothScroll/SmoothScrollContainer.gd +++ /dev/null @@ -1,916 +0,0 @@ -## Smooth scroll functionality for ScrollContainer -## -## Applies velocity based momentum and "overdrag" -## functionality to a ScrollContainer -@tool -extends ScrollContainer -class_name SmoothScrollContainer - -@export_group("Mouse Wheel") -## Drag impact for one scroll input -@export_range(0, 10, 0.01, "or_greater", "hide_slider") -var speed := 1000.0 -## ScrollDamper for wheel scrolling -@export -var wheel_scroll_damper: ScrollDamper = ExpoScrollDamper.new() - -@export_group("Dragging") -## ScrollDamper for dragging -@export -var dragging_scroll_damper: ScrollDamper = ExpoScrollDamper.new() -### Allow dragging with mouse or not -@export -var drag_with_mouse := true -## Allow dragging with touch or not -@export -var drag_with_touch := true - -@export_group("Container") -## Below this value, snap content to boundary -@export -var just_snap_under := 0.4 -## Margin of the currently focused element -@export_range(0, 50) -var follow_focus_margin := 20 -## Makes the container scrollable vertically -@export -var allow_vertical_scroll := true -## Makes the container scrollable horizontally -@export -var allow_horizontal_scroll := true -## Makes the container only scrollable where the content has overflow -@export -var auto_allow_scroll := true -## Whether the content of this container should be allowed to overshoot at the ends -## before interpolating back to its bounds -@export -var allow_overdragging := true - -@export_group("Scroll Bar") -## Hides scrollbar as long as not hovered or interacted with -@export -var hide_scrollbar_over_time := false: - set(val): hide_scrollbar_over_time = _set_hide_scrollbar_over_time(val) -## Time after scrollbar starts to fade out when 'hide_scrollbar_over_time' is true -@export -var scrollbar_hide_time := 5.0 -## Fadein time for scrollbar when 'hide_scrollbar_over_time' is true -@export -var scrollbar_fade_in_time := 0.2 -## Fadeout time for scrollbar when 'hide_scrollbar_over_time' is true -@export -var scrollbar_fade_out_time := 0.5 - -@export_group("Input") -## If true sets the input event as handled with set_input_as_handled() -@export -var handle_input := true - -@export_group("Debug") -## Adds debug information -@export -var debug_mode := false - -## Current velocity of the `content_node` -var velocity := Vector2(0,0) -## Control node to move when scrolling -var content_node: Control -## Current position of `content_node` -var pos := Vector2(0, 0) -## Current ScrollDamper to use, recording to last input type -var scroll_damper: ScrollDamper -## When true, `content_node`'s position is only set by dragging the h scroll bar -var h_scrollbar_dragging := false -## When true, `content_node`'s position is only set by dragging the v scroll bar -var v_scrollbar_dragging := false -## When ture, `content_node` follows drag position -var content_dragging := false -## When ture, `content_node` has moved by dragging -var content_dragging_moved := false -## Timer for hiding scroll bar -var scrollbar_hide_timer := Timer.new() -## Tween for showing scroll bar -var scrollbar_show_tween: Tween -## Tween for hiding scroll bar -var scrollbar_hide_tween: Tween -## Tween for scroll x to -var scroll_x_to_tween: Tween -## Tween for scroll y to -var scroll_y_to_tween: Tween -## [0,1] Mouse or touch's relative movement accumulation when overdrag[br] -## [2,3] Position where dragging starts[br] -## [4,5,6,7] Left_distance, right_distance, top_distance, bottom_distance -var drag_temp_data := [] -## Whether touch point is in deadzone. -var is_in_deadzone := false -## Whether mouse is on h or v scroll bar -var mouse_on_scrollbar := false - -## If content is being scrolled -var is_scrolling := false: - set(val): - if is_scrolling != val: - if val: - emit_signal("scroll_started") - else: - emit_signal("scroll_ended") - is_scrolling = val - -## Last type of input used to scroll -enum SCROLL_TYPE {WHEEL, BAR, DRAG} -var last_scroll_type: SCROLL_TYPE - -#region Virtual Functions - -func _ready() -> void: - if debug_mode: - setup_debug_drawing() - # Initialize variables - scroll_damper = wheel_scroll_damper - - get_v_scroll_bar().gui_input.connect(_scrollbar_input.bind(true)) - get_h_scroll_bar().gui_input.connect(_scrollbar_input.bind(false)) - get_v_scroll_bar().mouse_entered.connect(_mouse_on_scroll_bar.bind(true)) - get_v_scroll_bar().mouse_exited.connect(_mouse_on_scroll_bar.bind(false)) - get_h_scroll_bar().mouse_entered.connect(_mouse_on_scroll_bar.bind(true)) - get_h_scroll_bar().mouse_exited.connect(_mouse_on_scroll_bar.bind(false)) - get_viewport().gui_focus_changed.connect(_on_focus_changed) - - for c in get_children(): - if not c is ScrollBar: - content_node = c - - add_child(scrollbar_hide_timer) - scrollbar_hide_timer.one_shot = true - scrollbar_hide_timer.timeout.connect(_scrollbar_hide_timer_timeout) - if hide_scrollbar_over_time: - scrollbar_hide_timer.start(scrollbar_hide_time) - get_tree().node_added.connect(_on_node_added) - -func _process(delta: float) -> void: - if Engine.is_editor_hint(): return - scroll(true, velocity.y, pos.y, delta) - scroll(false, velocity.x, pos.x, delta) - update_scrollbars() - update_is_scrolling() - - if debug_mode: - queue_redraw() - -# Detecting mouse entering and exiting scroll bar -func _mouse_on_scroll_bar(entered: bool) -> void: - mouse_on_scrollbar = entered - -# Forwarding scroll inputs from scrollbar -func _scrollbar_input(event: InputEvent, vertical: bool) -> void: - if event is InputEventMouseButton: - if event.button_index == MOUSE_BUTTON_WHEEL_DOWN\ - or event.button_index == MOUSE_BUTTON_WHEEL_UP\ - or event.button_index == MOUSE_BUTTON_WHEEL_LEFT\ - or event.button_index == MOUSE_BUTTON_WHEEL_RIGHT: - _gui_input(event) - - if event.button_index == MOUSE_BUTTON_LEFT: - if event.pressed: - if vertical: - v_scrollbar_dragging = true - last_scroll_type = SCROLL_TYPE.BAR - kill_scroll_to_tweens() - else: - h_scrollbar_dragging = true - last_scroll_type = SCROLL_TYPE.BAR - kill_scroll_to_tweens() - else: - if vertical: - v_scrollbar_dragging = false - else: - h_scrollbar_dragging = false - - if event is InputEventScreenTouch: - if event.pressed: - if vertical: - v_scrollbar_dragging = true - last_scroll_type = SCROLL_TYPE.BAR - kill_scroll_to_tweens() - else: - h_scrollbar_dragging = true - last_scroll_type = SCROLL_TYPE.BAR - kill_scroll_to_tweens() - else: - if vertical: - v_scrollbar_dragging = false - else: - h_scrollbar_dragging = false - -func _gui_input(event: InputEvent) -> void: - # Show scroll bars when mouse moves - if hide_scrollbar_over_time and event is InputEventMouseMotion: - show_scrollbars() - - if event is InputEventMouseButton: - match event.button_index: - MOUSE_BUTTON_WHEEL_DOWN: - if event.pressed: - last_scroll_type = SCROLL_TYPE.WHEEL - if event.shift_pressed or not should_scroll_vertical(): - if should_scroll_horizontal(): - velocity.x -= speed * event.factor - else: - if should_scroll_vertical(): - velocity.y -= speed * event.factor - scroll_damper = wheel_scroll_damper - kill_scroll_to_tweens() - MOUSE_BUTTON_WHEEL_UP: - if event.pressed: - last_scroll_type = SCROLL_TYPE.WHEEL - if event.shift_pressed or not should_scroll_vertical(): - if should_scroll_horizontal(): - velocity.x += speed * event.factor - else: - if should_scroll_vertical(): - velocity.y += speed * event.factor - scroll_damper = wheel_scroll_damper - kill_scroll_to_tweens() - MOUSE_BUTTON_WHEEL_LEFT: - if event.pressed: - last_scroll_type = SCROLL_TYPE.WHEEL - if event.shift_pressed: - if should_scroll_vertical(): - velocity.y -= speed * event.factor - else: - if should_scroll_horizontal(): - velocity.x += speed * event.factor - scroll_damper = wheel_scroll_damper - kill_scroll_to_tweens() - MOUSE_BUTTON_WHEEL_RIGHT: - if event.pressed: - last_scroll_type = SCROLL_TYPE.WHEEL - if event.shift_pressed: - if should_scroll_vertical(): - velocity.y += speed * event.factor - else: - if should_scroll_horizontal(): - velocity.x -= speed * event.factor - scroll_damper = wheel_scroll_damper - kill_scroll_to_tweens() - MOUSE_BUTTON_LEFT: - if event.pressed: - if !drag_with_mouse: return - content_dragging = true - is_in_deadzone = true - scroll_damper = dragging_scroll_damper - last_scroll_type = SCROLL_TYPE.DRAG - init_drag_temp_data() - kill_scroll_to_tweens() - else: - content_dragging = false - is_in_deadzone = false - - if (event is InputEventScreenDrag and drag_with_touch) \ - or (event is InputEventMouseMotion and drag_with_mouse): - if content_dragging: - if should_scroll_horizontal(): - drag_temp_data[0] += event.relative.x - if should_scroll_vertical(): - drag_temp_data[1] += event.relative.y - remove_all_children_focus(self) - handle_content_dragging() - - if event is InputEventPanGesture: - if should_scroll_horizontal(): - velocity.x = -event.delta.x * speed - kill_scroll_to_tweens() - if should_scroll_vertical(): - velocity.y = -event.delta.y * speed - kill_scroll_to_tweens() - - if event is InputEventScreenTouch: - if event.pressed: - if !drag_with_touch: return - content_dragging = true - is_in_deadzone = true - scroll_damper = dragging_scroll_damper - last_scroll_type = SCROLL_TYPE.DRAG - init_drag_temp_data() - kill_scroll_to_tweens() - else: - content_dragging = false - is_in_deadzone = false - # Handle input if handle_input is true - if handle_input: - get_tree().get_root().set_input_as_handled() - -# Scroll to new focused element -func _on_focus_changed(control: Control) -> void: - if follow_focus: - self.ensure_control_visible(control) - -func _draw() -> void: - if debug_mode: - draw_debug() - -# Sets default mouse filter for SmoothScroll children to MOUSE_FILTER_PASS -func _on_node_added(node: Node) -> void: - if node is Control and Engine.is_editor_hint(): - if is_ancestor_of(node): - node.mouse_filter = Control.MOUSE_FILTER_PASS - -func _scrollbar_hide_timer_timeout() -> void: - if !any_scroll_bar_dragged(): - hide_scrollbars() - -func _set_hide_scrollbar_over_time(value: bool) -> bool: - if value == false: - if scrollbar_hide_timer != null: - scrollbar_hide_timer.stop() - if scrollbar_show_tween != null: - scrollbar_show_tween.kill() - if scrollbar_hide_tween != null: - scrollbar_hide_tween.kill() - get_h_scroll_bar().modulate = Color.WHITE - get_v_scroll_bar().modulate = Color.WHITE - else: - if scrollbar_hide_timer != null and scrollbar_hide_timer.is_inside_tree(): - scrollbar_hide_timer.start(scrollbar_hide_time) - return value - -func _get(property: StringName) -> Variant: - match property: - "scroll_horizontal": - if !content_node: return 0 - return -int(content_node.position.x) - "scroll_vertical": - if !content_node: return 0 - return -int(content_node.position.y) - _: - return null - -func _set(property: StringName, value: Variant) -> bool: - match property: - "scroll_horizontal": - if !content_node: - scroll_horizontal = 0 - return true - scroll_horizontal = value - kill_scroll_x_to_tween() - velocity.x = 0.0 - pos.x = clampf( - -value as float, - -get_child_size_x_diff(content_node, true), - 0.0 - ) - return true - "scroll_vertical": - if !content_node: - scroll_vertical = 0 - return true - scroll_vertical = value - kill_scroll_y_to_tween() - velocity.y = 0.0 - pos.y = clampf( - -value as float, - -get_child_size_y_diff(content_node, true), - 0.0 - ) - return true - _: - return false - -#endregion - -#region Scrolling Logic - -func scroll(vertical: bool, axis_velocity: float, axis_pos: float, delta: float): - # If no scroll needed, don't apply forces - if vertical: - if not should_scroll_vertical(): - return - else: - if not should_scroll_horizontal(): - return - if !scroll_damper: return - # Applies counterforces when overdragging - if not content_dragging: - axis_velocity = handle_overdrag(vertical, axis_velocity, axis_pos, delta) - # Move content node by applying velocity - var slide_result = scroll_damper.slide(axis_velocity, delta) - axis_velocity = slide_result[0] - axis_pos += slide_result[1] - # Snap to boundary if close enough - var snap_result = snap(vertical, axis_velocity, axis_pos) - axis_velocity = snap_result[0] - axis_pos = snap_result[1] - else: - # Preserve dragging velocity for 1 frame - # in case no movement event while releasing dragging with touch - if content_dragging_moved: - content_dragging_moved = false - else: - axis_velocity = 0.0 - # If using scroll bar dragging, set the content_node's - # position by using the scrollbar position - if handle_scrollbar_drag(): - return - - if vertical: - if not allow_overdragging: - # Clamp if calculated position is beyond boundary - if is_outside_top_boundary(axis_pos): - axis_pos = 0.0 - axis_velocity = 0.0 - elif is_outside_bottom_boundary(axis_pos): - axis_pos = -get_child_size_y_diff(content_node, true) - axis_velocity = 0.0 - - content_node.position.y = axis_pos - pos.y = axis_pos - velocity.y = axis_velocity - else: - if not allow_overdragging: - # Clamp if calculated position is beyond boundary - if is_outside_left_boundary(axis_pos): - axis_pos = 0.0 - axis_velocity = 0.0 - elif is_outside_right_boundary(axis_pos): - axis_pos = -get_child_size_x_diff(content_node, true) - axis_velocity = 0.0 - - content_node.position.x = axis_pos - pos.x = axis_pos - velocity.x = axis_velocity - -func handle_overdrag(vertical: bool, axis_velocity: float, axis_pos: float, delta: float) -> float: - if !scroll_damper: return 0.0 - # Calculate the size difference between this container and content_node - var size_diff = get_child_size_y_diff(content_node, true) \ - if vertical else get_child_size_x_diff(content_node, true) - # Calculate distance to left and right or top and bottom - var dist1 = get_child_top_dist(axis_pos, size_diff) \ - if vertical else get_child_left_dist(axis_pos, size_diff) - var dist2 = get_child_bottom_dist(axis_pos, size_diff) \ - if vertical else get_child_right_dist(axis_pos, size_diff) - # Calculate velocity to left and right or top and bottom - var target_vel1 = scroll_damper._calculate_velocity_to_dest(dist1, 0.0) - var target_vel2 = scroll_damper._calculate_velocity_to_dest(dist2, 0.0) - # Bounce when out of boundary. When velocity is not fast enough to go back, - # apply a opposite force and get a new velocity. If the new velocity is too fast, - # apply a velocity that makes it scroll back exactly. - if axis_pos > 0.0: - if axis_velocity > target_vel1: - axis_velocity = scroll_damper.attract( - dist1, - 0.0, - axis_velocity, - delta - ) - if axis_pos < -size_diff: - if axis_velocity < target_vel2: - axis_velocity = scroll_damper.attract( - dist2, - 0.0, - axis_velocity, - delta - ) - - return axis_velocity - -# Snap to boundary if close enough in next frame -func snap(vertical: bool, axis_velocity: float, axis_pos: float) -> Array: - # Calculate the size difference between this container and content_node - var size_diff = get_child_size_y_diff(content_node, true) \ - if vertical else get_child_size_x_diff(content_node, true) - # Calculate distance to left and right or top and bottom - var dist1 = get_child_top_dist(axis_pos, size_diff) \ - if vertical else get_child_left_dist(axis_pos, size_diff) - var dist2 = get_child_bottom_dist(axis_pos, size_diff) \ - if vertical else get_child_right_dist(axis_pos, size_diff) - if ( - dist1 > 0.0 \ - and abs(dist1) < just_snap_under \ - and abs(axis_velocity) < just_snap_under \ - ): - axis_pos -= dist1 - axis_velocity = 0.0 - elif ( - dist2 < 0.0 \ - and abs(dist2) < just_snap_under \ - and abs(axis_velocity) < just_snap_under \ - ): - axis_pos -= dist2 - axis_velocity = 0.0 - - return [axis_velocity, axis_pos] - -## Returns true when scrollbar was dragged -func handle_scrollbar_drag() -> bool: - if h_scrollbar_dragging: - velocity.x = 0.0 - pos.x = -get_h_scroll_bar().value - return true - - if v_scrollbar_dragging: - velocity.y = 0.0 - pos.y = -get_v_scroll_bar().value - return true - return false - -func handle_content_dragging() -> void: - if !dragging_scroll_damper: return - - if( - Vector2(drag_temp_data[0], drag_temp_data[1]).length() < scroll_deadzone \ - and is_in_deadzone - ): - return - elif is_in_deadzone == true: - is_in_deadzone = false - drag_temp_data[0] = 0.0 - drag_temp_data[1] = 0.0 - - content_dragging_moved = true - - var calculate_dest = func(delta: float, damping: float) -> float: - if delta >= 0.0: - return delta / (1 + delta * damping * 0.00001) - else: - return delta - - var calculate_position = func( - temp_dist1: float, # Temp distance - temp_dist2: float, - temp_relative: float # Event's relative movement accumulation - ) -> float: - if temp_relative + temp_dist1 > 0.0: - var delta = min(temp_relative, temp_relative + temp_dist1) - var dest = calculate_dest.call(delta, dragging_scroll_damper._attract_factor) - return dest - min(0.0, temp_dist1) - elif temp_relative + temp_dist2 < 0.0: - var delta = max(temp_relative, temp_relative + temp_dist2) - var dest = -calculate_dest.call(-delta, dragging_scroll_damper._attract_factor) - return dest - max(0.0, temp_dist2) - else: return temp_relative - - if should_scroll_vertical(): - var y_pos = calculate_position.call( - drag_temp_data[6], # Temp top_distance - drag_temp_data[7], # Temp bottom_distance - drag_temp_data[1] # Temp y relative accumulation - ) + drag_temp_data[3] - velocity.y = (y_pos - pos.y) / get_process_delta_time() - pos.y = y_pos - if should_scroll_horizontal(): - var x_pos = calculate_position.call( - drag_temp_data[4], # Temp left_distance - drag_temp_data[5], # Temp right_distance - drag_temp_data[0] # Temp x relative accumulation - ) + drag_temp_data[2] - velocity.x = (x_pos - pos.x) / get_process_delta_time() - pos.x = x_pos - -func remove_all_children_focus(node: Node) -> void: - if node is Control: - var control = node as Control - control.release_focus() - - for child in node.get_children(): - remove_all_children_focus(child) - -func update_is_scrolling() -> void: - if( - (content_dragging and not is_in_deadzone) - or any_scroll_bar_dragged() - or velocity != Vector2.ZERO - ): - is_scrolling = true - else: - is_scrolling = false - -func update_scrollbars() -> void: - # Update vertical scroll bar - if get_v_scroll_bar().value != -pos.y: - get_v_scroll_bar().set_value_no_signal(-pos.y) - get_v_scroll_bar().queue_redraw() - # Update horizontal scroll bar - if get_h_scroll_bar().value != -pos.x: - get_h_scroll_bar().set_value_no_signal(-pos.x) - get_h_scroll_bar().queue_redraw() - - # Always show sroll bars when scrolling or mouse is on any scroll bar - if hide_scrollbar_over_time and (is_scrolling or mouse_on_scrollbar): - show_scrollbars() - -func init_drag_temp_data() -> void: - # Calculate the size difference between this container and content_node - var content_node_size_diff = get_child_size_diff(content_node, true, true) - # Calculate distance to left, right, top and bottom - var content_node_boundary_dist = get_child_boundary_dist( - content_node.position, - content_node_size_diff - ) - drag_temp_data = [ - 0.0, - 0.0, - content_node.position.x, - content_node.position.y, - content_node_boundary_dist.x, - content_node_boundary_dist.y, - content_node_boundary_dist.z, - content_node_boundary_dist.w, - ] - -# Get container size x without v scroll bar 's width -func get_spare_size_x() -> float: - var size_x = size.x - if get_v_scroll_bar().visible: - size_x -= get_v_scroll_bar().size.x - return max(size_x, 0.0) - -# Get container size y without h scroll bar 's height -func get_spare_size_y() -> float: - var size_y = size.y - if get_h_scroll_bar().visible: - size_y -= get_h_scroll_bar().size.y - return max(size_y, 0.0) - -# Get container size without scroll bars' size -func get_spare_size() -> Vector2: - return Vector2(get_spare_size_x(), get_spare_size_y()) - -# Calculate the size x difference between this container and child node -func get_child_size_x_diff(child: Control, clamp: bool) -> float: - var child_size_x = child.size.x * child.scale.x - # Falsify the size of the child node to avoid errors - # when its size is smaller than this container 's - if clamp: - child_size_x = max(child_size_x, get_spare_size_x()) - return child_size_x - get_spare_size_x() - -# Calculate the size y difference between this container and child node -func get_child_size_y_diff(child: Control, clamp: bool) -> float: - var child_size_y = child.size.y * child.scale.y - # Falsify the size of the child node to avoid errors - # when its size is smaller than this container 's - if clamp: - child_size_y = max(child_size_y, get_spare_size_y()) - return child_size_y - get_spare_size_y() - -# Calculate the size difference between this container and child node -func get_child_size_diff(child: Control, clamp_x: bool, clamp_y: bool) -> Vector2: - return Vector2( - get_child_size_x_diff(child, clamp_x), - get_child_size_y_diff(child, clamp_y) - ) - -# Calculate distance to left -func get_child_left_dist(child_pos_x: float, child_size_diff_x: float) -> float: - return child_pos_x - -# Calculate distance to right -func get_child_right_dist(child_pos_x: float, child_size_diff_x: float) -> float: - return child_pos_x + child_size_diff_x - -# Calculate distance to top -func get_child_top_dist(child_pos_y: float, child_size_diff_y: float) -> float: - return child_pos_y - -# Calculate distance to bottom -func get_child_bottom_dist(child_pos_y: float, child_size_diff_y: float) -> float: - return child_pos_y + child_size_diff_y - -# Calculate distance to left, right, top and bottom -func get_child_boundary_dist(child_pos: Vector2, child_size_diff: Vector2) -> Vector4: - return Vector4( - get_child_left_dist(child_pos.x, child_size_diff.x), - get_child_right_dist(child_pos.x, child_size_diff.x), - get_child_top_dist(child_pos.y, child_size_diff.y), - get_child_bottom_dist(child_pos.y, child_size_diff.y), - ) - -func kill_scroll_x_to_tween() -> void: - if scroll_x_to_tween: scroll_x_to_tween.kill() - -func kill_scroll_y_to_tween() -> void: - if scroll_y_to_tween: scroll_y_to_tween.kill() - -func kill_scroll_to_tweens() -> void: - kill_scroll_x_to_tween() - kill_scroll_y_to_tween() - -#endregion - -#region Debug Drawing - -var debug_gradient := Gradient.new() - -func setup_debug_drawing() -> void: - debug_gradient.set_color(0.0, Color.GREEN) - debug_gradient.set_color(1.0, Color.RED) - -func draw_debug() -> void: - # Calculate the size difference between this container and content_node - var size_diff = get_child_size_diff(content_node, false, false) - # Calculate distance to left, right, top and bottom - var boundary_dist = get_child_boundary_dist( - content_node.position, - size_diff - ) - var bottom_distance = boundary_dist.w - var top_distance = boundary_dist.z - var right_distance = boundary_dist.y - var left_distance = boundary_dist.x - # Overdrag lines - # Top + Bottom - draw_line(Vector2(0.0, 0.0), Vector2(0.0, top_distance), debug_gradient.sample(clamp(top_distance / size.y, 0.0, 1.0)), 5.0) - draw_line(Vector2(0.0, size.y), Vector2(0.0, size.y+bottom_distance), debug_gradient.sample(clamp(-bottom_distance / size.y, 0.0, 1.0)), 5.0) - # Left + Right - draw_line(Vector2(0.0, size.y), Vector2(left_distance, size.y), debug_gradient.sample(clamp(left_distance / size.y, 0.0, 1.0)), 5.0) - draw_line(Vector2(size.x, size.y), Vector2(size.x+right_distance, size.y), debug_gradient.sample(clamp(-right_distance / size.y, 0.0, 1.0)), 5.0) - - # Velocity lines - var origin := Vector2(5.0, size.y/2) - draw_line(origin, origin + Vector2(0.0, velocity.y*0.01), debug_gradient.sample(clamp(velocity.y*2 / size.y, 0.0, 1.0)), 5.0) - draw_line(origin, origin + Vector2(0.0, velocity.x*0.01), debug_gradient.sample(clamp(velocity.x*2 / size.x, 0.0, 1.0)), 5.0) - -#endregion - -#region API Functions - -## Scrolls to specific x position -func scroll_x_to(x_pos: float, duration := 0.5) -> void: - if not should_scroll_horizontal(): return - if content_dragging: return - velocity.x = 0.0 - var size_x_diff = get_child_size_x_diff(content_node, true) - x_pos = clampf(x_pos, -size_x_diff, 0.0) - kill_scroll_x_to_tween() - scroll_x_to_tween = create_tween() - var tweener = scroll_x_to_tween.tween_property(self, "pos:x", x_pos, duration) - tweener.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUINT) - -## Scrolls to specific y position -func scroll_y_to(y_pos: float, duration := 0.5) -> void: - if not should_scroll_vertical(): return - if content_dragging: return - velocity.y = 0.0 - var size_y_diff = get_child_size_y_diff(content_node, true) - y_pos = clampf(y_pos, -size_y_diff, 0.0) - kill_scroll_y_to_tween() - scroll_y_to_tween = create_tween() - var tweener = scroll_y_to_tween.tween_property(self, "pos:y", y_pos, duration) - tweener.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_QUINT) - -## Scrolls up a page -func scroll_page_up(duration := 0.5) -> void: - var destination = content_node.position.y + get_spare_size_y() - scroll_y_to(destination, duration) - -## Scrolls down a page -func scroll_page_down(duration := 0.5) -> void: - var destination = content_node.position.y - get_spare_size_y() - scroll_y_to(destination, duration) - -## Scrolls left a page -func scroll_page_left(duration := 0.5) -> void: - var destination = content_node.position.x + get_spare_size_x() - scroll_x_to(destination, duration) - -## Scrolls right a page -func scroll_page_right(duration := 0.5) -> void: - var destination = content_node.position.x - get_spare_size_x() - scroll_x_to(destination, duration) - -## Adds velocity to the vertical scroll -func scroll_vertically(amount: float) -> void: - velocity.y -= amount - -## Adds velocity to the horizontal scroll -func scroll_horizontally(amount: float) -> void: - velocity.x -= amount - -## Scrolls to top -func scroll_to_top(duration := 0.5) -> void: - scroll_y_to(0.0, duration) - -## Scrolls to bottom -func scroll_to_bottom(duration := 0.5) -> void: - scroll_y_to(get_spare_size_y() - content_node.size.y, duration) - -## Scrolls to left -func scroll_to_left(duration := 0.5) -> void: - scroll_x_to(0.0, duration) - -## Scrolls to right -func scroll_to_right(duration := 0.5) -> void: - scroll_x_to(get_spare_size_x() - content_node.size.x, duration) - -func is_outside_top_boundary(y_pos: float = pos.y) -> bool: - var size_y_diff = get_child_size_y_diff(content_node,true) - var top_dist = get_child_top_dist(y_pos, size_y_diff) - return top_dist > 0.0 - -func is_outside_bottom_boundary(y_pos: float = pos.y) -> bool: - var size_y_diff = get_child_size_y_diff(content_node,true) - var bottom_dist = get_child_bottom_dist(y_pos, size_y_diff) - return bottom_dist < 0.0 - -func is_outside_left_boundary(x_pos: float = pos.x) -> bool: - var size_x_diff = get_child_size_x_diff(content_node,true) - var left_dist = get_child_left_dist(x_pos, size_x_diff) - return left_dist > 0.0 - -func is_outside_right_boundary(x_pos: float = pos.x) -> bool: - var size_x_diff = get_child_size_x_diff(content_node,true) - var right_dist = get_child_right_dist(x_pos, size_x_diff) - return right_dist < 0.0 - -## Returns true if any scroll bar is being dragged -func any_scroll_bar_dragged() -> bool: - return h_scrollbar_dragging or v_scrollbar_dragging - -## Returns true if there is enough content height to scroll -func should_scroll_vertical() -> bool: - var disable_scroll = (not allow_vertical_scroll) \ - or (auto_allow_scroll and get_child_size_y_diff(content_node, false) <= 0) \ - or !scroll_damper - if disable_scroll: - velocity.y = 0.0 - return false - else: - return true - -## Returns true if there is enough content width to scroll -func should_scroll_horizontal() -> bool: - var disable_scroll = (not allow_horizontal_scroll) \ - or (auto_allow_scroll and get_child_size_x_diff(content_node, false) <= 0) \ - or !scroll_damper - if disable_scroll: - velocity.x = 0.0 - return false - else: - return true - -## Fades out scrollbars within given [param time].[br] -## Default for [param time] is current [member scrollbar_fade_out_time] -func hide_scrollbars(time: float = scrollbar_fade_out_time) -> void: - # Kill scrollbar_show_tween to avoid animation conflict - if scrollbar_show_tween != null and scrollbar_show_tween.is_valid(): - scrollbar_show_tween.kill() - # Create new tweens if needed - if ( - get_v_scroll_bar().modulate != Color.TRANSPARENT \ - or get_h_scroll_bar().modulate != Color.TRANSPARENT - ): - if scrollbar_hide_tween and !scrollbar_hide_tween.is_running(): - scrollbar_hide_tween.kill() - if scrollbar_hide_tween == null or !scrollbar_hide_tween.is_valid(): - scrollbar_hide_tween = create_tween() - scrollbar_hide_tween.set_parallel(true) - scrollbar_hide_tween.tween_property(get_v_scroll_bar(), 'modulate', Color.TRANSPARENT, time) - scrollbar_hide_tween.tween_property(get_h_scroll_bar(), 'modulate', Color.TRANSPARENT, time) - -## Fades in scrollbars within given [param time].[br] -## Default for [param time] is current [member scrollbar_fade_in_time] -func show_scrollbars(time: float = scrollbar_fade_in_time) -> void: - # Restart timer - scrollbar_hide_timer.start(scrollbar_hide_time) - # Kill scrollbar_hide_tween to avoid animation conflict - if scrollbar_hide_tween != null and scrollbar_hide_tween.is_valid(): - scrollbar_hide_tween.kill() - # Create new tweens if needed - if ( - get_v_scroll_bar().modulate != Color.WHITE \ - or get_h_scroll_bar().modulate != Color.WHITE \ - ): - if scrollbar_show_tween and !scrollbar_show_tween.is_running(): - scrollbar_show_tween.kill() - if scrollbar_show_tween == null or !scrollbar_show_tween.is_valid(): - scrollbar_show_tween = create_tween() - scrollbar_show_tween.set_parallel(true) - scrollbar_show_tween.tween_property(get_v_scroll_bar(), 'modulate', Color.WHITE, time) - scrollbar_show_tween.tween_property(get_h_scroll_bar(), 'modulate', Color.WHITE, time) - -## Scroll to position to ensure the given control node is visible -func ensure_control_visible(control: Control) -> void: - if !content_node: return - if !content_node.is_ancestor_of(control): return - if !scroll_damper: return - - var size_diff = ( - control.get_global_rect().size - get_global_rect().size - ) / (get_global_rect().size / size) - var boundary_dist = get_child_boundary_dist( - (control.global_position - global_position) \ - / (get_global_rect().size / size), - size_diff - ) - var content_node_position = content_node.position - if boundary_dist.x < 0 + follow_focus_margin: - scroll_x_to(content_node_position.x - boundary_dist.x + follow_focus_margin) - elif boundary_dist.y > 0 - follow_focus_margin: - scroll_x_to(content_node_position.x - boundary_dist.y - follow_focus_margin) - if boundary_dist.z < 0 + follow_focus_margin: - scroll_y_to(content_node_position.y - boundary_dist.z + follow_focus_margin) - elif boundary_dist.w > 0 - follow_focus_margin: - scroll_y_to(content_node_position.y - boundary_dist.w - follow_focus_margin) - -#endregion diff --git a/flumi/addons/SmoothScroll/SmoothScrollContainer.gd.uid b/flumi/addons/SmoothScroll/SmoothScrollContainer.gd.uid deleted file mode 100644 index 305c994..0000000 --- a/flumi/addons/SmoothScroll/SmoothScrollContainer.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bgqglerkcylxx diff --git a/flumi/addons/SmoothScroll/class-icon.svg b/flumi/addons/SmoothScroll/class-icon.svg deleted file mode 100644 index 30862c1..0000000 --- a/flumi/addons/SmoothScroll/class-icon.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/flumi/addons/SmoothScroll/class-icon.svg.import b/flumi/addons/SmoothScroll/class-icon.svg.import deleted file mode 100644 index 488e0a4..0000000 --- a/flumi/addons/SmoothScroll/class-icon.svg.import +++ /dev/null @@ -1,37 +0,0 @@ -[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/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 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false diff --git a/flumi/addons/SmoothScroll/debug_font.tres b/flumi/addons/SmoothScroll/debug_font.tres deleted file mode 100644 index 3871a65..0000000 --- a/flumi/addons/SmoothScroll/debug_font.tres +++ /dev/null @@ -1,3 +0,0 @@ -[gd_resource type="SystemFont" format=3 uid="uid://cw8c0p3b5mv5y"] - -[resource] diff --git a/flumi/addons/SmoothScroll/icon.afdesign b/flumi/addons/SmoothScroll/icon.afdesign deleted file mode 100644 index 1b54598f495cee0592598511294de751b7dbc329..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49347 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

xQLNLba|Inf=BJS%rn0dn5$ zfv#LIyy>cL>K1}tBJd8TWPkJgSW39l%!U)6cVl+B0@Q*}MdZR^wyu;UNr!gG+gOQ* zY7KZVDsy2ja?J=R z_?)7~)9`ljzzcTKYt#%GUh^ncj1EBE^0UGMDm#|nM!8f}qjx(wIBh?`dzZvgW?w>T zMnRYc%CW`J=Y+;fG+$0{pW~)DU0iG}L3@2(IfM)TnPI}ajOZYhu%=x(@9xgEMOhW57d3|lTL(>}f4J(* zT&Fs{<(iaz! zo|QRRh_rtA-QIb+Daze$Nac?N7w|Mcj)JmgA?Z+R{DMU-S z5ySV7>Gc9`xFYz{p{U=5dmq&b`ywCnM=hzL{)9F@x@a3= z+BmrG4Q=#G8e2yb_C*97{^;!HQ=~g#My)YN{wwVxN8Mlk@JH!O*58 zFt|(Oin{S9Notj2z#Z?)ScdgD)N3#iEQFoOr7?QnyTj;0QdD(IbKo?mjjhQk|Egli zuYZ52)`wi5pmi#zqT_e<+a${dby12E+c_CwSjdFg`WqQy}f+}C>SHVY{%gUb3i zzTIQ8Pf_@RCpS^@QMmBV)Hv9#xGb$UXALBDDg;`+JpImEx`HHzY*EH$?Z^wJeBWL0 zLV#7D=Z@A_A$J~VYl@MkIsTFIg?g~m5&tK}7@5&O_5%|qx{)VS2y}AzZUH`PP07#o zsoxA(8bm-ewnzKj-!(dpb_zzUhrCb_>B)W1h~knH_ts&sm6r=IEUA;QoO$Uxsi7C^ z{AsLkr@w~82{G0~cIC;dW_4gluQ0pvhLriJk4};J^<6AFV5CYi#}2spQM*3vlkN0J z?RP7@ouUec8Ta3Vj?e5itf~WEwKiY2xo9HuTbkxaZ~DGMZkBA=@Kl3yVdp1&K>n2? z=@|0~02LBbow%tz zmO!-P>zIv~f{QLhB)$C+8k4Y7==R`}^?Lm}5Z} zi|QyEigDpxd(Wle#UZoL+GHvU(h4&Iqo*TE_$5Svk}pdraWf9SCVI(b(=2ZIIhr%s zW8z#ZpZD3@A#)KHg&C+Oa_4o7L(Dqc7A8mgIOy4{SyWk5 zp!hi&8XIx7nJZUc>a!(My<&Eldyr+{^(R*}KYHX`>Cy1O5|PN$gOuVCdD**Ea{;KK zwXc+`dtr4&tNF^rpv_h7?ugsL6aCP!#Z>dZWaqVitM|)r9yIK7 zx*|iFn{yJBeVRIHHkwKb;yVaqeNr_yJ;n%I1*zs^GeW6BX{ZzCdVcf5HDUf&*W;g!k=-;vKo6U0iAG!k3L zTIZx(?u30>xfUa1A_n}?MpvG}#PC53+c4XfBMDld397Nl@}}V#+)!*iV|Z+L0rK-L4ou=;d=`I*^`3#{_NBObE*_Q zE#8o2b~+++-M|k^zM8wQWz5OmDXF4n`>yu7=Ru&Q6vP9s)ytHRoF^;QhT>)-dsLD}64j6X=Za!9>$qi%G zosju#Jv!=0Smks~fu*NF4J%Jy@JnQDd6o$icaT41pY1}fv?dtp*R(i}!8<~W z8 z>tcNS-E9hC`!0}U&;hz);`UuqO8>f_rqr+oA|Vj{dN@a5TJKqAW$w?kuz``YIwsNbY3t~fQ^$4P*OcUE`Zp_t`xW36LB*{bYvH58M;C1S$0RVf0-egDZSes8A&&C02aUY=NGp^u z>!k}@UwecEB|#IGOGyD1kZ_D}prGhkcW)>k7;WFb8m9P4iUO2!;R8snMGRo&?zjRT z352FqaU$LFHcX5td&DIY>KooSxvg#aR5E zWP8Z;Q}T(c?2510KZW-sEA2GvN`t&|y(3yi-@>*nUQ4B&H^O&GPM`w%0_&mZ;i!eI zN2dbKq!OI{sxNa#D>1vmP(8wBM%atm?`Per+&zf=P4;Gb^RyhQu$O#I6uoyGQ%o|<$G~zXTrSp zzQTV|Wl<;##<;iUl@@(coEI;%XWZ;ivvTxvHUeB$EFo`5wqoo$PQkw2bdQyOds_#P zV4`+H^^-dq&)cwal}S+u#9BUxRs1c!;yl04fT`kKX1azZHpupl$oZ3Sr(coGjjala zHYDpmwB)%I7BR48F~WKYya~r%T>=r@7`+Se!*z@kTNX4pl5D=DpQ29m=Dc_5x(;it zLpo1;6u(0?dZ2_mPBCjhJPg`F8AQ2!gT<(@-09JUJQ>`95%vhA5VQ6=D{IbMyT5z6 zJDKSA7o4!2zRfAF%EcijpipMk zE_d#P8p!flMcc+`pzX6`kW?TsKUaOB(D~FNRUB6B`iM}K15T^u}c!kZcR;BVD2wYUb^uNt`PmIu3A!BIV(X;>vnYrJ3$uxI=%Yq{?T(x zf!mxtOav&2)lu3*q`~JJhwL5K1lHsKnq3HTE~Wd6EbPI}DQ>dt9l4hdoL#9tU|mbl z@;u!vloSc6*Nd$FrOS;eciXygCUNNMeh?&@I&Klb^0sB>LFmjsOwQUM@JnBKNTe%2 z#Z1YA1jLt*4x8)}Tt`-8=OK%btLKcmWB6l66D89#IsBU{Vt7?n!$vuvskPmU=btniReX9HvOh0u1k7=& zSmPMBv`N-GcN647mNE4AuGvT&t(LD6M;hA8h1z&&tshe9<8U<^O{QKM{AndvZeyu2 zi#znmZ!Nzub-r&fw0y2#3C%xC*-8P!2bGnaT*y;yIoj}7@c)UMz^OBB9GTc$!=NP{ z$jJyK0!R$!P&he1=PJYa*gee$+n5GtncbG0+4;`XtiF?xK}6z8kTlhYHV6mJmz)SK zA#E`7ewt|dXS2=ZvFk_h&gHFyEf4>Ilt@7}@bbl% z1wWx$>6n7OYbZ4!<0UK6Q?W_;vjeIVYXoc&d#>N`o;= z_zch<=>xy+m`z&?{R`OGATV7{T>?~iKp{@U?!7>#{)ktayMm5Ulc^Ngb0ufsT~A-_9NS46A@-Z)yoyJ(LQ%> z=ETi|va-^Gn#Lxc0r?3iw&D@)0tP(sWLDVdj}$vV69zq@+M9_YNryg*9N2x_EP)*| zfkqVATb@Hl{lA}lPz&|okijKoC2kQTXQN(^P5g9+K`CuST6WAXgn z#+h5eG_C$@+=Z)p5F8=Y8R-S@RR z)+j-B@Us7a5ITO_J9J6icdOx*x2j>VLTt<8Z2R*EF3T^2+O}@y>^gU4F>WeJrkM=) zeDgNeV#HhWYe#5npQJx zx&LyhgT4!&z)IItznSwN{T{@a`@wffp?rYcX}|u^0J=Llj`d+tM{Q~R$9cA4Uy?7g zA2=HdQIfHL@gk|HbQ1zCejCe}-HM|`{rpW61bB`DtdL*-_CVFIQ=@DqTG_+!?^oPc2&oz8NX?RQncH}%Z=R658 z)ITVqkWRjbhAyTQ?we~k7vl1QQ&E2mXE_1hLY)7)XK9sf-nR&KIzXIj&P+%d(%kGEh-5l7WftRL0MN7w;4 z1uw@N0fH|9-m&YoRn*RzhnQZ^r@y%n@dkW4yOoj@U@nuR02MWnmPPHkP;mI$vYCtwAAbqRj2m^9s zjyy~aYm`Jf?<=~|C>>mc6!)uq|9JtR91l7NUfsqExb!NQ8zE{pQq9Fk zvG4k6gq@-q>v+$vKI4RS+_O3TC!eExEYp?H6@#X`ut0$Rr}H|NM>O;hDp|b2k5MP{ zM`#IlZSB*=(Apz}=D)Q?T{C-MIuo$ji>W2c@qRKk4fr~;v9tBcS*0idMR%}fbhm63 z2BTu};L^GZB$gKl@EQU8pOyIlFGbM2J{^d04yy!lHMDOma$XR>-}N+qK-t8Vca&m! zPA1PRZ`D(`8tA~8`v}L^@dE+76;(3R95qY>p2Pw23ek8+X9<_20P*3@<}3F#lmd4B zAz#-@fs%FWML2!GQ%NmF@DuFS-dk2BAwQwuJrFg*T{! zU*|`h*u95+Z8FoE^_2cMP4*OUG+UG&HS^+$H#;pQ4jcKl^x2OU(4F|LAPi6wJ8;4iNkCu2?b)DF!4FJeAs0NTnW1*&i=TYB ztU^b+Cs+Dtp)t0Xe=+K0_*B4868L~MD~w4MyxeHx(PXl>)U_BRqMDTz2QW8}-r}lI z11>yR-y~)ls=dq^P>gFqK;EqZE6qC(;R~88e4jX0*PnR`*)^JYoqo_+N>K`MrlNAh zRP1}la;jc?t&ZKHy7QmfW74BLGp+$8r-15{GyNLlQMU^Mdu&BZHA**Br9kRPLu#h# z>XO5`yu&R?au}glMHFny-dbYqV7m18LhfigjOMyOARk>3sgl21p`p^gm_1s;UwhPd zuF%X|mIo%UzVlDM>eFA#;lXfIy!D1PU}LupQ3{!a*_Aj0kdEJDLt=?U&(}rWRCsU| ziilv@@6L@Hi_VuIpOi#UwK;U~{n?DZL<;SEiP(^z9Skz22n^O{=EU-$mtwjGob;dS zHnsvTc;LIjFoQv?u^&SQ-tKhZw7Frl38wL)2AW+6=`KwI>9g2Z=_CT?`4m8Rr=!Pj zUca0hR#su9l)o_8Y^k^t0YT52oz(TrmL4;*s<#$N>XRbS*~05ddt~*cX&UGv0L!(i zzBMK+1w%DEbZ_lyp9OWjY@g!&^Wek)M+zmsuDcv*jUQ~^M< z0wo{V(q-mT4&ib2&U?V@8^DX09Zkn%XnK*t{(){3Z#s+d@$p@6>ffIJdI6a-Mad-k zU-jFkNWOi5bo+$Df=%yEu9{Qe!Bc7-*R6#iwAF-IV!VHaSwperf#I&O9XR6DT)So( zsJ+JQzl3?*YJz zWY!sGLL2PA!~09OK{iIf2$JI&10^s+P=5O&&0vExwg;XvSh=2A)jyXISUz)Ee~DV7 z!_e2w>*PY9bN554RsEhFS)a4^?xD|)x)h$a%(Z487{f${SRpIcyWJ(N?0Z~j_SdgCryef5KN(mrLMAnyOM@6Pn)IP~rVMVA34pV9>w(MoQwu!+%y}_OCkbe9A^h zlFG#|FxSnKjhziFd8|8#ai zx7eNEwd}vR$sdHZsI;PXD}15U6!wGDq)xd;bl{;G2KHn@2!4 zOB2H#tkpmvMuGD@uQ%^6 z)Hn+XzQ5c4`Y>-Uw^0seFl4e?d&XM#ilzP8uJ9EWf2^GY@2!Y%oNjAk0qPT{>+Dr; z(eI)zR}nQvUFLUJ35uH}wcFhb;XWTKb*-)nc}z|2qpH7AUTF0p_Po zaqLQ4^J9CRWBw*{^k2?*}ZyDIRt(O39t37?EFLXb#ht>EQSR+#Ot$ zdZ%_w14=hiq)w7Gete0I*|1n}?Z+zj8E{;?Zp9DaCwpvoZJIu_AQ&$e_Nh69hR0u- zf{8&(rfg|;MQLa<#2mHC15$W9S;frbsln&=vreUs*?Uk&QkAJ1Mc=*GrhR2o{_x)# zJh95B~_#46CAX79(eXlEzY_fv))JDz^$T?=S7o69byeTnpufi7Yb z21$Lw6#wR@sPh?27w=57zzr)qda4A(Jmsq*WE2Qwr#joQS8Nd=>E&17+6hH$NX}qn zaaDaWHHaw90i4?C7wjn~ZpYQX4kNcMN{8ffaQ?*3!PC+()7qdD4C#bcfxq^2m%Ywa zB}?st$HKs0SW!x!D@;gP-l~x>wP5d8>v#V*m*y^Q7SL^4P<>gm$5YV@zXwVE)5qCA z`abP9|#e$sLBw{Cw9~JQ6urla#NNHGN)TJtM=Jm4yL8dLw&2Y_?e!?0a(?GDK2y0^{PWCgTM{ONxL#I(3Oy`a- z$(z!>*K+FIlFua6oj8L?SB1!i2}x1`85Syv<@qu~8~#_VWYqIBH`6uc9x?GFEdJk*>`dk{4l-t zesLZyq#JaCR*s8kEX+NMbetN_EJ*5EK{z0HXU|v$&#>i1+x2(14KKP9Bfx$?|B9i+ zZv1FR;JP7TL3-GFJA*=!iwpJVFB%$$JUFK+FdN)NYv-dp>XahCcy{W8MQJPtr%sI4RanjK<3g}f(^6}f>N zdk;?}GS^VHFr4&12uwz{3_qZl58}d?Q0GdnuXSlcx8G= zWVaRskeWT_kuGtn=u>(;ltUN`wvq5MBZ)1i16Aqad}W1+s$C_I#22ERbkJ_3Kr3dh z6`%$x3*-dAcB^5w8=cy^Uhm+csfqU)uAOgXsK6(z9kaH`oJt(He>bkm2GKSct*y1q ziIl{K5l9Q@ZB8n~`rDKD1y7F@0H^s9U{n)*vT$>08r0)4bwVtHSkKJL}I={lSD z+l$QKqoxqROcyOdc9ev9HrMu+WrwdTVM9SJE806YOVfAWMR zX2P+>Tl^ml=JnV}DJwR}czYlS5}!e0u#mmxSSLy4+Krnd21rCdi6i;T&jqHH&=)^@ zmChh7AVq0Mh z$wn1}*A3I7%SNaACf!HaW*hdx0GrL{O$c}qu%2(e8jEE2Kw$$80Tg>$)Qq=Wp+FD(t`sO7Z9bV|nySj^K=` ze)w=jiIRI8J7z36OtsmesnY+S20<_fZOr0+v@qKXi%s>?cWIl6Fj&v#cThI7N|XLK zzhJQP>L%#f7iXs=j+()VEqpJk9^Ai#QWB>Zqk~?REsYs$%Nn=o7|^p>9gcj=W(E!F z%dHvLXnG7y1KE-i@FL^$ae3yNyd%&VFj#V6uc_X=FXV7pppJF=gcQlY$FwuRHP~K` zk&(*g{edoXGc3K?_Nff~!+5v``A9)gA{+6DkdNx2OQ@@t)qTo>XFWPPf<8VPl-vCx zCykIQ|COLTB9`@uiZjwIyv|18hEk8|7@R8A0;%s!r_+$pa|grcL&DBHByd;L%_s0z z$4xsUE+f>Xog{PUj(&~F#oi)DFBHLYz==}7cIuldl|-Kj=*92~3OK#w2s7TCQ8JK=bBPu31&EN1*U zDb4&6+dd>sd*euOPQpGp>>T~57)0@sYuhb}f=7)WZL_!|QSt9zRg_*d0Az=v*CCBX zAhv9WHbJr|jlhT5zCdVq zhvJ>Y5tns5Wm2i<*W?b@O7H^yLlUjwvK>!Ug<`;*d1B<5=RTMBN`}5z>bY$dz~9+z zX&g|%&>hHyW+AQ^?)4L9BS4Ci8%&kA&K}95JGDjPRZ2Oqk9%*Zvdnq|CP2(qPtp^6 z0*Bih^5N)m9X+TO7cFz{w>={pQ-+j8E1?u1<=c)TZ*ju*PTi_tlM_G{g! zVa~ex6R0%w=&T-CniUy!ICtYy-XLlVHXUNjVss3acdDaTs#mhf34f>J@tM;ME0vwy+E`!>A|fYyMxey#L2k3&OLEUTzt&K9V8U z!IE+H7(C8_>23`tMjp@{o!hZ%$yD%c*TsH#K0_+;f5+EU4vT!f94A+{G_aB-E7H{2^rB{`SpF6{!ygG9d2(%L z@7r{(PwC`|71Aq`uKezot>>@5W%|eP7=P@s#WtgRMTxnQ+;u+ z_r4)NNJ$nO=bHe66ch|bALQf67h^VNo(1LIlkemOKNIpU^~iJLM}DTsN932jxNour zDDV&|XFb1Gk#KWuzbqoO&nZ09V??q(gdQ4p!Yq@)D-KbN7RvQydw1tOCv3(Q zk+7N8!{@r^glDtiSytl}m8FhUCTwDWg|ok`z5Fj;w-yVP1hdDXy@PaKoZ8w%=T`_C978h`d%=4y|q zCg!A86j`U%wn>tO^bDxka0G1T$+uc?moNS{in!lfk=aT2IDas{IGDh6xR4>>f2ti~ zRIB!!vaIMgWy6)3eajiQ#c8FSN3uXB3t*-ZwPmpzV22mArbX!KI4; ziz?s@I4wH(E@Rk%Tzk}c>V>>HtHDoAajUmd;8DJJ4;Nq|lE_z^y5hH=;+f}bx^<*6 zc0;}Gr+tWWq*uvBZrGvcf*a;A3jz62F)c^PK~X@z`=i{la)!w>Vm#@EwB=*#rLX&qm=6|E!qXZC_?>s<;?Hj$@jO9I{+d${qn zpDmOSWh<5{p^@tBsGgNSmcg9lBKt*(B-fQ5kQC@CM}phid?4UvY0lKf`xL z_bs z;y~)R+y0f2e(|gYAKI5%Hj7=qNb$7LlfXQk|9>y!lKIFAPQiOOlm_Vn8519HuKs`XV8sm z7CY6f2>hl_QYKo&4A%dTSpgJO;5rg$^(AnR0$RB~?ZI7y7*}D~4!5%CHK^-GTSu4)1X`Pa2S^Fh99=91Jjq#4vunFxCo->c(tXlI}EBDJm;{#d$a$^6fmhA%Bb z6uU)PH_IxJEwvEui5*H_%{9_YpEALs zC{W@?Q&9DprRHM1|G#dxU4M$KHLWqf1h4c;ja(gSiSv2!svsk$H{8RJ6SQCb1jeH} zO9_dcmtz%Ox0WTV_dY**`bU19M%vPb>#?u_ch#(<=;rJX*+bestlR-Sk<*{)T2FvF z{`A-+^AkH&XNz}a9fUMgHGUy!FVQVOHZ&AM9*UZf`i%*Z;l{UpRJ)H_zqHbAzcR;u*JUEP~;A^%7y z52L!rls}5W8!(zc>%?p8dzqgWtS6b~okn}~+SG5C)w%H9|I{Q?qLRDpoHOWU`P@8r z(Cg%x`oMqgycQdmpNAl}pLpt!x=iGLWGK@E8{eA~)J(zrQ_gO|ZA%$UF-TfZ^OlKD zlJFp|5Fn<(z%ilhO@Nd(Ti#oob#X9f#@k2zS+*W--%XoN-{fM?XVREbzHSH1Op0@1 zD%FfxNcRbN6TH_VWc@>D15i1xb-Un>unHvQZFb(8;CoG=hvLTY!|v!F>O|n7tdcwT z(O1{fKLn4Tf=Lv&56=3Kkk$tl^Y+$j+53dz*PU~iL3-0rlh_B)X|`h$TnK4u0fUwj zVv_Xu^n6psd`G-icXwAs&p|t7)Tfu?WX_PhA+`dh8?AO#u{2r!&HIylVZ4sn+^8X0 z$%WJ6ZsiPl2^~ZrgbkP}nK=dq@opjjmk;}5J^v4D@z9#O{*`Y}a6{~&ztERq@YeE| zMc^V_CfAQ<1TSQMJxHn?c@mJBkF@=DUcD`6UGUqT;WysZ^*u{!JWiwGs%hHE%U6Jz z{KLg?GwwhY&Nyg`KLbxcnJX_B828%qF-sf)JNL3J0uuI%&6a;ujf#9 zzu4;9>-l4lphl=k9Iviqmk@1UQhjDoANvODj6)8Hm|0Ke$+R>*^Amczhs$7o4vMrM zgz45DKU~SnCt=FEl|uDX*}~i)o6+Cu&YuV_t1^#m<$_MMC;7-j2>`1AZ-@fzp7oYg zwvgp{~`7+S6f@^-q8^$Fi;^P5_60$F{E zbfZ}=*KHGv+#rS4D`Ze6DLT((fj4cG{@DSiceaWbaB!$|S41VF;Rj@El?>zJ2Gmg`3SlPw*XMSO)t$E3^b! zR}pkj^t(ccMF)!Al-;E#nXO4;|7>LlDI@su{qG*+loiu%ml(U);>O{*<$~l!W6j#% zkoWT3J3?642t zCr=W_$Olu^)PMAJMwr133k3mHrTn)_9(fQECFARuW0OsHfg-t`EuzP6A#FlM+CBhZ#Q+25}ivAGobaiMewS1Cuk-H zEl6Zrju~nk<8X~5Vux{`NJ{c!%4*tadjnrJRq*`#VvmyA8SU70!iQeG zlM_UojOaJ04ta`PI!TH1u@hiKJaSxF7PnwNkCmAI#5QGg`xubEyL=`4&j(0O4*I0~ z#FkGszTG|bDxy-puxX5SH`4@E&q5K;;_!SV>+Pc0>qWi;E$FF^0`o zkG9KLpEoBY>E0+FmMGunhsVK_tH-F?JkUJW=`pe33qhuCF}SzayXuc?rlB|0D?O6= zl+pxwP(>+0HR=!29`E}QYS!r3Aru$|5gD#=J1URhj>6{iXRG=D+j^a9C-)?|tPb=;FH)NmksF}f^LeZf8cW;fxWcpqIV9nolzE8R(q zI_aKYKFDZ2Or=)XK(5LUSp|>*d~X6>%k_$pzoNnB!=Vrz<_gA!(-Nm$J%Ec4GcAtK z+x@(g@(zDqC0mWVb13%D20lh09Ae?#|1`1_wg-j;!%dD%iyR*R5wcinwm1iO5Aw)bybrnh>7 zQSb_qchrgQjC7Ey|NRR)gSxv+rpDhkpehiO6aScA*{xgBvKjdmpGcp5?RyG38(_+( z>x$L>x|#6Y;l&~-;+s~mbCP1H4}Kdo*R;@=IRcyU{_CrPqizeuyCh>6O@_^6sOJ%= ztT{o+Um4-SoJDU_b4IH!C)qt!n`>p&5?lExgVk|$wtH(HQul;#d!3*8Sh<=*A|P4# z>VL=&+;ya~NcCInUcCV1Dm0Q2Pjg;U)?NE(2?Z6gRz=ge2=~ z;nS}3SP{%`dPN5zl)qK2q%-_lE*sF;N8OAWe(9q!BMG+`0xuE~#j4*$FKuAz*-$Ea z`zAm<4+!qI508N%VpJW;Qg*br&in+MVh&gTI3ok`ZZcZYT18Pl+K1#cPZFo|HAye> zK_~+7AP(@#$@feC-007+++ciXM`!^euUHEt(8r)gd)dnb8)mFGxr@oHjHv^L2xWza zo}@U>IGFc|dN{MwM{aW0)m4VNf3qO&@y9fP@yoh-iZ#v3wHheD%{o2LU?i~v+a{qk z(~9ir=Ii}|#&qqsig%b&npg|C^_ue#w5#z@j6C(rpJ%5evf%OG9sx7mhbE>{D9g}b zA7QeA#j^w1!1~Sz$P;6W3f7MA*$YCZXt9D+uXi1y{0HK@uYq@((1FI`c_F{gq9tGc zv|b^8YJ^3tyZ=4+2U~hYm`miY$?(a%MVHF_cB5*A3ITJ}_fyp3pFLVw7wZtI4bkm% z=iWWb(7Ryx>YRpMTmN<{ zP3sn)YTuxtv%*>eyF^pI{c1EV{CI2&Do_q)1~|_Xu2Q(+|G5T7(b0~Tn+>O+61#58 zY`FsY(^eCU5l%vqS*L*fmGv8_ezj9Pol|8?J~JZjSXE*^Mr;Kt!&L#)n_{!Ch++jUd~1{QJJYwy`l( zj_qDbJE=arMjd$>43qbVri^~Wu*1AxO2QG^X(&7$R8p7TM9CnV*WVtlHAfF`{(^XM zn~Ui-S$MDR9w$SizHyGG$!(VLID{0~X!KnRAYW9PD)X>6YA-y|!#T_{eH&6EplI_Z zD@4x><{(_{l|&esX#~IeHQd1i$f|si(hQ5Nv^fkVqIg`!u@3BvS&~FZ`!vyBK2SxY zW;*Xp!?#aw=XNzt?;X2jjIR6=z3wO!|&FWLg(@ra`&>3?}g9p&-+b^GBj?l`gv>6(H~d4sGl@; zQI9{=rtlYujBG*+vxOD-O1DdtJ%z;j7(NrtKUx1Un8>_bz!Q1=3mV6d*=DhEt;4GY z=p^t!Gh{HSjQI->w#WRp6}Ee{`*!D^wMu!<1pj{29&DKmYRFeD8b`!GGty($ZnShU zVaT4iHs+cC&g(qH@0QYqQ?TL--l_qJJDYV{ZD#@%bUy59mE~ACNX0us@2ty}UBv~T zvuG4sgHV-5EU>_A{gG{g@rQV7>>bdR>Vl>l(Z-h&2@e?iB#G>O=!ax#No@4sc%VVS zz3Z=ibzVI>N@lAP?{sN(_BgTZ&RraUXy#;Mx_!{YWY)wgR)RG_SfxtCK|K~2h{VI} zkr5ej^HaUMuN~sCNB7+PzTZh6JKNiz?WLiFPg`s8$eXX)BYS~*Ia9qlAUM*CpEL=J zU%VgPSjQXF0HPw5hQ@6Gv~1VYPJ{b+dEL$@G}_-`D@?=2VX-}s(w;$gjavkD)s%yJ zMQy)meD(KheqEsmP3Nf_zkkd+VF!=3bXgz*4@bkL^UBRV5AOTJ1=_OlUB34h4X?If zj{VuDZer7TNvM9j#69|oNP}u-&B>`+^~)5NvCbT1gXtMJm#i%;>14c3<`A2RZr!y* z6SyP|l?HnnXYxpC-;bLrz%`o5M0ChBD*(eB1unfqT+`=TuQuC@h8mY&EuqMtcph@q z(Q4PAwOg-o?`!M(Nlx9r0arttDB*xk2PIzOqxd>O`(yFG)ek_Z-f1?dHQDFq#_;Ma z`-9@)KVP|a_5YzT0@9NI@cpoUN2v~DACC2=^qm*gl2zhZ=DDo1b6Gz#PCuXRNz!Ka z{?udgITDzeKR<<7;{(tBeDE4tbBk7$th|?J$OZ9Voom$I{~B(qfbsT65scoMrnCu(f;F1z;X?Ng#p;{F<>!}i-Lv2O>- z&b;X8#G`~%b#H4>pu`^Nd%Q?JBBtI^gu4c=$g&COSG$Ss`*8tjJMZ^hrSm#AE{(JKnh(`uWjQ3R^uM?r)@{SDLV^YvE8x0xNoc=JJs|- zW(e}tWr4kw?eJ|vNz-^u16nH0X?$@-reqncKgZy-kY;alwl+4+wY!(KCvsBJs?3Vw zXxT1!l+Gc-x$H0$G5&(=jxnPBru2*0>m!i~sIO!}#+6()j6bpDayTd(Sfp3{fawZ= z#}z{TOd=}L>4ndzo(?~hx&}l~&5#b*AO?E_&l$wBQF2t{&D!*~D6pKU%3P^O&oI zKb4@_e4EPK}?affpe;qAm9WLcyVQk7Gw zlDmep`CnxgdN@1xZOQMATBd?Xkjl>ynbL4Q3=AXI(=x>5+}g5Yc7k{s2pl)u_uVCo zwzr3$QFaqW6l*I!%TUs=^XzE8Q+XbjfqRyKg*Z+)9$W`E2>?$^D8`scT^Tw3TN8lG zgmTp}?&o$iRIrsl+u7)Vh9>z5Sw!q}f;Xa0j?4~0>;#yxA%;MKcGlvqdWBEQHi9xT z43vBrJdo>8O5ZxYFK74GC1gSf14lNBft&#y1pJ5sMiNhR(&nb+2p@@NO^XA2(bO^r z&K8V0zQB1H_Q~qgO=e|7{6v?9mg{0m(Yn)zD*!V&@f4vrr@smONu8eah!!=<|E$de z6cNe$OuQF@$WQ*oJA8Q{D}s@Xr!v1h1nAGj>nkIeI8}Xm?HJugxHc!DjiV3$Sm)zx zT%P(|Q3E?o4A7AJdr^vU;KOnbR~2~+yL|X!1C*yA2Jo@7N_=0H> z`$&j!A6sh3*?WTTcHG0S&z6Y9z8@C9_By2nxeX$#cliYn5gFJRm5&87`-8bV=R|f! z>oJ|G&?2eQc#THQoa*@YL=WM@nT4h4BqqU^KZhIqKYR4E>NwHayV~_AIf|YJ0ZCXzdDU4qSyF2z= z+>ll+a0BZ+5ET2-_D1>sK}#DI6CGLXz+G((QfGkSEm+n|35L;&q~D`+akB2N8;`n{ zHX)R%vuC;);tAJae^ZRRrdd`*^Kmw}ZrK2E-mEhZeR{en66ES(HcNf`yR(q>Im_1Q zJl3Hvm$-3jIlYsrBZE%IZbUTwo@nuKb-^n~`C5WoyvElVg%_~D?*HSDcB{&SnhhEq zK~qdl7jDpG447?t+l#>_cadTHumP>BaSBlvkGt|2#Jrp8Z!xZ3hcBN@@KII`9~ykiJu#-=*sF{T0cz`)zi*b zC}+z;Tr9Cn@zW&_@Df~xz_WhVE6j&ZuRvePdw{P?gJUGQN>$5Hp z<-2pZHZjTbGL9JQS4v@$hnC5DAtbo^QtJ~NO;h}()`)W^(?{>v)e32Eq)n@CyeYVb z;xSG?hsW-1)Q3iSna7b|h^|_}jNx}cq=)k`J8c>NF1(8m2Z0qw`%zF8hdxRsq|{}# zExBaxU-Y*=-l};`qi&{K>dKbj(zG%lU$1Py%U5L1*m0!1(alPT85$8$vgGEIyHvyZrXQPG(E?XmP zrz!}B9fnw)lW_gb*78G`fkP0fNa^n=$$`etgjO-um(@@!(H|lNWY94Dt?d1Jyo2S$ z*oy7NnV3j#fbaFs78GpBSn3Cn)huGM`D$>O0{)4Wo4J;2c{rb$amdexg{_fPRP(V@ zLr$e%tkA!8JGL+HwcY_;Y=p_eC_)0b*uAx{m?dn}n%zBxWSfk(DX$Rcx{~y1)h`)U zc=rT0@{e`67a1V#^$>4@dc)x<;wm^g!uo2Y3AKvzH9VeNe3tpIt&OWFbN6hQWiW5gV-p74*2|a>z@`B zz1cmK#xZ~q>7+dSurfB>yXqC|=WdPJcJJ9Om$S=qlOQ)smUQLhtBVRpo}9*Awf5V` zUrbs&rgb`_;6ba~yn^_DSr^#fAEb9?Lw|R$Utus>Yq$Z|^X^UbJ%W+LSzw(#$jDYn zG0ia%2uE!|A3~3mEqlwi1uZZC_@Y4@Caz)w5+qs@M3;Fgl-6F0DRwVgA+*6<4mKl@ zv9LT=_9}|)s1$7lUy~ggy0uZKlqJjq27sRDQOyfnQ=A=qyDx*JOY8$prPW#e5^1pw zhcGq2GuF-gtS|o3H3VB`xZm04pK8s?d^l6|-qsYEwHL|2W%_*-A4c57 z!^Fd62vWKD6Cdk~^b^TS0Qgd<_(htelK3a;CxeO>|1=V#N^g@F@+d#mf2{*FwQ9Hh z*YJ*C>rTQAm_(nOL=v}{g&UyN}PDaMRPZXZIj6)LQL<5cW zg6+H~47n+qxytW4!mqvHUDQ4qc68-wggP?<%R`EcqlU+*b%PXK*~C0nVEB%)5!m5O zx6T9H^PQuv?{ zzYq=u6uAiRQ?4^R4>6wbJD4AXw;m?8BTRkg5pE(FV>pJ`gmd9KhC-pm}+ks33iN1%#NV|oszv~E;oP*1{Q?&yFc zIi6xZga?PljuID6m$j*|$PB0;sMD5EBRZWe6B9Dmwo$*k;5w!%mIMg1gxS3^Pp^^w^DXcTRc!q8o~*FynDCR@Rwh zX6;i#)!$MXOGBm75BNxwQUCqHh(^(Sd2(Ooce9DwTff*6twyQHRtpv)9x%k%W#9ebmh^+bVd1JZ5|JQ>@-@IOfd3T3tm9g z&%;~);=Mc)?*sj4dFh;zXxm-Jy*LSs^@j*e{G}ThQ#r*4rL(-BgWTn&N@aEjy&fkk zYJp;hrb%?m_Q#RH0kOOsdwqo!uuR(8#8k$}vOuD@HEiL(=NSSuV18oxV{e;-(vOs$ zZ{}9(=3feMx6U7SF|5o2dy$D8Xbdt{ZfTx`|F_8O5`X3b_ZoV@HYgEEl7}sI+~(M) zzFkjdpRb;xUU*1sPIC)1o-HEI39;n*xY-a`4JfY>8jC_0Dj^SXH^ddZ$2kw}nGMtn zK8d^vzx4(?2}9ZC%AmPy`Y%p3U$~5 zd-$y2Kb$!W4?3)haK*3Dk~d5KV7m6eHcua^3L?W-l<25FQUlyUq5HF0>R#ryT_B#gSxqqcyD1Bg4mL0TYRLh4azd);q^db;cnQZq}|bte5=U^5N&zh+byiU4!A zoPDgzs1RU4OAlfE-ZNxJ<#6k8wFH4k_|&DWls)Ggwu_M8`Z^g{9L*(wXIZs7=Qcx~ zS1}vv@a|_j5)_UeMzeSMTRsPifm2U&mHnQ*g(bLrUP&3ZUvsvt%$h+s&r+qlX* z;=AQN-4*^0&JkB{OQARW8e{7_D03G~_!;ImAuDVcD$Xf>^FJiuWX;ik4@-FI`kO53 zyM`XTk=~4Z3mV8hnpPU(5vT+}Fau}d&htCA^Wa@laY|eHANvWc-szzPhK%;*yMc0z z67O+)0@IOjD%ieAg$pAVcG?Iiohf<8Ncvrq*r@frNZt~)wXmN*`g zh^W2-RGV*DYmNYBi{iKYQl}>#^~*8PJu7Huo3{r}aSHpLa*X$}{XtPVo?7~z28DFH$UVUw?S(yj?@l^J_;}ba+8ad z@@HG?zv|Q|BUTdTRc`V5Nk!nBwP{uZ7Z`mMbQR8&sZurdV}`pBkLo~6IWj?0lA27D zT^3!w=OWxP>9-sap8N=xlxM#XVF&8YpMQQU^y>mkRVe<1cWi=yV)vDU)AJQ_R3{=| zX9`DBR?UmJS1g_3AB{gu%63Pj`YM3N7%$&41+*%Zxen66z3J(2K(Z$Qy!fg@s|mR6=c zS!cP7<{hBZ1os{VRy0!%8cu=4^s2X!7W%%YZ6An#%Wq;@tLca5fj7I0-&)B11HGQ7?yH2zPNwr1&k!=-E{UATka30H_`FJL@mnAtb zY*4E%=q~0B_>xcG?!Yu-syCiIe&`DtM4AukqN-V zn|Q9Jhwdv|4c55}O3yt$ww$%`v|MoO|5H)u#!gd~CHz#oiT(sT3-U2GE5H^D-P2kL z_=B~b=lZT}#_~@pW|`O3b1wD&xC7Il4dRNjp$%Y{rx&9vXK&nVjH?@MKj_Y{=!b{j z-nMP;`n3tRCh}gJKfytN)<@4?Aem6=aAhBM zKK#Cqj$SPp6#e&oDOGOzp>FO2U+#w#Y)2{O{g$2e>f%Vh?VeyKDT7w=T}DA1Vez%0 zX}sjH&(*@W_rskn51;n=F5Sj7z2b&`2Z@P%5Rss2tUuX^HW8*>h-Z#!4*%#RKJCF# z+0^FW`)dZz9CF9*{PoI{VpTYyDHZLpafWkJ_ukJb?s;iQz4qL{9%^g-6l#Cb zm;VRgXKn(?S$xZ}37D)}7ng{w9Je_vtM*uX1I+HyZPgZK2&RNw3tq@AH|Gp$m*P^b2n_}buQsyiUjvXZi{RaU~Z2~{7hUL==PtW|w* z+Yi2Cc64ebnkY$DfgrFRfh#{NCdbv-{Ot0}hDa3a+r%zga(==L-jsaDsfWkpP~0jvpY^+K``Lw}9L+@C@Pf%<{x>c#ev7M6@Sc=CLxRu@x%G z;zRvy0~_lY@5$X=_HFZOH%pSPD?Ic#QqSmL(+$*|a?R9~JV;Qqa-S;o49ruPPoJ6a zTosv$wCdO!yJc&#r?wv+>#4c)^-|{0Q|v^rtS2}Dq58+GYj(yeMs6iJ8q23NScy*p zI$09#BX6Hi$r9!iP(wlziFU~AHH4EDlE37V+e=uk2hHvCung+ZImdb??3)T$7nktc zOAO%zE$)zyZRa!@Hz}MyidKIa=)L6jPnwruzowCDCI}q8DG49DrpjkBbx^6SdIW5* z;`L4_Xz+LM{aIWv>+FS6iQ@>1NolnzvGQbBz`oOoPkF37b5-$UjYTI;`1qK`j(EOz zEPBXp^y7uy_7BPLWE}7QlNo|ow=LeF*5*ySF-Jdl#`uxpGwZnWxT!0Ml-P9Cxk zNVpGts1M#>tC~opYaB<@{mr7=^qW5n6Nw$$uZ%j-*KP;OuhbX1AXoC=X1b^4Yn^SE zLvxwuENOS)&%gwfecF#1!!5~jIFJfX_$QTe*!0i#3hZH&|14Wp3jK5@!3V!b>Hz

w+ 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 float: - if time <= 0.0: return 0.0 - return time*time*time * _factor - - -func _calculate_time_by_velocity(velocity: float) -> float: - return pow(abs(velocity) / _factor, 1.0/3.0) - - -func _calculate_offset_by_time(time: float) -> float: - time = max(time, 0.0) - return 1.0/4.0 * _factor * time*time*time*time - - -func _calculate_time_by_offset(offset: float) -> float: - return pow(abs(offset) * 4.0 / _factor, 1.0/4.0) diff --git a/flumi/addons/SmoothScroll/scroll_damper/cubic_scroll_damper.gd.uid b/flumi/addons/SmoothScroll/scroll_damper/cubic_scroll_damper.gd.uid deleted file mode 100644 index 5917f98..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/cubic_scroll_damper.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dlagxcnf11lr4 diff --git a/flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd b/flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd deleted file mode 100644 index c6d9b9d..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd +++ /dev/null @@ -1,47 +0,0 @@ -extends ScrollDamper -class_name ExpoScrollDamper - - -## Friction, not physical. -## The higher the value, the more obvious the deceleration. -@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider") -var friction := 4.0: - set(val): - friction = max(val, 0.001) - _factor = pow(10.0, friction) - -## Factor to use in formula -var _factor := 10000.0: - set(val): _factor = max(val, 1.000000000001) - -## Minumun velocity. -@export_range(0.001, 100000.0, 0.001, "or_greater", "hide_slider") -var minimum_velocity := 0.4: - set(val): minimum_velocity = max(val, 0.001) - - -func _calculate_velocity_by_time(time: float) -> float: - var minimum_time = _calculate_time_by_velocity(minimum_velocity) - if time <= minimum_time: return 0.0 - return pow(_factor, time) - - -func _calculate_time_by_velocity(velocity: float) -> float: - return log(abs(velocity)) / log(_factor) - - -func _calculate_offset_by_time(time: float) -> float: - return pow(_factor, time) / log(_factor) - - -func _calculate_time_by_offset(offset: float) -> float: - return log(offset * log(_factor)) / log(_factor) - - -func _calculate_velocity_to_dest(from: float, to: float) -> float: - var dist = to - from - var min_time = _calculate_time_by_velocity(minimum_velocity) - var min_offset = _calculate_offset_by_time(min_time) - var time = _calculate_time_by_offset(abs(dist) + min_offset) - var vel = _calculate_velocity_by_time(time) * sign(dist) - return vel diff --git a/flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd.uid b/flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd.uid deleted file mode 100644 index bd22621..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/expo_scroll_damper.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b7h0k2h2qwlqv diff --git a/flumi/addons/SmoothScroll/scroll_damper/icon.afdesign b/flumi/addons/SmoothScroll/scroll_damper/icon.afdesign deleted file mode 100644 index 2bd817e29fbceefba87e9d291d30222734a24472..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36905 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 C39()P diff --git a/flumi/addons/SmoothScroll/scroll_damper/icon.svg b/flumi/addons/SmoothScroll/scroll_damper/icon.svg deleted file mode 100644 index 54a8de1..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/icon.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/flumi/addons/SmoothScroll/scroll_damper/icon.svg.import b/flumi/addons/SmoothScroll/scroll_damper/icon.svg.import deleted file mode 100644 index 240f33d..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/icon.svg.import +++ /dev/null @@ -1,37 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://4ok12qtgl7xq" -path="res://.godot/imported/icon.svg-5b01e8115f19d6d63dc265815ce29c75.ctex" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://addons/SmoothScroll/scroll_damper/icon.svg" -dest_files=["res://.godot/imported/icon.svg-5b01e8115f19d6d63dc265815ce29c75.ctex"] - -[params] - -compress/mode=0 -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 -svg/scale=1.0 -editor/scale_with_editor_scale=false -editor/convert_colors_with_editor_theme=false diff --git a/flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd b/flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd deleted file mode 100644 index c563513..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd +++ /dev/null @@ -1,33 +0,0 @@ -extends ScrollDamper -class_name LinearScrollDamper - - -## Friction, not physical. -## The higher the value, the more obvious the deceleration. -@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider") -var friction := 4.0: - set(val): - friction = max(val, 0.001) - _factor = pow(10.0, friction) - 1.0 - -## Factor to use in formula -var _factor := 10000.0: - set(val): _factor = max(val, 0.000000000001) - - -func _calculate_velocity_by_time(time: float) -> float: - if time <= 0.0: return 0.0 - return time * _factor - - -func _calculate_time_by_velocity(velocity: float) -> float: - return abs(velocity) / _factor - - -func _calculate_offset_by_time(time: float) -> float: - time = max(time, 0.0) - return 1.0/2.0 * _factor * time*time - - -func _calculate_time_by_offset(offset: float) -> float: - return sqrt(abs(offset) * 2.0 / _factor) diff --git a/flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd.uid b/flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd.uid deleted file mode 100644 index 632707a..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/linear_scroll_damper.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://dvvc75dvopgcg diff --git a/flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd b/flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd deleted file mode 100644 index 308c0e0..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd +++ /dev/null @@ -1,33 +0,0 @@ -extends ScrollDamper -class_name QuadScrollDamper - - -## Friction, not physical. -## The higher the value, the more obvious the deceleration. -@export_range(0.001, 10000.0, 0.001, "or_greater", "hide_slider") -var friction := 4.0: - set(val): - friction = max(val, 0.001) - _factor = pow(10.0, friction) - 1.0 - -## Factor to use in formula -var _factor := 10000.0: - set(val): _factor = max(val, 0.000000000001) - - -func _calculate_velocity_by_time(time: float) -> float: - if time <= 0.0: return 0.0 - return time*time * _factor - - -func _calculate_time_by_velocity(velocity: float) -> float: - return sqrt(abs(velocity) / _factor) - - -func _calculate_offset_by_time(time: float) -> float: - time = max(time, 0.0) - return 1.0/3.0 * _factor * time*time*time - - -func _calculate_time_by_offset(offset: float) -> float: - return pow(abs(offset) * 3.0 / _factor, 1.0/3.0) diff --git a/flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd.uid b/flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd.uid deleted file mode 100644 index 51ad970..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/quad_scroll_damper.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://ccgjrqkk3oksk diff --git a/flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd b/flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd deleted file mode 100644 index 448f0ee..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd +++ /dev/null @@ -1,74 +0,0 @@ -@icon("icon.svg") -extends Resource -class_name ScrollDamper - -## Abstract class - -## Rebound strength. The higher the value, the faster it attracts. -@export_range(0.0, 1.0, 0.001, "or_greater", "hide_slider") -var rebound_strength := 7.0: - set(val): - rebound_strength= max(val, 0.0) - _attract_factor = rebound_strength * rebound_strength * rebound_strength - -## Factor for attracting. -var _attract_factor := 400.0: - set(val): - _attract_factor = max(val, 0.0) - - -# Abstract method -func _calculate_velocity_by_time(time: float) -> float: - return 0.0 - -# Abstract method -func _calculate_time_by_velocity(velocity: float) -> float: - return 0.0 - -# Abstract method -func _calculate_offset_by_time(time: float) -> float: - return 0.0 - -# Abstract method -func _calculate_time_by_offset(offset: float) -> float: - return 0.0 - - -func _calculate_velocity_to_dest(from: float, to: float) -> float: - var dist = to - from - var time = _calculate_time_by_offset(abs(dist)) - var vel = _calculate_velocity_by_time(time) * sign(dist) - return vel - - -func _calculate_next_velocity(present_time: float, delta_time: float) -> float: - return _calculate_velocity_by_time(present_time - delta_time) - - -func _calculate_next_offset(present_time: float, delta_time: float) -> float: - return _calculate_offset_by_time(present_time) \ - - _calculate_offset_by_time(present_time - delta_time) - - -## Return the result of next velocity and position according to delta time -func slide(velocity: float, delta_time: float) -> Array: - var present_time = _calculate_time_by_velocity(velocity) - return [ - _calculate_next_velocity(present_time, delta_time) * sign(velocity), - _calculate_next_offset(present_time, delta_time) * sign(velocity) - ] - - -## Emulate force that attracts something to destination. -## Return the result of next velocity according to delta time -func attract(from: float, to: float, velocity: float, delta_time: float) -> float: - var dist = to - from - var target_vel = _calculate_velocity_to_dest(from, to) - velocity += _attract_factor * dist * delta_time \ - + _calculate_velocity_by_time(delta_time) * sign(dist) - if ( - (dist > 0 and velocity >= target_vel) \ - or (dist < 0 and velocity <= target_vel) \ - ): - velocity = target_vel - return velocity diff --git a/flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd.uid b/flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd.uid deleted file mode 100644 index 8f446a0..0000000 --- a/flumi/addons/SmoothScroll/scroll_damper/scroll_damper.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bcy471w0pi8af diff --git a/flumi/icon.svg.import b/flumi/icon.svg.import index 1115d0a..f26921f 100644 --- a/flumi/icon.svg.import +++ b/flumi/icon.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://b3qknee38ix28" +uid="uid://upg01x0wud8q" path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" metadata={ "vram_texture": false