private static void CalculatePosition(Rect rect, string pureLabel, int currentLine, ScriptInformation[] infos, Action <Rect, ScriptInformation> action) { foreach (var info in infos) { if (info != null && info.startLine <= currentLine && info.endLine >= currentLine) { var position = rect; int startColumn = 0; int endColumn = pureLabel.Length - 1; position.width = RichLabel.CalcSize(new GUIContent(pureLabel)).x; if (info.startLine == currentLine || info.endLine == currentLine) { if (info.startLine == currentLine) { startColumn = info.startColumn; } if (info.endLine == currentLine) { endColumn = info.endColumn; if (endColumn + 1 > pureLabel.Length) { endColumn = pureLabel.Length - 1; } } } { //For correcting the position and width, because we replace tab with space int tabCount = pureLabel.Count(l => l == '\t'); int offset = Mathf.Min(tabCount, startColumn); position.x -= tabWidth * offset; position.x += spaceWidth * 6 * offset; if (tabCount > startColumn) { position.width -= tabWidth * (tabCount - startColumn); position.width += spaceWidth * 6 * (tabCount - startColumn); } } if (info.startLine == currentLine) { if (startColumn > 0 && pureLabel.Length > startColumn) { float width = RichLabel.CalcSize(new GUIContent(pureLabel.Substring(0, startColumn))).x; position.x += width; position.width -= width; } } if (info.endLine == currentLine) { if (endColumn + 1 < pureLabel.Length && pureLabel.Length - endColumn > 0) { float width = RichLabel.CalcSize(new GUIContent(pureLabel.Substring(endColumn, pureLabel.Length - endColumn))).x; position.width -= width; } } action(position, info); } } }
public static void ShowPreviewSource(string[] lines, string[] pureLines, ScriptInformation[] infos, ref ScriptInformation[] selectedInfos) { if (lines == null || lines.Length == 0) { return; } if (pureLines == null || pureLines.Length != lines.Length) { pureLines = lines; } tabWidth = RichLabel.CalcSize(new GUIContent("\t")).x; spaceWidth = RichLabel.CalcSize(new GUIContent(" ")).x; var lineWidth = LinesStyle.CalcSize(new GUIContent(lines.Length.ToString())).x; Rect area = EditorGUILayout.BeginVertical(); ScriptInformation clickedInfo = null; for (int i = 0; i < lines.Length; i++) { Rect rect = uNodeGUIUtility.GetRect(new GUIContent(lines[i]), RichLabel); EditorGUI.LabelField(new Rect(rect.x, rect.y, lineWidth, rect.height), (i + 1).ToString(), LinesStyle); rect.x += lineWidth + 6; rect.width -= lineWidth + 6; if (Event.current.type == EventType.Repaint) { string label = lines[i].Replace("\t", " "); // string label = lines[i]; RichLabel.Draw(rect, label, false, false, false, false); if (selectedInfos == null) { continue; } CalculatePosition(rect, pureLines[i], i, selectedInfos, (position, info) => { GUI.DrawTexture(position, selectionTexture); }); } else if (Event.current.type == EventType.MouseDown) { if (infos == null) { continue; } CalculatePosition(rect, pureLines[i], i, infos, (position, info) => { if (position.Contains(Event.current.mousePosition)) { if (clickedInfo != null) { if (clickedInfo.lineRange > info.lineRange || clickedInfo.lineRange == info.lineRange && clickedInfo.columnRange > info.columnRange) { clickedInfo = info; } } else { clickedInfo = info; } } }); } } if (clickedInfo != null) { selectedInfos = new ScriptInformation[] { clickedInfo }; if (int.TryParse(clickedInfo.id, out var id)) { var obj = EditorUtility.InstanceIDToObject(id); if (obj is NodeComponent) { uNodeEditor.HighlightNode(obj as NodeComponent); } else if (obj is RootObject) { var root = obj as RootObject; if (root.startNode != null) { uNodeEditor.HighlightNode(root.startNode); } else { uNodeEditor.ChangeTarget(root); uNodeEditor.window.Refresh(); } } } else if (clickedInfo.id.StartsWith(CodeGenerator.KEY_INFORMATION_VARIABLE)) { } window?.Repaint(); } EditorGUILayout.EndVertical(); GUI.Box(new Rect(area.x + lineWidth, area.y, 2, area.height), ""); }