Files
SoulliesOfficial d4e860fa16 initial
2025-06-03 02:42:28 -04:00

252 lines
6.4 KiB
C#

//#define FR2_DEBUG
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Experimental.Rendering;
namespace vietlabs.fr2
{
public class FR2_SplitView
{
private const float SPLIT_SIZE = 2f;
private IWindow window;
private bool dirty;
public FR2_SplitView(IWindow w)
{
this.window = w;
}
[Serializable]
public class Info
{
public GUIContent title;
#if FR2_DEBUG
public Color color;
#endif
public Rect rect;
public float normWeight;
public int stIndex;
public bool visible = true;
public float weight = 1f;
public Action<Rect> draw;
public void DoDraw()
{
#if FR2_DEBUG
GUI2.Rect(rect, Color.white, 0.1f);
#endif
var drawRect = rect;
if (title != null)
{
var titleRect = new Rect(rect.x, rect.y, rect.width, 16f);
GUI2.Rect(titleRect, Color.black, 0.2f);
titleRect.xMin += 4f;
GUI.Label(titleRect, title, EditorStyles.boldLabel);
drawRect.yMin += 16f;
}
draw(drawRect);
}
}
public bool isHorz;
public List<Info> splits = new List<Info>();
public bool isVisible
{
get { return _visibleCount > 0; }
}
private int _visibleCount;
private Rect _rect;
public void CalculateWeight()
{
_visibleCount = 0;
var _totalWeight = 0f;
for (var i = 0; i < splits.Count; i++)
{
var info = splits[i];
if (!info.visible) continue;
info.stIndex = _visibleCount;
_totalWeight += info.weight;
_visibleCount++;
}
if (_visibleCount == 0 || _totalWeight == 0)
{
//Debug.LogWarning("Nothing visible!");
return;
}
var cWeight = 0f;
for (var i = 0; i < splits.Count; i++)
{
var info = splits[i];
if (!info.visible) continue;
cWeight += info.weight;
info.normWeight = info.weight / _totalWeight;
}
}
public void Draw(Rect rect)
{
if (rect.width > 0 || rect.height > 0)
{
_rect = rect;
}
if (dirty)
{
dirty = false;
CalculateWeight();
}
var sz = (_visibleCount - 1) * SPLIT_SIZE;
var dx = _rect.x;
var dy = _rect.y;
for (var i = 0; i < splits.Count; i++)
{
var info = splits[i];
if (!info.visible) continue;
var rr = new Rect
(
dx, dy,
isHorz ? (_rect.width - sz) * info.normWeight : _rect.width,
isHorz ? _rect.height : (_rect.height - sz) * info.normWeight
);
if (rr.width > 0 && rr.height > 0)
{
info.rect = rr;
}
if (info.draw != null) info.DoDraw();
if (info.stIndex < _visibleCount - 1)
{
DrawSpliter(i, isHorz ? info.rect.xMax : info.rect.yMax);
}
if (isHorz)
{
dx += info.rect.width + SPLIT_SIZE;
}
else
{
dy += info.rect.height + SPLIT_SIZE;
}
}
}
public void DrawLayout()
{
var rect = StartLayout(isHorz);
{
Draw(rect);
}
EndLayout(isHorz);
}
private int resizeIndex = -1;
void RefreshSpliterPos(int index, float px)
{
var sp1 = splits[index];
var sp2 = splits[index + 1];
var r1 = sp1.rect;
var r2 = sp2.rect;
var w1 = sp1.weight;
var w2 = sp2.weight;
var tt = w1 + w2;
var dd = isHorz ? (r2.xMax - r1.xMin) : (r2.yMax - r1.yMin) - SPLIT_SIZE;
var m = isHorz ? (Event.current.mousePosition.x - r1.x) : (Event.current.mousePosition.y - r1.y);
var pct = Mathf.Min(0.9f, Mathf.Max(0.1f, m / dd));
sp1.weight = tt * pct;
sp2.weight = tt * (1 - pct);
dirty = true;
if (window != null) window.WillRepaint = true;
}
void DrawSpliter(int index, float px)
{
var dRect = _rect;
if (isHorz)
{
dRect.x = px + SPLIT_SIZE;
dRect.width = SPLIT_SIZE;
}
else
{
dRect.y = px;
dRect.height = SPLIT_SIZE;
}
if (Event.current.type == EventType.Repaint || Event.current.type == EventType.MouseMove)
{
GUI2.Rect(dRect, Color.black, 0.4f);
}
var dRect2 = GUI2.Padding(dRect, -2f, -2f);
EditorGUIUtility.AddCursorRect(dRect2, isHorz ? MouseCursor.ResizeHorizontal : MouseCursor.ResizeVertical);
if (Event.current.type == EventType.MouseDown && dRect2.Contains(Event.current.mousePosition))
{
resizeIndex = index;
RefreshSpliterPos(index, px);
}
if (resizeIndex == index)
{
RefreshSpliterPos(index, px);
}
if (Event.current.type == EventType.MouseUp)
{
resizeIndex = -1;
}
}
Rect StartLayout(bool horz)
{
return horz
? EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true))
: EditorGUILayout.BeginVertical(GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
}
void EndLayout(bool horz)
{
if (horz)
{
EditorGUILayout.EndHorizontal();
}
else
{
EditorGUILayout.EndVertical();
}
}
}
}