Inheritance: UnityEngine.ScriptableObject
Esempio n. 1
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------
    public void Edit( Object _obj )
    {
        // check if repaint
        if ( curEdit != _obj ) {

            // check if we have atlas - editorinfo in the same directory
            Object obj = _obj;
            if ( obj is exTileSheet || obj is Texture2D || obj is Material ) {
                string assetPath = AssetDatabase.GetAssetPath(obj);
                string dirname = Path.GetDirectoryName(assetPath);
                string filename = Path.GetFileNameWithoutExtension(assetPath);
                obj = (exTileSheet)AssetDatabase.LoadAssetAtPath( Path.Combine( dirname, filename + ".asset" ),
                                                                typeof(exTileSheet) );
                if ( obj == null ) {
                    obj = _obj;
                }
            }

            // if this is another atlas, swtich to it.
            if ( obj is exTileSheet && obj != curEdit ) {
                curEdit = obj as exTileSheet;
                Init();

                Repaint ();
                return;
            }
        }
    }
Esempio n. 2
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    public void Edit(Object _obj)
    {
        // check if repaint
        if (curEdit != _obj)
        {
            // check if we have atlas - editorinfo in the same directory
            Object obj = _obj;
            if (obj is exTileSheet || obj is Texture2D || obj is Material)
            {
                string assetPath = AssetDatabase.GetAssetPath(obj);
                string dirname   = Path.GetDirectoryName(assetPath);
                string filename  = Path.GetFileNameWithoutExtension(assetPath);
                obj = (exTileSheet)AssetDatabase.LoadAssetAtPath(Path.Combine(dirname, filename + ".asset"),
                                                                 typeof(exTileSheet));
                if (obj == null)
                {
                    obj = _obj;
                }
            }

            // if this is another atlas, swtich to it.
            if (obj is exTileSheet && obj != curEdit)
            {
                curEdit = obj as exTileSheet;
                Init();

                Repaint();
                return;
            }
        }
    }
Esempio n. 3
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    public static exTileSheet Create(string _path, string _name)
    {
        //
        if (new DirectoryInfo(_path).Exists == false)
        {
            Debug.LogError("can't create asset, path not found");
            return(null);
        }
        if (string.IsNullOrEmpty(_name))
        {
            Debug.LogError("can't create asset, the name is empty");
            return(null);
        }
        string assetPath = Path.Combine(_path, _name + ".asset");

        // TODO {
        // exEditorHelper.RenameProjectWindowItem ( AssetDatabase.AssetPathToGUID (assetPath),
        //                                          "default asset" );
        // } TODO end

        //
        exTileSheet newTileSheet = ScriptableObject.CreateInstance <exTileSheet>();

        AssetDatabase.CreateAsset(newTileSheet, assetPath);
        Selection.activeObject = newTileSheet;
        return(newTileSheet);
    }
Esempio n. 4
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    bool HasSelected(exTileSheet _tileSheet, int _x, int _y)
    {
        int in_id = _x + _y * _tileSheet.col;

        foreach (int id in sheetSelectedGrids)
        {
            if (id == in_id)
            {
                return(true);
            }
        }

        return(false);
    }
Esempio n. 5
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------
    void AddRectSelected( exTileSheet _tileSheet, int _x, int _y )
    {
        int in_id = _x + _y * _tileSheet.col;

        bool found = false;
        foreach ( int id in sheetCommitGrids ) {
            if ( id == in_id ) {
                found = true;
                break;
            }
        }

        //
        if ( found == false ) {
            sheetCommitGrids.Add(in_id);
        }
    }
Esempio n. 6
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    void AddRectSelected(exTileSheet _tileSheet, int _x, int _y)
    {
        int in_id = _x + _y * _tileSheet.col;

        bool found = false;

        foreach (int id in sheetCommitGrids)
        {
            if (id == in_id)
            {
                found = true;
                break;
            }
        }

        //
        if (found == false)
        {
            sheetCommitGrids.Add(in_id);
        }
    }
Esempio n. 7
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------
    bool HasSelected( exTileSheet _tileSheet, int _x, int _y )
    {
        int in_id = _x + _y * _tileSheet.col;
        foreach ( int id in sheetSelectedGrids ) {
            if ( id == in_id ) {
                return true;
            }
        }

        return false;
    }
Esempio n. 8
0
    ///////////////////////////////////////////////////////////////////////////////
    // functions
    ///////////////////////////////////////////////////////////////////////////////
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------
    void TileSheetField( Rect _rect, exTileSheet _tileSheet )
    {
        if ( _tileSheet == null )
            return;

        int col = 0;
        int row = 0;
        int uvX = _tileSheet.padding;
        int uvY = _tileSheet.padding;

        // count the col
        while ( (uvX + _tileSheet.tileWidth + _tileSheet.padding) <= _tileSheet.texture.width ) {
            uvX = uvX + _tileSheet.tileWidth + _tileSheet.padding;
            ++col;
        }

        // count the row
        while ( (uvY + _tileSheet.tileHeight + _tileSheet.padding) <= _tileSheet.texture.height ) {
            uvY = uvY + _tileSheet.tileHeight + _tileSheet.padding;
            ++row;
        }

        // show texture by grids
        float curX = 0.0f;
        float curY = 0.0f;
        float interval = 2.0f;
        int borderSize = 1;
        uvX = _tileSheet.padding;
        uvY = _tileSheet.padding;
        int x = 0;
        int y = 0;

        //
        Event e = Event.current;
        sheetCommitGrids.Clear();

        // ========================================================
        // draw field
        // ========================================================

        // DISABLE {
        // Rect filedRect = new Rect( 15,
        //                            lastRect.yMax,
        //                            (_tileSheet.tileWidth + interval + 2 * borderSize) * col - interval,
        //                            (_tileSheet.tileHeight + interval + 2 * borderSize) * row - interval );
        // } DISABLE end
        float tileSheetHeight = (_tileSheet.tileHeight + interval + 2 * borderSize) * row - interval;
        Rect filedRect = new Rect( _rect.x,
                                   _rect.y,
                                   _rect.width,
                                   (tileSheetHeight < _rect.height) ? tileSheetHeight : _rect.height );

        GUI.BeginGroup(filedRect);
            while ( (uvY + _tileSheet.tileHeight + _tileSheet.padding) <= _tileSheet.texture.height ) {
                while ( (uvX + _tileSheet.tileWidth + _tileSheet.padding) <= _tileSheet.texture.width ) {

                    // ========================================================
                    // draw tile element
                    // ========================================================

                    Rect rect = new Rect( curX,
                                          curY,
                                          _tileSheet.tileWidth + 2 * borderSize,
                                          _tileSheet.tileHeight + 2 * borderSize );

                    // draw the texture
                    GUI.BeginGroup( new Rect ( rect.x + 1,
                                               rect.y + 1,
                                               rect.width - 2,
                                               rect.height - 2 ) );
                        Rect cellRect = new Rect( -uvX,
                                                  -uvY,
                                                  _tileSheet.texture.width,
                                                  _tileSheet.texture.height );
                        GUI.DrawTexture( cellRect, _tileSheet.texture );
                    GUI.EndGroup();

                    uvX = uvX + _tileSheet.tileWidth + _tileSheet.padding;
                    curX = curX + _tileSheet.tileWidth + interval + 2 * borderSize;

                    // ========================================================
                    // handle events
                    // ========================================================

                    //
                    if ( e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 1 ) {
                        if ( rect.Contains( e.mousePosition ) ) {
                            GUIUtility.keyboardControl = -1; // remove any keyboard control

                            sheetInRectSelectState = true;
                            mouseDownPos = e.mousePosition;
                            UpdateSelectRect ();

                            if ( e.command == false && e.control == false ) {
                                sheetSelectedGrids.Clear();
                            }

                            e.Use();
                            Repaint();
                        }
                    }

                    //
                    bool selectInRect = false;
                    if ( sheetInRectSelectState ) {
                        if ( exContains2D.RectRect( sheetSelectRect, rect ) != 0 ||
                             exIntersection2D.RectRect( sheetSelectRect, rect ) )
                        {
                            AddRectSelected( _tileSheet, x, y );
                            selectInRect = true;
                        }
                    }

                    // ========================================================
                    // draw grid, NOTE: we should handle event first to get if the rect is slected
                    // ========================================================

                    if ( HasSelected ( _tileSheet, x, y ) || selectInRect ) {
                        exEditorHelper.DrawRect ( rect,
                                                  new Color ( 0.0f, 0.5f, 1.0f, 0.4f ),
                                                  new Color ( 0.0f, 0.5f, 1.0f, 1.0f ) );
                    }
                    else {
                        exEditorHelper.DrawRect ( rect,
                                                  new Color ( 1.0f, 1.0f, 1.0f, 0.0f ),
                                                  Color.gray );
                    }

                    ++x;
                }

                // step uv
                uvX = _tileSheet.padding;
                uvY = uvY + _tileSheet.tileHeight + _tileSheet.padding;

                // step pos
                curX = 0.0f;
                curY = curY + _tileSheet.tileHeight + interval + 2 * borderSize;

                x = 0;
                ++y;
            }

            // DISABLE {
            // // ========================================================
            // // draw select rect
            // // ========================================================

            // if ( sheetInRectSelectState && (sheetSelectRect.width != 0.0f || sheetSelectRect.height != 0.0f) ) {
            //     exEditorHelper.DrawRect( sheetSelectRect, new Color( 0.0f, 0.5f, 1.0f, 0.2f ), new Color( 0.0f, 0.5f, 1.0f, 1.0f ) );
            // }
            // } DISABLE end

            // ========================================================
            // handle rect select
            // ========================================================

            if ( sheetInRectSelectState ) {
                if ( e.type == EventType.MouseDrag ) {
                    UpdateSelectRect ();
                    Repaint();

                    e.Use();
                }
            }

        GUI.EndGroup();
        GUILayoutUtility.GetRect ( filedRect.width, filedRect.height );

        // DISABLE: we use eraser button {

        // if ( e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 1 ) {
        //     if ( filedRect.Contains( e.mousePosition ) == false ) {
        //         sheetSelectedGrids.Clear();
        //         Repaint();

        //         e.Use();
        //     }
        // }
        // } DISABLE end
    }
Esempio n. 9
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    void PreviewTileSheet(float _x, float _y, exTileSheet _tileSheet)
    {
        int uvX = _tileSheet.padding;
        int uvY = _tileSheet.padding;

        if (_tileSheet.texture == null)
        {
            return;
        }

        // show texture by grids
        float curX       = 0.0f;
        float curY       = 0.0f;
        float interval   = 2.0f;
        int   borderSize = 1;

        uvX = _tileSheet.padding;
        uvY = _tileSheet.padding;

        //
        Rect filedRect = new Rect(_x,
                                  _y,
                                  (_tileSheet.tileWidth + interval + 2 * borderSize) * _tileSheet.col - interval,
                                  (_tileSheet.tileHeight + interval + 2 * borderSize) * _tileSheet.row - interval);

        GUI.BeginGroup(filedRect);

        while ((uvY + _tileSheet.tileHeight + _tileSheet.padding) <= _tileSheet.texture.height)
        {
            while ((uvX + _tileSheet.tileWidth + _tileSheet.padding) <= _tileSheet.texture.width)
            {
                Rect rect = new Rect(curX,
                                     curY,
                                     _tileSheet.tileWidth + 2 * borderSize,
                                     _tileSheet.tileHeight + 2 * borderSize);
                GUI.BeginGroup(new Rect(rect.x + 1,
                                        rect.y + 1,
                                        rect.width - 2,
                                        rect.height - 2));
                Rect cellRect = new Rect(-uvX,
                                         -uvY,
                                         _tileSheet.texture.width,
                                         _tileSheet.texture.height);
                GUI.DrawTexture(cellRect, _tileSheet.texture);
                GUI.EndGroup();
                exEditorHelper.DrawRect(rect,
                                        new Color(1.0f, 1.0f, 1.0f, 0.0f),
                                        Color.gray);

                uvX  = uvX + _tileSheet.tileWidth + _tileSheet.padding;
                curX = curX + _tileSheet.tileWidth + interval + 2 * borderSize;
            }

            // step uv
            uvX = _tileSheet.padding;
            uvY = uvY + _tileSheet.tileHeight + _tileSheet.padding;

            // step pos
            curX = 0.0f;
            curY = curY + _tileSheet.tileHeight + interval + 2 * borderSize;
        }

        GUI.EndGroup();
        GUILayoutUtility.GetRect(filedRect.width, filedRect.height);
    }
Esempio n. 10
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------
    void PreviewTileSheet( float _x, float _y, exTileSheet _tileSheet )
    {
        int uvX = _tileSheet.padding;
        int uvY = _tileSheet.padding;

        if ( _tileSheet.texture == null )
            return;

        // show texture by grids
        float curX = 0.0f;
        float curY = 0.0f;
        float interval = 2.0f;
        int borderSize = 1;
        uvX = _tileSheet.padding;
        uvY = _tileSheet.padding;

        //
        Rect filedRect = new Rect( _x,
                                   _y,
                                   (_tileSheet.tileWidth + interval + 2 * borderSize) * _tileSheet.col - interval,
                                   (_tileSheet.tileHeight + interval + 2 * borderSize) * _tileSheet.row - interval );
        GUI.BeginGroup(filedRect);

            while ( (uvY + _tileSheet.tileHeight + _tileSheet.padding) <= _tileSheet.texture.height ) {
                while ( (uvX + _tileSheet.tileWidth + _tileSheet.padding) <= _tileSheet.texture.width ) {
                    Rect rect = new Rect( curX,
                                          curY,
                                          _tileSheet.tileWidth + 2 * borderSize,
                                          _tileSheet.tileHeight + 2 * borderSize );
                    GUI.BeginGroup( new Rect ( rect.x + 1,
                                               rect.y + 1,
                                               rect.width - 2,
                                               rect.height - 2 ) );
                        Rect cellRect = new Rect( -uvX,
                                                  -uvY,
                                                  _tileSheet.texture.width,
                                                  _tileSheet.texture.height );
                        GUI.DrawTexture( cellRect, _tileSheet.texture );
                    GUI.EndGroup();
                    exEditorHelper.DrawRect ( rect,
                                              new Color ( 1.0f, 1.0f, 1.0f, 0.0f ),
                                              Color.gray );

                    uvX = uvX + _tileSheet.tileWidth + _tileSheet.padding;
                    curX = curX + _tileSheet.tileWidth + interval + 2 * borderSize;
                }

                // step uv
                uvX = _tileSheet.padding;
                uvY = uvY + _tileSheet.tileHeight + _tileSheet.padding;

                // step pos
                curX = 0.0f;
                curY = curY + _tileSheet.tileHeight + interval + 2 * borderSize;
            }

        GUI.EndGroup();
        GUILayoutUtility.GetRect ( filedRect.width, filedRect.height );
    }
Esempio n. 11
0
    ///////////////////////////////////////////////////////////////////////////////
    // functions
    ///////////////////////////////////////////////////////////////////////////////

    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    void TileSheetField(Rect _rect, exTileSheet _tileSheet)
    {
        if (_tileSheet == null)
        {
            return;
        }

        int col = 0;
        int row = 0;
        int uvX = _tileSheet.padding;
        int uvY = _tileSheet.padding;

        // count the col
        while ((uvX + _tileSheet.tileWidth + _tileSheet.padding) <= _tileSheet.texture.width)
        {
            uvX = uvX + _tileSheet.tileWidth + _tileSheet.padding;
            ++col;
        }

        // count the row
        while ((uvY + _tileSheet.tileHeight + _tileSheet.padding) <= _tileSheet.texture.height)
        {
            uvY = uvY + _tileSheet.tileHeight + _tileSheet.padding;
            ++row;
        }

        // show texture by grids
        float curX       = 0.0f;
        float curY       = 0.0f;
        float interval   = 2.0f;
        int   borderSize = 1;

        uvX = _tileSheet.padding;
        uvY = _tileSheet.padding;
        int x = 0;
        int y = 0;

        //
        Event e = Event.current;

        sheetCommitGrids.Clear();

        // ========================================================
        // draw field
        // ========================================================

        // DISABLE {
        // Rect filedRect = new Rect( 15,
        //                            lastRect.yMax,
        //                            (_tileSheet.tileWidth + interval + 2 * borderSize) * col - interval,
        //                            (_tileSheet.tileHeight + interval + 2 * borderSize) * row - interval );
        // } DISABLE end
        float tileSheetHeight = (_tileSheet.tileHeight + interval + 2 * borderSize) * row - interval;
        Rect  filedRect       = new Rect(_rect.x,
                                         _rect.y,
                                         _rect.width,
                                         (tileSheetHeight < _rect.height) ? tileSheetHeight : _rect.height);

        GUI.BeginGroup(filedRect);
        while ((uvY + _tileSheet.tileHeight + _tileSheet.padding) <= _tileSheet.texture.height)
        {
            while ((uvX + _tileSheet.tileWidth + _tileSheet.padding) <= _tileSheet.texture.width)
            {
                // ========================================================
                // draw tile element
                // ========================================================

                Rect rect = new Rect(curX,
                                     curY,
                                     _tileSheet.tileWidth + 2 * borderSize,
                                     _tileSheet.tileHeight + 2 * borderSize);

                // draw the texture
                GUI.BeginGroup(new Rect(rect.x + 1,
                                        rect.y + 1,
                                        rect.width - 2,
                                        rect.height - 2));
                Rect cellRect = new Rect(-uvX,
                                         -uvY,
                                         _tileSheet.texture.width,
                                         _tileSheet.texture.height);
                GUI.DrawTexture(cellRect, _tileSheet.texture);
                GUI.EndGroup();

                uvX  = uvX + _tileSheet.tileWidth + _tileSheet.padding;
                curX = curX + _tileSheet.tileWidth + interval + 2 * borderSize;

                // ========================================================
                // handle events
                // ========================================================

                //
                if (e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 1)
                {
                    if (rect.Contains(e.mousePosition))
                    {
                        GUIUtility.keyboardControl = -1;     // remove any keyboard control

                        sheetInRectSelectState = true;
                        mouseDownPos           = e.mousePosition;
                        UpdateSelectRect();

                        if (e.command == false && e.control == false)
                        {
                            sheetSelectedGrids.Clear();
                        }

                        e.Use();
                        Repaint();
                    }
                }

                //
                bool selectInRect = false;
                if (sheetInRectSelectState)
                {
                    if (exContains2D.RectRect(sheetSelectRect, rect) != 0 ||
                        exIntersection2D.RectRect(sheetSelectRect, rect))
                    {
                        AddRectSelected(_tileSheet, x, y);
                        selectInRect = true;
                    }
                }

                // ========================================================
                // draw grid, NOTE: we should handle event first to get if the rect is slected
                // ========================================================

                if (HasSelected(_tileSheet, x, y) || selectInRect)
                {
                    exEditorHelper.DrawRect(rect,
                                            new Color(0.0f, 0.5f, 1.0f, 0.4f),
                                            new Color(0.0f, 0.5f, 1.0f, 1.0f));
                }
                else
                {
                    exEditorHelper.DrawRect(rect,
                                            new Color(1.0f, 1.0f, 1.0f, 0.0f),
                                            Color.gray);
                }

                ++x;
            }

            // step uv
            uvX = _tileSheet.padding;
            uvY = uvY + _tileSheet.tileHeight + _tileSheet.padding;

            // step pos
            curX = 0.0f;
            curY = curY + _tileSheet.tileHeight + interval + 2 * borderSize;

            x = 0;
            ++y;
        }

        // DISABLE {
        // // ========================================================
        // // draw select rect
        // // ========================================================

        // if ( sheetInRectSelectState && (sheetSelectRect.width != 0.0f || sheetSelectRect.height != 0.0f) ) {
        //     exEditorHelper.DrawRect( sheetSelectRect, new Color( 0.0f, 0.5f, 1.0f, 0.2f ), new Color( 0.0f, 0.5f, 1.0f, 1.0f ) );
        // }
        // } DISABLE end

        // ========================================================
        // handle rect select
        // ========================================================

        if (sheetInRectSelectState)
        {
            if (e.type == EventType.MouseDrag)
            {
                UpdateSelectRect();
                Repaint();

                e.Use();
            }
        }

        GUI.EndGroup();
        GUILayoutUtility.GetRect(filedRect.width, filedRect.height);

        // DISABLE: we use eraser button {

        // if ( e.type == EventType.MouseDown && e.button == 0 && e.clickCount == 1 ) {
        //     if ( filedRect.Contains( e.mousePosition ) == false ) {
        //         sheetSelectedGrids.Clear();
        //         Repaint();

        //         e.Use();
        //     }
        // }
        // } DISABLE end
    }
Esempio n. 12
0
    // ------------------------------------------------------------------
    // Desc:
    // ------------------------------------------------------------------

    void OnGUI()
    {
        EditorGUI.indentLevel = 0;

        if (curEdit == null)
        {
            GUILayout.Space(10);
            GUILayout.Label("Please select a Tile Map");
            return;
        }

        // ========================================================
        //
        // ========================================================

        Rect lastRect = new Rect(10, 0, 1, 1);

        GUILayout.BeginHorizontal();
        GUILayout.BeginVertical(GUILayout.MaxWidth(300));

        GUILayout.Space(5);

        // ========================================================
        // Tile Sheet Field
        // ========================================================

        GUILayout.BeginHorizontal();
        exTileSheet newTileSheet =
            (exTileSheet)EditorGUILayout.ObjectField("Tile Sheet"
                                                     , curEdit.tileSheet
                                                     , typeof(exTileSheet)
                                                     , false
                                                     );

        if (newTileSheet != curEdit.tileSheet)
        {
            curEdit.tileSheet = newTileSheet;
            sheetSelectedGrids.Clear();
            sheetCommitGrids.Clear();
        }
        if (GUILayout.Button("Edit...", GUILayout.Width(40), GUILayout.Height(15)))
        {
            exTileSheetEditor editor = exTileSheetEditor.NewWindow();
            editor.Edit(curEdit.tileSheet);
        }
        GUILayout.EndHorizontal();

        // ========================================================
        // tile size
        // ========================================================

        if (curEdit.tileSheet)
        {
            EditorGUILayout.LabelField("Tile Size", curEdit.tileSheet.tileWidth + " x " + curEdit.tileSheet.tileHeight);
        }
        else
        {
            EditorGUILayout.LabelField("Tile Size", "0 x 0");
        }

        // ========================================================
        // tile sheet field
        // ========================================================

        EditorGUILayout.Space();
        lastRect = GUILayoutUtility.GetLastRect();
        TileSheetField(new Rect(15, lastRect.yMax, 300, 500),
                       curEdit.tileSheet);

        // ========================================================
        // tile map object
        // ========================================================

        GUILayout.Space(20);
        GUI.enabled = false;
        EditorGUILayout.ObjectField("Tile Map"
                                    , curEdit
                                    , typeof(exTileMap)
                                    , false
                                    );
        GUI.enabled = true;

        // ========================================================
        // col & row
        // ========================================================

        GUILayout.BeginHorizontal();
        int newCol = Mathf.Max(EditorGUILayout.IntField("Column", curEdit.col), 1);
        int newRow = Mathf.Max(EditorGUILayout.IntField("Row", curEdit.row), 1);

        if (newCol != curEdit.col || newRow != curEdit.row)
        {
            curEdit.Resize(newCol, newRow);
        }
        GUILayout.EndHorizontal();

        // ========================================================
        // Tile Width & Height
        // ========================================================

        GUILayout.BeginHorizontal();
        int newtileWidth = EditorGUILayout.IntField("Tile Width", curEdit.tileWidth);

        if (newtileWidth != curEdit.tileWidth)
        {
            curEdit.tileWidth         = newtileWidth;
            curEdit.editorNeedRebuild = true;
        }

        int newtileHeight = EditorGUILayout.IntField("Tile Height", curEdit.tileHeight);

        if (newtileHeight != curEdit.tileHeight)
        {
            curEdit.tileHeight        = newtileHeight;
            curEdit.editorNeedRebuild = true;
        }
        GUILayout.EndHorizontal();

        // ========================================================
        // Tile Offset X & Y
        // ========================================================

        GUILayout.BeginHorizontal();
        int newTileOffsetX = EditorGUILayout.IntField("Tile Offset X", curEdit.tileOffsetX);

        if (newTileOffsetX != curEdit.tileOffsetX)
        {
            curEdit.tileOffsetX       = newTileOffsetX;
            curEdit.editorNeedRebuild = true;
        }

        int newTileOffsetY = EditorGUILayout.IntField("Tile Offset Y", curEdit.tileOffsetY);

        if (newTileOffsetY != curEdit.tileOffsetY)
        {
            curEdit.tileOffsetY       = newTileOffsetY;
            curEdit.editorNeedRebuild = true;
        }
        GUILayout.EndHorizontal();

        // DEBUG {
        // ========================================================
        // Debug
        // ========================================================

        GUILayout.Space(20);
        GUILayout.Label("Debug");
        GUILayout.Label("Visible Grids " + debugVisibleGrids);
        // } DEBUG end


        GUILayout.EndVertical();

        GUILayout.Space(10);
        lastRect = GUILayoutUtility.GetLastRect();

        GUILayout.BeginVertical();

        // ========================================================
        // toolbar
        // ========================================================

        GUILayout.BeginHorizontal(EditorStyles.toolbar);

        // ========================================================
        // show grid
        // ========================================================

        curEdit.editorShowGrid = GUILayout.Toggle(curEdit.editorShowGrid, "Show Grid", EditorStyles.toolbarButton);
        GUILayout.Space(10);

        // ========================================================
        // edit tool
        // ========================================================

        curEdit.editorEditTool
            = (exTileMap.EditTool)GUILayout.Toolbar((int)curEdit.editorEditTool,
                                                    toolIcons,
                                                    EditorStyles.toolbarButton);
        GUILayout.Space(10);

        // ========================================================
        // edit mode
        // ========================================================

        if (sheetSelectedGrids.Count > 0 || sheetCommitGrids.Count > 0)
        {
            curEdit.editorEditMode = exTileMap.EditMode.Paint;
        }
        else
        {
            curEdit.editorEditMode = exTileMap.EditMode.Erase;
        }

        exTileMap.EditMode newEditMode
            = (exTileMap.EditMode)GUILayout.Toolbar((int)curEdit.editorEditMode,
                                                    modeIcons,
                                                    EditorStyles.toolbarButton);
        if (newEditMode != curEdit.editorEditMode)
        {
            curEdit.editorEditMode = newEditMode;
            if (curEdit.editorEditMode == exTileMap.EditMode.Erase)
            {
                sheetSelectedGrids.Clear();
                sheetCommitGrids.Clear();
            }
        }

        GUILayout.FlexibleSpace();

        // ========================================================
        // clear
        // ========================================================

        if (GUILayout.Button("Clear", EditorStyles.toolbarButton))
        {
            curEdit.Clear();
        }
        GUILayout.Space(10);

        // ========================================================
        // Help
        // ========================================================

        if (GUILayout.Button(exEditorHelper.HelpTexture(), EditorStyles.toolbarButton))
        {
            Help.BrowseURL("http://www.ex-dev.com/ex2d/wiki/doku.php?id=manual:tilemap_editor");
        }

        GUILayout.EndHorizontal();

        // ========================================================
        // tile map filed
        // ========================================================

        float toolbarHeight = EditorStyles.toolbar.CalcHeight(new GUIContent(""), 0);

        TileMapField(new Rect(lastRect.xMax,
                              toolbarHeight,
                              position.width - lastRect.xMax,
                              position.height - toolbarHeight),
                     curEdit);

        GUILayout.EndVertical();

        // ========================================================
        // draw vertical split line
        // ========================================================

        exEditorHelper.DrawLine(new Vector2(lastRect.xMax, 0),
                                new Vector2(lastRect.xMax, position.height),
                                Color.black,
                                1.0f);

        GUILayout.EndHorizontal();

        // ========================================================
        // NOTE: cancle select event of tile sheet. Should after TileMapField, so we put it here
        Event e = Event.current;

        // ========================================================

        if (e.type == EventType.MouseUp && e.button == 0)
        {
            if (sheetInRectSelectState)
            {
                sheetInRectSelectState = false;
                ConfirmRectSelection();
                Repaint();

                e.Use();
            }
            else
            {
                sheetCommitGrids.Clear();
                sheetSelectedGrids.Clear();
                Repaint();

                e.Use();
            }
        }

        // ========================================================
        // check dirty
        // ========================================================

        if (GUI.changed)
        {
            EditorUtility.SetDirty(curEdit);
        }
    }