Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- public class Zaicheg : MonoBehaviour
- {
- public GUISkin mys; // скин
- public float bHeight = 30f; // высота кнопок дефолтная
- public float bWidth = 100f; // ширина кнопок дефолтная
- int level = 0; // текущий уровень
- Item selected; // выбранная нами кнопка
- List<Item> list = new List<Item>(); // список элементов
- public Item itemTop; // объект служит родителем для элементов верхнего уровня
- int levelsCount = 0; // количество уровней иерархии
- public TextAsset txtStruct; // текстовый файл, в котором описана структура
- // элементы списка
- public class Item
- {
- public bool drop = true; // выпадает ли из неё меню
- public string name; // название
- public Item parent; // элемент-родитель
- public Item root; // корневой элемент
- public List<Item> childs = new List<Item>();
- public int level; // уровень в иерархии
- public int side; // 0 - сверху/снизу, 1 - слева/справа
- public int sideChilds; // 0 - сверху/снизу, 1 - слева/справа
- public int number; // порядковый номер на этом уровне у этого родителя
- public bool show; // отображать ли пункт
- public Rect bRect; // ректангл элемента
- Item itemTop; // храним информацию о "самом-самом верхнем элементе"
- // так, для порядку. Не используйте
- public Item()
- {
- }
- // основной конструктор. Пустой не используйте
- public Item(int _level, string _name, bool _drop, Item _itemTop)
- {
- level = _level;
- name = _name;
- drop = _drop;
- number = 0;
- show = false;
- parent = _itemTop;
- root = _itemTop;
- itemTop = _itemTop;
- }
- // устанавливаем положение элемента относительно других, исходя из его уровня
- public void SetSide()
- {
- if (level == 0)
- {
- side = 1;
- sideChilds = 0;
- }
- if (level > 0)
- {
- side = 0;
- sideChilds = 1;
- }
- }
- // вычисляем корневой объект иерархии для этого элемента
- public void CalcRoot()
- {
- Item lt = parent;
- while (lt.parent != null && lt.parent != itemTop)
- {
- lt = lt.parent;
- root = lt;
- }
- if (lt.parent == itemTop)
- {
- root = lt;
- }
- }
- }
- void Start()
- {
- // инициализируем, чтобы ошибок не было до момента определения
- selected = new Item(0, "", false, itemTop);
- itemTop = new Item(0, "itemTop", false, itemTop);
- ReadTXT(); // читаем файл и вытаскиваем из него нужную информацию
- Output(); // выводим отчёт о создании элементов
- }
- // парсинг файла и составление листа
- void ReadTXT()
- {
- string[] lines = txtStruct.text.Split('\n'); // разбиваем на строки
- string name = ""; // имя текущего элемента
- int level = 0; // уровень текущего элемента
- int prelevel = 0; // уровень предыдущего элемента
- // перебираем элементы
- for (int i = 0; i < lines.Length; i++)
- {
- level = lines[i].IndexOf('>'); // уровень определяется кол-вом пробелов перед тегом
- name = lines[i].Substring(level + 1); // имя — всё что после тега
- name = name.Trim(); // обрезаем пробелы по краям имени
- name = name.Trim('\n');
- list.Add(new Item(level, name, false, itemTop)); // создаём элемент
- // определяем его родителя
- if (level > 0)
- {
- // если его уровень больше чем у предшественника, то предшественник — родитель
- // если уровни равны, то у них общий родитель
- // если уровень меньше, то ищем предыдущий элемент с таким уровнем — с ним общий родитель
- if (level > prelevel)
- GetLast(0).parent = GetLast(1);
- else if (level == prelevel)
- GetLast(0).parent = GetLast(1).parent;
- else if (level < prelevel)
- for (int j = 0; j < list.Count; j++)
- if (list[j].level == level)
- GetLast(0).parent = list[j].parent;
- GetLast(0).parent.drop = true; // раз у элемента есть дети, то он выпадающий
- GetLast(0).parent.childs.Add(GetLast(0)); // записываем в родителя информацию о его детях
- }
- else
- {
- GetLast(0).parent = itemTop; // если уровень верхний, то родитель - нулл
- itemTop.childs.Add(GetLast(0));
- }
- prelevel = level;
- if (level > levelsCount)
- levelsCount = level; // считаем количество уровней
- }
- int numNull = 0;
- for (int i = 0; i < list.Count; i++)
- {
- list[i].SetSide(); // определяем стороны выпадания списков исходя из уровня
- list[i].CalcRoot(); // выявляем корни для всех элементов
- // определяем порядок внутри уровней и внутри родителей
- int num = 0;
- for (int j = 0; j < list.Count; j++)
- {
- if (list[j].parent == list[i])
- {
- list[j].number = num;
- num++;
- }
- }
- // определяем порядок для верхнего уровня
- if (list[i].parent == itemTop)
- {
- list[i].number = numNull;
- numNull++;
- }
- }
- selected = itemTop;
- }
- // выводим список в консоль
- void Output()
- {
- Debug.Log("======== Output ========");
- for (int i = 0; i < list.Count; i++)
- {
- Debug.Log("Имя: " + list[i].name);
- Debug.Log("Уровень: " + list[i].level);
- Debug.Log("Родитель: " + list[i].parent.name);
- Debug.Log("Корень: " + list[i].root.name);
- Debug.Log("Номер: " + list[i].number);
- }
- }
- void OnGUI()
- {
- GUI.skin = mys; // применяем скин
- CalcRectangles(); // считаем, какие элементы отображать и где их располагать
- // рисуем кнопки
- for (int i = 0; i < list.Count; i++)
- if (list[i].show)
- if (GUI.Button(list[i].bRect, list[i].name))
- selected = list[i];
- }
- // считаем, какие элементы отображать и где их располагать
- void CalcRectangles()
- {
- // по умолчанию ничего не отображается
- for (int i = 0; i < list.Count; i++)
- list[i].show = false;
- // устанавливаем элементы, которые должны отображаться
- // 1 — выбранный элемент
- // 2 — дети выбранного элемента
- // 3 — элементы, у которых общий родитель с выбранным элементом
- // 4 — элементы, которые по уровню ниже выбранного и имеют с ним общий корень
- for (int i = 0; i < list.Count; i++)
- {
- if (list[i].level == 0)
- list[i].show = true;
- if (list[i] == selected)
- list[i].show = true;
- if (list[i].parent == selected)
- list[i].show = true;
- if (list[i].parent == selected.parent)
- list[i].show = true;
- if (list[i].level < selected.level && list[i].root == selected.root)
- list[i].show = true;
- }
- // считаем ректанглы. Надо компактнее сделать
- for (int i = 0; i < list.Count; i++)
- {
- float left = 0f;
- float top = 0f;
- if (list[i].side == 1)
- {
- left = bWidth * list[i].number;
- top = 0;
- }
- if (list[i].side == 0)
- {
- if (list[i].parent.sideChilds == 0)
- {
- left = list[i].parent.bRect.xMin;
- top = list[i].parent.bRect.yMax + bHeight * list[i].number;
- }
- if (list[i].parent.sideChilds == 1)
- {
- left = list[i].parent.bRect.xMax;
- top = list[i].parent.bRect.yMin + bHeight * list[i].number;
- }
- }
- list[i].bRect = new Rect(left, top, bWidth, bHeight);
- }
- }
- // получаем последний элемент списка (или определённый с конца)
- Item GetLast(int i)
- {
- return list[list.Count - i - 1];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement