Ejemplo n.º 1
0
        /// <summary>Function to determine if the content plugin can open the specified file.</summary>
        /// <param name="file">The content file to evaluate.</param>
        /// <param name="fileManager">The content file manager.</param>
        /// <returns>
        ///   <b>true</b> if the plugin can open the file, or <b>false</b> if not.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="file" />, or the <paramref name="fileManager"/> parameter is <b>null</b>.</exception>
        public bool CanOpenContent(IContentFile file, IContentFileManager fileManager)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (fileManager == null)
            {
                throw new ArgumentNullException(nameof(fileManager));
            }

            using (Stream stream = file.OpenRead())
            {
                if (!_ddsCodec.IsReadable(stream))
                {
                    return(false);
                }

                IGorgonImageInfo metadata = _ddsCodec.GetMetaData(stream);

                // We won't be supporting 1D images in this editor.
                if ((metadata.ImageType == ImageType.Image1D) || (metadata.ImageType == ImageType.Unknown))
                {
                    return(false);
                }

                UpdateFileMetadataAttributes(file.Metadata.Attributes);
                return(true);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Function to find the image associated with the sprite file.
        /// </summary>
        /// <param name="spriteFile">The sprite file to evaluate.</param>
        /// <param name="fileManager">The file manager used to handle content files.</param>
        /// <returns>The file representing the image associated with the sprite.</returns>
        private IContentFile FindImage(IContentFile spriteFile, IContentFileManager fileManager)
        {
            if ((spriteFile.Metadata.DependsOn.Count == 0) ||
                (!spriteFile.Metadata.DependsOn.TryGetValue(CommonEditorContentTypes.ImageType, out string texturePath)))
            {
                return(null);
            }

            IContentFile textureFile = fileManager.GetFile(texturePath);

            if (textureFile == null)
            {
                CommonServices.Log.Print($"[ERROR] Sprite '{spriteFile.Path}' has texture '{texturePath}', but the file was not found on the file system.", LoggingLevel.Verbose);
                return(null);
            }

            string textureFileContentType = textureFile.Metadata.ContentMetadata?.ContentTypeID;

            if (string.IsNullOrWhiteSpace(textureFileContentType))
            {
                CommonServices.Log.Print($"[ERROR] Sprite texture '{texturePath}' was found but has no content type ID.", LoggingLevel.Verbose);
                return(null);
            }

            if ((!textureFile.Metadata.Attributes.TryGetValue(CommonEditorConstants.ContentTypeAttr, out string imageType)) ||
                (!string.Equals(imageType, textureFileContentType, StringComparison.OrdinalIgnoreCase)))
            {
                CommonServices.Log.Print($"[ERROR] Sprite '{spriteFile.Path}' has texture '{texturePath}', but the texture has a content type ID of '{textureFileContentType}', and the sprite requires a content type ID of '{imageType}'.", LoggingLevel.Verbose);
                return(null);
            }

            return(textureFile);
        }
Ejemplo n.º 3
0
 /// <summary>Initializes a new instance of the ImageContentVmParameters class.</summary>
 /// <param name="file">The file for the image content.</param>
 /// <param name="settings">The settings for the image editor.</param>
 /// <param name="cropResizeSettings">The crop/resize settings view model.</param>
 /// <param name="dimensionSettings">The image dimensions settings view model.</param>
 /// <param name="mipMapSettings">The mip map generation settings view model.</param>
 /// <param name="alphaSettings">The set alpha value settings view model.</param>
 /// <param name="imageData">The image data and related information.</param>
 /// <param name="videoAdapter">Information about the current video adapter.</param>
 /// <param name="formatSupport">A list of <see cref="IGorgonFormatSupportInfo"/> objects for each pixel format.</param>
 /// <param name="services">The services required by the image editor.</param>
 /// <exception cref="ArgumentNullException">Thrown when any of the parameters are <b>null</b>.</exception>
 /// <exception cref="ArgumentMissingException">Thrown when any required child parameters are <b>null</b>.</exception>
 public ImageContentParameters(IContentFile file,
                               ISettings settings,
                               ICropResizeSettings cropResizeSettings,
                               IDimensionSettings dimensionSettings,
                               IMipMapSettings mipMapSettings,
                               IAlphaSettings alphaSettings,
                               (IGorgonImage image, IGorgonVirtualFile workingFile, BufferFormat originalFormat) imageData,
Ejemplo n.º 4
0
        /// <summary>Function to open a content object from this plugin.</summary>
        /// <param name="file">The file that contains the content.</param>
        /// <param name = "fileManager" > The file manager used to access other content files.</param>
        /// <param name="injector">Parameters for injecting dependency objects.</param>
        /// <param name="scratchArea">The file system for the scratch area used to write transitory information.</param>
        /// <param name="undoService">The undo service for the plug in.</param>
        /// <returns>A new IEditorContent object.</returns>
        /// <remarks>
        /// The <paramref name="scratchArea" /> parameter is the file system where temporary files to store transitory information for the plug in is stored. This file system is destroyed when the
        /// application or plug in is shut down, and is not stored with the project.
        /// </remarks>
        protected async override Task <IEditorContent> OnOpenContentAsync(IContentFile file, IContentFileManager fileManager, IGorgonFileSystemWriter <Stream> scratchArea, IUndoService undoService)
        {
            FileInfo          texConvExe = GetTexConvExe();
            TexConvCompressor compressor = null;

            if (texConvExe.Exists)
            {
                compressor = new TexConvCompressor(texConvExe, scratchArea, _ddsCodec);
            }

            var imageIO = new ImageIOService(_ddsCodec,
                                             _codecs,
                                             new ExportImageDialogService(_settings),
                                             new ImportImageDialogService(_settings, _codecs),
                                             CommonServices.BusyService,
                                             scratchArea,
                                             compressor,
                                             CommonServices.Log);

            (IGorgonImage image, IGorgonVirtualFile workingFile, BufferFormat originalFormat)imageData = await Task.Run(() => {
                using (Stream inStream = file.OpenRead())
                {
                    return(imageIO.LoadImageFile(inStream, file.Name));
                }
            });

            var services = new ImageEditorServices
            {
                CommonServices        = CommonServices,
                ImageIO               = imageIO,
                UndoService           = undoService,
                ImageUpdater          = new ImageUpdaterService(),
                ExternalEditorService = new ImageExternalEditService(CommonServices.Log)
            };

            var cropResizeSettings = new CropResizeSettings();
            var dimensionSettings  = new DimensionSettings();
            var mipSettings        = new MipMapSettings();

            cropResizeSettings.Initialize(CommonServices);
            dimensionSettings.Initialize(new DimensionSettingsParameters(GraphicsContext.Graphics.VideoAdapter, CommonServices));
            mipSettings.Initialize(CommonServices);


            var content = new ImageContent();

            content.Initialize(new ImageContentParameters(file,
                                                          _settings,
                                                          cropResizeSettings,
                                                          dimensionSettings,
                                                          mipSettings,
                                                          imageData,
                                                          GraphicsContext.Graphics.VideoAdapter,
                                                          GraphicsContext.Graphics.FormatSupport,
                                                          services));

            return(content);
        }
        public void RemoveManagedFile(IContentFile file)
        {
            if (managedFiles.Contains(file))
            {
                UnregisterFromContentLoadedEvent(file);

                managedFiles.Remove(file);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Function to load the image to be used a thumbnail.
        /// </summary>
        /// <param name="thumbnailCodec">The codec for the thumbnail images.</param>
        /// <param name="thumbnailFile">The path to the thumbnail file.</param>
        /// <param name="content">The content being thumbnailed.</param>
        /// <param name="fileManager">The file manager used to handle content files.</param>
        /// <param name="cancelToken">The token used to cancel the operation.</param>
        /// <returns>The image, image content file and sprite, or just the thumbnail image if it was cached (sprite will be null).</returns>
        private (IGorgonImage image, IContentFile imageFile, GorgonSprite sprite) LoadThumbnailImage(IGorgonImageCodec thumbnailCodec, FileInfo thumbnailFile, IContentFile content, IContentFileManager fileManager, CancellationToken cancelToken)
        {
            IGorgonImage spriteImage;
            Stream       inStream  = null;
            Stream       imgStream = null;

            try
            {
                // If we've already got the file, then leave.
                if (thumbnailFile.Exists)
                {
                    inStream    = thumbnailFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
                    spriteImage = thumbnailCodec.LoadFromStream(inStream);

#pragma warning disable IDE0046 // Convert to conditional expression
                    if (cancelToken.IsCancellationRequested)
                    {
                        return(null, null, null);
                    }
#pragma warning restore IDE0046 // Convert to conditional expression

                    return(spriteImage, null, null);
                }

                IContentFile imageFile = FindImage(content, fileManager);
                if (imageFile == null)
                {
                    return(_noImage.Clone(), null, null);
                }

                imgStream = imageFile.OpenRead();
                inStream  = content.OpenRead();

                if ((!_ddsCodec.IsReadable(imgStream)) ||
                    (!_defaultCodec.IsReadable(inStream)))
                {
                    return(_noImage.Clone(), null, null);
                }

                spriteImage = _ddsCodec.LoadFromStream(imgStream);
                GorgonSprite sprite = _defaultCodec.FromStream(inStream);

                return(spriteImage, imageFile, sprite);
            }
            catch (Exception ex)
            {
                CommonServices.Log.Print($"[ERROR] Cannot create thumbnail for '{content.Path}'", LoggingLevel.Intermediate);
                CommonServices.Log.LogException(ex);
                return(null, null, null);
            }
            finally
            {
                imgStream?.Dispose();
                inStream?.Dispose();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Removes a specified content file from the container file.
        /// </summary>
        /// <param name="file"></param>
        public void RemoveContentFile(IContentFile contentFile)
        {
            if (!contentFilesDictionary.ContainsKey(contentFile.Path))
            {
                throw new InvalidOperationException(
                          String.Format("Cannot remove a content file with the follwing path \"{0}\", because it doesn't exist.",
                                        contentFile.Path));
            }

            contentFilesDictionary.Remove(contentFile.Path);
            contentFile.Owner = null;
            HasContentFilesCollectionChanged = true;
        }
Ejemplo n.º 8
0
        public void Save(IContentFile contentFile)
        {
            var folder = Path.Combine(BasePath, contentFile.Folder);

            if (Directory.Exists(folder) == false)
            {
                Directory.CreateDirectory(folder);
            }

            var filename = Path.Combine(folder, contentFile.Name);

            File.WriteAllText(filename, contentFile.Content);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
        /// </returns>
        public bool Equals(IContentFile other)
        {
            if (this.GetHashCode() == other.GetHashCode())
            {
                return(true);
            }

            if (this.Filename.Equals(other.Filename, StringComparison.InvariantCultureIgnoreCase))
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Function to load the texture for the sprite.
        /// </summary>
        /// <param name="textureFile">The file for the texture.</param>
        /// <returns>The sprite texture.</returns>
        private GorgonTexture2DView LoadSpriteTexture(IContentFile textureFile)
        {
            if (textureFile == null)
            {
                return(null);
            }

            using (Stream stream = textureFile.OpenRead())
            {
                return(GorgonTexture2DView.FromStream(_defaultSpriteCodec.Renderer.Graphics, stream, _defaultImageCodec, options: new GorgonTexture2DLoadOptions
                {
                    Binding = TextureBinding.ShaderResource,
                    Usage = ResourceUsage.Immutable,
                    Name = textureFile.Path,
                    IsTextureCube = false
                }));
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Function to update the dependencies for the sprite.
        /// </summary>
        /// <param name="fileStream">The stream for the file.</param>
        /// <param name="dependencyList">The list of dependency file paths.</param>
        /// <param name="fileManager">The content file management system.</param>
        private void UpdateDependencies(Stream fileStream, Dictionary <string, string> dependencyList, IContentFileManager fileManager)
        {
            string textureName = _defaultCodec.GetAssociatedTextureName(fileStream);

            if (string.IsNullOrWhiteSpace(textureName))
            {
                return;
            }
            IContentFile textureFile = fileManager.GetFile(textureName);

            // If we lack the texture (e.g. it's been deleted or something), then reset the value from the metadata.
            if (textureFile == null)
            {
                dependencyList.Remove(textureName);
                return;
            }

            dependencyList[CommonEditorContentTypes.ImageType] = textureName;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Function to save the sprites to the file system.
        /// </summary>
        /// <param name="path">The path to save the sprites into.</param>
        /// <param name="baseFileName">The base file name.</param>
        /// <param name="sprites">The sprites to save.</param>
        /// <param name="textureFile">The texture file associated with the sprites.</param>
        /// <exception cref="IOException">Thrown when the file system is locked by another thread (after 10 seconds).</exception>
        public void SaveSprites(string path, string baseFileName, IEnumerable <GorgonSprite> sprites, IContentFile textureFile)
        {
            int spriteIndex = 1;

            try
            {
                string fileName  = Path.GetFileNameWithoutExtension(baseFileName);
                string extension = Path.GetExtension(baseFileName);

                if ((!string.IsNullOrWhiteSpace(extension)) && (extension[0] != '.'))
                {
                    extension = "." + extension;
                }

                if (!_fileManager.BeginBatch())
                {
                    throw new IOException(Resources.GOREST_ERR_CANNOT_ACCESS_FILESYSTEM_LOCK);
                }

                foreach (GorgonSprite sprite in sprites)
                {
                    string filePath = $"{path}{fileName} ({spriteIndex++}){(string.IsNullOrWhiteSpace(extension) ? string.Empty : extension)}";

                    while (_fileManager.GetFile(filePath) != null)
                    {
                        filePath = $"{path}{fileName} ({spriteIndex++}){(string.IsNullOrWhiteSpace(extension) ? string.Empty : extension)}";
                    }

                    IContentFile outputFile = _fileManager.WriteFile(filePath, stream =>
                    {
                        _defaultCodec.Save(sprite, stream);
                    });
                    textureFile.LinkContent(outputFile);
                }
            }
            finally
            {
                _fileManager.EndBatch();
            }
        }
 /// <summary>Initializes a new instance of the <see cref="T:Gorgon.Editor.SpriteEditor.SpriteContentParameters"/> class.</summary>
 /// <param name="factory">The factory for building sprite content data.</param>
 /// <param name="spriteFile">The sprite file.</param>
 /// <param name="spriteTextureFile">The sprite texture file.</param>
 /// <param name="fileManager">The file manager used to access external content.</param>
 /// <param name="textureService">The texture service to use when reading sprite texture data.</param>
 /// <param name="sprite">The sprite being edited.</param>
 /// <param name="codec">The codec to use when reading/writing sprite data.</param>
 /// <param name="manualRectEdit">The manual rectangle editor view model.</param>
 /// <param name="manualVertexEdit">The manual vertex editor view model.</param>
 /// <param name="spritePickMaskEditor">The sprite picker mask color editor.</param>
 /// <param name="colorEditor">The color editor for the sprite.</param>
 /// <param name="anchorEditor">The anchor editor for the sprite.</param>
 /// <param name="wrapEditor">The texture wrapping state editor for the sprite.</param>
 /// <param name="settings">The plug in settings view model.</param>
 /// <param name="undoService">The undo service.</param>
 /// <param name="scratchArea">The file system used to write out temporary working data.</param>
 /// <param name="commonServices">Common application services.</param>
 public SpriteContentParameters(
     ISpriteContentFactory factory,
     IContentFile spriteFile,
     IContentFile spriteTextureFile,
     IContentFileManager fileManager,
     ISpriteTextureService textureService,
     GorgonSprite sprite,
     IGorgonSpriteCodec codec,
     IManualRectangleEditor manualRectEdit,
     IManualVertexEditor manualVertexEdit,
     ISpritePickMaskEditor spritePickMaskEditor,
     ISpriteColorEdit colorEditor,
     ISpriteAnchorEdit anchorEditor,
     ISpriteWrappingEditor wrapEditor,
     ISamplerBuildService samplerBuilder,
     IEditorPlugInSettings settings,
     IUndoService undoService,
     IGorgonFileSystemWriter <Stream> scratchArea,
     IViewModelInjection commonServices)
     : base(spriteFile, commonServices)
 {
     Factory               = factory ?? throw new ArgumentNullException(nameof(factory));
     Sprite                = sprite ?? throw new ArgumentNullException(nameof(sprite));
     UndoService           = undoService ?? throw new ArgumentNullException(nameof(undoService));
     ContentFileManager    = fileManager ?? throw new ArgumentNullException(nameof(fileManager));
     ScratchArea           = scratchArea ?? throw new ArgumentNullException(nameof(scratchArea));
     TextureService        = textureService ?? throw new ArgumentNullException(nameof(textureService));
     SpriteCodec           = codec ?? throw new ArgumentNullException(nameof(codec));
     ManualRectangleEditor = manualRectEdit ?? throw new ArgumentNullException(nameof(manualRectEdit));
     ManualVertexEditor    = manualVertexEdit ?? throw new ArgumentNullException(nameof(manualVertexEdit));
     SpritePickMaskEditor  = spritePickMaskEditor ?? throw new ArgumentNullException(nameof(spritePickMaskEditor));
     Settings              = settings ?? throw new ArgumentNullException(nameof(settings));
     ColorEditor           = colorEditor ?? throw new ArgumentNullException(nameof(colorEditor));
     AnchorEditor          = anchorEditor ?? throw new ArgumentNullException(nameof(anchorEditor));
     SpriteWrappingEditor  = wrapEditor ?? throw new ArgumentNullException(nameof(wrapEditor));
     SamplerBuilder        = samplerBuilder ?? throw new ArgumentNullException(nameof(samplerBuilder));
     SpriteTextureFile     = spriteTextureFile;
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Function to perform an export of an image.
        /// </summary>
        /// <param name="file">The file to export.</param>
        /// <param name="image">The image data to export.</param>
        /// <param name="codec">The codec to use when encoding the image.</param>
        /// <returns>The path to the exported file.</returns>
        public FileInfo ExportImage(IContentFile file, IGorgonImage image, IGorgonImageCodec codec)
        {
            _exportDialog.ContentFile   = file;
            _exportDialog.SelectedCodec = codec;
            string exportFilePath = _exportDialog.GetFilename();

            if (string.IsNullOrWhiteSpace(exportFilePath))
            {
                return(null);
            }

            _busyState.SetBusy();

            var result = new FileInfo(exportFilePath);

            _log.Print($"Exporting '{file.Name}' to '{exportFilePath}' as {codec.CodecDescription}", LoggingLevel.Verbose);

            codec.SaveToFile(image, result.FullName);

            _busyState.SetIdle();

            return(result);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Adds a given content file to the container file.
        /// </summary>
        /// <param name="file"></param>
        public void AddContentFile(IContentFile contentFile)
        {
            if (String.IsNullOrEmpty(contentFile.Path))
            {
                throw new ArgumentException(
                          String.Format("Cannot add a content file without the specified content path."),
                          "contentFile");
            }

            //Check for whitespaces

            if (contentFilesDictionary.ContainsKey(contentFile.Path))
            {
                throw new ArgumentException(
                          String.Format("Cannot add a content file with the follwing path \"{0}\"" +
                                        "because a content file with this path already exists.", contentFile.Path),
                          "contentFile");
            }

            contentFilesDictionary.Add(contentFile.Path, contentFile);
            contentFile.Owner = this;
            HasContentFilesCollectionChanged = true;
        }
Ejemplo n.º 16
0
        /// <summary>Function to determine if the content plugin can open the specified file.</summary>
        /// <param name="file">The content file to evaluate.</param>
        /// <param name="fileManager">The content file manager.</param>
        /// <returns>
        ///   <b>true</b> if the plugin can open the file, or <b>false</b> if not.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="file" />, or the <paramref name="fileManager" /> parameter is <b>null</b>.</exception>
        public bool CanOpenContent(IContentFile file, IContentFileManager fileManager)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (fileManager == null)
            {
                throw new ArgumentNullException(nameof(fileManager));
            }

            using (Stream stream = file.OpenRead())
            {
                if (_defaultCodec.IsReadable(stream))
                {
                    UpdateFileMetadataAttributes(file.Metadata.Attributes);
                    UpdateDependencies(stream, file.Metadata.DependsOn, fileManager);
                    return(true);
                }

                return(false);
            }
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="file"></param>
 public void LoadContent(IContentFile file)
 {
     LoadContent(new[] { file });
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ContentFileData"/> class.
 /// </summary>
 /// <param name="file">The file.</param>
 /// <param name="status">The status.</param>
 public ContentFileData(IContentFile file, ContentFileStatus status = ContentFileStatus.Added)
 {
     ContentFile = file;
     Status      = status;
 }
Ejemplo n.º 19
0
        /// <summary>Function to open a content object from this plugin.</summary>
        /// <param name="file">The file that contains the content.</param>
        /// <param name = "fileManager" > The file manager used to access other content files.</param>
        /// <param name="scratchArea">The file system for the scratch area used to write transitory information.</param>
        /// <param name="undoService">The undo service for the plug in.</param>
        /// <returns>A new IEditorContent object.</returns>
        /// <remarks>
        /// The <paramref name="scratchArea" /> parameter is the file system where temporary files to store transitory information for the plug in is stored. This file system is destroyed when the
        /// application or plug in is shut down, and is not stored with the project.
        /// </remarks>
        protected async override Task <IEditorContent> OnOpenContentAsync(IContentFile file, IContentFileManager fileManager, IGorgonFileSystemWriter <Stream> scratchArea, IUndoService undoService)
        {
            var content = new SpriteContent();
            GorgonTexture2DView   spriteImage = null;
            IContentFile          imageFile;
            GorgonSprite          sprite;
            ISpriteTextureService textureService;
            Stream stream = null;

            try
            {
                textureService = new SpriteTextureService(GraphicsContext, fileManager, _ddsCodec);

                // Load the sprite image.
                (spriteImage, imageFile) = await textureService.LoadFromSpriteContentAsync(file);

                // Load the sprite now.
                stream = file.OpenRead();
                sprite = _defaultCodec.FromStream(stream, spriteImage);

                var settings = new EditorPlugInSettings();
                ISpritePickMaskEditor spritePickMaskEditor = settings;
                settings.Initialize(new SettingsParameters(_settings, CommonServices));

                var manualRectEdit = new ManualRectangleEditor();
                manualRectEdit.Initialize(new ManualInputParameters(settings, CommonServices));

                var manualVertexEdit = new ManualVertexEditor();
                manualVertexEdit.Initialize(new ManualInputParameters(settings, CommonServices));

                var colorEditor = new SpriteColorEdit();
                colorEditor.Initialize(CommonServices);

                var anchorEditor = new SpriteAnchorEdit();
                anchorEditor.Initialize(CommonServices);

                var samplerBuilder = new SamplerBuildService(new GorgonSamplerStateBuilder(GraphicsContext.Graphics));

                var wrapEditor = new SpriteWrappingEditor();
                wrapEditor.Initialize(new SpriteWrappingEditorParameters(samplerBuilder, CommonServices));

                content.Initialize(new SpriteContentParameters(this,
                                                               file,
                                                               imageFile,
                                                               fileManager,
                                                               textureService,
                                                               sprite,
                                                               _defaultCodec,
                                                               manualRectEdit,
                                                               manualVertexEdit,
                                                               spritePickMaskEditor,
                                                               colorEditor,
                                                               anchorEditor,
                                                               wrapEditor,
                                                               samplerBuilder,
                                                               settings,
                                                               undoService,
                                                               scratchArea,
                                                               CommonServices));

                // If we have a texture, then read its data into RAM.
                if (sprite.Texture != null)
                {
                    await content.ExtractImageDataAsync();
                }

                return(content);
            }
            catch
            {
                spriteImage?.Dispose();
                throw;
            }
            finally
            {
                stream?.Dispose();
            }
        }
 private void UnregisterFromContentLoadedEvent(IContentFile contentFile)
 {
     RegisterForContentLoadedEvent(new IContentFile[] { contentFile });
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Function to open a content object from this plugin.
 /// </summary>
 /// <param name="file">The file that contains the content.</param>
 /// <param name="fileManager">The file manager used to access other content files.</param>
 /// <param name="scratchArea">The file system for the scratch area used to write transitory information.</param>
 /// <param name="undoService">The undo service for the plug in.</param>
 /// <returns>A new <see cref="IEditorContent"/> object.</returns>
 /// <remarks>
 /// <para>
 /// The <paramref name="scratchArea"/> parameter is the file system where temporary files to store transitory information for the plug in is stored. This file system is destroyed when the
 /// application or plug in is shut down, and is not stored with the project.
 /// </para>
 /// </remarks>
 protected abstract Task <IEditorContent> OnOpenContentAsync(IContentFile file, IContentFileManager fileManager, IGorgonFileSystemWriter <Stream> scratchArea, IUndoService undoService);
Ejemplo n.º 22
0
 /// <summary>
 /// Removes a specified content file from the container file.
 /// </summary>
 /// <param name="file"></param>
 public void RemoveContentFile(IContentFile contentFile)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 23
0
        /// <summary>Function to retrieve a thumbnail for the content.</summary>
        /// <param name="contentFile">The content file used to retrieve the data to build the thumbnail with.</param>
        /// <param name="fileManager">The content file manager.</param>
        /// <param name="outputFile">The output file for the thumbnail data.</param>
        /// <param name="cancelToken">The token used to cancel the thumbnail generation.</param>
        /// <returns>A <see cref="T:Gorgon.Graphics.Imaging.IGorgonImage"/> containing the thumbnail image data.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="contentFile" />, <paramref name="fileManager" />, or the <paramref name="outputFile" /> parameter is <b>null</b>.</exception>
        public async Task <IGorgonImage> GetThumbnailAsync(IContentFile contentFile, IContentFileManager fileManager, FileInfo outputFile, CancellationToken cancelToken)
        {
            if (contentFile == null)
            {
                throw new ArgumentNullException(nameof(contentFile));
            }

            if (fileManager == null)
            {
                throw new ArgumentNullException(nameof(fileManager));
            }

            if (outputFile == null)
            {
                throw new ArgumentNullException(nameof(outputFile));
            }

            // If the content is not a DDS image, then leave it.
            if ((!contentFile.Metadata.Attributes.TryGetValue(ImageContent.CodecAttr, out string codecName)) ||
                (string.IsNullOrWhiteSpace(codecName)) ||
                (!string.Equals(codecName, _ddsCodec.GetType().FullName, StringComparison.OrdinalIgnoreCase)))
            {
                return(null);
            }

            if (!outputFile.Directory.Exists)
            {
                outputFile.Directory.Create();
                outputFile.Directory.Refresh();
            }

            IGorgonImageCodec pngCodec = new GorgonCodecPng();

            (IGorgonImage thumbImage, bool needsConversion) = await Task.Run(() => LoadThumbNailImage(pngCodec, outputFile, contentFile, cancelToken));

            if ((thumbImage == null) || (cancelToken.IsCancellationRequested))
            {
                return(null);
            }

            if (!needsConversion)
            {
                return(thumbImage);
            }

            // We need to switch back to the main thread here to render the image, otherwise things will break.
            Cursor.Current = Cursors.WaitCursor;

            try
            {
                const float maxSize = 256;
                float       scale   = (maxSize / thumbImage.Width).Min(maxSize / thumbImage.Height);
                RenderThumbnail(ref thumbImage, scale);

                if (cancelToken.IsCancellationRequested)
                {
                    return(null);
                }

                // We're done on the main thread, we can switch to another thread to write the image.
                Cursor.Current = Cursors.Default;

                await Task.Run(() => pngCodec.SaveToFile(thumbImage, outputFile.FullName), cancelToken);

                if (cancelToken.IsCancellationRequested)
                {
                    return(null);
                }

                contentFile.Metadata.Attributes[CommonEditorConstants.ThumbnailAttr] = outputFile.Name;
                return(thumbImage);
            }
            catch (Exception ex)
            {
                CommonServices.Log.Print($"[ERROR] Cannot create thumbnail for '{contentFile.Path}'", LoggingLevel.Intermediate);
                CommonServices.Log.LogException(ex);
                return(null);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Function to load the image to be used a thumbnail.
        /// </summary>
        /// <param name="thumbnailCodec">The codec for the thumbnail images.</param>
        /// <param name="thumbnailFile">The path to the thumbnail file.</param>
        /// <param name="content">The content being thumbnailed.</param>
        /// <param name="cancelToken">The token used to cancel the operation.</param>
        /// <returns>The thumbnail image, and a flag to indicate whether the thumbnail needs conversion.</returns>
        private (IGorgonImage thumbnailImage, bool needsConversion) LoadThumbNailImage(IGorgonImageCodec thumbnailCodec, FileInfo thumbnailFile, IContentFile content, CancellationToken cancelToken)
        {
            IGorgonImage result;
            Stream       inStream = null;

            try
            {
                // If we've already got the file, then leave.
                if (thumbnailFile.Exists)
                {
                    inStream = thumbnailFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
                    result   = thumbnailCodec.LoadFromStream(inStream);

                    return(cancelToken.IsCancellationRequested ? (null, false) : (result, false));
                }

                inStream = content.OpenRead();
                result   = _ddsCodec.LoadFromStream(inStream);

                return(result, true);
            }
            catch (Exception ex)
            {
                CommonServices.Log.Print($"[ERROR] Cannot create thumbnail for '{content.Path}'", LoggingLevel.Intermediate);
                CommonServices.Log.LogException(ex);
                return(null, false);
            }
            finally
            {
                inStream?.Dispose();
            }
        }
 public void AddManagedFile(IContentFile file)
 {
     AddManagedFiles(new IContentFile[] { file });
 }
Ejemplo n.º 26
0
        /// <summary>Function to save the atlas data.</summary>
        /// <param name="atlas">The atlas data to save.</param>
        public void SaveAtlas(IReadOnlyDictionary <IContentFile, GorgonSprite> spriteFiles, GorgonTextureAtlas atlas)
        {
            IGorgonImage image     = null;
            string       directory = Path.GetDirectoryName(atlas.Textures[0].Texture.Name).FormatDirectory('/');
            Stream       outStream = null;

            try
            {
                _fileSystem.BeginBatch();

                if (!_fileSystem.DirectoryExists(directory))
                {
                    _fileSystem.CreateDirectory(directory);
                }

                void WriteImageFile(Stream stream) => _defaultImageCodec.SaveToStream(image, stream);

                // Check the files to ensure they're not open for editing.
                foreach (GorgonTexture2DView texture in atlas.Textures)
                {
                    IContentFile textureFile = _fileSystem.GetFile(texture.Texture.Name);

                    if ((textureFile != null) && (textureFile.IsOpen))
                    {
                        throw new IOException(string.Format(Resources.GORTAG_ERR_IMAGE_OPEN, textureFile.Path));
                    }
                }

                foreach ((GorgonSprite original, GorgonSprite sprite) in atlas.Sprites)
                {
                    IContentFile oldFile = spriteFiles.FirstOrDefault(item => item.Value == original).Key;

                    if ((oldFile != null) && (oldFile.IsOpen))
                    {
                        throw new IOException(string.Format(Resources.GORTAG_ERR_IMAGE_OPEN, oldFile.Path));
                    }
                }

                // Write textures.
                foreach (GorgonTexture2DView texture in atlas.Textures)
                {
                    image = texture.Texture.ToImage();
                    _fileSystem.WriteFile(texture.Texture.Name, WriteImageFile);
                    image.Dispose();
                }

                // Write out the updated sprites.
                foreach ((GorgonSprite original, GorgonSprite sprite) in atlas.Sprites)
                {
                    IContentFile oldTextureFile = null;
                    IContentFile textureFile    = _fileSystem.GetFile(sprite.Texture.Texture.Name);
                    IContentFile oldFile        = spriteFiles.FirstOrDefault(item => item.Value == original).Key;

                    if (oldFile.Metadata.DependsOn.TryGetValue(CommonEditorContentTypes.ImageType, out string oldTexturePath))
                    {
                        oldTextureFile = _fileSystem.GetFile(oldTexturePath);
                    }

                    outStream = oldFile.OpenWrite();
                    _defaultSpriteCodec.Save(sprite, outStream);

                    textureFile.LinkContent(oldFile);
                    oldTextureFile?.UnlinkContent(oldFile);

                    oldFile.RefreshMetadata();
                    oldFile.Refresh();
                    outStream.Dispose();
                }
            }
            finally
            {
                outStream?.Dispose();
                image?.Dispose();
                _fileSystem.EndBatch();
            }
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Function to create a new dependency node.
        /// </summary>
        /// <param name="project">The project that contains the file system.</param>
        /// <param name="fileSystemService">The file system service for the project.</param>
        /// <param name="parentNode">The node to use as a the parent of the node.</param>
        /// <param name="content">The content object referenced by the dependency node.</param>
        /// <returns>A new dependency node.</returns>
        /// <exception cref="ArgumentNullException">Thrown when any of the parameters are <b>null</b>.</exception>
        public DependencyNode CreateDependencyNode(IProject project, IFileSystemService fileSystemService, IFileExplorerNodeVm parentNode, IContentFile content)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (parentNode == null)
            {
                throw new ArgumentNullException(nameof(parentNode));
            }

            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            var fileNode = (IFileExplorerNodeVm)content;

            var dependNode = new DependencyNode(parentNode, (IFileExplorerNodeVm)content);

            dependNode.Initialize(new FileExplorerNodeParameters(fileNode.PhysicalPath, project, this, fileSystemService));

            return(dependNode);
        }
Ejemplo n.º 28
0
        /// <summary>Function to retrieve a thumbnail for the content.</summary>
        /// <param name="contentFile">The content file used to retrieve the data to build the thumbnail with.</param>
        /// <param name="fileManager">The content file manager.</param>
        /// <param name="outputFile">The output file for the thumbnail data.</param>
        /// <param name="cancelToken">The token used to cancel the thumbnail generation.</param>
        /// <returns>A <see cref="T:Gorgon.Graphics.Imaging.IGorgonImage"/> containing the thumbnail image data.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="contentFile" />, <paramref name="fileManager" /> or the <paramref name="outputFile" /> parameter is <b>null</b>.</exception>
        public async Task <IGorgonImage> GetThumbnailAsync(IContentFile contentFile, IContentFileManager fileManager, FileInfo outputFile, CancellationToken cancelToken)
        {
            if (contentFile == null)
            {
                throw new ArgumentNullException(nameof(contentFile));
            }

            if (fileManager == null)
            {
                throw new ArgumentNullException(nameof(fileManager));
            }

            if (outputFile == null)
            {
                throw new ArgumentNullException(nameof(outputFile));
            }

            // If the content is not a v3 sprite, then leave it.
            if ((!contentFile.Metadata.Attributes.TryGetValue(SpriteContent.CodecAttr, out string codecName)) ||
                (string.IsNullOrWhiteSpace(codecName)) ||
                (!string.Equals(codecName, _defaultCodec.GetType().FullName, StringComparison.OrdinalIgnoreCase)))
            {
                return(null);
            }

            if (!outputFile.Directory.Exists)
            {
                outputFile.Directory.Create();
                outputFile.Directory.Refresh();
            }

            IGorgonImageCodec pngCodec = new GorgonCodecPng();

            (IGorgonImage image, IContentFile imageFile, GorgonSprite sprite) = await Task.Run(() => LoadThumbnailImage(pngCodec, outputFile, contentFile, fileManager, cancelToken));

            if ((image == null) || (cancelToken.IsCancellationRequested))
            {
                return(null);
            }

            // We loaded a cached thumbnail.
            if ((sprite == null) || (imageFile == null))
            {
                return(image);
            }

            // We need to switch back to the main thread here to render the image, otherwise things will break.
            Cursor.Current = Cursors.WaitCursor;

            GorgonTexture2DView spriteTexture = null;
            IGorgonImage        resultImage   = null;

            try
            {
                spriteTexture = GorgonTexture2DView.CreateTexture(GraphicsContext.Graphics, new GorgonTexture2DInfo(imageFile.Path)
                {
                    Width   = image.Width,
                    Height  = image.Height,
                    Format  = image.Format,
                    Binding = TextureBinding.ShaderResource,
                    Usage   = ResourceUsage.Default
                }, image);
                sprite.Texture = spriteTexture;

                resultImage = RenderThumbnail(sprite);

                await Task.Run(() => pngCodec.SaveToFile(resultImage, outputFile.FullName), cancelToken);

                if (cancelToken.IsCancellationRequested)
                {
                    return(null);
                }

                contentFile.Metadata.Attributes[CommonEditorConstants.ThumbnailAttr] = outputFile.Name;
                return(resultImage);
            }
            catch (Exception ex)
            {
                CommonServices.Log.Print($"[ERROR] Cannot create thumbnail for '{contentFile.Path}'", LoggingLevel.Intermediate);
                CommonServices.Log.LogException(ex);
                return(null);
            }
            finally
            {
                image?.Dispose();
                spriteTexture?.Dispose();
                Cursor.Current = Cursors.Default;
            }
        }
Ejemplo n.º 29
0
 public async Task SaveAsync(IContentFile contentFile)
 {
     await Task.Run(() => Save(contentFile));
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Function to determine if the content file passed in is image content as supported by this editor.
 /// </summary>
 /// <param name="file">The file to evaluate.</param>
 /// <returns><b>true</b> if the file is an image, supported by this editor, or <b>false</b> if not.</returns>
 public bool IsContentImage(IContentFile file) => ((file != null) &&