728x90
반응형
기존 툴에서 검색 기능을 강화한 버전이다.
검색하면 해당 글자가 노란색으로 표기되고
search next prev를 통해 검색 위치로 이동이 가능하다.
현재 위치의 글자가 초록색으로 표시된다.
# 업데이트 목록
1. Clear 기능 추가 (폴드아웃, 검색 스크롤 등을 초기화)
2. 검색 툴바에 X 버튼 추가 (누르면 입력 삭제)
3. 검색 Prev, Next 버튼 추가 (현재 검색된 텍스트 위치로 이동)
4. 현재 검색 위치의 텍스트 색상을 초록색으로 표기
5. 검색 시 대소문자 구분 안하도록
using UnityEngine;
using UnityEditor;
using SimpleJSON;
using System.Collections.Generic;
public class JsonViewer : EditorWindow
{
private Dictionary<string, bool> m_isFoldoutArray = new Dictionary<string, bool>();
private JSONClass jsonClass;
private Vector2 m_scrollPosition;
private string jsonText;
private string search;
private int searchLastNumber = 0;
private int searchNumber = 0;
private int currentSearchNumber = 0;
private int scrollLine = 0;
private bool searchMoveFlag = false;
public void Initialize(string text)
{
jsonText = text;
currentSearchNumber = 0;
searchLastNumber = 0;
search = string.Empty;
m_isFoldoutArray.Clear();
GUIUtility.keyboardControl = 0;
JSONNode jNode = JSONNode.Parse(jsonText);
jsonClass = jNode as JSONClass;
SetFoldoutData(jsonClass);
}
public void SetJsonViewer()
{
GUILayout.BeginHorizontal();
{
DrawClearButtonGUI();
DrawSearchGUI();
}
GUILayout.EndHorizontal();
m_scrollPosition = EditorGUILayout.BeginScrollView(m_scrollPosition, false, true);
{
DrawJsonView(jsonClass, 0, 0);
}
EditorGUILayout.EndScrollView();
}
private void DrawJsonView(JSONNode jNode, int index, int loop = 0)
{
JSONClass nodeClass = jNode as JSONClass;
if (nodeClass == null)
{
JSONData nodeData = jNode as JSONData;
if (nodeData != null)
SetSearchColor(index + " : " + nodeData.Value);
return;
}
foreach (var pair in nodeClass.m_Dict)
{
var jsonArray = pair.Value as JSONArray;
var jsonClass = pair.Value as JSONClass;
var jsonData = pair.Value as JSONData;
if (jsonArray != null)
SetArrayGUI(jsonArray, pair.Key, pair.GetHashCode().ToString(), loop);
else if (jsonClass != null)
SetClassGUI(jsonClass, pair.Key, pair.GetHashCode().ToString(), loop);
else if (jsonData != null)
SetSearchColor(pair.Key + " : " + jsonData.Value);
else
SetSearchColor(pair.Key + " : " + (pair.Value == null ? "null" : pair.Value));
}
}
private void SetSearchColor(string orizinalText)
{
string lowerSearch = search.ToLower();
string lowerText = orizinalText.ToLower();
if (!string.IsNullOrEmpty(lowerSearch) && !string.IsNullOrEmpty(lowerText) && lowerText.Contains(lowerSearch))
{
searchNumber++;
searchLastNumber = Mathf.Max(searchLastNumber, searchNumber);
bool isSearchLine = searchNumber == currentSearchNumber;
if (searchMoveFlag && isSearchLine)
{
m_scrollPosition = new Vector2(m_scrollPosition.x, (scrollLine * 18.0f));
searchMoveFlag = false;
}
GUIStyle white = new GUIStyle(EditorStyles.label);
white.normal.textColor = isSearchLine ? Color.green : Color.yellow;
GUILayout.BeginHorizontal();
{
while (true)
{
if (string.IsNullOrEmpty(orizinalText))
break;
int indexOf = lowerText.IndexOf(lowerSearch);
if (indexOf == -1)
{
GUILayout.Label(orizinalText, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
break;
}
if (indexOf > 0)
{
string whiteColorText = orizinalText.Substring(0, indexOf);
GUILayout.Label(whiteColorText, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
}
string searchColorText = orizinalText.Substring(indexOf, lowerSearch.Length);
GUILayout.Label(searchColorText, white, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
int startIndex = (indexOf + lowerSearch.Length);
int endIndex = (orizinalText.Length - startIndex);
lowerText = lowerText.Substring(startIndex, endIndex);
orizinalText = orizinalText.Substring(startIndex, endIndex);
}
}
GUILayout.EndHorizontal();
}
else
{
GUILayout.Label(orizinalText, GUILayout.ExpandHeight(false));
}
scrollLine++;
}
private void SetArrayGUI(JSONArray jsonArray, string key, string hashKey, int loop)
{
if (m_isFoldoutArray.ContainsKey(hashKey))
{
string arrayName = (key + " : [" + jsonArray.Count + "]");
m_isFoldoutArray[hashKey] = ContainsFoldoutSearch(EditorGUILayout.Foldout(m_isFoldoutArray[hashKey], arrayName, true), key, jsonArray);
scrollLine++;
if (m_isFoldoutArray[hashKey])
{
DrawJsonViewBeginGUI(5, () =>
{
SetSearchColor("[");
DrawJsonViewBeginGUI(5, () =>
{
if (jsonArray.Count == 1)
{
DrawJsonViewGUI(jsonArray[0], 0, (loop + 1));
}
else
{
for (int i = 0; i < jsonArray.Count; ++i)
{
string subHashKey = jsonArray[i].GetHashCode().ToString();
if (m_isFoldoutArray.ContainsKey(subHashKey))
{
if (jsonArray[i].Count == 1)
{
DrawJsonViewGUI(jsonArray[i], i, (loop + 1));
}
else
{
string subArrayName = (i + " : {" + jsonArray[i].Count + "}");
m_isFoldoutArray[subHashKey] = ContainsFoldoutSearch(EditorGUILayout.Foldout(m_isFoldoutArray[subHashKey], subArrayName, true), string.Empty, jsonArray[i]);
scrollLine++;
if (m_isFoldoutArray[subHashKey])
{
DrawJsonViewGUI(jsonArray[i], i, (loop + 1));
}
}
}
}
}
});
SetSearchColor("]");
});
}
}
}
private void SetClassGUI(JSONClass jsonClass, string key, string hashKey, int loop)
{
if (m_isFoldoutArray.ContainsKey(hashKey))
{
string className = (key + " : {" + jsonClass.Count + "}");
m_isFoldoutArray[hashKey] = ContainsFoldoutSearch(EditorGUILayout.Foldout(m_isFoldoutArray[hashKey], className, true), key, jsonClass);
scrollLine++;
if (m_isFoldoutArray[hashKey])
{
DrawJsonViewBeginGUI(5, () =>
{
SetSearchColor("{");
DrawJsonViewGUI(jsonClass, 0, (loop + 1));
SetSearchColor("}");
});
}
}
}
private void DrawJsonViewBeginGUI(int space, System.Action action)
{
GUILayout.BeginHorizontal();
{
GUILayout.Space(space);
GUILayout.BeginVertical();
{
action();
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
private void DrawJsonViewGUI(JSONNode node, int index, int loop)
{
GUILayout.BeginHorizontal();
{
GUILayout.Space(25);
GUILayout.BeginVertical();
{
DrawJsonView(node, index, loop);
}
GUILayout.EndVertical();
}
GUILayout.EndHorizontal();
}
private void SetFoldoutData(JSONNode jNode)
{
JSONClass nodeClass = jNode as JSONClass;
if (nodeClass == null)
return;
string pairHashKey = string.Empty;
string hashKey = string.Empty;
foreach (var pair in nodeClass.m_Dict)
{
var jsonArray = pair.Value as JSONArray;
var jsonClass = pair.Value as JSONClass;
pairHashKey = pair.GetHashCode().ToString();
if (jsonArray != null)
{
if (!m_isFoldoutArray.ContainsKey(pairHashKey))
m_isFoldoutArray.Add(pairHashKey, false);
for (int i = 0; i < jsonArray.Count; ++i)
{
hashKey = jsonArray[i].GetHashCode().ToString();
if (!m_isFoldoutArray.ContainsKey(hashKey))
m_isFoldoutArray.Add(hashKey, false);
SetFoldoutData(jsonArray[i]);
}
}
else if (jsonClass != null)
{
if (!m_isFoldoutArray.ContainsKey(pairHashKey))
m_isFoldoutArray.Add(pairHashKey, false);
hashKey = jsonClass.GetHashCode().ToString();
if (!m_isFoldoutArray.ContainsKey(hashKey))
m_isFoldoutArray.Add(hashKey, false);
SetFoldoutData(jsonClass);
}
}
}
private bool ContainsFoldoutSearch(bool defaultFoldout, string key, JSONNode node)
{
if (string.IsNullOrEmpty(search))
return defaultFoldout;
string lowerSearch = search.ToLower();
string lowerKey = key.ToLower();
if (!string.IsNullOrEmpty(lowerKey) && key.Contains(lowerSearch))
return true;
for (int i = 0; i < node.Count; ++i)
{
if (node[i] == null)
continue;
JSONArray jsonArray = node[i] as JSONArray;
if (jsonArray != null)
{
for (int j = 0; j < jsonArray.Count; ++j)
{
if (jsonArray[j] == null)
continue;
string lowerValue = jsonArray[j].Value.ToLower();
if (lowerValue.Contains(lowerSearch))
return true;
}
}
JSONClass jsonClass = node[i] as JSONClass;
if (jsonClass != null)
{
for (int j = 0; j < jsonClass.Count; ++j)
{
if (jsonClass[j] == null)
continue;
string lowerValue = jsonClass[j].Value.ToLower();
if (lowerValue.Contains(lowerSearch))
return true;
}
}
}
return defaultFoldout;
}
private void DrawClearButtonGUI()
{
if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.MaxWidth(60f)))
{
Initialize(jsonText);
}
}
private void DrawSearchGUI()
{
scrollLine = 0;
searchNumber = 0;
searchMoveFlag = false;
string prevSearch = search;
search = EditorGUILayout.TextField(prevSearch, (GUIStyle)"ToolbarSeachTextField", GUILayout.ExpandWidth(true));
if (search != prevSearch)
searchLastNumber = 0;
if (GUILayout.Button("", (GUIStyle)"ToolbarSeachCancelButton"))
{
searchLastNumber = 0;
search = EditorGUILayout.TextField(string.Empty, (GUIStyle)"ToolbarSeachTextField", GUILayout.ExpandWidth(true));
GUIUtility.keyboardControl = 0;
}
if (GUILayout.Button("Search Prev", EditorStyles.toolbarButton, GUILayout.MaxWidth(100f)))
{
currentSearchNumber--;
if (currentSearchNumber <= 0)
currentSearchNumber = searchLastNumber;
searchMoveFlag = true;
}
if (GUILayout.Button("Search Next", EditorStyles.toolbarButton, GUILayout.MaxWidth(100f)))
{
if (currentSearchNumber >= searchLastNumber)
currentSearchNumber = 0;
currentSearchNumber++;
searchMoveFlag = true;
}
}
private void OnGUI()
{
SetJsonViewer();
}
}
반응형
'유니티 > 기본기' 카테고리의 다른 글
유니티 Shader 공부 (SubShader, LOD) (0) | 2020.07.28 |
---|---|
유니티 Shader 공부 (Properties) (2) | 2020.07.27 |
유니티 JsonViewer 툴 (Newtonsoft.json) (4) | 2020.06.24 |
네스티드 프리팹 (Netsted Prefabs) (2) | 2020.04.06 |
GUI (ezgui-ngui-ugui) (0) | 2020.04.06 |