Implement SuiScroller

This commit is contained in:
JeremyStar™ 2024-05-08 21:01:46 +02:00
parent 246536b89e
commit f9875906af
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
6 changed files with 287 additions and 0 deletions

View file

@ -6,6 +6,7 @@
[ext_resource type="PackedScene" uid="uid://1r7pvm0biuk7" path="res://SUI/scenesrc/SuiHeader.tscn" id="2_pcev0"]
[ext_resource type="PackedScene" uid="uid://bso65vpjqc4g4" path="res://SUI/scenesrc/SuiText.tscn" id="4_1lt1v"]
[ext_resource type="Texture2D" uid="uid://beqhfqbyme6in" path="res://SUI/dist/example.png" id="4_12skp"]
[ext_resource type="PackedScene" uid="uid://b31tqrkh73to2" path="res://SUI/scenesrc/SuiScroller.tscn" id="6_6g04c"]
[node name="Test" type="Control"]
layout_mode = 3
@ -47,3 +48,79 @@ offset_top = 368.0
offset_right = -6.0
offset_bottom = -8.0
text = "Button: Normal [b]Bold[/b] [i]Italic[/i] [b][i]Bold Italic[/i][/b] [code]Code -->[/code]"
[node name="SuiScroller" parent="." instance=ExtResource("6_6g04c")]
layout_mode = 1
offset_left = 11.0
offset_top = 8.0
offset_right = -662.0
offset_bottom = -324.0
[node name="Control" type="Control" parent="SuiScroller"]
anchors_preset = 0
offset_right = 273.5
offset_bottom = 194.5
[node name="ColorBlue" type="ColorRect" parent="SuiScroller/Control"]
layout_mode = 0
offset_right = 191.0
offset_bottom = 141.0
color = Color(0.310936, 0.514811, 0.811473, 1)
[node name="ColorTeal" type="ColorRect" parent="SuiScroller/Control"]
layout_mode = 0
offset_left = 322.0
offset_top = 33.0
offset_right = 535.0
offset_bottom = 174.0
color = Color(0.0305469, 0.474519, 0.382426, 1)
[node name="ColorOrange" type="ColorRect" parent="SuiScroller/Control"]
layout_mode = 0
offset_left = 121.0
offset_top = 180.0
offset_right = 262.0
offset_bottom = 409.0
color = Color(0.878086, 0.420512, 0.0292931, 1)
[node name="ColorBlurple" type="ColorRect" parent="SuiScroller/Control"]
layout_mode = 0
offset_left = 315.0
offset_top = 208.0
offset_right = 643.0
offset_bottom = 441.0
color = Color(0.448018, 0.409285, 0.95843, 1)
[node name="DotStart" type="ColorRect" parent="SuiScroller/Control"]
layout_mode = 1
offset_right = 2.0
offset_bottom = 2.0
color = Color(0.839216, 0.0196078, 0.196078, 1)
[node name="DotEnd" type="ColorRect" parent="SuiScroller/Control"]
layout_mode = 0
offset_left = 641.0
offset_top = 439.0
offset_right = 643.0
offset_bottom = 441.0
color = Color(0.839216, 0.0196078, 0.196078, 1)
[node name="SuiScroller2" parent="." instance=ExtResource("6_6g04c")]
layout_mode = 1
offset_left = 348.0
offset_top = 209.0
offset_right = -325.0
offset_bottom = -123.0
[node name="Control" type="Control" parent="SuiScroller2"]
anchors_preset = 0
offset_right = 273.5
offset_bottom = 194.5
[node name="ColorRed" type="ColorRect" parent="SuiScroller2/Control"]
layout_mode = 0
offset_left = 64.0
offset_top = 39.0
offset_right = 255.0
offset_bottom = 180.0
color = Color(0.834501, 0, 0.0728748, 1)

View file

@ -21,6 +21,7 @@ boot_splash/show_image=false
window/size/viewport_width=960
window/size/viewport_height=540
window/size/resizable=false
[filesystem]

View file

@ -0,0 +1,36 @@
[gd_scene load_steps=3 format=3 uid="uid://b31tqrkh73to2"]
[ext_resource type="Script" path="res://SUI/src/SuiScroller.gd" id="1_dcfql"]
[ext_resource type="Theme" uid="uid://jg7l68yqa6n2" path="res://SUI/themes/ScrollBar.tres" id="2_4lteo"]
[node name="SuiScroller" type="Control"]
clip_contents = true
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_right = -860.0
offset_bottom = -440.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_dcfql")
speed_value = 0.0
[node name="HScrollBar" type="HScrollBar" parent="."]
modulate = Color(1, 1, 1, 0.501961)
layout_mode = 1
offset_top = 86.5
offset_right = 86.5
offset_bottom = 100.0
theme = ExtResource("2_4lteo")
[node name="VScrollBar" type="VScrollBar" parent="."]
modulate = Color(1, 1, 1, 0.501961)
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -13.5
offset_bottom = 86.5
grow_horizontal = 0
theme = ExtResource("2_4lteo")

157
sui/src/SuiScroller.gd Normal file
View file

@ -0,0 +1,157 @@
@tool
extends SuiBaseClass
@export_category("Base Configuration")
@export_subgroup("Visibility")
@export var hscroll_visibility: SuiTypes.ScrollVisibility = SuiTypes.ScrollVisibility.AUTO
@export var vscroll_visibility: SuiTypes.ScrollVisibility = SuiTypes.ScrollVisibility.AUTO
@export_category("Advanced Configuration")
@export_subgroup("Scroller speed")
@export var speed_mode: SuiTypes.ScrollMode = SuiTypes.ScrollMode.MULTIPLY_CUSTOM_VALUE
@export var speed_multiplier: float = 1
@export var speed_value: float = 1
@export_subgroup("Scroller size")
@export var size_mode: SuiTypes.ScrollMode = SuiTypes.ScrollMode.MULTIPLY_VIEWPORT
@export var size_multiplier: float = 0.025
@export var size_value: float = 0
@export_category("Debugging")
@export var editor_clip_content: bool = true
func _ready() -> void:
super()
if !in_editor(): logger = core.logger.get_instance("SUI/src/SuiScroller.gd", self)
func update_element() -> void:
# Clip contents
if in_editor() and !editor_clip_content: clip_contents = false
else: clip_contents = true
# Update sizes and positions
match(size_mode):
SuiTypes.ScrollMode.MULTIPLY_VIEWPORT:
var window_size: Vector2i = Vector2i(ProjectSettings.get("display/window/size/viewport_width"), ProjectSettings.get("display/window/size/viewport_height"))
# Find smaller value
var scale_size: int
if window_size.x < window_size.y: scale_size = window_size.x
elif window_size.x > window_size.y: scale_size = window_size.y
$HScrollBar.size.y = scale_size*size_multiplier
$VScrollBar.size.x = scale_size*size_multiplier
SuiTypes.ScrollMode.MULTIPLY_CUSTOM_VALUE:
$HScrollBar.size.y = size_value*size_multiplier
$VScrollBar.size.x = size_value*size_multiplier
SuiTypes.ScrollMode.CUSTOM_VALUE:
$HScrollBar.size.y = size_value
$VScrollBar.size.x = size_value
$HScrollBar.size.x = size.x-$VScrollBar.size.x
$VScrollBar.size.y = size.y-$HScrollBar.size.y
$HScrollBar.position.x = 0
$HScrollBar.position.y = size.y-$HScrollBar.size.y
$VScrollBar.position.x = size.x-$VScrollBar.size.x
$VScrollBar.position.y = 0
# Update scrollbar properties
# Determine scroll speed
var speed: float
match(speed_mode):
SuiTypes.ScrollMode.MULTIPLY_VIEWPORT:
# Find smaller value
var scale_size: float
if size.x < size.y: scale_size = size.x
elif size.x > size.y: scale_size = size.y
speed = scale_size*speed_multiplier
SuiTypes.ScrollMode.MULTIPLY_CUSTOM_VALUE:
speed = speed_value*speed_multiplier
SuiTypes.ScrollMode.CUSTOM_VALUE:
speed = speed_value
# HScrollBar
$HScrollBar.step = speed
$HScrollBar.page = speed
# VScrollBar
$VScrollBar.step = speed
$VScrollBar.page = speed
# Update visibility
# HScrollBar
match(hscroll_visibility):
SuiTypes.ScrollVisibility.AUTO:
$HScrollBar.visible = true
$HScrollBar.modulate = Color8(255, 255, 255, 128)
SuiTypes.ScrollVisibility.SHOWN:
$HScrollBar.visible = true
$HScrollBar.modulate = Color8(255, 255, 255, 255)
SuiTypes.ScrollVisibility.HIDDEN: $HScrollBar.visible = false
_:
if in_editor(): printerr("Invalid hscroll_visibility value '" + str(hscroll_visibility) + "'")
else: logger.crash("Invalid hscroll_visibility value '" + str(hscroll_visibility) + "'")
# VScrollBar
match(vscroll_visibility):
SuiTypes.ScrollVisibility.AUTO:
$VScrollBar.visible = true
$VScrollBar.modulate = Color8(255, 255, 255, 128)
SuiTypes.ScrollVisibility.SHOWN:
$VScrollBar.visible = true
$VScrollBar.modulate = Color8(255, 255, 255, 255)
SuiTypes.ScrollVisibility.HIDDEN: $VScrollBar.visible = false
_:
if in_editor(): printerr("Invalid vscroll_visibility value '" + str(hscroll_visibility) + "'")
else: logger.crash("Invalid vscroll_visibility value '" + str(hscroll_visibility) + "'")
if in_editor() and get_child_count() == 3:
var container: Control = get_child(2)
# Update container position
container.position.x = 0
container.position.y = 0
return
# Move control
if get_child_count() == 3 and get_child(2) != $VScrollBar: move_child(get_child(2), 0)
# Make scrolling possible
if get_child_count() == 3 and get_child(0).is_class("Control"):
var container: Control = get_child(0)
var max_scrolling_distance: Vector2 = Vector2.ZERO
# Update container size
if vscroll_visibility == SuiTypes.ScrollVisibility.HIDDEN: container.size.x = size.x
else: container.size.x = size.x-$VScrollBar.size.x
if vscroll_visibility == SuiTypes.ScrollVisibility.HIDDEN: container.size.y = size.y
else: container.size.y = size.y-$HScrollBar.size.y
# Update container position
container.position.x = -$HScrollBar.value
container.position.y = -$VScrollBar.value
# Get max scrolling distance
for child in container.get_children(true):
# Ensure 'size' and 'position' variables are either a Vector2 or Vector2i if not of type Control.
if !child.is_class("Control"):
match(typeof(child.get("size"))):
Variant.Type.TYPE_VECTOR2: pass
Variant.Type.TYPE_VECTOR2I: pass
_: continue
match(typeof(child.get("position"))):
Variant.Type.TYPE_VECTOR2: pass
Variant.Type.TYPE_VECTOR2I: pass
_: continue
if child.size.x+child.position.x > max_scrolling_distance.x:
max_scrolling_distance.x = child.size.x+child.position.x-container.size.x
if child.size.y+child.position.y > max_scrolling_distance.y:
max_scrolling_distance.y = child.size.y+child.position.y-container.size.y
# Update scroll bar max value
$HScrollBar.max_value = max_scrolling_distance.x
$VScrollBar.max_value = max_scrolling_distance.y
else:
$HScrollBar.max_value = size.x
$VScrollBar.max_value = size.y
func _get_configuration_warnings():
if get_child_count() != 3:
return ["SuiScroller is intended to operate with one child only."]
elif !get_child(2).is_class("Control"):
return ["SuiScroller only supports Controls."]
return []

13
sui/src/SuiTypes.gd Normal file
View file

@ -0,0 +1,13 @@
extends Node
class_name SuiTypes
enum ScrollVisibility {
AUTO,
SHOWN,
HIDDEN
}
enum ScrollMode {
MULTIPLY_VIEWPORT,
MULTIPLY_CUSTOM_VALUE,
CUSTOM_VALUE
}

View file

@ -0,0 +1,3 @@
[gd_resource type="Theme" format=3 uid="uid://jg7l68yqa6n2"]
[resource]