You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/3rd/Plugins/Smart-Inspector/Runtime/Fluent UITK/FluentElement.Callbacks.cs

152 lines
5.3 KiB
C#

3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace AV.UITK
{
public partial class FluentElement<T>
{
public delegate void Call<in TEvent>(TEvent evt, CallHandle c) where TEvent : EventBase<TEvent>, new();
static class EventStorage<TEvent> where TEvent : EventBase<TEvent>, new()
{
public static Dictionary<Call<TEvent>, CallHandle> Handlers = new Dictionary<Call<TEvent>, CallHandle>();
}
/// <summary> Returns all callbacks registered to this element. </summary>
public IEnumerable<FluentUITK.EventFunctor> GetCallbacks()
{
return FluentUITK.GetCallbacks(x);
}
// TODO: OnBind
// TODO: OnAnyChange
public FluentElement<T> OnChange<TValue>(Call<ChangeEvent<TValue>> evt) { Register(evt); return x; }
public FluentElement<T> OnChange<TValue>(EventCallback<ChangeEvent<TValue>> evt) { Register(evt); return x; }
public FluentElement<T> OnChange<TValue>(Action evt)
{
Register<ChangeEvent<TValue>>(_ => evt()); return x;
}
public FluentElement<T> OnAttach(Call<AttachToPanelEvent> evt) { Register(evt); return x; }
public FluentElement<T> OnAttach(EventCallback<AttachToPanelEvent> evt) { Register(evt); return x; }
public FluentElement<T> OnAttach(Action evt)
{
Register<AttachToPanelEvent>(_ => evt()); return x;
}
public FluentElement<T> OnLayoutUpdate(Call<GeometryChangedEvent> evt) { Register(evt); return x; }
public FluentElement<T> OnLayoutUpdate(EventCallback<GeometryChangedEvent> evt) { Register(evt); return x; }
public FluentElement<T> OnLayoutUpdate(Action evt)
{
Register<GeometryChangedEvent>(_ => evt()); return x;
}
public FluentElement<T> OnClick(Action up)
{
OnClick((_, __) => up()); return x;
}
public FluentElement<T> OnClick(Action up, MouseButton button)
{
OnClick((evt, c) => up(), (int)button); return x;
}
public FluentElement<T> OnClick(EventCallback<MouseUpEvent> up)
{
OnClick((evt, _) => up(evt)); return x;
}
public FluentElement<T> OnClick(EventCallback<MouseUpEvent> up, MouseButton button)
{
OnClick((evt, _) => up(evt), (int)button); return x;
}
public FluentElement<T> OnClick(Call<MouseUpEvent> up)
{
// LMB is used as default value
OnClick(up, 0); return x;
}
public FluentElement<T> OnClick(Call<MouseUpEvent> up, MouseButton button)
{
OnClick(up, (int)button); return x;
}
FluentElement<T> OnClick(Call<MouseUpEvent> up, int button)
{
var isMouseOver = false;
// TODO: Could be improved by avoiding extra enter leave events?
Register<MouseEnterEvent>(evt => isMouseOver = true);
Register<MouseLeaveEvent>(evt => isMouseOver = false);
Register<MouseUpEvent>((evt, c) =>
{
if (button != -1 && evt.button != button)
return;
if (isMouseOver)
up.Invoke(evt, c);
});
return x;
}
public FluentElement<T> Register<TEvent>(EventCallback<TEvent> evt, TrickleDown trickleDown = TrickleDown.NoTrickleDown) where TEvent : EventBase<TEvent>, new()
{
x.RegisterCallback(evt, trickleDown);
return x;
}
public FluentElement<T> Register<TEvent>(Call<TEvent> c, TrickleDown trickleDown = TrickleDown.NoTrickleDown) where TEvent : EventBase<TEvent>, new()
{
var handler = new CallHandle
{
x = x,
eventTypeId = EventBase<TEvent>.TypeId()
};
var callback = (EventCallback<TEvent>)(evt =>
{
handler.evt = evt;
handler.totalCalls++;
handler.trickle = trickleDown;
c.Invoke(evt, handler);
});
handler.callback = callback;
x.RegisterCallback(callback, trickleDown);
if (EventStorage<TEvent>.Handlers.ContainsKey(c))
EventStorage<TEvent>.Handlers[c] = handler;
else
EventStorage<TEvent>.Handlers.Add(c, handler);
return x;
}
public FluentElement<T> Unregister<TEvent>(Call<TEvent> c) where TEvent : EventBase<TEvent>, new()
{
if (EventStorage<TEvent>.Handlers.TryGetValue(c, out var handler))
Unregister(handler);
return x;
}
public FluentElement<T> Unregister<TEvent>(EventCallback<TEvent> callback) where TEvent : EventBase<TEvent>, new()
{
x.UnregisterCallback(callback);
return x;
}
public FluentElement<T> Unregister(CallHandle handle)
{
FluentUITK.UnregisterCallback(x, handle.eventTypeId, handle.callback, handle.trickle);
return x;
}
}
}