Files
barotrauma-localmods/Quick Interactions/CSharp/Client/CrabUI/Layouts/CUILayout.cs

180 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using Barotrauma;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
namespace QICrabUI
{
/// <summary>
/// Base class for all layouts
/// </summary>
public class CUILayout
{
public CUIComponent Host;
//NOTE: This looks ugly, but no matter how i try to isolate this logic it gets only uglier
// i've been stuck here for too long so i'll just do this
// and each update pattern in fact used only once, so i think no big deal
/// <summary>
/// This is just for debug, don't use it
/// </summary>
public void ForceMarkUnchanged()
{
decorChanged = false;
changed = false;
absoluteChanged = false;
foreach (CUIComponent child in Host.Children)
{
child.Layout.ForceMarkUnchanged();
}
}
private void propagateChangedDown()
{
changed = true;
DecorChanged = true;
foreach (CUIComponent child in Host.Children)
{
child.Layout.propagateChangedDown();
}
}
protected bool changed = true; public bool Changed
{
get => changed;
set
{
changed = value;
if (value)
{
if (Host.Parent != null) Host.Parent.Layout.propagateChangedDown();
else propagateChangedDown();
}
}
}
private void propagateDecorChangedDown()
{
DecorChanged = true;
foreach (CUIComponent child in Host.Children)
{
child.Layout.propagateDecorChangedDown();
}
}
/// <summary>
/// It doesn't optimize anything
/// </summary>
public bool SelfAndParentChanged
{
set
{
if (value)
{
changed = true;
DecorChanged = true;
if (Host.Parent != null)
{
Host.Parent.Layout.changed = true;
Host.Parent.Layout.propagateDecorChangedDown();
}
}
}
}
public bool ChildChanged
{
set
{
if (value) propagateChangedDown();
}
}
private void propagateAbsoluteChangedUp()
{
absoluteChanged = true;
Host.Parent?.Layout.propagateAbsoluteChangedUp();
}
protected bool absoluteChanged = true; public bool AbsoluteChanged
{
get => absoluteChanged;
set
{
if (!value) absoluteChanged = false;
if (value && Host.Parent != null) Host.Parent.Layout.absoluteChanged = true;
//if (value && Host.Parent != null) Host.Parent.Layout.propagateAbsoluteChangedUp();
}
}
protected bool decorChanged = true; public bool DecorChanged
{
get => decorChanged;
set
{
decorChanged = value;
}
}
internal virtual void Update()
{
if (Changed)
{
if (Host.CullChildren)
{
foreach (CUIComponent c in Host.Children)
{
c.CulledOut = !c.UnCullable && !c.Real.Intersect(Host.Real);
}
}
Changed = false;
}
}
internal virtual void UpdateDecor()
{
if (DecorChanged)
{
Host.UpdatePseudoChildren();
DecorChanged = false;
}
}
internal virtual void ResizeToContent()
{
if (AbsoluteChanged && (Host.FitContent.X || Host.FitContent.Y))
{
// do something
}
AbsoluteChanged = false;
}
public CUILayout() { }
public CUILayout(CUIComponent host)
{
Host = host;
}
public override string ToString() => this.GetType().Name;
public static CUILayout Parse(string raw)
{
if (raw != null)
{
raw = raw.Trim();
if (CUIReflection.CUILayoutTypes.ContainsKey(raw))
{
return (CUILayout)Activator.CreateInstance(CUIReflection.CUILayoutTypes[raw]);
}
}
return new CUILayoutSimple();
}
}
}