// border editing callback
    private void OnSpriteEdited(PivotEditingResult result, SVGSpriteAssetFile spriteAsset, Vector2 editedPivot, Vector4 editedBorder)
    {
        SVGCanvasBehaviour svgCanvas = target as SVGCanvasBehaviour;

        if ((svgCanvas != null) && (result == PivotEditingResult.Ok))
        {
            SVGUIAtlas uiAtlas = svgCanvas.UIAtlas;
            if (uiAtlas != null)
            {
                // assign the new border
                uiAtlas.UpdateBorder(spriteAsset, editedBorder);
                SVGUtils.MarkObjectDirty(uiAtlas);
                SVGUtils.MarkSceneDirty();

                // get the list of instantiated SVG sprites that reference the edited one
                List <GameObject> spritesInstances = new List <GameObject>();
                uiAtlas.GetSpritesInstances(spritesInstances, spriteAsset.SpriteRef);
                foreach (GameObject gameObj in spritesInstances)
                {
                    Image uiImage = (Image)gameObj.GetComponent <Image>();
                    if (uiImage != null)
                    {
                        // the Image component won't recognize the change of sprite border, so in order to refresh
                        // instantiated objects we have to unset-set the sprite property
                        uiImage.sprite = null;
                        uiImage.sprite = spriteAsset.SpriteData.Sprite;
                    }
                }
            }
        }
    }
    protected override bool SvgInputAssetDrawImplementation(SVGBasicAtlas basicAtlas, SVGAssetInput svgAsset, int svgAssetIndex)
    {
        SVGUIAtlas uiAtlas = basicAtlas as SVGUIAtlas;
        bool       isDirty = false;

        // scale adjustment for this SVG
        EditorGUILayout.LabelField(new GUIContent("Scale adjustment", "An additional scale factor used to adjust this SVG content only"), GUILayout.Width(105));
        float offsetScale = EditorGUILayout.FloatField(svgAsset.Scale, GUILayout.Width(45));

        EditorGUILayout.LabelField("", GUILayout.Width(5));
        if (offsetScale != svgAsset.Scale)
        {
            uiAtlas.SvgAssetScaleAdjustmentSet(svgAsset, Math.Abs(offsetScale));
            isDirty = true;
        }

        // 'explode groups' flag
        bool separateGroups = EditorGUILayout.Toggle("", svgAsset.SeparateGroups, GUILayout.Width(14));

        EditorGUILayout.LabelField("Separate groups", GUILayout.Width(105));
        // if group explosion flag has been changed, update it
        if (separateGroups != svgAsset.SeparateGroups)
        {
            uiAtlas.SvgAssetSeparateGroupsSet(svgAsset, separateGroups);
            isDirty = true;
        }

        // if 'Remove' button is clicked, remove the SVG entry
        if (GUILayout.Button("Remove", EditorStyles.miniButton, GUILayout.Width(70)))
        {
            uiAtlas.SvgAssetRemove(svgAssetIndex);
            isDirty = true;
        }
        return(isDirty);
    }
    private void SpritePreview(SVGUIAtlas uiAtlas, Canvas canvas, SVGSpriteAssetFile spriteAsset)
    {
        SVGUIWidgetType widgetType;
        Sprite          sprite     = spriteAsset.SpriteData.Sprite;
        Texture2D       texture    = sprite.texture;
        Rect            spriteRect = sprite.textureRect;
        Rect            uv         = new Rect(spriteRect.x / texture.width, spriteRect.y / texture.height, spriteRect.width / texture.width, spriteRect.height / texture.height);

        GUILayoutOption[] spriteTextureOptions = new GUILayoutOption[2] {
            GUILayout.Width(uiAtlas.SpritesPreviewSize), GUILayout.Height(uiAtlas.SpritesPreviewSize)
        };

        EditorGUILayout.BeginHorizontal(GUILayout.MinHeight(uiAtlas.SpritesPreviewSize + 5));
        {
            EditorGUILayout.LabelField(sprite.name, GUILayout.MinWidth(10));
            // reserve space for drawing sprite
            EditorGUILayout.LabelField("", spriteTextureOptions);
            Rect  guiRect       = GUILayoutUtility.GetLastRect();
            float maxSpriteDim  = Math.Max(spriteRect.width, spriteRect.height);
            float previewWidth  = (spriteRect.width / maxSpriteDim) * uiAtlas.SpritesPreviewSize;
            float previewHeight = (spriteRect.height / maxSpriteDim) * uiAtlas.SpritesPreviewSize;
            float previewX      = (uiAtlas.SpritesPreviewSize - previewWidth) / 2;
            float previewY      = 0;
            Rect  previewRect   = new Rect(guiRect.xMin + previewX, guiRect.yMin + previewY, previewWidth, previewHeight);
            GUI.DrawTextureWithTexCoords(previewRect, texture, uv, true);
            EditorGUILayout.Space();
            // sprite dimensions
            EditorGUILayout.LabelField("[" + spriteRect.width + " x " + spriteRect.height + "]", GUILayout.MaxWidth(120));

            if (GUILayout.Button("Edit", EditorStyles.miniButton))
            {
                // show pivot editor
                SVGPivotEditor.Show(spriteAsset, this.OnSpriteEdited);
            }

            widgetType = (SVGUIWidgetType)EditorGUILayout.EnumPopup("", spriteAsset.InstantiatedWidgetType, new GUILayoutOption[] { GUILayout.Width(80) });

            // instantiate
            if (GUILayout.Button("Instantiate", EditorStyles.miniButton))
            {
                GameObject gameObj = uiAtlas.InstantiateWidget(canvas, spriteAsset.SpriteRef, widgetType);
                // set the created instance as selected
                if (gameObj != null)
                {
                    Selection.objects = new UnityEngine.Object[1] {
                        gameObj as UnityEngine.Object
                    };
                }
            }

            EditorGUILayout.Space();
        }
        EditorGUILayout.EndHorizontal();

        if (widgetType != spriteAsset.InstantiatedWidgetType)
        {
            spriteAsset.InstantiatedWidgetType = widgetType;
        }
    }
    private void DrawInspector()
    {
        bool resizeOnStart;

        EditorGUILayout.BeginHorizontal();
        {
            EditorGUILayout.PrefixLabel("Resize on Start()");
            resizeOnStart = EditorGUILayout.Toggle(this.m_EditedLoader.ResizeOnStart);
        }
        EditorGUILayout.EndHorizontal();

        SVGUIAtlas uiAtlas = this.m_EditedLoader.UIAtlas;

        if ((uiAtlas != null) && (this.m_EditedLoader.SpriteReference != null))
        {
            SVGSpriteAssetFile spriteAsset = uiAtlas.GetGeneratedSprite(this.m_EditedLoader.SpriteReference);
            string             buttonText  = (spriteAsset != null) ? spriteAsset.SpriteData.Sprite.name : "<select>";

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.PrefixLabel("Sprite");
                if (GUILayout.Button(buttonText, "DropDown"))
                {
                    SVGSpriteSelector.Show(uiAtlas, "", this.OnSpriteSelect);
                }
                if (GUILayout.Button("Edit", GUILayout.Width(80)))
                {
                    // show pivot editor
                    SVGPivotEditor.Show(spriteAsset, this.OnSpriteEdited);
                }
            }
            EditorGUILayout.EndHorizontal();
        }

        if (this.m_EditedLoader.ResizeOnStart != resizeOnStart)
        {
            this.m_EditedLoader.ResizeOnStart = resizeOnStart;
            SVGUtils.MarkObjectDirty(this.m_EditedLoader);
        }
    }
    // border editing callback
    private void OnSpriteEdited(PivotEditingResult result, SVGSpriteAssetFile spriteAsset, Vector2 editedPivot, Vector4 editedBorder)
    {
        SVGUISpriteLoaderBehaviour spriteLoader = target as SVGUISpriteLoaderBehaviour;

        if ((spriteLoader != null) && (result == PivotEditingResult.Ok))
        {
            SVGUIAtlas uiAtlas = spriteLoader.UIAtlas;
            if (uiAtlas != null)
            {
                // assign the new border
                uiAtlas.UpdateBorder(spriteAsset, editedPivot, editedBorder);
                SVGUtils.MarkObjectDirty(uiAtlas);
                Image uiImage = spriteLoader.GetComponent <Image>();
                if (uiImage != null)
                {
                    // the Image component does not recognize the change of sprite border, so in order to refresh
                    // instantiated objects we have to unset-set the sprite property
                    uiImage.sprite = null;
                    uiImage.sprite = spriteAsset.SpriteData.Sprite;
                }
            }
        }
    }
    private bool DrawInspector(SVGUIAtlas uiAtlas, Canvas canvas)
    {
        Rect scollRect;
        bool isDirty = false;
        // get current event
        Event currentEvent = Event.current;

        // show current options
        EditorGUILayout.LabelField("Canvas scale factor", uiAtlas.CanvasScaleFactor.ToString());
        float offsetScale          = EditorGUILayout.FloatField(this.m_OffsetScaleContent, uiAtlas.OffsetScale);
        bool  pow2Textures         = EditorGUILayout.Toggle(this.m_Pow2TexturesContent, uiAtlas.Pow2Textures);
        int   maxTexturesDimension = EditorGUILayout.IntField(this.m_MaxTexturesDimensionContent, uiAtlas.MaxTexturesDimension);
        int   border             = EditorGUILayout.IntField(this.m_SpritesPaddingContent, uiAtlas.SpritesBorder);
        Color clearColor         = EditorGUILayout.ColorField(this.m_ClearColorContent, uiAtlas.ClearColor);
        bool  fastUpload         = EditorGUILayout.Toggle(this.m_FastUploadContent, uiAtlas.FastUpload);
        float spritesPreviewSize = (float)EditorGUILayout.IntField(this.m_SpritesPreviewSizeContent, (int)uiAtlas.SpritesPreviewSize);

        // output folder
        this.OutputFolderDraw(uiAtlas);

        // draw the list of input SVG files / assets
        isDirty |= this.SvgInputAssetsDraw(uiAtlas, currentEvent, out scollRect);

        // update button
        if (this.UpdateButtonDraw(uiAtlas))
        {
            // regenerate/update sprites
            uiAtlas.UpdateEditorSprites();
            isDirty = true;
        }

        GUILayout.Space(10);

        if (uiAtlas.SvgAssetsCount() > 0)
        {
            // list of sprites, grouped by SVG document
            //Vector2 spritesScrollPos = EditorGUILayout.BeginScrollView(this.m_SvgSpritesScrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
            Vector2 spritesScrollPos = EditorGUILayout.BeginScrollView(this.m_SvgSpritesScrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true), GUILayout.MinHeight(uiAtlas.SpritesPreviewSize * 5));
            bool    separatorNeeded  = false;

            for (int i = 0; i < uiAtlas.SvgAssetsCount(); ++i)
            {
                SVGAssetInput             svgAsset      = uiAtlas.SvgAsset(i);
                List <SVGSpriteAssetFile> spritesAssets = uiAtlas.GetGeneratedSpritesByDocument(svgAsset.TxtAsset);
                if (spritesAssets != null && spritesAssets.Count > 0)
                {
                    // line separator
                    if (separatorNeeded)
                    {
                        EditorGUILayout.Separator();
                        GUILayout.Box(GUIContent.none, this.m_GreyLine, GUILayout.ExpandWidth(true), GUILayout.Height(1));
                        EditorGUILayout.Separator();
                    }
                    // display sprites list
                    foreach (SVGSpriteAssetFile spriteAsset in spritesAssets)
                    {
                        this.SpritePreview(uiAtlas, canvas, spriteAsset);
                    }
                    // we have displayed some sprites, next time a line separator is needed
                    separatorNeeded = true;
                }
            }
            EditorGUILayout.EndScrollView();

            if (this.m_SvgSpritesScrollPos != spritesScrollPos)
            {
                this.m_SvgSpritesScrollPos = spritesScrollPos;
            }
        }

        // events handler
        isDirty |= this.HandleDragEvents(uiAtlas, currentEvent, scollRect);

        // a negative value is not allowed for texture max dimension
        maxTexturesDimension = (maxTexturesDimension < 0) ? 1024 : maxTexturesDimension;
        // a negative value is not allowed for border
        border = (border < 0) ? 0 : border;
        // if offset additional scale has been changed, update it
        if (uiAtlas.OffsetScale != offsetScale)
        {
            uiAtlas.OffsetScale = Math.Abs(offsetScale);
            isDirty             = true;
        }
        // if power-of-two forcing flag has been changed, update it
        if (uiAtlas.Pow2Textures != pow2Textures)
        {
            uiAtlas.Pow2Textures = pow2Textures;
            isDirty = true;
        }
        // if desired maximum texture dimension has been changed, update it
        if (uiAtlas.MaxTexturesDimension != maxTexturesDimension)
        {
            uiAtlas.MaxTexturesDimension = maxTexturesDimension;
            isDirty = true;
        }
        // if border between each packed SVG has been changed, update it
        if (uiAtlas.SpritesBorder != border)
        {
            uiAtlas.SpritesBorder = border;
            isDirty = true;
        }
        // if surface clear color has been changed, update it
        if (uiAtlas.ClearColor != clearColor)
        {
            uiAtlas.ClearColor = clearColor;
            isDirty            = true;
        }
        // if "fast upload" flag has been changed, update it
        if (uiAtlas.FastUpload != fastUpload)
        {
            uiAtlas.FastUpload = fastUpload;
            isDirty            = true;
        }
        // if sprites preview size has been changed, update it
        if (uiAtlas.SpritesPreviewSize != spritesPreviewSize)
        {
            uiAtlas.SpritesPreviewSize = spritesPreviewSize;
            isDirty = true;
        }

        return(isDirty);
    }