본문 바로가기

유니티/기본기

유니티 JsonViewer 툴 V2 (Newtonsoft.json)

728x90
반응형

기존 툴에서 검색 기능을 강화한 버전이다.
검색하면 해당 글자가 노란색으로 표기되고
search next prev를 통해 검색 위치로 이동이 가능하다.
현재 위치의 글자가 초록색으로 표시된다.

 

# 업데이트 목록

1. Clear 기능 추가 (폴드아웃, 검색 스크롤 등을 초기화)
2. 검색 툴바에 X 버튼 추가 (누르면 입력 삭제)
3. 검색 Prev, Next 버튼 추가 (현재 검색된 텍스트 위치로 이동)
4. 현재 검색 위치의 텍스트 색상을 초록색으로 표기
5. 검색 시 대소문자 구분 안하도록

 

JsonViewer.cs
0.01MB

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();
    }
}

 

다람쥐와 포동포동이

 

RememberCook 9월 28일 정식 출시!

두번째 게임인 RememberCook이 출시되었습니다. 귀여운 캐릭터들이 나오는 간단한 게임이며 플레이어의 공간인지능력을 테스트하는 게임입니다. 아래 링크를 통해 다운 받으실 수 있으니 많은 관��

chipmunk-plump-plump.tistory.com

반응형