Показать сообщение отдельно
Старый 31.01.2013, 20:02   #2
WISHMASTER35
Бывалый
 
Аватар для WISHMASTER35
 
Регистрация: 21.12.2008
Адрес: UA
Сообщений: 878
Написано 105 полезных сообщений
(для 357 пользователей)
Ответ: Рисуем список текстур в редакторе

И основной класс. Кода конечно много, но как мог оптимизировал.
Тут, кстати, спойлера нету?
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;
		}
	}
	
}

Последний раз редактировалось WISHMASTER35, 31.01.2013 в 21:18.
(Offline)
 
Ответить с цитированием