WISHMASTER35 |
31.01.2013 20:02 |
Ответ: Рисуем список текстур в редакторе
И основной класс. Кода конечно много, но как мог оптимизировал.
Тут, кстати, спойлера нету?
Код:
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
public class ImagesListViewer {
private static Color SELECT_COLOR = new Color( 61/255f, 128/255f, 223/255f );
private const string DRAG_AND_DROP = "drag block";
public static int SelectionGrid(List<Texture> items, int index) {
Rect rect = new Rect();
int xCount, yCount;
index = SelectionGrid(items, index, out rect, out xCount, out yCount);
float width = rect.width / xCount;
float height = rect.height / yCount;
GUI.BeginGroup(rect);
Vector2 mouse = Event.current.mousePosition;
int posX = Mathf.FloorToInt(mouse.x/width);
int posY = Mathf.FloorToInt(mouse.y/height);
int realIndex = -1; // номер элемента под курсором
if(posX >= 0 && posX < xCount && posY >= 0 && posY < yCount) realIndex = posY*xCount + posX;
int dropX = Mathf.Clamp(posX, 0, xCount-1);
int dropY = Mathf.Clamp(posY, 0, yCount-1);
if(dropY == yCount-1 && items.Count%xCount != 0) dropX = Mathf.Clamp(dropX, 0, items.Count%xCount);
int dropIndex = dropY*xCount + dropX; // ближайший элемент к курсору
if(Event.current.type == EventType.MouseDrag && Event.current.button == 0 && realIndex == index && realIndex != -1) { //начинаем DragAndDrop
DragAndDrop.PrepareStartDrag();
DragAndDrop.objectReferences = new Object[0];
DragAndDrop.paths = new string[0];
DragAndDrop.SetGenericData(DRAG_AND_DROP, new Index(index));
DragAndDrop.StartDrag("DragAndDrop");
Event.current.Use();
}
if(Event.current.type == EventType.DragUpdated) { // проверяем можем ли принять DragAndDrop
Index data = (Index) DragAndDrop.GetGenericData(DRAG_AND_DROP);
if(data != null) {
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
Event.current.Use();
}
if(DragAndDrop.objectReferences.Length == 1) {
if(DragAndDrop.objectReferences[0] is Texture) {
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
Event.current.Use();
}
}
}
if(Event.current.type == EventType.DragPerform) { // DragAndDrop завершен
Index data = (Index) DragAndDrop.GetGenericData(DRAG_AND_DROP);
if(data != null) {
Texture moveItem = items[data.index];
items.RemoveAt(data.index);
if(dropIndex > data.index) dropIndex--;
dropIndex = Mathf.Clamp(dropIndex, 0, items.Count);
items.Insert(dropIndex, moveItem);
index = dropIndex;
}
if(DragAndDrop.objectReferences.Length == 1) {
if(DragAndDrop.objectReferences[0] is Texture) {
if(realIndex != -1) items[realIndex] = (Texture) DragAndDrop.objectReferences[0];
}
}
DragAndDrop.AcceptDrag();
Event.current.Use();
}
if(Event.current.type == EventType.Repaint && DragAndDrop.visualMode == DragAndDropVisualMode.Link) { // рисуем красную полоску
Vector2 pos = new Vector2(2+dropX*width, 2+dropY*height);
Rect lineRect = new Rect(pos.x-2, pos.y, 2, width-2);
FillRect(lineRect, Color.red);
}
GUI.EndGroup();
return index;
}
private static int SelectionGrid(List<Texture> items, int index, out Rect rect, out int xCount, out int yCount) {
xCount = Mathf.FloorToInt( Screen.width/66f ); // количество элементов по горизонтале
yCount = Mathf.CeilToInt( (float)items.Count/xCount ); // количество элементов по вертикали
rect = GUILayoutUtility.GetAspectRect((float)xCount/yCount); // выделить место для картинок и лейбов
float labelHeight = GUI.skin.label.CalcHeight(GUIContent.none, 0); // высота текста
GUILayout.Space(labelHeight*yCount);
rect.height += labelHeight*yCount;
float itemWidth = rect.width / xCount;
float itemHeight = rect.height / yCount;
for(int y=0, i=0; y<yCount; y++) {
for(int x=0; x<xCount && i<items.Count; x++, i++) {
Rect position = new Rect(rect.x+itemWidth*x, rect.y+itemHeight*y, itemWidth, itemHeight);
position.xMin += 2;
position.yMin += 2;
bool selected = DrawItem(position, items[i], i == index, i);
if(selected) index = i;
}
}
return index;
}
private static bool DrawItem(Rect position, Texture texture, bool selected, int index) {
Rect texturePosition = position;
texturePosition.height = texturePosition.width;
Rect labelPosition = position;
labelPosition.yMin += texturePosition.height;
if(selected) FillRect(labelPosition, SELECT_COLOR);
if(texture) {
GUI.DrawTexture(texturePosition, texture);
GUI.Label(labelPosition, texture.name);
} else {
FillRect(texturePosition, Color.gray);
GUI.Label(labelPosition, "Null");
}
if(Event.current.type == EventType.MouseDown && position.Contains(Event.current.mousePosition)) {
Event.current.Use();
return true;
}
return false;
}
private static void FillRect(Rect rect, Color color) {
Color oldColor = GUI.color;
GUI.color = color;
GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture);
GUI.color = oldColor;
}
class Index {
public int index;
public Index(int index) {
this.index = index;
}
}
}
|