LMQT/Assets/TouchScript/Editor/EditorUI/PagedList.cs
2024-12-10 09:03:45 +08:00

199 lines
4.7 KiB
C#

/*
* @author Valentin Simonov / http://va.lent.in/
*/
using System;
using UnityEditor;
using UnityEngine;
namespace TouchScript.Editor.EditorUI
{
public class PagedList
{
private class Styles
{
public int HeaderHeight = 0;
public int FooterHeight = 20;
public int FooterButtonWidth = 60;
public int FooterButtonHeight = 20;
public int FooterButtonSpace = 10;
public int FooterTextWidth = 8;
public GUIContent TextPrev = new GUIContent("< Prev");
public GUIContent TextNext = new GUIContent("Next >");
public int GetIntFieldSize(int value)
{
if (value < 10) return FooterTextWidth + 8;
if (value < 100) return 2 * FooterTextWidth + 8;
if (value < 1000) return 3 * FooterTextWidth + 8;
return 4;
}
}
public int ItemHeight { get; set; }
public int Count
{
get
{
return count;
}
set
{
if (count == value) return;
count = value;
reset();
}
}
public int PagesTotal
{
get
{
return pagesTotal;
}
}
public int SelectedId
{
get
{
return selectedId;
}
}
private static Styles styles;
private Action<int> onSelectionChange;
private Action<int, Rect, bool> drawItem;
private int count = 0;
// Starts from 1
private int page = 1;
private int pagesTotal = 1;
private int itemsPerPage = 1;
private int selectedId = -1;
private int oldSelectedId = -1;
public PagedList(int itemHeight, Action<int, Rect, bool> drawItem, Action<int> onSelectionChange)
{
if (styles == null) styles = new Styles();
ItemHeight = itemHeight;
this.onSelectionChange = onSelectionChange;
this.drawItem = drawItem;
}
public int FitHeight(int numberOfItems)
{
return ItemHeight * numberOfItems + styles.FooterHeight + styles.HeaderHeight;
}
public void Draw(Rect rect)
{
var h = rect.height;
h -= styles.HeaderHeight + styles.FooterHeight;
if (h < 0) return;
rect.y += styles.HeaderHeight;
rect.height = ItemHeight;
itemsPerPage = Mathf.FloorToInt(h / 22f);
pagesTotal = Mathf.CeilToInt((float)count / itemsPerPage);
int start = (Count - 1) - (page - 1) * itemsPerPage;
if (start < 0) return;
var i = start;
var t = 0;
while (t < itemsPerPage)
{
if (i < 0) draw(-1, rect);
else draw(i, rect);
rect.y += ItemHeight;
i--;
t++;
}
rect.height = styles.FooterHeight;
drawFooter(rect);
if (oldSelectedId != selectedId)
{
oldSelectedId = selectedId;
onSelectionChange(selectedId);
}
}
private void drawFooter(Rect parentRect)
{
parentRect.y += 5;
parentRect.height -= 5;
var rect = new Rect(parentRect.x, parentRect.y, styles.FooterButtonWidth, styles.FooterButtonHeight);
if (GUI.Button(rect, styles.TextPrev))
{
setPage(page - 1);
}
rect.x += rect.width + styles.FooterButtonSpace;
rect.width = styles.GetIntFieldSize(page);
var newPage = EditorGUI.DelayedIntField(rect, page);
if (page != newPage) setPage(newPage);
rect.x += rect.width + styles.FooterButtonSpace;
rect.width = 16;
GUI.Label(rect, "of");
rect.x += rect.width + styles.FooterButtonSpace;
rect.width = styles.GetIntFieldSize(page);
using (var scope = new EditorGUI.DisabledScope(true))
{
EditorGUI.IntField(rect, PagesTotal);
}
rect.x += rect.width + styles.FooterButtonSpace;
rect.width = styles.FooterButtonWidth;
if (GUI.Button(rect, styles.TextNext))
{
setPage(page + 1);
}
}
private void draw(int id, Rect rect)
{
switch (Event.current.type)
{
case EventType.Repaint:
case EventType.Layout:
drawItem(id, rect, selectedId == id);
break;
case EventType.MouseDown:
if (rect.Contains(Event.current.mousePosition))
{
selectedId = id;
Event.current.Use();
//GUI.changed = true;
}
break;
}
}
private void setPage(int newPage)
{
if (newPage < 1) newPage = 1;
else if (newPage > PagesTotal) newPage = PagesTotal;
page = newPage;
}
private void reset()
{
page = 1;
selectedId = -1;
oldSelectedId = -1;
}
}
}