maint: added livewatch asset
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class VariableCellGUI
|
||||
{
|
||||
public bool IsSelected { get; set; }
|
||||
public int RowIndex { get; set; }
|
||||
public int SelectedColumnIndex { get; set; }
|
||||
public bool IsNarrowMode { get; set; }
|
||||
public float ValueColumnWidth { get; set; }
|
||||
public WatchVariable Variable { get; set; }
|
||||
public Rect ValuesRect { get; set; }
|
||||
public VariableSelectedFitInfo SelectedFitInfo { get; set; }
|
||||
public bool PreferRightSelection { get; set; }
|
||||
public List<int> IndicesToDisplay { get; set; }
|
||||
|
||||
private VariableSelectedFitInfo _currentFitInfo = new();
|
||||
|
||||
private float currentSideOffset;
|
||||
private bool isRightSelection => PreferRightSelection ? SelectedFitInfo.CanFitRight : !SelectedFitInfo.CanFitLeft;
|
||||
|
||||
public void DrawValueCellSegment(Rect rect, string value, List<int> contentIndices, float progress)
|
||||
{
|
||||
if (Event.current.type is not EventType.Repaint)
|
||||
return;
|
||||
|
||||
currentSideOffset = 0;
|
||||
|
||||
if (value == string.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var isSelected = contentIndices.Contains(SelectedColumnIndex);
|
||||
|
||||
EditorGUI.DrawRect(rect.Extrude(ExtrudeFlags.All, -1f), Colors.SegmentFrame);
|
||||
EditorGUI.DrawRect(rect.Extrude(ExtrudeFlags.All, -2.5f), RowIndex % 2 == 0 ? Colors.Background : Colors.BackgroundOdd);
|
||||
|
||||
var innerRect = rect.Extrude(ExtrudeFlags.All, -4f);
|
||||
currentSideOffset = 4;
|
||||
|
||||
var progressPixels = Mathf.FloorToInt(Mathf.Clamp(progress * innerRect.height, 2, innerRect.height));
|
||||
var progressRect = innerRect.CropFromPositionWithSize(CropEdge.BottomLocal, 0.5f, progressPixels);
|
||||
var progressColor = RowIndex % 2 == 0 ? Colors.SegmentFill : Colors.SegmentFillOdd;
|
||||
|
||||
DrawFormatCells(progressRect, contentIndices, progressColor);
|
||||
DrawDividerCells(progressRect.Extrude(ExtrudeFlags.Left | ExtrudeFlags.Right, 4f), contentIndices);
|
||||
|
||||
if (isSelected)
|
||||
return;
|
||||
|
||||
var estimatedSize = Styles.VariableValue.CalcSize(WatchEditorServices.GUICache.GetContent(value));
|
||||
estimatedSize.x -= 4;
|
||||
var valueRect = innerRect;
|
||||
|
||||
if (estimatedSize.x > valueRect.width)
|
||||
{
|
||||
var dotsRect = valueRect
|
||||
.CropFromPositionWithSize(CropEdge.RightLocal, 0, 7)
|
||||
.CropFromPositionWithSize(CropEdge.BottomLocal, valueRect.height/2f - 6, 3);
|
||||
|
||||
GUI.DrawTexture(dotsRect,
|
||||
Textures.Dots);
|
||||
valueRect = valueRect.Extrude(ExtrudeFlags.Right, -6);
|
||||
}
|
||||
|
||||
if (valueRect.width > 5)
|
||||
{
|
||||
var style = estimatedSize.x > valueRect.width ? Styles.VariableValueLeft : Styles.VariableValue;
|
||||
DrawLabelWitchSearchResult(valueRect, Variable.GetValueText(contentIndices[0]), contentIndices[0], style);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawSelectedCell(Rect rect, string value, int index)
|
||||
{
|
||||
if (Event.current.type is not (EventType.Repaint or EventType.Layout))
|
||||
return;
|
||||
|
||||
var availableRect = rect.Extrude(ExtrudeFlags.All, -1);
|
||||
var estimatedSize = Styles.VariableValueSelected.CalcSize(WatchEditorServices.GUICache.GetContent(value))
|
||||
+ Vector2.right * 10;
|
||||
var resultWidth = Mathf.Max(availableRect.width, estimatedSize.x);
|
||||
|
||||
if (Event.current.type is not EventType.Repaint)
|
||||
{
|
||||
var cellRectRight = availableRect.CropFromStartToPosition(CropEdge.LeftLocal, resultWidth);
|
||||
_currentFitInfo.CanFitRight = cellRectRight.xMax <= ValuesRect.xMax;
|
||||
|
||||
var cellRectLeft = availableRect.CropFromStartToPosition(CropEdge.RightLocal, resultWidth);
|
||||
_currentFitInfo.CanFitLeft = cellRectLeft.xMin >= ValuesRect.xMin;
|
||||
|
||||
SelectedFitInfo.MergeWith(_currentFitInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
var edge = PreferRightSelection
|
||||
? SelectedFitInfo.CanFitRight ? CropEdge.LeftLocal : CropEdge.RightLocal
|
||||
: SelectedFitInfo.CanFitLeft ? CropEdge.RightLocal : CropEdge.LeftLocal;
|
||||
|
||||
var distToValuesEdge = edge == CropEdge.LeftLocal
|
||||
? ValuesRect.xMax - availableRect.xMin
|
||||
: availableRect.xMax - ValuesRect.xMin;
|
||||
|
||||
if (distToValuesEdge > 40)
|
||||
resultWidth = Mathf.Min(resultWidth, distToValuesEdge - 5);
|
||||
|
||||
var cellBackRect = availableRect.CropFromStartToPosition(edge, resultWidth);
|
||||
|
||||
if (IsNarrowMode)
|
||||
{
|
||||
cellBackRect = cellBackRect.OffsetByX(Mathf.Max(rect.width, Constants.VariableSelectionLineMinWidth)
|
||||
* (edge == CropEdge.LeftLocal ? 1 : - 1));
|
||||
cellBackRect = cellBackRect.Extrude(
|
||||
ExtrudeFlags.Top | ExtrudeFlags.Bottom,
|
||||
-Mathf.Abs(cellBackRect.height - estimatedSize.y)/2f);
|
||||
}
|
||||
|
||||
EditorGUI.DrawRect(cellBackRect, IsNarrowMode ? Colors.CellBackgroundSelectedGraph : Colors.CellBackgroundSelected);
|
||||
|
||||
DrawPreviewTriangles(cellBackRect);
|
||||
DrawSelectedCelLine(rect);
|
||||
|
||||
var cellValueRect = cellBackRect;
|
||||
var isTextFit = estimatedSize.x < cellValueRect.width;
|
||||
var textStyle = isTextFit ? Styles.VariableValueSelected : Styles.VariableValueSelectedLeft;
|
||||
cellValueRect = cellValueRect.CropFromPositionToEnd(CropEdge.LeftLocal, isTextFit ? 0 : 5);
|
||||
DrawLabelWitchSearchResult(cellValueRect, value, index, textStyle);
|
||||
}
|
||||
|
||||
public void DrawSelectedCelLine(Rect rect)
|
||||
{
|
||||
if (Event.current.type is not EventType.Repaint)
|
||||
return;
|
||||
|
||||
var edge = PreferRightSelection
|
||||
? SelectedFitInfo.CanFitRight ? CropEdge.LeftLocal : CropEdge.RightLocal
|
||||
: SelectedFitInfo.CanFitLeft ? CropEdge.RightLocal : CropEdge.LeftLocal;
|
||||
|
||||
var lineRect = IsNarrowMode
|
||||
? rect
|
||||
: rect.CropFromPositionWithSize(edge, 1, 3);
|
||||
|
||||
if (IsNarrowMode && lineRect.width < Constants.VariableSelectionLineMinWidth)
|
||||
{
|
||||
lineRect = new Rect(
|
||||
lineRect.center.x - Constants.VariableSelectionLineMinWidth / 2,
|
||||
lineRect.y,
|
||||
Constants.VariableSelectionLineMinWidth,
|
||||
lineRect.height);
|
||||
}
|
||||
|
||||
EditorGUI.DrawRect(lineRect, IsNarrowMode ? Colors.CellSelectionLineGraph : Colors.CellSelectionLine);
|
||||
}
|
||||
|
||||
private void DrawLabelWitchSearchResult(Rect labelRect, string text, int index, GUIStyle style, bool forceFullSelection = false)
|
||||
{
|
||||
if (Event.current.type is not EventType.Repaint)
|
||||
return;
|
||||
|
||||
if (labelRect.width > ValueColumnWidth)
|
||||
labelRect = labelRect.FitInRect(ValuesRect);
|
||||
style.Draw(labelRect, WatchEditorServices.GUICache.GetContent(text), -1);
|
||||
}
|
||||
|
||||
private void DrawFormatCells(Rect rect, List<int> contentIndices, Color fallbackColor)
|
||||
{
|
||||
{
|
||||
TryDrawFormatRect(rect
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
void TryDrawFormatRect(Rect formatRect
|
||||
)
|
||||
{
|
||||
if (fallbackColor != Color.clear)
|
||||
EditorGUI.DrawRect(formatRect, fallbackColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDividerCells(Rect rect, List<int> contentIndices)
|
||||
{
|
||||
WatchEditorServices.CellDividerDrawer.Draw(rect, Mathf.FloorToInt(ValueColumnWidth));
|
||||
}
|
||||
|
||||
|
||||
private Rect GetCellRect(int index, Rect rect, List<int> contentIndices)
|
||||
{
|
||||
var cellWidth = ValueColumnWidth;
|
||||
|
||||
if (index == 0)
|
||||
cellWidth -= currentSideOffset;
|
||||
|
||||
if (index == contentIndices.Count - 1)
|
||||
cellWidth -= currentSideOffset;
|
||||
|
||||
var cellRect = rect.CropFromPositionWithSize(
|
||||
CropEdge.LeftLocal,
|
||||
index * ValueColumnWidth + (index == 0 ? 0 : -currentSideOffset),
|
||||
cellWidth);
|
||||
|
||||
return cellRect;
|
||||
}
|
||||
|
||||
private void DrawPreviewTriangles(Rect rect)
|
||||
{
|
||||
var isSelectedNumberValid = Variable.IsValidNumberValue(SelectedColumnIndex, out var selectedNumberValue);
|
||||
|
||||
if (Variable.Values.IsOriginalAt(SelectedColumnIndex))
|
||||
{
|
||||
var prevToSelectedIndex = IndicesToDisplay.IndexOf(SelectedColumnIndex) - 1;
|
||||
|
||||
if (prevToSelectedIndex >= 0)
|
||||
{
|
||||
var isPrevNumberValid = Variable.IsValidNumberValue(IndicesToDisplay[prevToSelectedIndex], out var prevNumberValue);
|
||||
var isTopAngle = isPrevNumberValid && prevNumberValue >= selectedNumberValue;
|
||||
var isNextToSearchResult = false;
|
||||
var triangleLeftRect = rect
|
||||
.CropFromPositionWithSize(CropEdge.LeftLocal, IsNarrowMode ? 1 : (isRightSelection ? 3 : 0), 4)
|
||||
.CropFromPositionWithSize(isTopAngle ? CropEdge.TopLocal : CropEdge.BottomLocal, IsSelected && !IsNarrowMode ? 3 : 0, 4);
|
||||
GUI.DrawTexture(triangleLeftRect, isTopAngle
|
||||
? (isNextToSearchResult ? Textures.BlueTriangleTopLeft : Textures.WhiteTriangleTopLeft)
|
||||
: (isNextToSearchResult ? Textures.BlueTriangleBottomLeft : Textures.WhiteTriangleBottomLeft));
|
||||
}
|
||||
}
|
||||
|
||||
var nextToSelectedIndex = IndicesToDisplay.IndexOf(SelectedColumnIndex) + 1;
|
||||
if (nextToSelectedIndex < IndicesToDisplay.Count && Variable.Values.IsOriginalAt(IndicesToDisplay[nextToSelectedIndex]))
|
||||
{
|
||||
var isNextNumberValid = Variable.IsValidNumberValue(IndicesToDisplay[nextToSelectedIndex], out var nextNumberValue);
|
||||
var isTopAngle = isNextNumberValid && nextNumberValue >= selectedNumberValue;
|
||||
var isNextToSearchResult = false;
|
||||
var triangleRightRect = rect
|
||||
.CropFromPositionWithSize(CropEdge.RightLocal, isRightSelection || IsNarrowMode ? 0 : 3, 4)
|
||||
.CropFromPositionWithSize(isTopAngle ? CropEdge.TopLocal : CropEdge.BottomLocal, IsSelected && !IsNarrowMode ? 3 : 0, 4);
|
||||
GUI.DrawTexture(triangleRightRect, isTopAngle
|
||||
? (isNextToSearchResult ? Textures.BlueTriangleTopRight : Textures.WhiteTriangleTopRight)
|
||||
: (isNextToSearchResult ? Textures.BlueTriangleBottomRight : Textures.WhiteTriangleBottomRight));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user