Skip to content

Commit

Permalink
Feature: Support auto layout window
Browse files Browse the repository at this point in the history
  • Loading branch information
inmny committed Dec 24, 2023
1 parent e3c8e0a commit b4adea9
Show file tree
Hide file tree
Showing 7 changed files with 460 additions and 0 deletions.
8 changes: 8 additions & 0 deletions general/ui/window/AutoLayoutElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using NeoModLoader.General.UI.Prefabs;
using UnityEngine;

namespace NeoModLoader.General.UI.Window;

public abstract class AutoLayoutElement<T> : APrefab<T> where T : AutoLayoutElement<T>
{
}
44 changes: 44 additions & 0 deletions general/ui/window/AutoLayoutGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using UnityEngine;
using UnityEngine.UI;

namespace NeoModLoader.General.UI.Window;

public abstract class AutoLayoutGroup<T> : AutoLayoutElement<AutoLayoutGroup<T>> where T : LayoutGroup
{
public virtual void AddChild(GameObject pChild, int pIndex = -1)
{
Transform child_transform;
(child_transform = pChild.transform).SetParent(transform);
child_transform.localScale = Vector3.one;
var child_count = transform.childCount;
child_transform.SetSiblingIndex((pIndex + child_count) % child_count);
}
public virtual T GetLayoutGroup()
{
T layout_group = gameObject.GetComponent<T>();

return layout_group != null ? layout_group : gameObject.AddComponent<T>();
}
public TSub BeginSubGroup<TSub, TSubGroup>(Vector2 pSize = default)
where TSub : AutoLayoutGroup<TSubGroup>
where TSubGroup : LayoutGroup
{
GameObject game_object =
new (nameof(TSubGroup), typeof(TSub), typeof(TSubGroup));

TSub sub_group = game_object.GetComponent<TSub>();

if (pSize != default)
{
sub_group.SetSize(pSize);
}

AddChild(game_object);

return sub_group;
}
public virtual void SetSize(Vector2 pSize)
{
GetComponent<RectTransform>().sizeDelta = pSize;
}
}
117 changes: 117 additions & 0 deletions general/ui/window/AutoLayoutWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using NeoModLoader.General.UI.Window.Layout;
using UnityEngine;
using UnityEngine.UI;

namespace NeoModLoader.General.UI.Window;

public abstract class AutoLayoutWindow<T> : AutoVertLayoutGroup where T : AutoLayoutWindow<T>
{
/// <summary>
/// Component ScrollWindow of Instance for easy click show/hide/back
/// </summary>
protected ScrollWindow ScrollWindowComponent { get; private set; }
/// <summary>
/// Transform of Background/Scroll View/Viewport/Content of Instance
/// </summary>
protected Transform ContentTransform { get; set; }
/// <summary>
/// Transform of Background of Instance
/// </summary>
protected Transform BackgroundTransform { get; set; }
/// <summary>
/// It will be set to true after <see cref="Init"/> is called.
/// </summary>
protected new bool Initialized;
/// <summary>
/// It will be set to true after <see cref="OnFirstEnable"/> and <see cref="OnNormalEnable"/> called.
/// </summary>
protected bool IsOpened;
/// <summary>
/// It will be set to false after <see cref="OnFirstEnable"/> called.
/// </summary>
protected bool IsFirstOpen = true;
/// <summary>
/// WindowID of Instance
/// </summary>
protected string WindowID { get; private set; }
public static T CreateWindow(string pWindowID, string pWindowTitleKey)
{
ScrollWindow window = WindowCreator.CreateEmptyWindow(pWindowID, pWindowTitleKey);

window.gameObject.SetActive(false);

window.transform_content.gameObject.AddComponent<VerticalLayoutGroup>();
T auto_layout_window = window.transform_content.gameObject.AddComponent<T>();

auto_layout_window.BackgroundTransform = window.transform.Find("Background");
window.transform_scrollRect.gameObject.SetActive(true);

auto_layout_window.ContentTransform = window.transform_content;
auto_layout_window.ScrollWindowComponent = window;

var layout_group = auto_layout_window.GetLayoutGroup();

layout_group.childAlignment = TextAnchor.UpperCenter;
layout_group.childControlHeight = false;
layout_group.childControlWidth = false;
layout_group.childForceExpandHeight = false;
layout_group.childForceExpandWidth = false;
layout_group.childScaleHeight = false;
layout_group.childScaleWidth = false;
layout_group.spacing = 10;
layout_group.padding = new RectOffset(3, 3, 10, 10);

ContentSizeFitter fitter = window.transform_content.gameObject.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;

auto_layout_window.Init();

auto_layout_window.Initialized = true;

return auto_layout_window;
}
protected abstract new void Init();
public static void Reconstruct(ref T pWindow)
{
pWindow.ScrollWindowComponent.clickHide();
ScrollWindow.allWindows.Remove(pWindow.WindowID);

string pWindowID = pWindow.WindowID;
string pWindowTitleKey = pWindow.ScrollWindowComponent.titleText.GetComponent<LocalizedText>().key;

GameObject.Destroy(pWindow.ScrollWindowComponent.gameObject);
pWindow = CreateWindow(pWindowID, pWindowTitleKey);
}

private void OnEnable()
{
if (!Initialized) return;
if (IsFirstOpen)
{
IsFirstOpen = false;
OnFirstEnable();
}
OnNormalEnable();
IsOpened = true;
}

private void OnDisable()
{
if (!Initialized) return;
IsOpened = false;
OnNormalDisable();
}

public virtual void OnNormalDisable()
{
}

public virtual void OnFirstEnable()
{
}

public virtual void OnNormalEnable()
{
}
}
68 changes: 68 additions & 0 deletions general/ui/window/layout/AutoGridLayoutGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using UnityEngine;
using UnityEngine.UI;

namespace NeoModLoader.General.UI.Window.Layout;

public class AutoGridLayoutGroup : AutoLayoutGroup<GridLayoutGroup>
{
public ContentSizeFitter fitter { get; private set; }
public GridLayoutGroup layout { get; private set; }
protected override void Init()
{
if (Initialized) return;
Initialized = true;
fitter = gameObject.GetComponent<ContentSizeFitter>();
layout = gameObject.GetComponent<GridLayoutGroup>();
}
public void Setup(
int pConstraintCount,
GridLayoutGroup.Constraint pConstraint = GridLayoutGroup.Constraint.FixedColumnCount,
Vector2 pSize = default,
Vector2 pCellSize = default,
Vector2 pSpacing = default,
GridLayoutGroup.Axis pStartAxis = GridLayoutGroup.Axis.Horizontal,
GridLayoutGroup.Corner pStartCorner = GridLayoutGroup.Corner.UpperLeft)
{
Init();
if (pSize == default)
{
fitter.enabled = true;
}
else
{
fitter.enabled = false;
GetComponent<RectTransform>().sizeDelta = pSize;
}
layout.constraint = pConstraint;
layout.constraintCount = pConstraintCount;

layout.cellSize = pCellSize == default ? new Vector2(16, 16) : pCellSize;
layout.spacing = pSpacing == default ? new Vector2(3, 3) : pSpacing;

layout.startAxis = pStartAxis;
layout.startCorner = pStartCorner;
}
internal static void _init()
{
GameObject game_object =
new(nameof(AutoGridLayoutGroup), typeof(GridLayoutGroup), typeof(AutoGridLayoutGroup), typeof(ContentSizeFitter));

ContentSizeFitter fitter = game_object.GetComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;

var layout_group = game_object.GetComponent<GridLayoutGroup>();

layout_group.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
layout_group.constraintCount = 3;

layout_group.cellSize = new Vector2(16, 16);
layout_group.spacing = new Vector2(3, 3);

layout_group.startAxis = GridLayoutGroup.Axis.Horizontal;
layout_group.startCorner = GridLayoutGroup.Corner.UpperLeft;


Prefab = game_object.GetComponent<AutoGridLayoutGroup>();
}
}
55 changes: 55 additions & 0 deletions general/ui/window/layout/AutoHoriLayoutGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using UnityEngine;
using UnityEngine.UI;

namespace NeoModLoader.General.UI.Window.Layout;

public class AutoHoriLayoutGroup : AutoLayoutGroup<HorizontalLayoutGroup>
{
public ContentSizeFitter fitter { get; private set; }
public HorizontalLayoutGroup layout { get; private set; }
protected override void Init()
{
if (Initialized) return;
Initialized = true;
fitter = gameObject.GetComponent<ContentSizeFitter>();
layout = gameObject.GetComponent<HorizontalLayoutGroup>();
}
public void Setup(Vector2 pSize = default, TextAnchor pAlignment = TextAnchor.MiddleLeft, float pSpacing = 3, RectOffset pPadding = null)
{
Init();
if (pSize == default)
{
fitter.enabled = true;
}
else
{
fitter.enabled = false;
GetComponent<RectTransform>().sizeDelta = pSize;
}
layout.childAlignment = pAlignment;
layout.spacing = pSpacing;
layout.padding = pPadding ?? new RectOffset(3, 3, 3, 3);
}
internal static void _init()
{
GameObject game_object =
new(nameof(AutoHoriLayoutGroup), typeof(HorizontalLayoutGroup), typeof(AutoHoriLayoutGroup), typeof(ContentSizeFitter));

ContentSizeFitter fitter = game_object.GetComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;

var layout_group = game_object.GetComponent<HorizontalLayoutGroup>();
layout_group.childAlignment = TextAnchor.MiddleLeft;
layout_group.childControlHeight = false;
layout_group.childControlWidth = false;
layout_group.childForceExpandHeight = false;
layout_group.childForceExpandWidth = false;
layout_group.childScaleHeight = false;
layout_group.childScaleWidth = false;
layout_group.spacing = 3;
layout_group.padding = new RectOffset(3, 3, 3, 3);

Prefab = game_object.GetComponent<AutoHoriLayoutGroup>();
}
}
55 changes: 55 additions & 0 deletions general/ui/window/layout/AutoVertLayoutGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using UnityEngine;
using UnityEngine.UI;

namespace NeoModLoader.General.UI.Window.Layout;

public class AutoVertLayoutGroup : AutoLayoutGroup<VerticalLayoutGroup>
{
public ContentSizeFitter fitter { get; private set; }
public VerticalLayoutGroup layout { get; private set; }
protected override void Init()
{
if (Initialized) return;
Initialized = true;
fitter = gameObject.GetComponent<ContentSizeFitter>();
layout = gameObject.GetComponent<VerticalLayoutGroup>();
}
public void Setup(Vector2 pSize = default, TextAnchor pAlignment = TextAnchor.UpperCenter, float pSpacing = 3, RectOffset pPadding = null)
{
Init();
if(pSize == default)
{
fitter.enabled = true;
}
else
{
fitter.enabled = false;
GetComponent<RectTransform>().sizeDelta = pSize;
}
layout.childAlignment = pAlignment;
layout.spacing = pSpacing;
layout.padding = pPadding ?? new RectOffset(3, 3, 3, 3);
}
internal static void _init()
{
GameObject game_object =
new(nameof(AutoVertLayoutGroup), typeof(VerticalLayoutGroup), typeof(AutoVertLayoutGroup), typeof(ContentSizeFitter));

ContentSizeFitter fitter = game_object.GetComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;

var layout_group = game_object.GetComponent<VerticalLayoutGroup>();
layout_group.childAlignment = TextAnchor.UpperCenter;
layout_group.childControlHeight = false;
layout_group.childControlWidth = false;
layout_group.childForceExpandHeight = false;
layout_group.childForceExpandWidth = false;
layout_group.childScaleHeight = false;
layout_group.childScaleWidth = false;
layout_group.spacing = 3;
layout_group.padding = new RectOffset(3, 3, 3, 3);

Prefab = game_object.GetComponent<AutoVertLayoutGroup>();
}
}
Loading

0 comments on commit b4adea9

Please sign in to comment.