mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-14 15:46:36 +08:00
More progress
This commit is contained in:
138
src/UI/Widgets/AutoSliderScrollbar.cs
Normal file
138
src/UI/Widgets/AutoSliderScrollbar.cs
Normal file
@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer;
|
||||
using UnityExplorer.Core;
|
||||
using UnityExplorer.UI;
|
||||
using UnityExplorer.UI.Models;
|
||||
|
||||
namespace UnityExplorer.UI.Utility
|
||||
{
|
||||
// A Slider Scrollbar which automatically resizes for the content size (no pooling).
|
||||
// Currently just used for the C# Console input field.
|
||||
|
||||
public class AutoSliderScrollbar : UIBehaviourModel
|
||||
{
|
||||
public override GameObject UIRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Slider)
|
||||
return Slider.gameObject;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//public event Action<float> OnValueChanged;
|
||||
|
||||
internal readonly Scrollbar Scrollbar;
|
||||
internal readonly Slider Slider;
|
||||
internal RectTransform ContentRect;
|
||||
internal RectTransform ViewportRect;
|
||||
|
||||
//internal InputFieldScroller m_parentInputScroller;
|
||||
|
||||
public AutoSliderScrollbar(Scrollbar scrollbar, Slider slider, RectTransform contentRect, RectTransform viewportRect)
|
||||
{
|
||||
this.Scrollbar = scrollbar;
|
||||
this.Slider = slider;
|
||||
this.ContentRect = contentRect;
|
||||
this.ViewportRect = viewportRect;
|
||||
|
||||
this.Scrollbar.onValueChanged.AddListener(this.OnScrollbarValueChanged);
|
||||
this.Slider.onValueChanged.AddListener(this.OnSliderValueChanged);
|
||||
|
||||
//this.RefreshVisibility();
|
||||
this.Slider.Set(0f, false);
|
||||
}
|
||||
|
||||
private float lastAnchorPosition;
|
||||
private float lastContentHeight;
|
||||
private float lastViewportHeight;
|
||||
private bool _refreshWanted;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
_refreshWanted = false;
|
||||
if (ContentRect.localPosition.y != lastAnchorPosition)
|
||||
{
|
||||
lastAnchorPosition = ContentRect.localPosition.y;
|
||||
_refreshWanted = true;
|
||||
}
|
||||
if (ContentRect.rect.height != lastContentHeight)
|
||||
{
|
||||
lastContentHeight = ContentRect.rect.height;
|
||||
_refreshWanted = true;
|
||||
}
|
||||
if (ViewportRect.rect.height != lastViewportHeight)
|
||||
{
|
||||
lastViewportHeight = ViewportRect.rect.height;
|
||||
_refreshWanted = true;
|
||||
}
|
||||
|
||||
if (_refreshWanted)
|
||||
UpdateSliderHandle();
|
||||
}
|
||||
|
||||
public void UpdateSliderHandle()
|
||||
{
|
||||
// calculate handle size based on viewport / total data height
|
||||
var totalHeight = ContentRect.rect.height;
|
||||
var viewportHeight = ViewportRect.rect.height;
|
||||
|
||||
if (totalHeight <= viewportHeight)
|
||||
{
|
||||
Slider.value = 0f;
|
||||
Slider.interactable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var handleHeight = viewportHeight * Math.Min(1, viewportHeight / totalHeight);
|
||||
handleHeight = Math.Max(15f, handleHeight);
|
||||
|
||||
// resize the handle container area for the size of the handle (bigger handle = smaller container)
|
||||
var container = Slider.m_HandleContainerRect;
|
||||
container.offsetMax = new Vector2(container.offsetMax.x, -(handleHeight * 0.5f));
|
||||
container.offsetMin = new Vector2(container.offsetMin.x, handleHeight * 0.5f);
|
||||
|
||||
// set handle size
|
||||
Slider.handleRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, handleHeight);
|
||||
|
||||
// if slider is 100% height then make it not interactable
|
||||
Slider.interactable = !Mathf.Approximately(handleHeight, viewportHeight);
|
||||
|
||||
float val = 0f;
|
||||
if (totalHeight > 0f)
|
||||
val = (float)((decimal)ContentRect.localPosition.y / (decimal)(totalHeight - ViewportRect.rect.height));
|
||||
|
||||
Slider.value = val;
|
||||
}
|
||||
|
||||
public void OnScrollbarValueChanged(float value)
|
||||
{
|
||||
value = 1f - value;
|
||||
if (this.Slider.value != value)
|
||||
this.Slider.Set(value, false);
|
||||
//OnValueChanged?.Invoke(value);
|
||||
}
|
||||
|
||||
public void OnSliderValueChanged(float value)
|
||||
{
|
||||
value = 1f - value;
|
||||
this.Scrollbar.value = value;
|
||||
//OnValueChanged?.Invoke(value);
|
||||
}
|
||||
|
||||
public override void ConstructUI(GameObject parent)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user