示例#1
0
    /// <summary>
    /// Replace the sprites within the atlas.
    /// </summary>

    static void ReplaceSprites(NGUIAtlas atlas, List <SpriteEntry> sprites)
    {
        // Get the list of sprites we'll be updating
        List <NGUIAtlas.Sprite> spriteList = atlas.spriteList;
        List <NGUIAtlas.Sprite> kept       = new List <NGUIAtlas.Sprite>();

        // The atlas must be in pixels
        atlas.coordinates = NGUIAtlas.Coordinates.Pixels;

        // Run through all the textures we added and add them as sprites to the atlas
        for (int i = 0; i < sprites.Count; ++i)
        {
            SpriteEntry      se     = sprites[i];
            NGUIAtlas.Sprite sprite = AddSprite(spriteList, se);
            kept.Add(sprite);
        }

        // Remove unused sprites
        for (int i = spriteList.Count; i > 0;)
        {
            NGUIAtlas.Sprite sp = spriteList[--i];
            if (!kept.Contains(sp))
            {
                spriteList.RemoveAt(i);
            }
        }
        atlas.MarkAsDirty();
    }
示例#2
0
    /// <summary>
    /// Update the sprite atlas, keeping only the sprites that are on the specified list.
    /// </summary>

    static void UpdateAtlas(NGUIAtlas atlas, List <SpriteEntry> sprites)
    {
        if (sprites.Count > 0)
        {
            // Combine all sprites into a single texture and save it
            if (UpdateTexture(atlas, sprites))
            {
                // Replace the sprites within the atlas
                ReplaceSprites(atlas, sprites);

                // Release the temporary textures
                ReleaseSprites(sprites);
            }
            else
            {
                return;
            }
        }
        else
        {
            atlas.spriteList.Clear();
            string path = NGUIEditorTools.GetSaveableTexturePath(atlas);
            atlas.spriteMaterial.mainTexture = null;
            if (!string.IsNullOrEmpty(path))
            {
                AssetDatabase.DeleteAsset(path);
            }
        }
        atlas.MarkAsDirty();

        Debug.Log("The atlas has been updated. Don't forget to save the scene to write the changes!");
    }
示例#3
0
    /// <summary>
    /// Mark all widgets associated with this atlas as having changed.
    /// </summary>

    public void MarkAsDirty()
    {
#if UNITY_EDITOR
        UnityEditor.EditorUtility.SetDirty(gameObject);
#endif
        if (mReplacement != null)
        {
            mReplacement.MarkAsDirty();
        }

        NGUISprite[] list = NGUITools.FindActive <NGUISprite>();

        for (int i = 0, imax = list.Length; i < imax; ++i)
        {
            NGUISprite sp = list[i];

            if (CheckIfRelated(this, sp.atlas))
            {
                NGUIAtlas atl = sp.atlas;
                sp.atlas = null;
                sp.atlas = atl;
#if UNITY_EDITOR
                UnityEditor.EditorUtility.SetDirty(sp);
#endif
            }
        }

        NGUIFont[] fonts = Resources.FindObjectsOfTypeAll(typeof(NGUIFont)) as NGUIFont[];

        for (int i = 0, imax = fonts.Length; i < imax; ++i)
        {
            NGUIFont font = fonts[i];

            if (CheckIfRelated(this, font.atlas))
            {
                NGUIAtlas atl = font.atlas;
                font.atlas = null;
                font.atlas = atl;
#if UNITY_EDITOR
                UnityEditor.EditorUtility.SetDirty(font);
#endif
            }
        }

        NGUILabel[] labels = NGUITools.FindActive <NGUILabel>();

        for (int i = 0, imax = labels.Length; i < imax; ++i)
        {
            NGUILabel lbl = labels[i];

            if (lbl.font != null && CheckIfRelated(this, lbl.font.atlas))
            {
                NGUIFont font = lbl.font;
                lbl.font = null;
                lbl.font = font;
#if UNITY_EDITOR
                UnityEditor.EditorUtility.SetDirty(lbl);
#endif
            }
        }
    }
示例#4
0
    /// <summary>
    /// Update the sprite atlas, keeping only the sprites that are on the specified list.
    /// </summary>
    static void UpdateAtlas(NGUIAtlas atlas, List<SpriteEntry> sprites)
    {
        if (sprites.Count > 0)
        {
            // Combine all sprites into a single texture and save it
            if (UpdateTexture(atlas, sprites))
            {
                // Replace the sprites within the atlas
                ReplaceSprites(atlas, sprites);

                // Release the temporary textures
                ReleaseSprites(sprites);
            }
            else return;
        }
        else
        {
            atlas.spriteList.Clear();
            string path = NGUIEditorTools.GetSaveableTexturePath(atlas);
            atlas.spriteMaterial.mainTexture = null;
            if (!string.IsNullOrEmpty(path)) AssetDatabase.DeleteAsset(path);
        }
        atlas.MarkAsDirty();

        Debug.Log("The atlas has been updated. Don't forget to save the scene to write the changes!");
    }
示例#5
0
    /// <summary>
    /// Replace the sprites within the atlas.
    /// </summary>
    static void ReplaceSprites(NGUIAtlas atlas, List<SpriteEntry> sprites)
    {
        // Get the list of sprites we'll be updating
        List<NGUIAtlas.Sprite> spriteList = atlas.spriteList;
        List<NGUIAtlas.Sprite> kept = new List<NGUIAtlas.Sprite>();

        // The atlas must be in pixels
        atlas.coordinates = NGUIAtlas.Coordinates.Pixels;

        // Run through all the textures we added and add them as sprites to the atlas
        for (int i = 0; i < sprites.Count; ++i)
        {
            SpriteEntry se = sprites[i];
            NGUIAtlas.Sprite sprite = AddSprite(spriteList, se);
            kept.Add(sprite);
        }

        // Remove unused sprites
        for (int i = spriteList.Count; i > 0; )
        {
            NGUIAtlas.Sprite sp = spriteList[--i];
            if (!kept.Contains(sp)) spriteList.RemoveAt(i);
        }
        atlas.MarkAsDirty();
    }
    /// <summary>
    /// Draw the inspector widget.
    /// </summary>
    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls(80f);
        mAtlas = target as NGUIAtlas;

        NGUIEditorTools.DrawSeparator();

        if (mAtlas.replacement != null)
        {
            mType = AtlasType.Reference;
            mReplacement = mAtlas.replacement;
        }

        AtlasType after = (AtlasType)EditorGUILayout.EnumPopup("Atlas Type", mType);

        if (mType != after)
        {
            if (after == AtlasType.Normal)
            {
                OnSelectAtlas(null);
            }
            else
            {
                mType = AtlasType.Reference;
            }
        }

        if (mType == AtlasType.Reference)
        {
            ComponentSelector.Draw<NGUIAtlas>(mAtlas.replacement, OnSelectAtlas);

            NGUIEditorTools.DrawSeparator();
            EditorGUILayout.HelpBox("You can have one atlas simply point to " +
                "another one. This is useful if you want to be " +
                "able to quickly replace the contents of one " +
                "atlas with another one, for example for " +
                "swapping an SD atlas with an HD one, or " +
                "replacing an English atlas with a Chinese " +
                "one. All the sprites referencing this atlas " +
                "will update their references to the new one.", MessageType.Info);

            if (mReplacement != mAtlas && mAtlas.replacement != mReplacement)
            {
                NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                mAtlas.replacement = mReplacement;
                UnityEditor.EditorUtility.SetDirty(mAtlas);
            }
            return;
        }

        if (!mConfirmDelete)
        {
            NGUIEditorTools.DrawSeparator();
            Material mat = EditorGUILayout.ObjectField("Material", mAtlas.spriteMaterial, typeof(Material), false) as Material;

            if (mAtlas.spriteMaterial != mat)
            {
                NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                mAtlas.spriteMaterial = mat;

                // Ensure that this atlas has valid import settings
                if (mAtlas.texture != null) NGUIEditorTools.ImportTexture(mAtlas.texture, false, false);

                mAtlas.MarkAsDirty();
                mConfirmDelete = false;
            }

            if (mat != null)
            {
                TextAsset ta = EditorGUILayout.ObjectField("TP Import", null, typeof(TextAsset), false) as TextAsset;

                if (ta != null)
                {
                    // Ensure that this atlas has valid import settings
                    if (mAtlas.texture != null) NGUIEditorTools.ImportTexture(mAtlas.texture, false, false);

                    NGUIEditorTools.RegisterUndo("Import Sprites", mAtlas);
                    NGUIJson.LoadSpriteData(mAtlas, ta);
                    if (mSprite != null) mSprite = mAtlas.GetSprite(mSprite.name);
                    mAtlas.MarkAsDirty();
                }

                NGUIAtlas.Coordinates coords = (NGUIAtlas.Coordinates)EditorGUILayout.EnumPopup("Coordinates", mAtlas.coordinates);

                if (coords != mAtlas.coordinates)
                {
                    NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                    mAtlas.coordinates = coords;
                    mConfirmDelete = false;
                }

                float pixelSize = EditorGUILayout.FloatField("Pixel Size", mAtlas.pixelSize, GUILayout.Width(120f));

                if (pixelSize != mAtlas.pixelSize)
                {
                    NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                    mAtlas.pixelSize = pixelSize;
                    mConfirmDelete = false;
                }
            }
        }

        if (mAtlas.spriteMaterial != null)
        {
            Color blue = new Color(0f, 0.7f, 1f, 1f);
            Color green = new Color(0.4f, 1f, 0f, 1f);

            if (mConfirmDelete)
            {
                if (mSprite != null)
                {
                    // Show the confirmation dialog
                    NGUIEditorTools.DrawSeparator();
                    GUILayout.Label("Are you sure you want to delete '" + mSprite.name + "'?");
                    NGUIEditorTools.DrawSeparator();

                    GUILayout.BeginHorizontal();
                    {
                        GUI.backgroundColor = Color.green;
                        if (GUILayout.Button("Cancel")) mConfirmDelete = false;
                        GUI.backgroundColor = Color.red;

                        if (GUILayout.Button("Delete"))
                        {
                            NGUIEditorTools.RegisterUndo("Delete Sprite", mAtlas);
                            mAtlas.spriteList.Remove(mSprite);
                            mConfirmDelete = false;
                        }
                        GUI.backgroundColor = Color.white;
                    }
                    GUILayout.EndHorizontal();
                }
                else mConfirmDelete = false;
            }
            else
            {
                if (mSprite == null && mAtlas.spriteList.Count > 0)
                {
                    string spriteName = EditorPrefs.GetString("NGUI Selected Sprite");
                    if (!string.IsNullOrEmpty(spriteName)) mSprite = mAtlas.GetSprite(spriteName);
                    if (mSprite == null) mSprite = mAtlas.spriteList[0];
                }

                if (!mConfirmDelete && mSprite != null)
                {
                    NGUIEditorTools.DrawSeparator();
                    NGUIEditorTools.AdvancedSpriteField(mAtlas, mSprite.name, SelectSprite, true);

                    if (mSprite == null) return;

                    Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D;

                    if (tex != null)
                    {
                        Rect inner = mSprite.inner;
                        Rect outer = mSprite.outer;

                        if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels)
                        {
                            GUI.backgroundColor = green;
                            outer = NGUIEditorTools.IntRect("Dimensions", mSprite.outer);

                            Vector4 border = new Vector4(
                                mSprite.inner.xMin - mSprite.outer.xMin,
                                mSprite.inner.yMin - mSprite.outer.yMin,
                                mSprite.outer.xMax - mSprite.inner.xMax,
                                mSprite.outer.yMax - mSprite.inner.yMax);

                            GUI.backgroundColor = blue;
                            border = NGUIEditorTools.IntPadding("Border", border);
                            GUI.backgroundColor = Color.white;

                            inner.xMin = mSprite.outer.xMin + border.x;
                            inner.yMin = mSprite.outer.yMin + border.y;
                            inner.xMax = mSprite.outer.xMax - border.z;
                            inner.yMax = mSprite.outer.yMax - border.w;
                        }
                        else
                        {
                            // Draw the inner and outer rectangle dimensions
                            GUI.backgroundColor = green;
                            outer = EditorGUILayout.RectField("Outer Rect", mSprite.outer);
                            GUI.backgroundColor = blue;
                            inner = EditorGUILayout.RectField("Inner Rect", mSprite.inner);
                            GUI.backgroundColor = Color.white;
                        }

                        if (outer.xMax < outer.xMin) outer.xMax = outer.xMin;
                        if (outer.yMax < outer.yMin) outer.yMax = outer.yMin;

                        if (outer != mSprite.outer)
                        {
                            float x = outer.xMin - mSprite.outer.xMin;
                            float y = outer.yMin - mSprite.outer.yMin;

                            inner.x += x;
                            inner.y += y;
                        }

                        // Sanity checks to ensure that the inner rect is always inside the outer
                        inner.xMin = Mathf.Clamp(inner.xMin, outer.xMin, outer.xMax);
                        inner.xMax = Mathf.Clamp(inner.xMax, outer.xMin, outer.xMax);
                        inner.yMin = Mathf.Clamp(inner.yMin, outer.yMin, outer.yMax);
                        inner.yMax = Mathf.Clamp(inner.yMax, outer.yMin, outer.yMax);

                        bool changed = false;

                        if (mSprite.inner != inner || mSprite.outer != outer)
                        {
                            NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                            mSprite.inner = inner;
                            mSprite.outer = outer;
                            MarkSpriteAsDirty();
                            changed = true;
                        }

                        EditorGUILayout.Separator();

                        if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels)
                        {
                            int left	= Mathf.RoundToInt(mSprite.paddingLeft	 * mSprite.outer.width);
                            int right	= Mathf.RoundToInt(mSprite.paddingRight	 * mSprite.outer.width);
                            int top		= Mathf.RoundToInt(mSprite.paddingTop	 * mSprite.outer.height);
                            int bottom	= Mathf.RoundToInt(mSprite.paddingBottom * mSprite.outer.height);

                            NGUIEditorTools.IntVector a = NGUIEditorTools.IntPair("Padding", "Left", "Top", left, top);
                            NGUIEditorTools.IntVector b = NGUIEditorTools.IntPair(null, "Right", "Bottom", right, bottom);

                            if (changed || a.x != left || a.y != top || b.x != right || b.y != bottom)
                            {
                                NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                                mSprite.paddingLeft		= a.x / mSprite.outer.width;
                                mSprite.paddingTop		= a.y / mSprite.outer.height;
                                mSprite.paddingRight	= b.x / mSprite.outer.width;
                                mSprite.paddingBottom	= b.y / mSprite.outer.height;
                                MarkSpriteAsDirty();
                            }
                        }
                        else
                        {
                            // Create a button that can make the coordinates pixel-perfect on click
                            GUILayout.BeginHorizontal();
                            {
                                GUILayout.Label("Correction", GUILayout.Width(75f));

                                Rect corrected0 = outer;
                                Rect corrected1 = inner;

                                if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels)
                                {
                                    corrected0 = NGUIMath.MakePixelPerfect(corrected0);
                                    corrected1 = NGUIMath.MakePixelPerfect(corrected1);
                                }
                                else
                                {
                                    corrected0 = NGUIMath.MakePixelPerfect(corrected0, tex.width, tex.height);
                                    corrected1 = NGUIMath.MakePixelPerfect(corrected1, tex.width, tex.height);
                                }

                                if (corrected0 == mSprite.outer && corrected1 == mSprite.inner)
                                {
                                    GUI.color = Color.grey;
                                    GUILayout.Button("Make Pixel-Perfect");
                                    GUI.color = Color.white;
                                }
                                else if (GUILayout.Button("Make Pixel-Perfect"))
                                {
                                    outer = corrected0;
                                    inner = corrected1;
                                    GUI.changed = true;
                                }
                            }
                            GUILayout.EndHorizontal();
                        }
                    }

                    // This functionality is no longer used. It became obsolete when the Atlas Maker was added.
                    /*NGUIEditorTools.DrawSeparator();

                    GUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.PrefixLabel("Add/Delete");

                        if (GUILayout.Button("Clone Sprite"))
                        {
                            NGUIEditorTools.RegisterUndo("Add Sprite", mAtlas);
                            NGUIAtlas.Sprite newSprite = new NGUIAtlas.Sprite();

                            if (mSprite != null)
                            {
                                newSprite.name = "Copy of " + mSprite.name;
                                newSprite.outer = mSprite.outer;
                                newSprite.inner = mSprite.inner;
                            }
                            else
                            {
                                newSprite.name = "New Sprite";
                            }

                            mAtlas.spriteList.Add(newSprite);
                            mSprite = newSprite;
                        }

                        // Show the delete button
                        GUI.backgroundColor = Color.red;

                        if (mSprite != null && GUILayout.Button("Delete", GUILayout.Width(55f)))
                        {
                            mConfirmDelete = true;
                        }
                        GUI.backgroundColor = Color.white;
                    }
                    GUILayout.EndHorizontal();*/

                    if (NGUIEditorTools.previousSelection != null)
                    {
                        NGUIEditorTools.DrawSeparator();

                        GUI.backgroundColor = Color.green;

                        if (GUILayout.Button("<< Return to " + NGUIEditorTools.previousSelection.name))
                        {
                            NGUIEditorTools.SelectPrevious();
                        }
                        GUI.backgroundColor = Color.white;
                    }
                }
            }
        }
    }
    /// <summary>
    /// Draw the inspector widget.
    /// </summary>

    public override void OnInspectorGUI()
    {
        EditorGUIUtility.LookLikeControls(80f);
        mAtlas = target as NGUIAtlas;

        NGUIEditorTools.DrawSeparator();

        if (mAtlas.replacement != null)
        {
            mType        = AtlasType.Reference;
            mReplacement = mAtlas.replacement;
        }

        AtlasType after = (AtlasType)EditorGUILayout.EnumPopup("Atlas Type", mType);

        if (mType != after)
        {
            if (after == AtlasType.Normal)
            {
                OnSelectAtlas(null);
            }
            else
            {
                mType = AtlasType.Reference;
            }
        }

        if (mType == AtlasType.Reference)
        {
            ComponentSelector.Draw <NGUIAtlas>(mAtlas.replacement, OnSelectAtlas);

            NGUIEditorTools.DrawSeparator();
            EditorGUILayout.HelpBox("You can have one atlas simply point to " +
                                    "another one. This is useful if you want to be " +
                                    "able to quickly replace the contents of one " +
                                    "atlas with another one, for example for " +
                                    "swapping an SD atlas with an HD one, or " +
                                    "replacing an English atlas with a Chinese " +
                                    "one. All the sprites referencing this atlas " +
                                    "will update their references to the new one.", MessageType.Info);

            if (mReplacement != mAtlas && mAtlas.replacement != mReplacement)
            {
                NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                mAtlas.replacement = mReplacement;
                UnityEditor.EditorUtility.SetDirty(mAtlas);
            }
            return;
        }

        if (!mConfirmDelete)
        {
            NGUIEditorTools.DrawSeparator();
            Material mat = EditorGUILayout.ObjectField("Material", mAtlas.spriteMaterial, typeof(Material), false) as Material;

            if (mAtlas.spriteMaterial != mat)
            {
                NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                mAtlas.spriteMaterial = mat;

                // Ensure that this atlas has valid import settings
                if (mAtlas.texture != null)
                {
                    NGUIEditorTools.ImportTexture(mAtlas.texture, false, false);
                }

                mAtlas.MarkAsDirty();
                mConfirmDelete = false;
            }

            if (mat != null)
            {
                TextAsset ta = EditorGUILayout.ObjectField("TP Import", null, typeof(TextAsset), false) as TextAsset;

                if (ta != null)
                {
                    // Ensure that this atlas has valid import settings
                    if (mAtlas.texture != null)
                    {
                        NGUIEditorTools.ImportTexture(mAtlas.texture, false, false);
                    }

                    NGUIEditorTools.RegisterUndo("Import Sprites", mAtlas);
                    NGUIJson.LoadSpriteData(mAtlas, ta);
                    if (mSprite != null)
                    {
                        mSprite = mAtlas.GetSprite(mSprite.name);
                    }
                    mAtlas.MarkAsDirty();
                }

                NGUIAtlas.Coordinates coords = (NGUIAtlas.Coordinates)EditorGUILayout.EnumPopup("Coordinates", mAtlas.coordinates);

                if (coords != mAtlas.coordinates)
                {
                    NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                    mAtlas.coordinates = coords;
                    mConfirmDelete     = false;
                }

                float pixelSize = EditorGUILayout.FloatField("Pixel Size", mAtlas.pixelSize, GUILayout.Width(120f));

                if (pixelSize != mAtlas.pixelSize)
                {
                    NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                    mAtlas.pixelSize = pixelSize;
                    mConfirmDelete   = false;
                }
            }
        }

        if (mAtlas.spriteMaterial != null)
        {
            Color blue  = new Color(0f, 0.7f, 1f, 1f);
            Color green = new Color(0.4f, 1f, 0f, 1f);

            if (mConfirmDelete)
            {
                if (mSprite != null)
                {
                    // Show the confirmation dialog
                    NGUIEditorTools.DrawSeparator();
                    GUILayout.Label("Are you sure you want to delete '" + mSprite.name + "'?");
                    NGUIEditorTools.DrawSeparator();

                    GUILayout.BeginHorizontal();
                    {
                        GUI.backgroundColor = Color.green;
                        if (GUILayout.Button("Cancel"))
                        {
                            mConfirmDelete = false;
                        }
                        GUI.backgroundColor = Color.red;

                        if (GUILayout.Button("Delete"))
                        {
                            NGUIEditorTools.RegisterUndo("Delete Sprite", mAtlas);
                            mAtlas.spriteList.Remove(mSprite);
                            mConfirmDelete = false;
                        }
                        GUI.backgroundColor = Color.white;
                    }
                    GUILayout.EndHorizontal();
                }
                else
                {
                    mConfirmDelete = false;
                }
            }
            else
            {
                if (mSprite == null && mAtlas.spriteList.Count > 0)
                {
                    string spriteName = EditorPrefs.GetString("NGUI Selected Sprite");
                    if (!string.IsNullOrEmpty(spriteName))
                    {
                        mSprite = mAtlas.GetSprite(spriteName);
                    }
                    if (mSprite == null)
                    {
                        mSprite = mAtlas.spriteList[0];
                    }
                }

                if (!mConfirmDelete && mSprite != null)
                {
                    NGUIEditorTools.DrawSeparator();
                    NGUIEditorTools.AdvancedSpriteField(mAtlas, mSprite.name, SelectSprite, true);

                    if (mSprite == null)
                    {
                        return;
                    }

                    Texture2D tex = mAtlas.spriteMaterial.mainTexture as Texture2D;

                    if (tex != null)
                    {
                        Rect inner = mSprite.inner;
                        Rect outer = mSprite.outer;

                        if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels)
                        {
                            GUI.backgroundColor = green;
                            outer = NGUIEditorTools.IntRect("Dimensions", mSprite.outer);

                            Vector4 border = new Vector4(
                                mSprite.inner.xMin - mSprite.outer.xMin,
                                mSprite.inner.yMin - mSprite.outer.yMin,
                                mSprite.outer.xMax - mSprite.inner.xMax,
                                mSprite.outer.yMax - mSprite.inner.yMax);

                            GUI.backgroundColor = blue;
                            border = NGUIEditorTools.IntPadding("Border", border);
                            GUI.backgroundColor = Color.white;

                            inner.xMin = mSprite.outer.xMin + border.x;
                            inner.yMin = mSprite.outer.yMin + border.y;
                            inner.xMax = mSprite.outer.xMax - border.z;
                            inner.yMax = mSprite.outer.yMax - border.w;
                        }
                        else
                        {
                            // Draw the inner and outer rectangle dimensions
                            GUI.backgroundColor = green;
                            outer = EditorGUILayout.RectField("Outer Rect", mSprite.outer);
                            GUI.backgroundColor = blue;
                            inner = EditorGUILayout.RectField("Inner Rect", mSprite.inner);
                            GUI.backgroundColor = Color.white;
                        }

                        if (outer.xMax < outer.xMin)
                        {
                            outer.xMax = outer.xMin;
                        }
                        if (outer.yMax < outer.yMin)
                        {
                            outer.yMax = outer.yMin;
                        }

                        if (outer != mSprite.outer)
                        {
                            float x = outer.xMin - mSprite.outer.xMin;
                            float y = outer.yMin - mSprite.outer.yMin;

                            inner.x += x;
                            inner.y += y;
                        }

                        // Sanity checks to ensure that the inner rect is always inside the outer
                        inner.xMin = Mathf.Clamp(inner.xMin, outer.xMin, outer.xMax);
                        inner.xMax = Mathf.Clamp(inner.xMax, outer.xMin, outer.xMax);
                        inner.yMin = Mathf.Clamp(inner.yMin, outer.yMin, outer.yMax);
                        inner.yMax = Mathf.Clamp(inner.yMax, outer.yMin, outer.yMax);

                        bool changed = false;

                        if (mSprite.inner != inner || mSprite.outer != outer)
                        {
                            NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                            mSprite.inner = inner;
                            mSprite.outer = outer;
                            MarkSpriteAsDirty();
                            changed = true;
                        }

                        EditorGUILayout.Separator();

                        if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels)
                        {
                            int left   = Mathf.RoundToInt(mSprite.paddingLeft * mSprite.outer.width);
                            int right  = Mathf.RoundToInt(mSprite.paddingRight * mSprite.outer.width);
                            int top    = Mathf.RoundToInt(mSprite.paddingTop * mSprite.outer.height);
                            int bottom = Mathf.RoundToInt(mSprite.paddingBottom * mSprite.outer.height);

                            NGUIEditorTools.IntVector a = NGUIEditorTools.IntPair("Padding", "Left", "Top", left, top);
                            NGUIEditorTools.IntVector b = NGUIEditorTools.IntPair(null, "Right", "Bottom", right, bottom);

                            if (changed || a.x != left || a.y != top || b.x != right || b.y != bottom)
                            {
                                NGUIEditorTools.RegisterUndo("Atlas Change", mAtlas);
                                mSprite.paddingLeft   = a.x / mSprite.outer.width;
                                mSprite.paddingTop    = a.y / mSprite.outer.height;
                                mSprite.paddingRight  = b.x / mSprite.outer.width;
                                mSprite.paddingBottom = b.y / mSprite.outer.height;
                                MarkSpriteAsDirty();
                            }
                        }
                        else
                        {
                            // Create a button that can make the coordinates pixel-perfect on click
                            GUILayout.BeginHorizontal();
                            {
                                GUILayout.Label("Correction", GUILayout.Width(75f));

                                Rect corrected0 = outer;
                                Rect corrected1 = inner;

                                if (mAtlas.coordinates == NGUIAtlas.Coordinates.Pixels)
                                {
                                    corrected0 = NGUIMath.MakePixelPerfect(corrected0);
                                    corrected1 = NGUIMath.MakePixelPerfect(corrected1);
                                }
                                else
                                {
                                    corrected0 = NGUIMath.MakePixelPerfect(corrected0, tex.width, tex.height);
                                    corrected1 = NGUIMath.MakePixelPerfect(corrected1, tex.width, tex.height);
                                }

                                if (corrected0 == mSprite.outer && corrected1 == mSprite.inner)
                                {
                                    GUI.color = Color.grey;
                                    GUILayout.Button("Make Pixel-Perfect");
                                    GUI.color = Color.white;
                                }
                                else if (GUILayout.Button("Make Pixel-Perfect"))
                                {
                                    outer       = corrected0;
                                    inner       = corrected1;
                                    GUI.changed = true;
                                }
                            }
                            GUILayout.EndHorizontal();
                        }
                    }

                    // This functionality is no longer used. It became obsolete when the Atlas Maker was added.

                    /*NGUIEditorTools.DrawSeparator();
                     *
                     * GUILayout.BeginHorizontal();
                     * {
                     *      EditorGUILayout.PrefixLabel("Add/Delete");
                     *
                     *      if (GUILayout.Button("Clone Sprite"))
                     *      {
                     *              NGUIEditorTools.RegisterUndo("Add Sprite", mAtlas);
                     *              NGUIAtlas.Sprite newSprite = new NGUIAtlas.Sprite();
                     *
                     *              if (mSprite != null)
                     *              {
                     *                      newSprite.name = "Copy of " + mSprite.name;
                     *                      newSprite.outer = mSprite.outer;
                     *                      newSprite.inner = mSprite.inner;
                     *              }
                     *              else
                     *              {
                     *                      newSprite.name = "New Sprite";
                     *              }
                     *
                     *              mAtlas.spriteList.Add(newSprite);
                     *              mSprite = newSprite;
                     *      }
                     *
                     *      // Show the delete button
                     *      GUI.backgroundColor = Color.red;
                     *
                     *      if (mSprite != null && GUILayout.Button("Delete", GUILayout.Width(55f)))
                     *      {
                     *              mConfirmDelete = true;
                     *      }
                     *      GUI.backgroundColor = Color.white;
                     * }
                     * GUILayout.EndHorizontal();*/

                    if (NGUIEditorTools.previousSelection != null)
                    {
                        NGUIEditorTools.DrawSeparator();

                        GUI.backgroundColor = Color.green;

                        if (GUILayout.Button("<< Return to " + NGUIEditorTools.previousSelection.name))
                        {
                            NGUIEditorTools.SelectPrevious();
                        }
                        GUI.backgroundColor = Color.white;
                    }
                }
            }
        }
    }