riversong code showcase

This commit is contained in:
Daniele Marotta
2026-05-21 15:52:18 +02:00
commit 4c9eea1c02
462 changed files with 23406 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
using System;
using Cysharp.Threading.Tasks;
using UnityEngine.UIElements;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class RuntimeTooltipUIController : UIControllerSystem<RuntimeTooltipUIView>, IDisposable
{
private VisualElement _currentSource;
public RuntimeTooltipUIController(IServiceLocator serviceLocator) : base(serviceLocator)
{
}
protected override RuntimeTooltipUIView View => UIRoot.GetView<RuntimeTooltipUIView>();
public override async UniTask InitializeAsync()
{
await base.InitializeAsync();
View.Show(false);
UIRoot.RootVisualElement.RegisterCallback<PointerEnterEvent>(OnPointerEnter, TrickleDown.TrickleDown);
UIRoot.RootVisualElement.RegisterCallback<PointerLeaveEvent>(OnPointerLeave, TrickleDown.TrickleDown);
}
public void Dispose()
{
UIRoot.RootVisualElement.UnregisterCallback<PointerEnterEvent>(OnPointerEnter, TrickleDown.TrickleDown);
UIRoot.RootVisualElement.UnregisterCallback<PointerLeaveEvent>(OnPointerLeave, TrickleDown.TrickleDown);
}
private void OnPointerEnter(PointerEnterEvent evt)
{
if (evt.target is not VisualElement element) return;
var source = element.GetFirstAncestorOrSelf(static candidate => !string.IsNullOrEmpty(candidate.tooltip));
if (source == null || ReferenceEquals(source, _currentSource)) return;
_currentSource = source;
View.Show(true);
View.AnchorTooltip(source, source.tooltip);
}
private void OnPointerLeave(PointerLeaveEvent evt)
{
if (!ReferenceEquals(evt.target, _currentSource)) return;
_currentSource = null;
View.Show(false);
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
namespace DanieleMarotta.RiversongCodeShowcase
{
[UIView("runtime-tooltip")]
public class RuntimeTooltipUIView : UIView
{
private Label _content;
public override UniTask InitializeAsync(UIService uiService, VisualElement rootElement)
{
base.InitializeAsync(uiService, rootElement);
_content = rootElement.Q<Label>(className: "runtime-tooltip__content");
RootElement.SetPickingModeRecursive(PickingMode.Ignore);
return UniTask.CompletedTask;
}
public void AnchorTooltip(VisualElement anchor, string text)
{
_content.text = text;
var placeAbove = anchor.worldBound.center.y > Screen.height * 0.2f;
RootElement.EnableInClassList("runtime-tooltip--above", placeAbove);
RootElement.EnableInClassList("runtime-tooltip--below", !placeAbove);
RootElement.schedule.Execute(() => ClampToScreen(anchor.worldBound, placeAbove));
}
private void ClampToScreen(Rect anchor, bool placeAbove)
{
var width = RootElement.resolvedStyle.width;
var height = RootElement.resolvedStyle.height;
if (width <= 0 || height <= 0) return;
var left = Mathf.Clamp(anchor.center.x - width / 2, 0, Mathf.Max(0, Screen.width - width));
const float verticalGap = 32;
var top = placeAbove ? anchor.yMin - verticalGap - height : anchor.yMax + verticalGap;
top = Mathf.Clamp(top, 0, Mathf.Max(0, Screen.height - height));
RootElement.style.left = left + width / 2;
RootElement.style.top = placeAbove ? top + height : top;
}
}
}