public static void ListView <TD>(Rect rect, MultiColumnState <TD, TC> multiColumnState, MultiColumnViewOption <TD> mvcOption) { UVC.ProfilerUtilities.BeginSample("MultiColumnView::ListView"); bool controlModifier = ((Application.platform == RuntimePlatform.OSXEditor) ? Event.current.command : Event.current.control); GUI.BeginGroup(rect); float headerHeight = mvcOption.headerStyle.lineHeight + mvcOption.headerStyle.margin.vertical + mvcOption.headerStyle.padding.vertical; float rowHeight = mvcOption.rowStyle.lineHeight + mvcOption.rowStyle.margin.vertical; float scrollbarWidth = 0.0f; float total = multiColumnState.GetRowCount(); int size = Mathf.RoundToInt((rect.height - headerHeight) / rowHeight); if (total > size) { scrollbarWidth = 16.0f; mvcOption.scrollbarPos.y = GUI.VerticalScrollbar(new Rect(rect.width - scrollbarWidth, 0, rect.width, rect.height), mvcOption.scrollbarPos.y, size, 0, total); if (rect.Contains(Event.current.mousePosition) && Event.current.type == EventType.ScrollWheel) { mvcOption.scrollbarPos.y += Mathf.Sign(Event.current.delta.y) * 3.0f; Event.current.Use(); } } GUI.BeginGroup(new Rect(0, 0, rect.width - scrollbarWidth, rect.height)); var headers = multiColumnState.GetColumns().Select(c => c.GetHeader()); var widths = headers.Select(c => mvcOption.widthTable[c.text]).ToArray(); float maxWidth = widths.Sum(); var headerRect = new Rect(0, 0, maxWidth, headerHeight); ListViewHeader(headerRect, c => { multiColumnState.Accending = !multiColumnState.Accending; multiColumnState.SetSortByColumn(c); }, () => false, multiColumnState.GetColumns(), mvcOption); int lowIdx = Mathf.RoundToInt(mvcOption.scrollbarPos.y); int highIdx = lowIdx + size; var totalRows = multiColumnState.GetRows(); var rows = totalRows.Where((_, idx) => InBetween(idx, lowIdx, highIdx)); int currentIdx = lowIdx; float rowHeighStart = headerHeight; foreach (var rowIt in rows) { //D.Log("C# null: " + ((rowIt.data==null)?"true":"false") + ", Unity: " + rowIt.data + ", Type: " + rowIt.data.GetType()); Action selectAction = () => { if (!controlModifier) { foreach (var r in totalRows) { r.selected = false; } } if ((Event.current.modifiers & EventModifiers.Shift) > 0) { var selection = totalRows.Where((_, idx) => InBetween(idx, selectedIdx, currentIdx)); foreach (var e in selection) { e.selected = true; } } else { selectedIdx = currentIdx; rowIt.selected = !rowIt.selected; } if (Event.current.clickCount > 1) { var selection = totalRows.Where(idx => idx.selected); foreach (var e in selection) { mvcOption.doubleClickAction(e.data); } } }; var rowRect = new Rect(0, rowHeighStart, maxWidth, rowHeight); ListViewRow(rowRect, selectAction, () => rowIt.selected, rowIt, widths, mvcOption); rowHeighStart += rowHeight; currentIdx++; } GUI.EndGroup(); GUI.EndGroup(); int id = GUIUtility.GetControlID(listViewHash, FocusType.Passive); Event ev = Event.current; EventType evt = ev.GetTypeForControl(id); if (rect.Contains(ev.mousePosition) && evt == EventType.MouseDown && ev.button == 0) { Event.current.Use(); foreach (var r in totalRows) { r.selected = false; } } if (controlModifier && Event.current.keyCode == KeyCode.A) { foreach (var r in totalRows) { r.selected = true; } Event.current.Use(); } UVC.ProfilerUtilities.EndSample(); }
static void ListViewHeader <TD>(Rect rect, Action <MultiColumnState <TD, TC> .Column> action, Func <bool> selectedFunc, IEnumerable <MultiColumnState <TD, TC> .Column> columns, MultiColumnViewOption <TD> mvcOption) { float x = rect.x; foreach (var columnIt in columns) { var cell = columnIt.GetHeader(); float width = mvcOption.widthTable[cell.text]; var r = new Rect(x, rect.y, width, rect.height); bool bHover = r.Contains(Event.current.mousePosition); Action <Vector2> dragAction = v => { mvcOption.widthTable[cell.text] = Mathf.Max(mvcOption.widthTable[cell.text] + v.x, dragResize); }; ListViewCell <TD>(r, () => action(columnIt), dragAction, selectedFunc, bHover, cell, mvcOption.headerStyle, () => mvcOption.headerRightClickMenu(columnIt), () => false); x += width; } }
static void ListViewRow <TD>(Rect rect, Action action, Func <bool> selectedFunc, MultiColumnState <TD, TC> .Row row, float[] widths, MultiColumnViewOption <TD> mvcOption) { //int id = GUIUtility.GetControlID(listViewCellHash, FocusType.Native); var columns = row.Columns.ToArray(); bool bHover = rect.Contains(Event.current.mousePosition); float x = rect.x; for (int i = 0; i < widths.Length && i < columns.Length; ++i) { var width = widths[i]; var column = columns[i]; var r = new Rect(x, rect.y, width, rect.height); ListViewCell <TD>(r, action, _ => { }, selectedFunc, bHover, column.GetContent(row.data), mvcOption.rowStyle, mvcOption.rowRightClickMenu, () => mvcOption.cellClickAction(row, column)); x += width; } }
private void Initialize() { columnActive = new MultiColumnState.Column(new GUIContent("", "Active Branch"), data => currentBranch == data.name ? activeBranch : emptyGUIContent); columnPath = new MultiColumnState.Column(new GUIContent("Path"), data => new GUIContent(data.name)); columnAuthor = new MultiColumnState.Column(new GUIContent("Author"), data => new GUIContent(data.author)); columnRevision = new MultiColumnState.Column(new GUIContent("Revision"), data => new GUIContent(data.revision.ToString())); columnDate = new MultiColumnState.Column(new GUIContent("Date"), data => new GUIContent(data.date.ToString("yyyy-MM-dd HH:mm:ss"))); multiColumnState = new MultiColumnState(); Func <MultiColumnState.Row, MultiColumnState.Column, bool> cellClickAction = (row, column) => { GUI.FocusControl(""); DebugLog.Log(row.data + " : " + column.GetContent(row.data).text); return(false); }; var guiSkin = EditorGUIUtility.GetBuiltinSkin(EditorGUIUtility.isProSkin ? EditorSkin.Scene : EditorSkin.Inspector); Func <MultiColumnState.Row, MultiColumnState.Column, GenericMenu> rowRightClickMenu = (row, column) => { GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Switch"), false, () => Switch(row.data.name)); menu.AddItem(new GUIContent("Merge"), false, () => MergeWithConfirm(row.data.name)); return(menu); }; Func <MultiColumnState.Column, GenericMenu> headerRightClickMenu = column => { GenericMenu menu = new GenericMenu(); return(menu); }; options = new MultiColumnViewOption { headerStyle = new GUIStyle(guiSkin.button), rowStyle = new GUIStyle(guiSkin.label), rowRightClickMenu = rowRightClickMenu, headerRightClickMenu = headerRightClickMenu, cellClickAction = cellClickAction, widths = new float[] { 200 }, doubleClickAction = path => { //DebugLog.Log(path.name); } }; options.headerStyle.fixedHeight = 20.0f; options.rowStyle.onNormal.background = IconUtils.CreateSquareTexture(4, 1, new Color(0.24f, 0.5f, 0.87f, 0.75f)); options.rowStyle.margin = new RectOffset(2, 2, 2, 1); options.rowStyle.border = new RectOffset(0, 0, 0, 0); options.rowStyle.padding = new RectOffset(0, 0, 0, 0); multiColumnState.AddColumn(columnActive); options.widthTable.Add(columnActive.GetHeader().text, 25); multiColumnState.AddColumn(columnPath); options.widthTable.Add(columnPath.GetHeader().text, 350); multiColumnState.AddColumn(columnAuthor); options.widthTable.Add(columnAuthor.GetHeader().text, 90); multiColumnState.AddColumn(columnRevision); options.widthTable.Add(columnRevision.GetHeader().text, 80); multiColumnState.AddColumn(columnDate); options.widthTable.Add(columnDate.GetHeader().text, 150); }