void ListArea(Rect rect, PresetLibrary lib, object newPresetObject)
{
if (lib == null)
{
return;
}
Event evt = Event.current;
if (m_PresetLibraryFileLocation == PresetFileLocation.ProjectFolder && evt.type == EventType.Repaint)
{
m_IsOpenForEdit = AssetDatabase.IsOpenForEdit(pathWithExtension, StatusQueryOptions.UseCachedIfPossible);
}
else if (m_PresetLibraryFileLocation == PresetFileLocation.PreferencesFolder)
{
m_IsOpenForEdit = true;
}
if (!m_IsOpenForEdit)
{
Rect versionControlRect = new Rect(rect.x, rect.yMax - versionControlAreaHeight, rect.width, versionControlAreaHeight);
VersionControlArea(versionControlRect);
rect.height -= versionControlAreaHeight;
}
// To ensure we setup grid to visible rect we need to run once to check if scrollbar is taking up screen estate.
// To optimize the first width is based on the last frame and we therefore most likely will only run once.
for (int i = 0; i < 2; i++)
{
gridWidth = m_ShowedScrollBarLastFrame ? rect.width - 17 : rect.width;
SetupGrid(gridWidth, lib.Count());
bool isShowingScrollBar = m_Grid.height > rect.height;
if (isShowingScrollBar == m_ShowedScrollBarLastFrame)
{
break;
}
else
{
m_ShowedScrollBarLastFrame = isShowingScrollBar;
}
}
// Draw horizontal lines for scrollview content to clip against
if ((m_ShowedScrollBarLastFrame || alwaysShowScrollAreaHorizontalLines) && Event.current.type == EventType.Repaint)
{
Rect scrollEdgeRect = new RectOffset(1, 1, 1, 1).Add(rect);
scrollEdgeRect.height = 1;
EditorGUI.DrawRect(scrollEdgeRect, new Color(0, 0, 0, 0.3f));
scrollEdgeRect.y += rect.height + 1;
EditorGUI.DrawRect(scrollEdgeRect, new Color(0, 0, 0, 0.3f));
}
Rect contentRect = new Rect(0, 0, 1, m_Grid.height);
m_State.m_ScrollPosition = GUI.BeginScrollView(rect, m_State.m_ScrollPosition, contentRect);
{
int startIndex, endIndex;
float yOffset = 0f;
int maxIndex = m_ShowAddNewPresetItem ? lib.Count() : lib.Count() - 1;
bool isGridVisible = m_Grid.IsVisibleInScrollView(rect.height, m_State.m_ScrollPosition.y, yOffset, maxIndex, out startIndex, out endIndex);
bool drawDragInsertionMarker = false;
if (isGridVisible)
{
// Handle renaming overlay before item handling because its needs mouse input first to end renaming if clicked outside
if (GetRenameOverlay().IsRenaming() && !GetRenameOverlay().isWaitingForDelay)
{
if (!m_State.m_RenameOverlay.OnGUI())
{
EndRename();
evt.Use();
}
Repaint();
}
for (int i = startIndex; i <= endIndex; ++i)
{
int itemControlID = i + 1000000;
Rect itemRect = m_Grid.CalcRect(i, yOffset);
Rect previewRect = itemRect;
Rect labelRect = itemRect;
switch (m_State.itemViewMode)
{
case PresetLibraryEditorState.ItemViewMode.List:
previewRect.width = m_State.m_PreviewHeight * m_PreviewAspect;
labelRect.x += previewRect.width + 8f;
labelRect.width -= previewRect.width + 10f;
labelRect.height = kGridLabelHeight;
labelRect.y = itemRect.yMin + (itemRect.height - kGridLabelHeight) * 0.5f;
break;
case PresetLibraryEditorState.ItemViewMode.Grid:
// only preview is shown: no label
break;
}
// Add new preset button
if (m_ShowAddNewPresetItem && i == lib.Count())
{
CreateNewPresetButton(previewRect, newPresetObject, lib, m_IsOpenForEdit);
continue;
}
// Rename overlay
bool isRenamingThisItem = IsRenaming(i);
if (isRenamingThisItem)
{
Rect renameRect = labelRect;
renameRect.y -= 1f; renameRect.x -= 1f; // adjustment to fit perfectly
m_State.m_RenameOverlay.editFieldRect = renameRect;
}
// Handle event
switch (evt.type)
{
case EventType.Repaint:
if (m_State.m_HoverIndex == i)
{
if (itemRect.Contains(evt.mousePosition))
{
// TODO: We need a better hover effect so disabling for now...
//if (!GetRenameOverlay().IsRenaming ())
// DrawHoverEffect (itemRect, false);
}
else
{
m_State.m_HoverIndex = -1;
}
}
if (m_DragState.draggingIndex == i || GUIUtility.hotControl == itemControlID)
{
DrawHoverEffect(itemRect, false);
}
lib.Draw(previewRect, i);
if (!isRenamingThisItem && drawLabels)
{
GUI.Label(labelRect, GUIContent.Temp(lib.GetName(i)));
}
if (m_DragState.dragUponIndex == i && m_DragState.draggingIndex != m_DragState.dragUponIndex)
{
drawDragInsertionMarker = true;
}
// We delete presets on alt-click
if (GUIUtility.hotControl == 0 && Event.current.alt && m_IsOpenForEdit)
{
EditorGUIUtility.AddCursorRect(itemRect, MouseCursor.ArrowMinus);
}
break;
case EventType.MouseDown:
if (evt.button == 0 && itemRect.Contains(evt.mousePosition))
{
GUIUtility.hotControl = itemControlID;
if (evt.clickCount == 1)
{
m_ItemClickedCallback(evt.clickCount, lib.GetPreset(i));
evt.Use();
}
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl == itemControlID && m_IsOpenForEdit)
{
DragAndDropDelay delay = (DragAndDropDelay)GUIUtility.GetStateObject(typeof(DragAndDropDelay), itemControlID);
if (delay.CanStartDrag())
{
// Start drag
DragAndDrop.PrepareStartDrag();
DragAndDrop.SetGenericData("DraggingPreset", i);
DragAndDrop.StartDrag("");
m_DragState.draggingIndex = i;
m_DragState.dragUponIndex = i;
GUIUtility.hotControl = 0;
}
evt.Use();
}
break;
case EventType.DragUpdated:
case EventType.DragPerform:
{
Rect dragRect = GetDragRect(itemRect);
if (dragRect.Contains(evt.mousePosition))
{
m_DragState.dragUponIndex = i;
m_DragState.dragUponRect = itemRect;
if (m_State.itemViewMode == PresetLibraryEditorState.ItemViewMode.List)
{
m_DragState.insertAfterIndex = ((evt.mousePosition.y - dragRect.y) / dragRect.height) > 0.5f;
}
else
{
m_DragState.insertAfterIndex = ((evt.mousePosition.x - dragRect.x) / dragRect.width) > 0.5f;
}
bool perform = evt.type == EventType.DragPerform;
if (perform)
{
if (m_DragState.draggingIndex >= 0)
{
MovePreset(m_DragState.draggingIndex, m_DragState.dragUponIndex, m_DragState.insertAfterIndex);
DragAndDrop.AcceptDrag();
}
ClearDragState();
}
DragAndDrop.visualMode = DragAndDropVisualMode.Move;
evt.Use();
}
}
break;
case EventType.DragExited:
if (m_DragState.IsDragging())
{
ClearDragState();
evt.Use();
}
break;
case EventType.MouseUp:
if (GUIUtility.hotControl == itemControlID)
{
GUIUtility.hotControl = 0;
if (evt.button == 0 && itemRect.Contains(evt.mousePosition))
{
if (Event.current.alt && m_IsOpenForEdit)
{
DeletePreset(i);
evt.Use();
}
}
}
break;
case EventType.ContextClick:
if (itemRect.Contains(evt.mousePosition))
{
PresetContextMenu.Show(m_IsOpenForEdit, i, newPresetObject, this);
evt.Use();
}
break;
case EventType.MouseMove:
if (itemRect.Contains(evt.mousePosition))
{
if (m_State.m_HoverIndex != i)
{
m_State.m_HoverIndex = i;
Repaint();
}
}
else if (m_State.m_HoverIndex == i)
{
m_State.m_HoverIndex = -1;
Repaint();
}
break;
}
} // end foreach item
// Draw above all items
if (drawDragInsertionMarker)
{
DrawDragInsertionMarker();
}
}
} GUI.EndScrollView();
}