151 lines
4.3 KiB
C#
151 lines
4.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Cryville.Crtr.Browsing {
|
|
public class PVPNumber : PropertyValuePanel {
|
|
double m_value;
|
|
public override object Value {
|
|
get {
|
|
float s_value = GetDisplayValue();
|
|
return IntegerMode ? (int)s_value : (object)s_value;
|
|
}
|
|
set {
|
|
if (value is double) m_value = (double)value;
|
|
else m_value = IntegerMode ? (int)value : (double)(float)value;
|
|
float s_value = GetDisplayValue();
|
|
m_text.text = s_value.ToString();
|
|
if (Range != null && MaxStep == 0) {
|
|
SetRatio((float)(m_value - Range.Value.x) / (Range.Value.y - Range.Value.x));
|
|
}
|
|
}
|
|
}
|
|
|
|
float GetDisplayValue() {
|
|
double s_value = m_value;
|
|
if (Precision > 0)
|
|
s_value = Math.Round(s_value / Precision) * Precision;
|
|
if (IntegerMode)
|
|
s_value = Math.Round(s_value);
|
|
return (float)s_value;
|
|
}
|
|
|
|
public bool IntegerMode { get; set; }
|
|
public bool LogarithmicMode { get; set; }
|
|
public float MaxStep { get; set; }
|
|
public double Precision { get; set; }
|
|
public Vector2? Range { get; set; }
|
|
|
|
[SerializeField]
|
|
EventTrigger m_ctn;
|
|
[SerializeField]
|
|
RectTransform m_handleArea;
|
|
[SerializeField]
|
|
RectTransform m_handle;
|
|
[SerializeField]
|
|
Text m_text;
|
|
#pragma warning disable IDE0051
|
|
void Start() {
|
|
var ev = new EventTrigger.Entry { eventID = EventTriggerType.InitializePotentialDrag };
|
|
ev.callback.AddListener(e => OnInitializePotentialDrag((PointerEventData)e));
|
|
m_ctn.triggers.Add(ev);
|
|
ev = new EventTrigger.Entry { eventID = EventTriggerType.Drag };
|
|
ev.callback.AddListener(e => OnDrag((PointerEventData)e));
|
|
m_ctn.triggers.Add(ev);
|
|
ev = new EventTrigger.Entry { eventID = EventTriggerType.EndDrag };
|
|
ev.callback.AddListener(e => OnEndDrag((PointerEventData)e));
|
|
m_ctn.triggers.Add(ev);
|
|
ev = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick };
|
|
ev.callback.AddListener(e => OnPointerClick((PointerEventData)e));
|
|
m_ctn.triggers.Add(ev);
|
|
|
|
if (MaxStep != 0) SetRatio(0.5f);
|
|
}
|
|
|
|
void Update() {
|
|
if (use && MaxStep != 0) {
|
|
SetRatio(GetRatioFromPos(pp));
|
|
SetValueFromPos(pp);
|
|
}
|
|
}
|
|
|
|
void OnRectTransformDimensionsChange() {
|
|
m_handleArea.sizeDelta = new Vector2(m_handle.rect.height - m_handle.rect.width, 0);
|
|
}
|
|
#pragma warning restore IDE0051
|
|
|
|
Vector2 pp;
|
|
bool use, nouse;
|
|
public void OnInitializePotentialDrag(PointerEventData eventData) {
|
|
eventData.useDragThreshold = false;
|
|
pp = eventData.position;
|
|
}
|
|
|
|
public void OnDrag(PointerEventData eventData) {
|
|
if (nouse) return;
|
|
if (!use) {
|
|
var delta = eventData.position - pp;
|
|
float dx = Mathf.Abs(delta.x), dy = Mathf.Abs(delta.y);
|
|
if (dx > dy) use = true;
|
|
else if (dx < dy) nouse = true;
|
|
}
|
|
if (use) {
|
|
pp = eventData.position;
|
|
if (MaxStep == 0) SetValueFromPos(eventData.position);
|
|
eventData.Use();
|
|
}
|
|
}
|
|
|
|
public void OnEndDrag(PointerEventData eventData) {
|
|
if (!nouse) {
|
|
SetValueFromPos(eventData.position);
|
|
Callback(Value);
|
|
if (MaxStep != 0) SetRatio(0.5f);
|
|
eventData.Use();
|
|
use = false;
|
|
}
|
|
nouse = false;
|
|
}
|
|
|
|
public void OnPointerClick(PointerEventData eventData) {
|
|
SetValueFromPos(eventData.position);
|
|
Callback(Value);
|
|
eventData.Use();
|
|
}
|
|
|
|
float GetRatioFromPos(Vector2 pos) {
|
|
Vector2 lp;
|
|
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_handleArea, pos, null, out lp)) {
|
|
lp -= m_handleArea.rect.position;
|
|
return Mathf.Clamp01(lp.x / m_handleArea.rect.width);
|
|
}
|
|
return float.NegativeInfinity;
|
|
}
|
|
|
|
void SetValueFromPos(Vector2 pos) {
|
|
double ratio = GetRatioFromPos(pos);
|
|
double result;
|
|
if (MaxStep == 0) {
|
|
if (LogarithmicMode) throw new NotImplementedException();
|
|
else result = (1 - ratio) * Range.Value.x + ratio * Range.Value.y;
|
|
}
|
|
else {
|
|
double delta = (ratio - 0.5f) * 2 * MaxStep * Time.deltaTime;
|
|
if (LogarithmicMode) result = Math.Pow(Math.E, Math.Log(m_value) + delta);
|
|
else result = m_value + delta;
|
|
}
|
|
if (Range != null) {
|
|
if (result < Range.Value.x) result = Range.Value.x;
|
|
else if (result > Range.Value.y) result = Range.Value.y;
|
|
}
|
|
Value = result;
|
|
}
|
|
|
|
void SetRatio(float ratio) {
|
|
m_handle.anchorMin = new Vector2(ratio, m_handle.anchorMin.y);
|
|
m_handle.anchorMax = new Vector2(ratio, m_handle.anchorMax.y);
|
|
}
|
|
}
|
|
}
|