Files
Fishery/Source/FisheryLib/GUIScope.cs
T

201 lines
4.7 KiB
C#

// Copyright (c) 2023 bradson
// This Source Code Form is subject to the terms of the MIT license.
// If a copy of the license was not distributed with this file,
// You can obtain one at https://opensource.org/licenses/MIT/.
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using UnityEngine;
using Verse;
namespace FisheryLib;
[PublicAPI]
public static class GUIScope
{
public readonly record struct WidgetGroup : IDisposable
{
public WidgetGroup(in Rect rect) => Widgets.BeginGroup(rect);
public void Dispose() => Widgets.EndGroup();
}
public readonly record struct ScrollView : IDisposable
{
private const float SCROLL_BAR_WIDTH = 16f;
private readonly ScrollViewStatus _scrollViewStatus;
private readonly float _outRectHeight;
public readonly Vector2 ViewSize;
public ref float Height
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref _scrollViewStatus.Height;
}
public Vector2 Position
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _scrollViewStatus.Position;
}
public ScrollView(in Rect outRect, ScrollViewStatus scrollViewStatus, bool showScrollbars = true)
{
_scrollViewStatus = scrollViewStatus;
_outRectHeight = outRect.height;
var viewRect = new Rect(0f, 0f, outRect.width, Math.Max(Height, _outRectHeight));
if (Height - 0.1f >= outRect.height)
viewRect.width -= SCROLL_BAR_WIDTH;
ViewSize = viewRect.size;
Height = 0f;
Widgets.BeginScrollView(outRect, ref _scrollViewStatus.Position, viewRect, showScrollbars);
}
public void Dispose() => Widgets.EndScrollView();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool CanCull(float entryHeight, float entryY)
=> entryY + entryHeight < Position.y
|| entryY > Position.y + _outRectHeight;
}
public class ScrollViewStatus
{
public Vector2 Position;
public float Height;
}
public readonly record struct ListingStandard : IDisposable
{
public Listing_Standard Listing
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
}
public ListingStandard(in Rect rect, Listing_Standard? listing = null)
=> (Listing = listing ?? new()).Begin(rect);
public void Dispose() => Listing.End();
}
public readonly record struct ScrollableListingStandard : IDisposable
{
private readonly ListingStandard _listingStandard;
private readonly ScrollView _scrollView;
public Listing_Standard Listing
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _listingStandard.Listing;
}
public Vector2 ScrollViewSize
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _scrollView.ViewSize;
}
public Vector2 ScrollViewPosition
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _scrollView.Position;
}
public ScrollableListingStandard(Rect outRect, ScrollViewStatus scrollViewStatus,
Listing_Standard? listing = null, bool showScrollbars = true)
{
_scrollView = new(outRect, scrollViewStatus, showScrollbars);
_listingStandard = new(new(0f, 0f, ScrollViewSize.x, float.PositiveInfinity), listing);
}
public void Dispose()
{
_scrollView.Height = Listing.CurHeight + 12f;
_listingStandard.Dispose();
_scrollView.Dispose();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryCull(float entryHeight)
{
var canCull = _scrollView.CanCull(entryHeight, Listing.curY);
if (canCull)
Listing.curY += entryHeight;
return canCull;
}
}
public readonly record struct TextAnchor : IDisposable
{
private readonly UnityEngine.TextAnchor _default;
public TextAnchor(UnityEngine.TextAnchor anchor)
{
_default = Text.Anchor;
Text.Anchor = anchor;
}
public void Dispose() => Text.Anchor = _default;
}
public readonly record struct WordWrap : IDisposable
{
private readonly bool _default;
public WordWrap(bool wordWrap)
{
_default = Text.WordWrap;
Text.WordWrap = wordWrap;
}
public void Dispose() => Text.WordWrap = _default;
}
public readonly record struct Color : IDisposable
{
private readonly UnityEngine.Color _default;
public Color(UnityEngine.Color color)
{
_default = GUI.color;
GUI.color = color;
}
public void Dispose() => GUI.color = _default;
}
public readonly record struct Font : IDisposable
{
private readonly GameFont _default;
public Font(GameFont font)
{
_default = Text.Font;
Text.Font = font;
}
public void Dispose() => Text.Font = _default;
}
public readonly record struct FontSize : IDisposable
{
private readonly int _default;
public FontSize(int size)
{
var curFontStyle = Text.CurFontStyle;
_default = curFontStyle.fontSize;
curFontStyle.fontSize = size;
}
public void Dispose() => Text.CurFontStyle.fontSize = _default;
}
}