added a disfunctionalk popup system

This commit is contained in:
Sebastian Bularca
2026-04-06 12:28:01 +02:00
parent cbf9f384d9
commit b8fa26865d
28 changed files with 3865 additions and 3663 deletions

View File

@@ -45,6 +45,8 @@ namespace Jovian.PopupSystem.UI {
float maxWidth;
bool isVisible;
bool layoutDirty;
Canvas rootCanvas;
Camera canvasCamera;
public CanvasGroup CanvasGroup => canvasGroup;
public RectTransform Content => content;
@@ -172,9 +174,20 @@ namespace Jovian.PopupSystem.UI {
}
}
private void CacheCanvas() {
if(rootCanvas != null) {
return;
}
rootCanvas = GetComponentInParent<Canvas>()?.rootCanvas;
canvasCamera = rootCanvas != null && rootCanvas.renderMode != RenderMode.ScreenSpaceOverlay
? rootCanvas.worldCamera : null;
}
private void PositionAnchoredTo(RectTransform target, AnchorSide side) {
var targetRect = GetScreenRect(target);
var popupSize = GetScreenRect((RectTransform)transform).size;
CacheCanvas();
var targetRect = GetScreenRect(target, canvasCamera);
var popupRect = GetScreenRect((RectTransform)transform, canvasCamera);
var popupSize = popupRect.size;
var pos = side switch {
AnchorSide.Below => new Vector2(targetRect.center.x - popupSize.x * 0.5f, targetRect.yMin - popupSize.y),
@@ -188,26 +201,36 @@ namespace Jovian.PopupSystem.UI {
}
private void PositionAtScreenPoint(Vector2 screenPos) {
CacheCanvas();
var rt = (RectTransform)transform;
if(layoutDirty) {
LayoutRebuilder.ForceRebuildLayoutImmediate(content);
layoutDirty = false;
}
var popupSize = rt.rect.size;
var popupSize = GetScreenRect(rt, canvasCamera).size;
// Clamp to screen
screenPos.x = Mathf.Clamp(screenPos.x, screenEdgePadding, Screen.width - popupSize.x - screenEdgePadding);
screenPos.y = Mathf.Clamp(screenPos.y, screenEdgePadding, Screen.height - popupSize.y - screenEdgePadding);
rt.position = screenPos;
// Convert screen position to parent local space
var parentRt = rt.parent as RectTransform;
if(parentRt != null) {
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRt, screenPos, canvasCamera, out var localPos);
rt.localPosition = localPos;
}
else {
rt.position = screenPos;
}
}
private static readonly Vector3[] cornersBuffer = new Vector3[4];
private static Rect GetScreenRect(RectTransform rt) {
private static Rect GetScreenRect(RectTransform rt, Camera camera) {
rt.GetWorldCorners(cornersBuffer);
var min = new Vector2(cornersBuffer[0].x, cornersBuffer[0].y);
var max = new Vector2(cornersBuffer[2].x, cornersBuffer[2].y);
// Convert world corners to screen space
var min = RectTransformUtility.WorldToScreenPoint(camera, cornersBuffer[0]);
var max = RectTransformUtility.WorldToScreenPoint(camera, cornersBuffer[2]);
return new Rect(min, max - min);
}
}