mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-24 03:56:31 +00:00
A mix between Tiled and GUI stuff (#553)
* mostly restored the tiled importer unit tests * code cleanup * code cleanup * almost got tiled maps serialization independent of the content pipeline * refactored the tiled map content importer so that tiled maps can be loaded at runtime * code cleanup * removed nuspec files * experimenting with an XML based GUI markup parser * a few more markup parser features * finally got a working open file dialog * experimenting with markup bindings * attached properties * working on the gui stuff again * working on a better textbox * multiline textboxing * new text box is really coming along * removed the content explorer experiment * restored the old gui demo back to the way it was before (for now)
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@ bld/
|
||||
site/
|
||||
|
||||
# Cake
|
||||
tools/
|
||||
/tools/
|
||||
|
||||
# NuGet Packages
|
||||
artifacts/
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<DockPanel LastChildFill="True">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" BackgroundColor="#111111">
|
||||
<Button Name="OpenButton" Content="Open" />
|
||||
<Button Name="QuitButton" Content="Quit" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Vertical" Width="150" BackgroundColor="Green">
|
||||
<Label Content="{{Title}}"></Label>
|
||||
</StackPanel>
|
||||
|
||||
<Label DockPanel.Dock="Bottom" Name="StatusLabel" Content="TODO" />
|
||||
|
||||
<TextBox Text="Single line of text" />
|
||||
|
||||
<TextBox2 Name="TextBox" BackgroundColor="WhiteSmoke" Text="This is a test.
|
||||
With multi-line text." />
|
||||
</DockPanel>
|
||||
@@ -1,4 +1,5 @@
|
||||
using MonoGame.Extended;
|
||||
using System;
|
||||
using MonoGame.Extended;
|
||||
using MonoGame.Extended.Gui;
|
||||
using MonoGame.Extended.Gui.Controls;
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
<ItemGroup>
|
||||
<MonoGameContentReference Include="**\*.mgcb" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Features\MainWindow.mgeml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Features\MainWindow.mgeml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MonoGame.Content.Builder" Version="3.7.0.8" />
|
||||
<PackageReference Include="MonoGame.Framework.DesktopGL.Core" Version="3.7.0.7" />
|
||||
|
||||
@@ -5,6 +5,7 @@ using MonoGame.Extended;
|
||||
using MonoGame.Extended.BitmapFonts;
|
||||
using MonoGame.Extended.Gui;
|
||||
using MonoGame.Extended.Gui.Controls;
|
||||
using MonoGame.Extended.Gui.Markup;
|
||||
using MonoGame.Extended.ViewportAdapters;
|
||||
|
||||
namespace Gui
|
||||
@@ -38,6 +39,21 @@ namespace Gui
|
||||
BitmapFont.UseKernings = false;
|
||||
Skin.CreateDefault(font);
|
||||
|
||||
//var parser = new MarkupParser();
|
||||
|
||||
//var mainScreen = new Screen
|
||||
//{
|
||||
// Content = parser.Parse("Features/MainWindow.mgeml", new object())
|
||||
//};
|
||||
|
||||
//var textBox = mainScreen.FindControl<TextBox>("TextBox");
|
||||
//var statusLabel = mainScreen.FindControl<Label>("StatusLabel");
|
||||
|
||||
//textBox.CaretIndexChanged += (sender, args) =>
|
||||
// statusLabel.Content = $"Ln {textBox.LineIndex + 1}, Ch {textBox.CaretIndex + 1}";
|
||||
|
||||
|
||||
|
||||
var stackTest = new DemoViewModel("Stack Panels",
|
||||
new StackPanel
|
||||
{
|
||||
|
||||
@@ -2,13 +2,13 @@ namespace MonoGame.Extended.Content.Pipeline
|
||||
{
|
||||
public class ContentImporterResult<T>
|
||||
{
|
||||
public string FilePath { get; private set; }
|
||||
public T Data { get; private set; }
|
||||
|
||||
public ContentImporterResult(string filePath, T data)
|
||||
{
|
||||
FilePath = filePath;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public string FilePath { get; }
|
||||
public T Data { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline
|
||||
{
|
||||
public interface IExternalReferenceRepository
|
||||
{
|
||||
ExternalReference<TInput> GetExternalReference<TInput>(string source);
|
||||
}
|
||||
|
||||
public class ContentItem<T> : ContentItem, IExternalReferenceRepository
|
||||
{
|
||||
public ContentItem(T data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public T Data { get; }
|
||||
|
||||
private readonly Dictionary<string, ContentItem> _externalReferences = new Dictionary<string, ContentItem>();
|
||||
|
||||
public void BuildExternalReference<TInput>(ContentProcessorContext context, string source, OpaqueDataDictionary parameters = null)
|
||||
{
|
||||
var sourceAsset = new ExternalReference<TInput>(source);
|
||||
var externalReference = context.BuildAsset<TInput, TInput>(sourceAsset, "", parameters, "", "");
|
||||
_externalReferences.Add(source, externalReference);
|
||||
}
|
||||
|
||||
public ExternalReference<TInput> GetExternalReference<TInput>(string source)
|
||||
{
|
||||
if (_externalReferences.TryGetValue(source, out var contentItem))
|
||||
return contentItem as ExternalReference<TInput>;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace MonoGame.Extended.Content.Pipeline.TextureAtlases
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} {1}", Width, Height);
|
||||
return $"{Width} {Height}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
public static class ContentWriterExtensions
|
||||
{
|
||||
// ReSharper disable once SuggestBaseTypeForParameter
|
||||
public static void WriteTiledMapProperties(this ContentWriter writer,
|
||||
IReadOnlyCollection<TiledMapPropertyContent> value)
|
||||
public static void WriteTiledMapProperties(this ContentWriter writer, IReadOnlyCollection<TiledMapPropertyContent> value)
|
||||
{
|
||||
writer.Write(value.Count);
|
||||
foreach (var property in value)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
public class TiledMapContentItem : ContentItem<TiledMapContent>
|
||||
{
|
||||
public TiledMapContentItem(TiledMapContent data)
|
||||
: base(data)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
public class TiledMapGroupLayerContent : TiledMapLayerContent
|
||||
{
|
||||
[XmlElement(ElementName = "layer", Type = typeof(TiledMapTileLayerContent))]
|
||||
[XmlElement(ElementName = "imagelayer", Type = typeof(TiledMapImageLayerContent))]
|
||||
[XmlElement(ElementName = "objectgroup", Type = typeof(TiledMapObjectLayerContent))]
|
||||
[XmlElement(ElementName = "group", Type = typeof(TiledMapGroupLayerContent))]
|
||||
public List<TiledMapLayerContent> Layers { get; set; }
|
||||
|
||||
protected TiledMapGroupLayerContent() : base(TiledMapLayerType.GroupLayer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[ContentImporter(".tmx", DefaultProcessor = "TiledMapProcessor", DisplayName = "Tiled Map Importer - MonoGame.Extended")]
|
||||
public class TiledMapImporter : ContentImporter<TiledMapContent>
|
||||
public class TiledMapImporter : ContentImporter<TiledMapContentItem>
|
||||
{
|
||||
public override TiledMapContent Import(string filePath, ContentImporterContext context)
|
||||
public override TiledMapContentItem Import(string filePath, ContentImporterContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -27,13 +27,13 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
|
||||
ContentLogger.Log($"Imported '{filePath}'");
|
||||
|
||||
return map;
|
||||
return new TiledMapContentItem(map);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
context.Logger.LogImportantMessage(e.StackTrace);
|
||||
throw e;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using MonoGame.Extended.Tiled;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
// This content class is going to be a lot more complex than the others we use.
|
||||
// Objects can reference a template file which has starting values for the
|
||||
// object. The value in the object file overrides any value specified in the
|
||||
// template. All values have to be able to store a null value so we know if the
|
||||
// XML parser actually found a value for the property and not just a default
|
||||
// value. Default values are used when the object and any templates don't
|
||||
// specify a value.
|
||||
public class TiledMapObjectContent
|
||||
{
|
||||
private uint? _globalIdentifier;
|
||||
private int? _identifier;
|
||||
private float? _height;
|
||||
private float? _rotation;
|
||||
private bool? _visible;
|
||||
private float? _width;
|
||||
private float? _x;
|
||||
private float? _y;
|
||||
|
||||
[XmlAttribute(DataType = "int", AttributeName = "id")]
|
||||
public int Identifier { get => _identifier ?? 0; set => _identifier = value; }
|
||||
|
||||
[XmlAttribute(DataType = "string", AttributeName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "string", AttributeName = "type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "x")]
|
||||
public float X { get => _x ?? 0; set => _x = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "y")]
|
||||
public float Y { get => _y ?? 0; set => _y = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "width")]
|
||||
public float Width { get => _width ?? 0; set => _width = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "height")]
|
||||
public float Height { get => _height ?? 0; set => _height = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "rotation")]
|
||||
public float Rotation { get => _rotation ?? 0; set => _rotation = value; }
|
||||
|
||||
[XmlAttribute(DataType = "boolean", AttributeName = "visible")]
|
||||
public bool Visible { get => _visible ?? true; set => _visible = value; }
|
||||
|
||||
[XmlArray("properties")]
|
||||
[XmlArrayItem("property")]
|
||||
public List<TiledMapPropertyContent> Properties { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "unsignedInt", AttributeName = "gid")]
|
||||
public uint GlobalIdentifier { get => _globalIdentifier??0; set => _globalIdentifier = value; }
|
||||
|
||||
[XmlElement(ElementName = "ellipse")]
|
||||
public TiledMapEllipseContent Ellipse { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "polygon")]
|
||||
public TiledMapPolygonContent Polygon { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "polyline")]
|
||||
public TiledMapPolylineContent Polyline { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "string", AttributeName = "template")]
|
||||
public string TemplateSource { get; set; }
|
||||
|
||||
internal static void Process(TiledMapObjectContent obj, ContentProcessorContext context)
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(obj.TemplateSource))
|
||||
{
|
||||
var template = context.BuildAndLoadAsset<TiledMapObjectLayerContent, TiledMapObjectTemplateContent>(new ExternalReference<TiledMapObjectLayerContent>(obj.TemplateSource), "");
|
||||
|
||||
// Nothing says a template can't reference another template.
|
||||
// Yay recusion!
|
||||
Process(template.Object, context);
|
||||
|
||||
if (!obj._globalIdentifier.HasValue && template.Object._globalIdentifier.HasValue)
|
||||
obj.GlobalIdentifier = template.Object.GlobalIdentifier;
|
||||
if (!obj._height.HasValue && template.Object._height.HasValue)
|
||||
obj.Height = template.Object.Height;
|
||||
if (!obj._identifier.HasValue && template.Object._identifier.HasValue)
|
||||
obj.Identifier = template.Object.Identifier;
|
||||
if (!obj._rotation.HasValue && template.Object._rotation.HasValue)
|
||||
obj.Rotation = template.Object.Rotation;
|
||||
if (!obj._visible.HasValue && template.Object._visible.HasValue)
|
||||
obj.Visible = template.Object.Visible;
|
||||
if (!obj._width.HasValue && template.Object._width.HasValue)
|
||||
obj.Width = template.Object.Width;
|
||||
if (!obj._x.HasValue && template.Object._x.HasValue)
|
||||
obj.X = template.Object.X;
|
||||
if (!obj._y.HasValue && template.Object._y.HasValue)
|
||||
obj.Y = template.Object.Y;
|
||||
if (obj.Ellipse == null && template.Object.Ellipse != null)
|
||||
obj.Ellipse = template.Object.Ellipse;
|
||||
if (String.IsNullOrWhiteSpace(obj.Name) && !String.IsNullOrWhiteSpace(template.Object.Name))
|
||||
obj.Name = template.Object.Name;
|
||||
if (obj.Polygon == null && template.Object.Polygon != null)
|
||||
obj.Polygon = template.Object.Polygon;
|
||||
if (obj.Polyline == null && template.Object.Polyline != null)
|
||||
obj.Polyline = template.Object.Polyline;
|
||||
foreach (var tProperty in template.Object.Properties)
|
||||
if (!obj.Properties.Exists(p => p.Name == tProperty.Name))
|
||||
obj.Properties.Add(tProperty);
|
||||
if (String.IsNullOrWhiteSpace(obj.Type) && !String.IsNullOrWhiteSpace(template.Object.Type))
|
||||
obj.Type = template.Object.Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[XmlRoot(ElementName = "template")]
|
||||
public class TiledMapObjectTemplateContent
|
||||
{
|
||||
[XmlElement(ElementName = "tileset")]
|
||||
public TiledMapTilesetContent Tileset { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public ExternalReference<TiledMapTilesetContent> TilesetReference { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "object")]
|
||||
public TiledMapObjectContent Object { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
@@ -33,14 +32,14 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
}
|
||||
}
|
||||
|
||||
private TiledMapObjectTemplateContent DeserializeTileMapObjectTemplateContent(string filePath, ContentImporterContext context)
|
||||
private static TiledMapObjectTemplateContent DeserializeTileMapObjectTemplateContent(string filePath, ContentImporterContext context)
|
||||
{
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
var templateSerializer = new XmlSerializer(typeof(TiledMapObjectTemplateContent));
|
||||
var template = (TiledMapObjectTemplateContent)templateSerializer.Deserialize(reader);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(template.Tileset?.Source))
|
||||
if (!string.IsNullOrWhiteSpace(template.Tileset?.Source))
|
||||
{
|
||||
template.Tileset.Source = $"{Path.GetDirectoryName(filePath)}/{template.Tileset.Source}";
|
||||
ContentLogger.Log($"Adding dependency '{template.Tileset.Source}'");
|
||||
|
||||
@@ -3,90 +3,171 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MonoGame.Extended.Tiled;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
using MonoGame.Utilities;
|
||||
using CompressionMode = System.IO.Compression.CompressionMode;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[ContentProcessor(DisplayName = "Tiled Map Processor - MonoGame.Extended")]
|
||||
public class TiledMapProcessor : ContentProcessor<TiledMapContent, TiledMapContent>
|
||||
public static class TiledMapContentHelper
|
||||
{
|
||||
public override TiledMapContent Process(TiledMapContent map, ContentProcessorContext context)
|
||||
public static void Process(TiledMapObjectContent obj, ContentProcessorContext context)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(obj.TemplateSource))
|
||||
{
|
||||
var externalReference = new ExternalReference<TiledMapObjectLayerContent>(obj.TemplateSource);
|
||||
var template = context.BuildAndLoadAsset<TiledMapObjectLayerContent, TiledMapObjectTemplateContent>(externalReference, "");
|
||||
|
||||
// Nothing says a template can't reference another template.
|
||||
// Yay recusion!
|
||||
Process(template.Object, context);
|
||||
|
||||
if (!obj._globalIdentifier.HasValue && template.Object._globalIdentifier.HasValue)
|
||||
obj.GlobalIdentifier = template.Object.GlobalIdentifier;
|
||||
|
||||
if (!obj._height.HasValue && template.Object._height.HasValue)
|
||||
obj.Height = template.Object.Height;
|
||||
|
||||
if (!obj._identifier.HasValue && template.Object._identifier.HasValue)
|
||||
obj.Identifier = template.Object.Identifier;
|
||||
|
||||
if (!obj._rotation.HasValue && template.Object._rotation.HasValue)
|
||||
obj.Rotation = template.Object.Rotation;
|
||||
|
||||
if (!obj._visible.HasValue && template.Object._visible.HasValue)
|
||||
obj.Visible = template.Object.Visible;
|
||||
|
||||
if (!obj._width.HasValue && template.Object._width.HasValue)
|
||||
obj.Width = template.Object.Width;
|
||||
|
||||
if (!obj._x.HasValue && template.Object._x.HasValue)
|
||||
obj.X = template.Object.X;
|
||||
|
||||
if (!obj._y.HasValue && template.Object._y.HasValue)
|
||||
obj.Y = template.Object.Y;
|
||||
|
||||
if (obj.Ellipse == null && template.Object.Ellipse != null)
|
||||
obj.Ellipse = template.Object.Ellipse;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(obj.Name) && !string.IsNullOrWhiteSpace(template.Object.Name))
|
||||
obj.Name = template.Object.Name;
|
||||
|
||||
if (obj.Polygon == null && template.Object.Polygon != null)
|
||||
obj.Polygon = template.Object.Polygon;
|
||||
|
||||
if (obj.Polyline == null && template.Object.Polyline != null)
|
||||
obj.Polyline = template.Object.Polyline;
|
||||
|
||||
foreach (var tProperty in template.Object.Properties)
|
||||
{
|
||||
if (!obj.Properties.Exists(p => p.Name == tProperty.Name))
|
||||
obj.Properties.Add(tProperty);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(obj.Type) && !string.IsNullOrWhiteSpace(template.Object.Type))
|
||||
obj.Type = template.Object.Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[ContentProcessor(DisplayName = "Tiled Map Processor - MonoGame.Extended")]
|
||||
public class TiledMapProcessor : ContentProcessor<TiledMapContentItem, TiledMapContentItem>
|
||||
{
|
||||
public override TiledMapContentItem Process(TiledMapContentItem contentItem, ContentProcessorContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
ContentLogger.Logger = context.Logger;
|
||||
var map = contentItem.Data;
|
||||
|
||||
if (map.Orientation == TiledMapOrientationContent.Hexagonal || map.Orientation == TiledMapOrientationContent.Staggered)
|
||||
throw new NotSupportedException($"{map.Orientation} Tiled Maps are currently not implemented!");
|
||||
|
||||
foreach (var tileset in map.Tilesets)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(tileset.Source))
|
||||
// Load the Texture2DContent for the tileset as it will be saved into the map content file.
|
||||
tileset.Image.ContentRef = context.BuildAsset<Texture2DContent, Texture2DContent>(new ExternalReference<Texture2DContent>(tileset.Image.Source), "", new OpaqueDataDictionary() { { "ColorKeyColor", tileset.Image.TransparentColor }, { "ColorKeyEnabled", true } }, "", "");
|
||||
if (string.IsNullOrWhiteSpace(tileset.Source))
|
||||
{
|
||||
// Load the Texture2DContent for the tileset as it will be saved into the map content file.
|
||||
//var externalReference = new ExternalReference<Texture2DContent>(tileset.Image.Source);
|
||||
var parameters = new OpaqueDataDictionary
|
||||
{
|
||||
{ "ColorKeyColor", tileset.Image.TransparentColor },
|
||||
{ "ColorKeyEnabled", true }
|
||||
};
|
||||
//tileset.Image.ContentRef = context.BuildAsset<Texture2DContent, Texture2DContent>(externalReference, "", parameters, "", "");
|
||||
contentItem.BuildExternalReference<Texture2DContent>(context, tileset.Image.Source, parameters);
|
||||
}
|
||||
else
|
||||
// Link to the tileset for the content loader to load at runtime.
|
||||
tileset.Content = context.BuildAsset<TiledMapTilesetContent, TiledMapTilesetContent>(new ExternalReference<TiledMapTilesetContent>(tileset.Source), "");
|
||||
|
||||
{
|
||||
// Link to the tileset for the content loader to load at runtime.
|
||||
//var externalReference = new ExternalReference<TiledMapTilesetContent>(tileset.Source);
|
||||
//tileset.Content = context.BuildAsset<TiledMapTilesetContent, TiledMapTilesetContent>(externalReference, "");
|
||||
contentItem.BuildExternalReference<TiledMapTilesetContent>(context, tileset.Source);
|
||||
}
|
||||
}
|
||||
|
||||
ProcessLayers(map, context, map.Layers);
|
||||
ProcessLayers(contentItem, map, context, map.Layers);
|
||||
|
||||
return map;
|
||||
return contentItem;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
context.Logger.LogImportantMessage(ex.Message);
|
||||
context.Logger.LogImportantMessage("Hello World!");
|
||||
throw ex;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessLayers(TiledMapContent map, ContentProcessorContext context, List<TiledMapLayerContent> layers)
|
||||
private static void ProcessLayers(TiledMapContentItem contentItem, TiledMapContent map, ContentProcessorContext context, List<TiledMapLayerContent> layers)
|
||||
{
|
||||
foreach (var layer in layers)
|
||||
{
|
||||
if (layer is TiledMapImageLayerContent imageLayer)
|
||||
switch (layer)
|
||||
{
|
||||
ContentLogger.Log($"Processing image layer '{imageLayer.Name}'");
|
||||
imageLayer.Image.ContentRef = context.BuildAsset<Texture2DContent, Texture2DContent>(new ExternalReference<Texture2DContent>(imageLayer.Image.Source), "", new OpaqueDataDictionary() { { "ColorKeyColor", imageLayer.Image.TransparentColor }, { "ColorKeyEnabled", true } }, "", "");
|
||||
ContentLogger.Log($"Processed image layer '{imageLayer.Name}'");
|
||||
case TiledMapImageLayerContent imageLayer:
|
||||
ContentLogger.Log($"Processing image layer '{imageLayer.Name}'");
|
||||
//var externalReference = new ExternalReference<Texture2DContent>(imageLayer.Image.Source);
|
||||
var parameters = new OpaqueDataDictionary
|
||||
{
|
||||
{ "ColorKeyColor", imageLayer.Image.TransparentColor },
|
||||
{ "ColorKeyEnabled", true }
|
||||
};
|
||||
//imageLayer.Image.ContentRef = context.BuildAsset<Texture2DContent, Texture2DContent>(externalReference, "", parameters, "", "");
|
||||
contentItem.BuildExternalReference<Texture2DContent>(context, imageLayer.Image.Source, parameters);
|
||||
ContentLogger.Log($"Processed image layer '{imageLayer.Name}'");
|
||||
break;
|
||||
|
||||
case TiledMapTileLayerContent tileLayer when tileLayer.Data.Chunks.Count > 0:
|
||||
throw new NotSupportedException($"{map.FilePath} contains data chunks. These are currently not supported.");
|
||||
|
||||
case TiledMapTileLayerContent tileLayer:
|
||||
var data = tileLayer.Data;
|
||||
var encodingType = data.Encoding ?? "xml";
|
||||
var compressionType = data.Compression ?? "xml";
|
||||
|
||||
ContentLogger.Log($"Processing tile layer '{tileLayer.Name}': Encoding: '{encodingType}', Compression: '{compressionType}'");
|
||||
var tileData = DecodeTileLayerData(encodingType, tileLayer);
|
||||
var tiles = CreateTiles(map.RenderOrder, map.Width, map.Height, tileData);
|
||||
tileLayer.Tiles = tiles;
|
||||
ContentLogger.Log($"Processed tile layer '{tileLayer}': {tiles.Length} tiles");
|
||||
break;
|
||||
|
||||
case TiledMapObjectLayerContent objectLayer:
|
||||
ContentLogger.Log($"Processing object layer '{objectLayer.Name}'");
|
||||
|
||||
foreach (var obj in objectLayer.Objects)
|
||||
TiledMapContentHelper.Process(obj, context);
|
||||
|
||||
ContentLogger.Log($"Processed object layer '{objectLayer.Name}'");
|
||||
break;
|
||||
|
||||
case TiledMapGroupLayerContent groupLayer:
|
||||
ProcessLayers(contentItem, map, context, groupLayer.Layers);
|
||||
break;
|
||||
}
|
||||
|
||||
if (layer is TiledMapTileLayerContent tileLayer)
|
||||
{
|
||||
if (tileLayer.Data.Chunks.Count > 0)
|
||||
throw new NotSupportedException($"{map.FilePath} contains data chunks. These are currently not supported.");
|
||||
|
||||
var data = tileLayer.Data;
|
||||
var encodingType = data.Encoding ?? "xml";
|
||||
var compressionType = data.Compression ?? "xml";
|
||||
|
||||
ContentLogger.Log(
|
||||
$"Processing tile layer '{tileLayer.Name}': Encoding: '{encodingType}', Compression: '{compressionType}'");
|
||||
|
||||
var tileData = DecodeTileLayerData(encodingType, tileLayer);
|
||||
var tiles = CreateTiles(map.RenderOrder, map.Width, map.Height, tileData);
|
||||
tileLayer.Tiles = tiles;
|
||||
|
||||
ContentLogger.Log($"Processed tile layer '{tileLayer}': {tiles.Length} tiles");
|
||||
}
|
||||
|
||||
if (layer is TiledMapObjectLayerContent objectLayer)
|
||||
{
|
||||
ContentLogger.Log($"Processing object layer '{objectLayer.Name}'");
|
||||
foreach (var obj in objectLayer.Objects)
|
||||
TiledMapObjectContent.Process(obj, context);
|
||||
ContentLogger.Log($"Processed object layer '{objectLayer.Name}'");
|
||||
}
|
||||
|
||||
if (layer is TiledMapGroupLayerContent groupLayer)
|
||||
ProcessLayers(map, context, groupLayer.Layers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
public struct TiledMapTile
|
||||
{
|
||||
internal readonly uint GlobalTileIdentifierWithFlags;
|
||||
|
||||
public readonly ushort X;
|
||||
public readonly ushort Y;
|
||||
|
||||
public int GlobalIdentifier => (int)(GlobalTileIdentifierWithFlags & ~(uint)TiledMapTileFlipFlags.All);
|
||||
public bool IsFlippedHorizontally => (GlobalTileIdentifierWithFlags & (uint)TiledMapTileFlipFlags.FlipHorizontally) != 0;
|
||||
public bool IsFlippedVertically => (GlobalTileIdentifierWithFlags & (uint)TiledMapTileFlipFlags.FlipVertically) != 0;
|
||||
public bool IsFlippedDiagonally => (GlobalTileIdentifierWithFlags & (uint)TiledMapTileFlipFlags.FlipDiagonally) != 0;
|
||||
public bool IsBlank => GlobalIdentifier == 0;
|
||||
public TiledMapTileFlipFlags Flags => (TiledMapTileFlipFlags)(GlobalTileIdentifierWithFlags & (uint)TiledMapTileFlipFlags.All);
|
||||
|
||||
internal TiledMapTile(uint globalTileIdentifierWithFlags, ushort x, ushort y)
|
||||
{
|
||||
GlobalTileIdentifierWithFlags = globalTileIdentifierWithFlags;
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"GlobalIdentifier: {GlobalIdentifier}, Flags: {Flags}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
public class TiledMapTilesetContentItem : ContentItem<TiledMapTilesetContent>
|
||||
{
|
||||
public TiledMapTilesetContentItem(TiledMapTilesetContent data)
|
||||
: base(data)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[ContentImporter(".tsx", DefaultProcessor = "TiledMapTilesetProcessor", DisplayName = "Tiled Map Tileset Importer - MonoGame.Extended")]
|
||||
public class TiledMapTilesetImporter : ContentImporter<TiledMapTilesetContent>
|
||||
[ContentImporter(".tsx", DefaultProcessor = "TiledMapTilesetProcessor", DisplayName = "Tiled Map Tileset Importer - MonoGame.Extended")]
|
||||
public class TiledMapTilesetImporter : ContentImporter<TiledMapTilesetContentItem>
|
||||
{
|
||||
public override TiledMapTilesetContent Import(string filePath, ContentImporterContext context)
|
||||
public override TiledMapTilesetContentItem Import(string filePath, ContentImporterContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -24,12 +23,12 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
|
||||
ContentLogger.Log($"Imported '{filePath}'");
|
||||
|
||||
return tileset;
|
||||
return new TiledMapTilesetContentItem(tileset);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
context.Logger.LogImportantMessage(e.StackTrace);
|
||||
throw e;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,17 +44,21 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
context.AddDependency(tileset.Image.Source);
|
||||
|
||||
foreach (var tile in tileset.Tiles)
|
||||
foreach (var obj in tile.Objects)
|
||||
if (!String.IsNullOrWhiteSpace(obj.TemplateSource))
|
||||
{
|
||||
obj.TemplateSource = $"{Path.GetDirectoryName(filePath)}/{obj.TemplateSource}";
|
||||
ContentLogger.Log($"Adding dependency '{obj.TemplateSource}'");
|
||||
{
|
||||
foreach (var obj in tile.Objects)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(obj.TemplateSource))
|
||||
{
|
||||
obj.TemplateSource = $"{Path.GetDirectoryName(filePath)}/{obj.TemplateSource}";
|
||||
ContentLogger.Log($"Adding dependency '{obj.TemplateSource}'");
|
||||
|
||||
// We depend on the template.
|
||||
context.AddDependency(obj.TemplateSource);
|
||||
}
|
||||
// We depend on the template.
|
||||
context.AddDependency(obj.TemplateSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tileset;
|
||||
return tileset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,42 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[ContentProcessor(DisplayName = "Tiled Map Tileset Processor - MonoGame.Extended")]
|
||||
public class TiledMapTilesetProcessor : ContentProcessor<TiledMapTilesetContent, TiledMapTilesetContent>
|
||||
public class TiledMapTilesetProcessor : ContentProcessor<TiledMapTilesetContentItem, TiledMapTilesetContentItem>
|
||||
{
|
||||
public override TiledMapTilesetContent Process(TiledMapTilesetContent tileset, ContentProcessorContext context)
|
||||
public override TiledMapTilesetContentItem Process(TiledMapTilesetContentItem contentItem, ContentProcessorContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
ContentLogger.Logger = context.Logger;
|
||||
var tileset = contentItem.Data;
|
||||
|
||||
ContentLogger.Logger = context.Logger;
|
||||
ContentLogger.Log($"Processing tileset '{tileset.Name}'");
|
||||
|
||||
// Build the Texture2D asset and load it as it will be saved as part of this tileset file.
|
||||
tileset.Image.ContentRef = context.BuildAsset<Texture2DContent, Texture2DContent>(new ExternalReference<Texture2DContent>(tileset.Image.Source), "", new OpaqueDataDictionary() { { "ColorKeyColor", tileset.Image.TransparentColor }, { "ColorKeyEnabled", true } }, "", "");
|
||||
//var externalReference = new ExternalReference<Texture2DContent>(tileset.Image.Source);
|
||||
var parameters = new OpaqueDataDictionary
|
||||
{
|
||||
{ "ColorKeyColor", tileset.Image.TransparentColor },
|
||||
{ "ColorKeyEnabled", true }
|
||||
};
|
||||
//tileset.Image.ContentRef = context.BuildAsset<Texture2DContent, Texture2DContent>(externalReference, "", parameters, "", "");
|
||||
contentItem.BuildExternalReference<Texture2DContent>(context, tileset.Image.Source, parameters);
|
||||
|
||||
foreach (var tile in tileset.Tiles)
|
||||
foreach (var obj in tile.Objects)
|
||||
TiledMapObjectContent.Process(obj, context);
|
||||
{
|
||||
foreach (var obj in tile.Objects)
|
||||
{
|
||||
TiledMapContentHelper.Process(obj, context);
|
||||
}
|
||||
}
|
||||
|
||||
ContentLogger.Log($"Processed tileset '{tileset.Name}'");
|
||||
ContentLogger.Log($"Processed tileset '{tileset.Name}'");
|
||||
|
||||
return tileset;
|
||||
return contentItem;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -2,26 +2,24 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
|
||||
using MonoGame.Extended.Tiled;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[ContentTypeWriter]
|
||||
class TiledMapTilesetWriter : ContentTypeWriter<TiledMapTilesetContent>
|
||||
public class TiledMapTilesetWriter : ContentTypeWriter<TiledMapTilesetContentItem>
|
||||
{
|
||||
public override string GetRuntimeReader(TargetPlatform targetPlatform)
|
||||
=> "MonoGame.Extended.Tiled.TiledMapTilesetReader, MonoGame.Extended.Tiled";
|
||||
public override string GetRuntimeReader(TargetPlatform targetPlatform) => "MonoGame.Extended.Tiled.TiledMapTilesetReader, MonoGame.Extended.Tiled";
|
||||
|
||||
public override string GetRuntimeType(TargetPlatform targetPlatform)
|
||||
=> "MonoGame.Extended.Tiled.TiledMapTileset, MonoGame.Extended.Tiled";
|
||||
public override string GetRuntimeType(TargetPlatform targetPlatform) => "MonoGame.Extended.Tiled.TiledMapTileset, MonoGame.Extended.Tiled";
|
||||
|
||||
protected override void Write(ContentWriter writer, TiledMapTilesetContent tileset)
|
||||
protected override void Write(ContentWriter writer, TiledMapTilesetContentItem contentItem)
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteTileset(writer, tileset);
|
||||
WriteTileset(writer, contentItem.Data, contentItem);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -30,9 +28,11 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteTileset(ContentWriter writer, TiledMapTilesetContent tileset)
|
||||
public static void WriteTileset(ContentWriter writer, TiledMapTilesetContent tileset, IExternalReferenceRepository externalReferenceRepository)
|
||||
{
|
||||
writer.WriteExternalReference(tileset.Image.ContentRef);
|
||||
var externalReference = externalReferenceRepository.GetExternalReference<Texture2DContent>(tileset.Image.Source);
|
||||
|
||||
writer.WriteExternalReference(externalReference);
|
||||
writer.Write(tileset.TileWidth);
|
||||
writer.Write(tileset.TileHeight);
|
||||
writer.Write(tileset.TileCount);
|
||||
@@ -45,7 +45,6 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
WriteTilesetTile(writer, tilesetTile);
|
||||
|
||||
writer.WriteTiledMapProperties(tileset.Properties);
|
||||
|
||||
}
|
||||
|
||||
private static void WriteTilesetTile(ContentWriter writer, TiledMapTilesetTileContent tilesetTile)
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
|
||||
using MonoGame.Extended.Tiled;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
{
|
||||
[ContentTypeWriter]
|
||||
public class TiledMapWriter : ContentTypeWriter<TiledMapContent>
|
||||
public class TiledMapWriter : ContentTypeWriter<TiledMapContentItem>
|
||||
{
|
||||
protected override void Write(ContentWriter writer, TiledMapContent map)
|
||||
private TiledMapContentItem _contentItem;
|
||||
|
||||
protected override void Write(ContentWriter writer, TiledMapContentItem contentItem)
|
||||
{
|
||||
_contentItem = contentItem;
|
||||
|
||||
var map = contentItem.Data;
|
||||
|
||||
try
|
||||
{
|
||||
WriteMetaData(writer, map);
|
||||
@@ -23,7 +29,6 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ContentLogger.Logger.LogImportantMessage("Wtf");
|
||||
ContentLogger.Logger.LogImportantMessage(ex.StackTrace);
|
||||
throw;
|
||||
}
|
||||
@@ -41,29 +46,31 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
writer.WriteTiledMapProperties(map.Properties);
|
||||
}
|
||||
|
||||
private static void WriteTilesets(ContentWriter writer, IReadOnlyCollection<TiledMapTilesetContent> tilesets)
|
||||
private void WriteTilesets(ContentWriter writer, IReadOnlyCollection<TiledMapTilesetContent> tilesets)
|
||||
{
|
||||
writer.Write(tilesets.Count);
|
||||
|
||||
foreach (var tileset in tilesets)
|
||||
WriteTileset(writer, tileset);
|
||||
}
|
||||
|
||||
private static void WriteTileset(ContentWriter writer, TiledMapTilesetContent tileset)
|
||||
private void WriteTileset(ContentWriter writer, TiledMapTilesetContent tileset)
|
||||
{
|
||||
writer.Write(tileset.FirstGlobalIdentifier);
|
||||
if (tileset.Content != null)
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tileset.Source))
|
||||
{
|
||||
writer.Write(true);
|
||||
writer.WriteExternalReference(tileset.Content);
|
||||
writer.WriteExternalReference(_contentItem.GetExternalReference<TiledMapTilesetContent>(tileset.Source));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(false);
|
||||
TiledMapTilesetWriter.WriteTileset(writer, tileset);
|
||||
TiledMapTilesetWriter.WriteTileset(writer, tileset, _contentItem);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteLayers(ContentWriter writer, IReadOnlyCollection<TiledMapLayerContent> layers)
|
||||
private void WriteLayers(ContentWriter writer, IReadOnlyCollection<TiledMapLayerContent> layers)
|
||||
{
|
||||
writer.Write(layers.Count);
|
||||
|
||||
@@ -71,7 +78,7 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
WriteLayer(writer, layer);
|
||||
}
|
||||
|
||||
private static void WriteLayer(ContentWriter writer, TiledMapLayerContent layer)
|
||||
private void WriteLayer(ContentWriter writer, TiledMapLayerContent layer)
|
||||
{
|
||||
writer.Write((byte)layer.Type);
|
||||
|
||||
@@ -102,9 +109,10 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteImageLayer(ContentWriter writer, TiledMapImageLayerContent imageLayer)
|
||||
private void WriteImageLayer(ContentWriter writer, TiledMapImageLayerContent imageLayer)
|
||||
{
|
||||
writer.WriteExternalReference(imageLayer.Image.ContentRef);
|
||||
var externalReference = _contentItem.GetExternalReference<Texture2DContent>(imageLayer.Image.Source);
|
||||
writer.WriteExternalReference(externalReference);
|
||||
writer.Write(new Vector2(imageLayer.X, imageLayer.Y));
|
||||
}
|
||||
|
||||
@@ -208,14 +216,8 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
return TiledMapObjectType.Rectangle;
|
||||
}
|
||||
|
||||
public override string GetRuntimeType(TargetPlatform targetPlatform)
|
||||
{
|
||||
return "MonoGame.Extended.Tiled.TiledMap, MonoGame.Extended.Tiled";
|
||||
}
|
||||
public override string GetRuntimeType(TargetPlatform targetPlatform) => "MonoGame.Extended.Tiled.TiledMap, MonoGame.Extended.Tiled";
|
||||
|
||||
public override string GetRuntimeReader(TargetPlatform targetPlatform)
|
||||
{
|
||||
return "MonoGame.Extended.Tiled.TiledMapReader, MonoGame.Extended.Tiled";
|
||||
}
|
||||
public override string GetRuntimeReader(TargetPlatform targetPlatform) => "MonoGame.Extended.Tiled.TiledMapReader, MonoGame.Extended.Tiled";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MonoGame.Extended.Gui.Controls
|
||||
{
|
||||
public class Box : Control
|
||||
{
|
||||
public override IEnumerable<Control> Children { get; } = Enumerable.Empty<Control>();
|
||||
|
||||
public override Size GetContentSize(IGuiContext context)
|
||||
{
|
||||
return new Size(Width, Height);
|
||||
}
|
||||
|
||||
public Color FillColor { get; set; } = Color.White;
|
||||
|
||||
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
|
||||
{
|
||||
base.Draw(context, renderer, deltaSeconds);
|
||||
renderer.FillRectangle(ContentRectangle, FillColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
private bool _isPressed;
|
||||
public bool IsPressed
|
||||
{
|
||||
get { return _isPressed; }
|
||||
get => _isPressed;
|
||||
set
|
||||
{
|
||||
if (_isPressed != value)
|
||||
@@ -29,7 +29,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
private ControlStyle _pressedStyle;
|
||||
public ControlStyle PressedStyle
|
||||
{
|
||||
get { return _pressedStyle; }
|
||||
get => _pressedStyle;
|
||||
set
|
||||
{
|
||||
if (_pressedStyle != value)
|
||||
|
||||
@@ -1,27 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MonoGame.Extended.Gui.Controls
|
||||
{
|
||||
public class Box : Control
|
||||
{
|
||||
public override IEnumerable<Control> Children { get; } = Enumerable.Empty<Control>();
|
||||
|
||||
public override Size GetContentSize(IGuiContext context)
|
||||
{
|
||||
return new Size(Width, Height);
|
||||
}
|
||||
|
||||
public Color FillColor { get; set; } = Color.White;
|
||||
|
||||
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
|
||||
{
|
||||
base.Draw(context, renderer, deltaSeconds);
|
||||
renderer.FillRectangle(ContentRectangle, FillColor);
|
||||
}
|
||||
}
|
||||
|
||||
public class CheckBox : CompositeControl
|
||||
{
|
||||
public CheckBox()
|
||||
@@ -63,13 +43,13 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
|
||||
public override object Content
|
||||
{
|
||||
get { return _contentLabel.Content; }
|
||||
set { _contentLabel.Content = value; }
|
||||
get => _contentLabel.Content;
|
||||
set => _contentLabel.Content = value;
|
||||
}
|
||||
|
||||
public bool IsChecked
|
||||
{
|
||||
get { return _toggleButton.IsChecked; }
|
||||
get => _toggleButton.IsChecked;
|
||||
set
|
||||
{
|
||||
_toggleButton.IsChecked = value;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
private object _content;
|
||||
public object Content
|
||||
{
|
||||
get { return _content; }
|
||||
get => _content;
|
||||
set
|
||||
{
|
||||
if (_content != value)
|
||||
@@ -25,9 +25,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
{
|
||||
get
|
||||
{
|
||||
var control = Content as Control;
|
||||
|
||||
if (control != null)
|
||||
if (Content is Control control)
|
||||
yield return control;
|
||||
}
|
||||
}
|
||||
@@ -42,18 +40,13 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
|
||||
public override void Update(IGuiContext context, float deltaSeconds)
|
||||
{
|
||||
var control = _content as Control;
|
||||
|
||||
if (control != null)
|
||||
if (_content is Control control && _contentChanged)
|
||||
{
|
||||
if (_contentChanged)
|
||||
{
|
||||
control.Parent = this;
|
||||
control.ActualSize = ContentRectangle.Size;
|
||||
control.Position = new Point(Padding.Left, Padding.Top);
|
||||
control.InvalidateMeasure();
|
||||
_contentChanged = false;
|
||||
}
|
||||
control.Parent = this;
|
||||
control.ActualSize = ContentRectangle.Size;
|
||||
control.Position = new Point(Padding.Left, Padding.Top);
|
||||
control.InvalidateMeasure();
|
||||
_contentChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +54,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
{
|
||||
base.Draw(context, renderer, deltaSeconds);
|
||||
|
||||
var control = Content as Control;
|
||||
|
||||
if (control != null)
|
||||
if (Content is Control control)
|
||||
{
|
||||
control.Draw(context, renderer, deltaSeconds);
|
||||
}
|
||||
@@ -79,9 +70,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
|
||||
public override Size GetContentSize(IGuiContext context)
|
||||
{
|
||||
var control = Content as Control;
|
||||
|
||||
if (control != null)
|
||||
if (Content is Control control)
|
||||
return control.CalculateActualSize(context);
|
||||
|
||||
var text = Content?.ToString();
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Skin Skin
|
||||
{
|
||||
get { return _skin; }
|
||||
get => _skin;
|
||||
set
|
||||
{
|
||||
if (_skin != value)
|
||||
@@ -75,7 +75,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool IsHovered
|
||||
{
|
||||
get { return _isHovered; }
|
||||
get => _isHovered;
|
||||
private set
|
||||
{
|
||||
if (_isHovered != value)
|
||||
@@ -128,7 +128,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
private bool _isEnabled;
|
||||
public bool IsEnabled
|
||||
{
|
||||
get { return _isEnabled; }
|
||||
get => _isEnabled;
|
||||
set
|
||||
{
|
||||
if (_isEnabled != value)
|
||||
@@ -144,7 +144,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
private ControlStyle _hoverStyle;
|
||||
public ControlStyle HoverStyle
|
||||
{
|
||||
get { return _hoverStyle; }
|
||||
get => _hoverStyle;
|
||||
set
|
||||
{
|
||||
if (_hoverStyle != value)
|
||||
@@ -158,7 +158,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
private ControlStyle _disabledStyle;
|
||||
public ControlStyle DisabledStyle
|
||||
{
|
||||
get { return _disabledStyle; }
|
||||
get => _disabledStyle;
|
||||
set
|
||||
{
|
||||
_disabledStyle = value;
|
||||
@@ -255,17 +255,17 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
|
||||
public object GetAttachedProperty(string name)
|
||||
{
|
||||
object value;
|
||||
|
||||
if (AttachedProperties.TryGetValue(name, out value))
|
||||
return value;
|
||||
|
||||
return null;
|
||||
return AttachedProperties.TryGetValue(name, out var value) ? value : null;
|
||||
}
|
||||
|
||||
public void SetAttachedProperty(string name, object value)
|
||||
{
|
||||
AttachedProperties[name] = value;
|
||||
}
|
||||
|
||||
public virtual Type GetAttachedPropertyType(string propertyName)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,15 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
}
|
||||
|
||||
public const string DockProperty = "Dock";
|
||||
|
||||
public override Type GetAttachedPropertyType(string propertyName)
|
||||
{
|
||||
if (string.Equals(DockProperty, propertyName, StringComparison.OrdinalIgnoreCase))
|
||||
return typeof(Dock);
|
||||
|
||||
return base.GetAttachedPropertyType(propertyName);
|
||||
}
|
||||
|
||||
public bool LastChildFill { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace MonoGame.Extended.Gui.Controls
|
||||
{
|
||||
public class Submit : Button
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
public char? PasswordCharacter { get; set; }
|
||||
|
||||
private string _text;
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return _text; }
|
||||
@@ -52,8 +53,9 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
public override Size GetContentSize(IGuiContext context)
|
||||
{
|
||||
var font = Font ?? context.DefaultFont;
|
||||
var stringSize = (Size)font.MeasureString(Text ?? string.Empty);
|
||||
return new Size(stringSize.Width, stringSize.Height < font.LineHeight ? font.LineHeight : stringSize.Height);
|
||||
var stringSize = (Size) font.MeasureString(Text ?? string.Empty);
|
||||
return new Size(stringSize.Width,
|
||||
stringSize.Height < font.LineHeight ? font.LineHeight : stringSize.Height);
|
||||
}
|
||||
|
||||
//protected override Size2 CalculateDesiredSize(IGuiContext context, Size2 availableSize)
|
||||
@@ -125,7 +127,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
foreach (var glyph in font.GetGlyphs(textInfo.Text, textInfo.Position))
|
||||
{
|
||||
var fontRegionWidth = glyph.FontRegion?.Width ?? 0;
|
||||
var glyphMiddle = (int)(glyph.Position.X + fontRegionWidth * 0.5f);
|
||||
var glyphMiddle = (int) (glyph.Position.X + fontRegionWidth * 0.5f);
|
||||
|
||||
if (position.X >= glyphMiddle)
|
||||
{
|
||||
@@ -149,7 +151,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
case Keys.Back:
|
||||
if (Text.Length > 0)
|
||||
{
|
||||
if (SelectionStart > 0)// && _selectionIndexes.Count <= 1)
|
||||
if (SelectionStart > 0) // && _selectionIndexes.Count <= 1)
|
||||
{
|
||||
SelectionStart--;
|
||||
Text = Text.Remove(SelectionStart, 1);
|
||||
@@ -163,9 +165,10 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
// _selectionIndexes.Clear();
|
||||
//}
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Delete:
|
||||
if (SelectionStart < Text.Length)// && _selectionIndexes.Count <= 1)
|
||||
if (SelectionStart < Text.Length) // && _selectionIndexes.Count <= 1)
|
||||
{
|
||||
Text = Text.Remove(SelectionStart, 1);
|
||||
}
|
||||
@@ -192,6 +195,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
SelectionStart--;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Right:
|
||||
if (SelectionStart < Text.Length)
|
||||
@@ -206,6 +210,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
SelectionStart++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Home:
|
||||
SelectionStart = 0;
|
||||
@@ -230,6 +235,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
Text = Text.Insert(SelectionStart, args.Character.ToString());
|
||||
SelectionStart++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -252,7 +258,8 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
var textInfo = GetTextInfo(context, text, ContentRectangle, HorizontalTextAlignment, VerticalTextAlignment);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(textInfo.Text))
|
||||
renderer.DrawText(textInfo.Font, textInfo.Text, textInfo.Position + TextOffset, textInfo.Color, textInfo.ClippingRectangle);
|
||||
renderer.DrawText(textInfo.Font, textInfo.Text, textInfo.Position + TextOffset, textInfo.Color,
|
||||
textInfo.ClippingRectangle);
|
||||
|
||||
if (IsFocused)
|
||||
{
|
||||
@@ -307,7 +314,9 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
if (caretRectangle.Right > ClippingRectangle.Right)
|
||||
textInfo.Position.X -= caretRectangle.Right - ClippingRectangle.Right;
|
||||
|
||||
caretRectangle.X = caretRectangle.Right < ClippingRectangle.Right ? caretRectangle.Right : ClippingRectangle.Right;
|
||||
caretRectangle.X = caretRectangle.Right < ClippingRectangle.Right
|
||||
? caretRectangle.Right
|
||||
: ClippingRectangle.Right;
|
||||
caretRectangle.Width = 1;
|
||||
|
||||
if (caretRectangle.Left < ClippingRectangle.Left)
|
||||
@@ -315,6 +324,7 @@ namespace MonoGame.Extended.Gui.Controls
|
||||
textInfo.Position.X += ClippingRectangle.Left - caretRectangle.Left;
|
||||
caretRectangle.X = ClippingRectangle.Left;
|
||||
}
|
||||
|
||||
return (Rectangle) caretRectangle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using MonoGame.Extended.Input.InputListeners;
|
||||
|
||||
namespace MonoGame.Extended.Gui.Controls
|
||||
{
|
||||
public class TextBox2 : Control
|
||||
{
|
||||
public TextBox2()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public TextBox2(string text)
|
||||
{
|
||||
Text = text ?? string.Empty;
|
||||
HorizontalTextAlignment = HorizontalAlignment.Left;
|
||||
VerticalTextAlignment = VerticalAlignment.Top;
|
||||
}
|
||||
|
||||
|
||||
private const float _caretBlinkRate = 0.53f;
|
||||
private float _nextCaretBlink = _caretBlinkRate;
|
||||
private bool _isCaretVisible = true;
|
||||
|
||||
private readonly List<StringBuilder> _lines = new List<StringBuilder>();
|
||||
public string Text
|
||||
{
|
||||
get => string.Concat(_lines.SelectMany(s => $"{s}\n"));
|
||||
set
|
||||
{
|
||||
_lines.Clear();
|
||||
|
||||
var line = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
var c = value[i];
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
_lines.Add(line);
|
||||
line = new StringBuilder();
|
||||
}
|
||||
else if(c != '\r')
|
||||
{
|
||||
line.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
_lines.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
public int CaretIndex => ColumnIndex * LineIndex + ColumnIndex;
|
||||
public int LineIndex { get; set; }
|
||||
public int ColumnIndex { get; set; }
|
||||
public int TabStops { get; set; } = 4;
|
||||
|
||||
public override IEnumerable<Control> Children => Enumerable.Empty<Control>();
|
||||
|
||||
public string GetLineText(int lineIndex) => _lines[lineIndex].ToString();
|
||||
public int GetLineLength(int lineIndex) => _lines[lineIndex].Length;
|
||||
|
||||
public override Size GetContentSize(IGuiContext context)
|
||||
{
|
||||
var font = Font ?? context.DefaultFont;
|
||||
var stringSize = (Size)font.MeasureString(Text ?? string.Empty);
|
||||
return new Size(stringSize.Width, stringSize.Height < font.LineHeight ? font.LineHeight : stringSize.Height);
|
||||
}
|
||||
|
||||
public override bool OnKeyPressed(IGuiContext context, KeyboardEventArgs args)
|
||||
{
|
||||
switch (args.Key)
|
||||
{
|
||||
case Keys.Tab:
|
||||
Tab();
|
||||
break;
|
||||
case Keys.Back:
|
||||
Backspace();
|
||||
break;
|
||||
case Keys.Delete:
|
||||
Delete();
|
||||
break;
|
||||
case Keys.Left:
|
||||
Left();
|
||||
break;
|
||||
case Keys.Right:
|
||||
Right();
|
||||
break;
|
||||
case Keys.Up:
|
||||
Up();
|
||||
break;
|
||||
case Keys.Down:
|
||||
Down();
|
||||
break;
|
||||
case Keys.Home:
|
||||
Home();
|
||||
break;
|
||||
case Keys.End:
|
||||
End();
|
||||
break;
|
||||
case Keys.Enter:
|
||||
Type('\n');
|
||||
return true;
|
||||
default:
|
||||
if (args.Character.HasValue)
|
||||
Type(args.Character.Value);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_isCaretVisible = true;
|
||||
return base.OnKeyPressed(context, args);
|
||||
}
|
||||
|
||||
public void Type(char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
var lineText = GetLineText(LineIndex);
|
||||
var left = lineText.Substring(0, ColumnIndex);
|
||||
var right = lineText.Substring(ColumnIndex);
|
||||
_lines.Insert(LineIndex + 1, new StringBuilder(right));
|
||||
_lines[LineIndex] = new StringBuilder(left);
|
||||
LineIndex++;
|
||||
Home();
|
||||
break;
|
||||
case '\t':
|
||||
Tab();
|
||||
break;
|
||||
default:
|
||||
_lines[LineIndex].Insert(ColumnIndex, c);
|
||||
ColumnIndex++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Backspace()
|
||||
{
|
||||
if (ColumnIndex == 0 && LineIndex > 0)
|
||||
{
|
||||
var topLineLength = GetLineLength(LineIndex - 1);
|
||||
|
||||
if (RemoveLineBreak(LineIndex - 1))
|
||||
{
|
||||
LineIndex--;
|
||||
ColumnIndex = topLineLength;
|
||||
}
|
||||
}
|
||||
else if (Left())
|
||||
{
|
||||
RemoveCharacter(LineIndex, ColumnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
var lineLength = GetLineLength(LineIndex);
|
||||
|
||||
if (ColumnIndex == lineLength)
|
||||
RemoveLineBreak(LineIndex);
|
||||
else
|
||||
RemoveCharacter(LineIndex, ColumnIndex);
|
||||
}
|
||||
|
||||
public void RemoveCharacter(int lineIndex, int columnIndex)
|
||||
{
|
||||
_lines[lineIndex].Remove(columnIndex, 1);
|
||||
}
|
||||
|
||||
public bool RemoveLineBreak(int lineIndex)
|
||||
{
|
||||
if (lineIndex < _lines.Count - 1)
|
||||
{
|
||||
var topLine = _lines[lineIndex];
|
||||
var bottomLine = _lines[lineIndex + 1];
|
||||
_lines.RemoveAt(lineIndex + 1);
|
||||
topLine.Append(bottomLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Home()
|
||||
{
|
||||
ColumnIndex = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool End()
|
||||
{
|
||||
ColumnIndex = GetLineLength(LineIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Up()
|
||||
{
|
||||
if (LineIndex > 0)
|
||||
{
|
||||
LineIndex--;
|
||||
|
||||
if (ColumnIndex > GetLineLength(LineIndex))
|
||||
ColumnIndex = GetLineLength(LineIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Down()
|
||||
{
|
||||
if (LineIndex < _lines.Count - 1)
|
||||
{
|
||||
LineIndex++;
|
||||
|
||||
if (ColumnIndex > GetLineLength(LineIndex))
|
||||
ColumnIndex = GetLineLength(LineIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Left()
|
||||
{
|
||||
if (ColumnIndex == 0)
|
||||
{
|
||||
if (LineIndex == 0)
|
||||
return false;
|
||||
|
||||
LineIndex--;
|
||||
ColumnIndex = GetLineLength(LineIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
ColumnIndex--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Right()
|
||||
{
|
||||
if (ColumnIndex == _lines[LineIndex].Length)
|
||||
{
|
||||
if (LineIndex == _lines.Count - 1)
|
||||
return false;
|
||||
|
||||
LineIndex++;
|
||||
ColumnIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ColumnIndex++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Tab()
|
||||
{
|
||||
var spaces = TabStops - ColumnIndex % TabStops;
|
||||
|
||||
for (var s = 0; s < spaces; s++)
|
||||
Type(' ');
|
||||
|
||||
return spaces > 0;
|
||||
}
|
||||
|
||||
public override void Draw(IGuiContext context, IGuiRenderer renderer, float deltaSeconds)
|
||||
{
|
||||
base.Draw(context, renderer, deltaSeconds);
|
||||
|
||||
var text = Text;
|
||||
var textInfo = GetTextInfo(context, text, ContentRectangle, HorizontalTextAlignment, VerticalTextAlignment);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(textInfo.Text))
|
||||
renderer.DrawText(textInfo.Font, textInfo.Text, textInfo.Position + TextOffset, textInfo.Color, textInfo.ClippingRectangle);
|
||||
|
||||
if (IsFocused)
|
||||
{
|
||||
var caretRectangle = GetCaretRectangle(textInfo);
|
||||
|
||||
if (_isCaretVisible)
|
||||
renderer.DrawRectangle(caretRectangle, TextColor);
|
||||
|
||||
_nextCaretBlink -= deltaSeconds;
|
||||
|
||||
if (_nextCaretBlink <= 0)
|
||||
{
|
||||
_isCaretVisible = !_isCaretVisible;
|
||||
_nextCaretBlink = _caretBlinkRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle GetCaretRectangle(TextInfo textInfo)
|
||||
{
|
||||
var font = textInfo.Font;
|
||||
var text = GetLineText(LineIndex);
|
||||
var offset = new Vector2(0, font.LineHeight * LineIndex);
|
||||
var caretRectangle = font.GetStringRectangle(text.Substring(0, ColumnIndex), textInfo.Position + offset);
|
||||
|
||||
// TODO: Finish the caret position stuff when it's outside the clipping rectangle
|
||||
if (caretRectangle.Right > ClippingRectangle.Right)
|
||||
textInfo.Position.X -= caretRectangle.Right - ClippingRectangle.Right;
|
||||
|
||||
caretRectangle.X = caretRectangle.Right < ClippingRectangle.Right ? caretRectangle.Right : ClippingRectangle.Right;
|
||||
caretRectangle.Width = 1;
|
||||
|
||||
if (caretRectangle.Left < ClippingRectangle.Left)
|
||||
{
|
||||
textInfo.Position.X += ClippingRectangle.Left - caretRectangle.Left;
|
||||
caretRectangle.X = ClippingRectangle.Left;
|
||||
}
|
||||
|
||||
return (Rectangle)caretRectangle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ namespace MonoGame.Extended.Gui
|
||||
private TextureRegion2D _backgroundRegion;
|
||||
public TextureRegion2D BackgroundRegion
|
||||
{
|
||||
get { return _backgroundRegion; }
|
||||
get => _backgroundRegion;
|
||||
set
|
||||
{
|
||||
_backgroundRegion = value;
|
||||
@@ -68,7 +68,7 @@ namespace MonoGame.Extended.Gui
|
||||
private Size _size;
|
||||
public Size Size
|
||||
{
|
||||
get { return _size; }
|
||||
get => _size;
|
||||
set
|
||||
{
|
||||
_size = value;
|
||||
@@ -85,14 +85,14 @@ namespace MonoGame.Extended.Gui
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return Size.Width; }
|
||||
set { Size = new Size(value, Size.Height); }
|
||||
get => Size.Width;
|
||||
set => Size = new Size(value, Size.Height);
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return Size.Height; }
|
||||
set { Size = new Size(Size.Width, value); }
|
||||
get => Size.Height;
|
||||
set => Size = new Size(Size.Width, value);
|
||||
}
|
||||
|
||||
public Size ActualSize { get; internal set; }
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace MonoGame.Extended.Gui
|
||||
private Screen _activeScreen;
|
||||
public Screen ActiveScreen
|
||||
{
|
||||
get { return _activeScreen; }
|
||||
get => _activeScreen;
|
||||
set
|
||||
{
|
||||
if (_activeScreen != value)
|
||||
|
||||
@@ -9,11 +9,6 @@ namespace MonoGame.Extended.Gui
|
||||
|
||||
public static class LayoutHelper
|
||||
{
|
||||
//public static Size2 GetSizeWithMargins(Control control, IGuiContext context, Size2 availableSize)
|
||||
//{
|
||||
// return control.GetDesiredSize(context, availableSize) + control.Margin.Size;
|
||||
//}
|
||||
|
||||
public static void PlaceControl(IGuiContext context, Control control, float x, float y, float width, float height)
|
||||
{
|
||||
var rectangle = new Rectangle((int)x, (int)y, (int)width, (int)height);
|
||||
@@ -25,18 +20,6 @@ namespace MonoGame.Extended.Gui
|
||||
control.InvalidateMeasure();
|
||||
}
|
||||
|
||||
//public static void PlaceWindow(IGuiContext context, Window window, float x, float y, float width, float height)
|
||||
//{
|
||||
// var rectangle = new Rectangle((int)x, (int)y, (int)width, (int)height);
|
||||
// var availableSize = new Size2(width, height);
|
||||
// var desiredSize = window.GetDesiredSize(context, availableSize);
|
||||
// var alignedRectangle = AlignRectangle(HorizontalAlignment.Centre, VerticalAlignment.Centre, desiredSize, rectangle);
|
||||
|
||||
// window.Position = new Vector2(alignedRectangle.X, alignedRectangle.Y);
|
||||
// window.Size = alignedRectangle.Size;
|
||||
// window.Layout(context, window.BoundingRectangle);
|
||||
//}
|
||||
|
||||
public static Rectangle AlignRectangle(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, Size size, Rectangle targetRectangle)
|
||||
{
|
||||
var x = GetHorizontalPosition(horizontalAlignment, size, targetRectangle);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MonoGame.Extended.Gui.Controls;
|
||||
|
||||
namespace MonoGame.Extended.Gui.Markup
|
||||
{
|
||||
public class MarkupParser
|
||||
{
|
||||
public MarkupParser()
|
||||
{
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, Type> _controlTypes =
|
||||
typeof(Control).Assembly
|
||||
.ExportedTypes
|
||||
.Where(t => t.IsSubclassOf(typeof(Control)))
|
||||
.ToDictionary(t => t.Name, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static readonly Dictionary<Type, Func<string, object>> _converters =
|
||||
new Dictionary<Type, Func<string, object>>
|
||||
{
|
||||
{typeof(object), s => s},
|
||||
{typeof(string), s => s},
|
||||
{typeof(bool), s => bool.Parse(s)},
|
||||
{typeof(int), s => int.Parse(s)},
|
||||
{typeof(Color), s => s.StartsWith("#") ? ColorHelper.FromHex(s) : ColorHelper.FromName(s)}
|
||||
};
|
||||
|
||||
private static object ConvertValue(Type propertyType, string input, object dataContext)
|
||||
{
|
||||
var value = ParseBinding(input, dataContext);
|
||||
|
||||
if (_converters.TryGetValue(propertyType, out var converter))
|
||||
return converter(value); //property.SetValue(control, converter(value));
|
||||
|
||||
if (propertyType.IsEnum)
|
||||
return
|
||||
Enum.Parse(propertyType, value,
|
||||
true); // property.SetValue(control, Enum.Parse(propertyType, value, true));
|
||||
|
||||
throw new InvalidOperationException($"Converter not found for {propertyType}");
|
||||
}
|
||||
|
||||
private static object ParseChildNode(XmlNode node, Control parent, object dataContext)
|
||||
{
|
||||
if (node is XmlText)
|
||||
return node.InnerText.Trim();
|
||||
|
||||
if (_controlTypes.TryGetValue(node.Name, out var type))
|
||||
{
|
||||
var typeInfo = type.GetTypeInfo();
|
||||
var control = (Control) Activator.CreateInstance(type);
|
||||
|
||||
// ReSharper disable once AssignNullToNotNullAttribute
|
||||
foreach (var attribute in node.Attributes.Cast<XmlAttribute>())
|
||||
{
|
||||
var property = typeInfo.GetProperty(attribute.Name);
|
||||
|
||||
if (property != null)
|
||||
{
|
||||
var value = ConvertValue(property.PropertyType, attribute.Value, dataContext);
|
||||
property.SetValue(control, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var parts = attribute.Name.Split('.');
|
||||
var parentType = parts[0];
|
||||
var propertyName = parts[1];
|
||||
var propertyType = parent.GetAttachedPropertyType(propertyName);
|
||||
var propertyValue = ConvertValue(propertyType, attribute.Value, dataContext);
|
||||
|
||||
if (!string.Equals(parent.GetType().Name, parentType, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
$"Attached properties are only supported on the immediate parent type {parentType}");
|
||||
|
||||
control.SetAttachedProperty(propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (node.HasChildNodes)
|
||||
{
|
||||
switch (control)
|
||||
{
|
||||
case ContentControl contentControl:
|
||||
if (node.ChildNodes.Count > 1)
|
||||
throw new InvalidOperationException("A content control can only have one child");
|
||||
|
||||
contentControl.Content = ParseChildNode(node.ChildNodes[0], control, dataContext);
|
||||
break;
|
||||
case LayoutControl layoutControl:
|
||||
foreach (var childControl in ParseChildNodes(node.ChildNodes, control, dataContext))
|
||||
layoutControl.Items.Add(childControl as Control);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Unknown control type {node.Name}");
|
||||
}
|
||||
|
||||
private static string ParseBinding(string expression, object dataContext)
|
||||
{
|
||||
if (dataContext != null && expression.StartsWith("{{") && expression.EndsWith("}}"))
|
||||
{
|
||||
var binding = expression.Substring(2, expression.Length - 4);
|
||||
var bindingValue = dataContext
|
||||
.GetType()
|
||||
.GetProperty(binding)
|
||||
?.GetValue(dataContext);
|
||||
|
||||
return $"{bindingValue}";
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
private static IEnumerable<object> ParseChildNodes(XmlNodeList nodes, Control parent, object dataContext)
|
||||
{
|
||||
foreach (var node in nodes.Cast<XmlNode>())
|
||||
{
|
||||
if (node.Name == "xml")
|
||||
{
|
||||
// TODO: Validate header
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return ParseChildNode(node, parent, dataContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Control Parse(string filePath, object dataContext)
|
||||
{
|
||||
var d = new XmlDocument();
|
||||
d.Load(filePath);
|
||||
return ParseChildNodes(d.ChildNodes, null, dataContext)
|
||||
.LastOrDefault() as Control;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,9 +47,7 @@ namespace MonoGame.Extended.Gui
|
||||
|
||||
public ControlStyle GetStyle(string name)
|
||||
{
|
||||
ControlStyle controlStyle;
|
||||
|
||||
if (Styles.TryGetValue(name, out controlStyle))
|
||||
if (Styles.TryGetValue(name, out var controlStyle))
|
||||
return controlStyle;
|
||||
|
||||
return null;
|
||||
@@ -177,6 +175,12 @@ namespace MonoGame.Extended.Gui
|
||||
{nameof(Control.BorderColor), new Color(67, 67, 70)},
|
||||
{nameof(Control.BorderThickness), 2},
|
||||
},
|
||||
new ControlStyle(typeof(TextBox2)) {
|
||||
{nameof(Control.BackgroundColor), Color.DarkGray},
|
||||
{nameof(Control.TextColor), Color.Black},
|
||||
{nameof(Control.BorderColor), new Color(67, 67, 70)},
|
||||
{nameof(Control.BorderThickness), 2},
|
||||
},
|
||||
new ControlStyle(typeof(Button)) {
|
||||
{
|
||||
nameof(Button.HoverStyle), new ControlStyle {
|
||||
|
||||
+15
-15
@@ -1,11 +1,18 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
[XmlRoot(ElementName = "map")]
|
||||
public class TiledMapContent
|
||||
{
|
||||
public TiledMapContent()
|
||||
{
|
||||
Properties = new List<TiledMapPropertyContent>();
|
||||
Tilesets = new List<TiledMapTilesetContent>();
|
||||
Layers = new List<TiledMapLayerContent>();
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public string Name { get; set; }
|
||||
|
||||
@@ -36,14 +43,14 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
[XmlAttribute(AttributeName = "tileheight")]
|
||||
public int TileHeight { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "hexsidelength")]
|
||||
public int HexSideLength { get; set; }
|
||||
[XmlAttribute(AttributeName = "hexsidelength")]
|
||||
public int HexSideLength { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "staggeraxis")]
|
||||
public TiledMapStaggerAxisContent StaggerAxis { get; set; }
|
||||
[XmlAttribute(AttributeName = "staggeraxis")]
|
||||
public TiledMapStaggerAxisContent StaggerAxis { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "staggerindex")]
|
||||
public TiledMapStaggerIndexContent StaggerIndex { get; set; }
|
||||
[XmlAttribute(AttributeName = "staggerindex")]
|
||||
public TiledMapStaggerIndexContent StaggerIndex { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "tileset")]
|
||||
public List<TiledMapTilesetContent> Tilesets { get; set; }
|
||||
@@ -51,18 +58,11 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
[XmlElement(ElementName = "layer", Type = typeof(TiledMapTileLayerContent))]
|
||||
[XmlElement(ElementName = "imagelayer", Type = typeof(TiledMapImageLayerContent))]
|
||||
[XmlElement(ElementName = "objectgroup", Type = typeof(TiledMapObjectLayerContent))]
|
||||
[XmlElement(ElementName = "group", Type = typeof(TiledMapGroupLayerContent))]
|
||||
[XmlElement(ElementName = "group", Type = typeof(TiledMapGroupLayerContent))]
|
||||
public List<TiledMapLayerContent> Layers { get; set; }
|
||||
|
||||
[XmlArray("properties")]
|
||||
[XmlArrayItem("property")]
|
||||
public List<TiledMapPropertyContent> Properties { get; set; }
|
||||
|
||||
public TiledMapContent()
|
||||
{
|
||||
Properties = new List<TiledMapPropertyContent>();
|
||||
Tilesets = new List<TiledMapTilesetContent>();
|
||||
Layers = new List<TiledMapLayerContent>();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapEllipseContent
|
||||
{
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapGroupLayerContent : TiledMapLayerContent
|
||||
{
|
||||
protected TiledMapGroupLayerContent()
|
||||
: base(TiledMapLayerType.GroupLayer)
|
||||
{
|
||||
}
|
||||
|
||||
[XmlElement(ElementName = "layer", Type = typeof(TiledMapTileLayerContent))]
|
||||
[XmlElement(ElementName = "imagelayer", Type = typeof(TiledMapImageLayerContent))]
|
||||
[XmlElement(ElementName = "objectgroup", Type = typeof(TiledMapObjectLayerContent))]
|
||||
[XmlElement(ElementName = "group", Type = typeof(TiledMapGroupLayerContent))]
|
||||
public List<TiledMapLayerContent> Layers { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
+4
-6
@@ -1,17 +1,15 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapImageContent
|
||||
{
|
||||
//[XmlIgnore]
|
||||
//public Texture2DContent Content { get; set; }
|
||||
|
||||
[XmlIgnore]
|
||||
public ExternalReference<Texture2DContent> ContentRef { get; set; }
|
||||
//[XmlIgnore]
|
||||
//public ExternalReference<Texture2DContent> ContentRef { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "source")]
|
||||
public string Source { get; set; }
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapImageLayerContent : TiledMapLayerContent
|
||||
{
|
||||
+9
-10
@@ -1,14 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
[XmlInclude(typeof(TiledMapTileLayerContent))]
|
||||
[XmlInclude(typeof(TiledMapImageLayerContent))]
|
||||
[XmlInclude(typeof(TiledMapObjectLayerContent))]
|
||||
public abstract class TiledMapLayerContent
|
||||
{
|
||||
protected TiledMapLayerContent(TiledMapLayerType type)
|
||||
{
|
||||
Type = type;
|
||||
Opacity = 1.0f;
|
||||
Visible = true;
|
||||
Properties = new List<TiledMapPropertyContent>();
|
||||
}
|
||||
|
||||
[XmlAttribute(AttributeName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
@@ -31,14 +38,6 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
[XmlIgnore]
|
||||
public TiledMapLayerType Type { get; }
|
||||
|
||||
protected TiledMapLayerContent(TiledMapLayerType type)
|
||||
{
|
||||
Type = type;
|
||||
Opacity = 1.0f;
|
||||
Visible = true;
|
||||
Properties = new List<TiledMapPropertyContent>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
+1
-2
@@ -4,9 +4,8 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapLayerModelContent
|
||||
{
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
// This content class is going to be a lot more complex than the others we use.
|
||||
// Objects can reference a template file which has starting values for the
|
||||
// object. The value in the object file overrides any value specified in the
|
||||
// template. All values have to be able to store a null value so we know if the
|
||||
// XML parser actually found a value for the property and not just a default
|
||||
// value. Default values are used when the object and any templates don't
|
||||
// specify a value.
|
||||
public class TiledMapObjectContent
|
||||
{
|
||||
// TODO: HACK These shouldn't be public
|
||||
public uint? _globalIdentifier;
|
||||
public int? _identifier;
|
||||
public float? _height;
|
||||
public float? _rotation;
|
||||
public bool? _visible;
|
||||
public float? _width;
|
||||
public float? _x;
|
||||
public float? _y;
|
||||
|
||||
[XmlAttribute(DataType = "int", AttributeName = "id")]
|
||||
public int Identifier { get => _identifier ?? 0; set => _identifier = value; }
|
||||
|
||||
[XmlAttribute(DataType = "string", AttributeName = "name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "string", AttributeName = "type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "x")]
|
||||
public float X { get => _x ?? 0; set => _x = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "y")]
|
||||
public float Y { get => _y ?? 0; set => _y = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "width")]
|
||||
public float Width { get => _width ?? 0; set => _width = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "height")]
|
||||
public float Height { get => _height ?? 0; set => _height = value; }
|
||||
|
||||
[XmlAttribute(DataType = "float", AttributeName = "rotation")]
|
||||
public float Rotation { get => _rotation ?? 0; set => _rotation = value; }
|
||||
|
||||
[XmlAttribute(DataType = "boolean", AttributeName = "visible")]
|
||||
public bool Visible { get => _visible ?? true; set => _visible = value; }
|
||||
|
||||
[XmlArray("properties")]
|
||||
[XmlArrayItem("property")]
|
||||
public List<TiledMapPropertyContent> Properties { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "unsignedInt", AttributeName = "gid")]
|
||||
public uint GlobalIdentifier { get => _globalIdentifier??0; set => _globalIdentifier = value; }
|
||||
|
||||
[XmlElement(ElementName = "ellipse")]
|
||||
public TiledMapEllipseContent Ellipse { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "polygon")]
|
||||
public TiledMapPolygonContent Polygon { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "polyline")]
|
||||
public TiledMapPolylineContent Polyline { get; set; }
|
||||
|
||||
[XmlAttribute(DataType = "string", AttributeName = "template")]
|
||||
public string TemplateSource { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public enum TiledMapObjectDrawOrderContent : byte
|
||||
{
|
||||
+8
-9
@@ -1,11 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapObjectLayerContent : TiledMapLayerContent
|
||||
{
|
||||
public TiledMapObjectLayerContent()
|
||||
: base(TiledMapLayerType.ObjectLayer)
|
||||
{
|
||||
Objects = new List<TiledMapObjectContent>();
|
||||
}
|
||||
|
||||
[XmlAttribute(AttributeName = "color")]
|
||||
public string Color { get; set; }
|
||||
|
||||
@@ -14,13 +19,7 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
|
||||
[XmlAttribute(AttributeName = "draworder")]
|
||||
public TiledMapObjectDrawOrderContent DrawOrder { get; set; }
|
||||
|
||||
public TiledMapObjectLayerContent()
|
||||
: base(TiledMapLayerType.ObjectLayer)
|
||||
{
|
||||
Objects = new List<TiledMapObjectContent>();
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
[XmlRoot(ElementName = "template")]
|
||||
public class TiledMapObjectTemplateContent
|
||||
{
|
||||
[XmlElement(ElementName = "tileset")]
|
||||
public TiledMapTilesetContent Tileset { get; set; }
|
||||
|
||||
//[XmlIgnore]
|
||||
//public ExternalReference<TiledMapTilesetContent> TilesetReference { get; set; }
|
||||
|
||||
[XmlElement(ElementName = "object")]
|
||||
public TiledMapObjectContent Object { get; set; }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public enum TiledMapOrientationContent : byte
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapPolygonContent
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapPolylineContent
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapPropertyContent
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public enum TiledMapStaggerAxisContent : byte
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public enum TiledMapStaggerIndexContent : byte
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public struct TiledMapTileContent
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public enum TiledMapTileDrawOrderContent : byte
|
||||
{
|
||||
+6
-7
@@ -1,10 +1,14 @@
|
||||
using System.Xml.Serialization;
|
||||
using MonoGame.Extended.Tiled;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapTileLayerContent : TiledMapLayerContent
|
||||
{
|
||||
public TiledMapTileLayerContent()
|
||||
: base(TiledMapLayerType.TileLayer)
|
||||
{
|
||||
}
|
||||
|
||||
[XmlAttribute(AttributeName = "x")]
|
||||
public int X { get; set; }
|
||||
|
||||
@@ -22,10 +26,5 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
|
||||
[XmlIgnore]
|
||||
public TiledMapTile[] Tiles { get; set; }
|
||||
|
||||
public TiledMapTileLayerContent()
|
||||
: base(TiledMapLayerType.TileLayer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapTileLayerDataChunkContent
|
||||
{
|
||||
+7
-7
@@ -1,10 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapTileLayerDataContent
|
||||
{
|
||||
public TiledMapTileLayerDataContent()
|
||||
{
|
||||
Tiles = new List<TiledMapTileContent>();
|
||||
}
|
||||
|
||||
[XmlAttribute(AttributeName = "encoding")]
|
||||
public string Encoding { get; set; }
|
||||
|
||||
@@ -19,12 +24,7 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
|
||||
[XmlText]
|
||||
public string Value { get; set; }
|
||||
|
||||
public TiledMapTileLayerDataContent()
|
||||
{
|
||||
Tiles = new List<TiledMapTileContent>();
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Encoding} {Compression}";
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
[XmlRoot(ElementName = "tileoffset")]
|
||||
public class TiledMapTileOffsetContent
|
||||
+10
-11
@@ -1,14 +1,20 @@
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
[XmlRoot(ElementName = "tileset")]
|
||||
public class TiledMapTilesetContent
|
||||
{
|
||||
[XmlIgnore]
|
||||
public ExternalReference<TiledMapTilesetContent> Content { get; set; }
|
||||
public TiledMapTilesetContent()
|
||||
{
|
||||
TileOffset = new TiledMapTileOffsetContent();
|
||||
Tiles = new List<TiledMapTilesetTileContent>();
|
||||
Properties = new List<TiledMapPropertyContent>();
|
||||
}
|
||||
|
||||
//[XmlIgnore]
|
||||
//public ExternalReference<TiledMapTilesetContent> Content { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "firstgid")]
|
||||
public int FirstGlobalIdentifier { get; set; }
|
||||
@@ -53,13 +59,6 @@ namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
[XmlElement(ElementName = "image")]
|
||||
public TiledMapImageContent Image { get; set; }
|
||||
|
||||
public TiledMapTilesetContent()
|
||||
{
|
||||
TileOffset = new TiledMapTileOffsetContent();
|
||||
Tiles = new List<TiledMapTilesetTileContent>();
|
||||
Properties = new List<TiledMapPropertyContent>();
|
||||
}
|
||||
|
||||
public bool ContainsGlobalIdentifier(int globalIdentifier)
|
||||
{
|
||||
return (globalIdentifier >= FirstGlobalIdentifier) && (globalIdentifier < FirstGlobalIdentifier + TileCount);
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapTilesetGridContent
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapTilesetTileAnimationFrameContent
|
||||
{
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tiled
|
||||
namespace MonoGame.Extended.Tiled.Serialization
|
||||
{
|
||||
public class TiledMapTilesetTileContent
|
||||
{
|
||||
@@ -62,12 +62,8 @@ namespace MonoGame.Extended.Tiled
|
||||
|
||||
private static TiledMapTileset ReadTileset(ContentReader reader, TiledMap map)
|
||||
{
|
||||
TiledMapTileset tileset;
|
||||
var external = reader.ReadBoolean();
|
||||
if (external)
|
||||
tileset = reader.ReadExternalReference<TiledMapTileset>();
|
||||
else
|
||||
tileset = TiledMapTilesetReader.ReadTileset(reader);
|
||||
var external = reader.ReadBoolean();
|
||||
var tileset = external ? reader.ReadExternalReference<TiledMapTileset>() : TiledMapTilesetReader.ReadTileset(reader);
|
||||
|
||||
return tileset;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using MonoGame.Extended.Tiled;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MonoGame.Extended.Tiled
|
||||
{
|
||||
|
||||
@@ -52,11 +52,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Tweening"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGame.Extended.Animations", "MonoGame.Extended.Animations\MonoGame.Extended.Animations.csproj", "{587CE536-216F-41A1-B223-AE502C125B09}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{F3E80350-2F27-4EDB-8BE9-0145643A5336}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
NuGet\readme.txt = NuGet\readme.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pong", "Demos\Pong\Pong.csproj", "{55033148-02B0-4810-840A-011516846975}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platformer", "Demos\Platformer\Platformer.csproj", "{1DDD3C52-B2F2-4DB3-8BF9-57BD93928EA8}"
|
||||
@@ -360,7 +355,6 @@ Global
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{F3E80350-2F27-4EDB-8BE9-0145643A5336} = {068B9F42-8B49-4FAF-9D8C-701862FAC799}
|
||||
{55033148-02B0-4810-840A-011516846975} = {932F8931-4A8D-4205-BFCF-98E794207786}
|
||||
{1DDD3C52-B2F2-4DB3-8BF9-57BD93928EA8} = {932F8931-4A8D-4205-BFCF-98E794207786}
|
||||
{F46BC5FE-4939-4069-911F-5774AB0A3F51} = {932F8931-4A8D-4205-BFCF-98E794207786}
|
||||
|
||||
@@ -257,7 +257,7 @@ namespace MonoGame.Extended.BitmapFonts
|
||||
private readonly BitmapFont _font;
|
||||
private readonly StringBuilder _text;
|
||||
private int _index;
|
||||
private Point2 _position;
|
||||
private readonly Point2 _position;
|
||||
private Vector2 _positionDelta;
|
||||
private BitmapFontGlyph _currentGlyph;
|
||||
private BitmapFontGlyph? _previousGlyph;
|
||||
|
||||
+32
@@ -3,6 +3,38 @@
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="TestData\isometric.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\isometric_tileset.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\level01.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\template.tx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\test-object-layer.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\test-tileset-base64.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\test-tileset-csv.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\test-tileset-gzip.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\test-tileset-xml.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="TestData\test-tileset-zlib.tmx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MonoGame.Framework.DesktopGL.Core" Version="3.7.0.7" />
|
||||
|
||||
+176
-169
@@ -1,197 +1,204 @@
|
||||
//using System.Linq;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||
using MonoGame.Extended.Content.Pipeline.Tiled;
|
||||
using MonoGame.Extended.Tiled.Serialization;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
//namespace MonoGame.Extended.Content.Pipeline.Tests.Tiled
|
||||
//{
|
||||
//
|
||||
// public class TiledMapImporterProcessorTests
|
||||
// {
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_Import_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "level01.tmx");
|
||||
namespace MonoGame.Extended.Content.Pipeline.Tests.Tiled
|
||||
{
|
||||
|
||||
// var logger = Substitute.For<ContentBuildLogger>();
|
||||
// var importer = new TmxMapImporter();
|
||||
// var importerContext = Substitute.For<ContentImporterContext>();
|
||||
// importerContext.Logger.Returns(logger);
|
||||
public class TiledMapImporterProcessorTests
|
||||
{
|
||||
[Fact]
|
||||
public void TiledMapImporter_Import_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "level01.tmx");
|
||||
|
||||
// var map = importer.Import(filePath, importerContext);
|
||||
var logger = Substitute.For<ContentBuildLogger>();
|
||||
var importer = new TiledMapImporter();
|
||||
var importerContext = Substitute.For<ContentImporterContext>();
|
||||
importerContext.Logger.Returns(logger);
|
||||
|
||||
// Assert.Equal("1.0", map.Version);
|
||||
// Assert.Equal(TmxOrientation.Orthogonal, map.Orientation);
|
||||
// Assert.Equal(TmxRenderOrder.RightDown, map.RenderOrder);
|
||||
// Assert.Equal(20, map.Width);
|
||||
// Assert.Equal(10, map.Height);
|
||||
// Assert.Equal(128, map.TileWidth);
|
||||
// Assert.Equal(128, map.TileHeight);
|
||||
// Assert.Equal("#7d7d7d", map.BackgroundColor);
|
||||
// Assert.Equal("awesome", map.Properties[0].Name);
|
||||
// Assert.Equal("42", map.Properties[0].Value);
|
||||
// Assert.Equal(1, map.Tilesets.Count);
|
||||
// Assert.Equal(3, map.Layers.Count);
|
||||
// Assert.Equal(TmxOrientation.Orthogonal,map.Orientation);
|
||||
var contentItem = importer.Import(filePath, importerContext);
|
||||
var map = contentItem.Data;
|
||||
|
||||
// var tileset = map.Tilesets.First();
|
||||
// Assert.Equal(1, tileset.FirstGlobalIdentifier);
|
||||
// Assert.Equal("free-tileset.png", tileset.Image.Source);
|
||||
// Assert.Equal(652, tileset.Image.Width);
|
||||
// Assert.Equal(783, tileset.Image.Height);
|
||||
// Assert.Equal(2, tileset.Margin);
|
||||
// Assert.Equal(30, tileset.TileCount);
|
||||
// Assert.Equal("free-tileset", tileset.Name);
|
||||
// Assert.Equal(null, tileset.Source);
|
||||
// Assert.Equal(2, tileset.Spacing);
|
||||
// Assert.Equal(0, tileset.TerrainTypes.Count);
|
||||
// Assert.Equal(0, tileset.Properties.Count);
|
||||
// Assert.Equal(128, tileset.TileHeight);
|
||||
// Assert.Equal(128, tileset.TileWidth);
|
||||
// Assert.Equal(0, tileset.TileOffset.X);
|
||||
// Assert.Equal(0, tileset.TileOffset.Y);
|
||||
Assert.Equal("1.0", map.Version);
|
||||
Assert.Equal(TiledMapOrientationContent.Orthogonal, map.Orientation);
|
||||
Assert.Equal(TiledMapTileDrawOrderContent.RightDown, map.RenderOrder);
|
||||
Assert.Equal(20, map.Width);
|
||||
Assert.Equal(10, map.Height);
|
||||
Assert.Equal(128, map.TileWidth);
|
||||
Assert.Equal(128, map.TileHeight);
|
||||
Assert.Equal("#7d7d7d", map.BackgroundColor);
|
||||
Assert.Equal("awesome", map.Properties[0].Name);
|
||||
Assert.Equal("42", map.Properties[0].Value);
|
||||
Assert.Single(map.Tilesets);
|
||||
Assert.Equal(3, map.Layers.Count);
|
||||
Assert.Equal(TiledMapOrientationContent.Orthogonal, map.Orientation);
|
||||
|
||||
// var tileLayer2 = (TmxTileLayer) map.Layers[0];
|
||||
// Assert.Equal("Tile Layer 2", tileLayer2.Name);
|
||||
// Assert.Equal(1, tileLayer2.Opacity);
|
||||
// Assert.Equal(0, tileLayer2.Properties.Count);
|
||||
// Assert.Equal(true, tileLayer2.Visible);
|
||||
// Assert.Equal(200, tileLayer2.Data.Tiles.Count);
|
||||
// Assert.Equal(0, tileLayer2.X);
|
||||
// Assert.Equal(0, tileLayer2.Y);
|
||||
var tileset = map.Tilesets.First();
|
||||
Assert.Equal(1, tileset.FirstGlobalIdentifier);
|
||||
Assert.Equal("free-tileset.png", Path.GetFileName(tileset.Image.Source));
|
||||
Assert.Equal(652, tileset.Image.Width);
|
||||
Assert.Equal(783, tileset.Image.Height);
|
||||
Assert.Equal(2, tileset.Margin);
|
||||
Assert.Equal(30, tileset.TileCount);
|
||||
Assert.Equal("free-tileset", tileset.Name);
|
||||
Assert.Null(tileset.Source);
|
||||
Assert.Equal(2, tileset.Spacing);
|
||||
//Assert.Equal(0, tileset.TerrainTypes.Count);
|
||||
Assert.Empty(tileset.Properties);
|
||||
Assert.Equal(128, tileset.TileHeight);
|
||||
Assert.Equal(128, tileset.TileWidth);
|
||||
Assert.Equal(0, tileset.TileOffset.X);
|
||||
Assert.Equal(0, tileset.TileOffset.Y);
|
||||
|
||||
// var imageLayer = (TmxImageLayer)map.Layers[1];
|
||||
// Assert.Equal("Image Layer 1", imageLayer.Name);
|
||||
// Assert.Equal(1, imageLayer.Opacity);
|
||||
// Assert.Equal(0, imageLayer.Properties.Count);
|
||||
// Assert.Equal(true, imageLayer.Visible);
|
||||
// Assert.Equal("hills.png", imageLayer.Image.Source);
|
||||
// Assert.Equal(100, imageLayer.X);
|
||||
// Assert.Equal(100, imageLayer.Y);
|
||||
var tileLayer2 = (TiledMapTileLayerContent)map.Layers[0];
|
||||
Assert.Equal("Tile Layer 2", tileLayer2.Name);
|
||||
Assert.Equal(1, tileLayer2.Opacity);
|
||||
Assert.Empty(tileLayer2.Properties);
|
||||
Assert.True(tileLayer2.Visible);
|
||||
Assert.Equal(200, tileLayer2.Data.Tiles.Count);
|
||||
Assert.Equal(0, tileLayer2.X);
|
||||
Assert.Equal(0, tileLayer2.Y);
|
||||
|
||||
// var tileLayer1 = (TmxTileLayer)map.Layers[2];
|
||||
// Assert.Equal("Tile Layer 1", tileLayer1.Name);
|
||||
// Assert.Equal(2, tileLayer1.Properties.Count);
|
||||
var imageLayer = (TiledMapImageLayerContent)map.Layers[1];
|
||||
Assert.Equal("Image Layer 1", imageLayer.Name);
|
||||
Assert.Equal(1, imageLayer.Opacity);
|
||||
Assert.Empty(imageLayer.Properties);
|
||||
Assert.True(imageLayer.Visible);
|
||||
Assert.Equal("hills.png", Path.GetFileName(imageLayer.Image.Source));
|
||||
Assert.Equal(100, imageLayer.X);
|
||||
Assert.Equal(100, imageLayer.Y);
|
||||
|
||||
// Assert.Equal("customlayerprop", tileLayer1.Properties[0].Name);
|
||||
// Assert.Equal("1", tileLayer1.Properties[0].Value);
|
||||
var tileLayer1 = (TiledMapTileLayerContent)map.Layers[2];
|
||||
Assert.Equal("Tile Layer 1", tileLayer1.Name);
|
||||
Assert.Equal(2, tileLayer1.Properties.Count);
|
||||
|
||||
// Assert.Equal("customlayerprop2", tileLayer1.Properties[1].Name);
|
||||
// Assert.Equal("2", tileLayer1.Properties[1].Value);
|
||||
// }
|
||||
Assert.Equal("customlayerprop", tileLayer1.Properties[0].Name);
|
||||
Assert.Equal("1", tileLayer1.Properties[0].Value);
|
||||
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_Xml_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-xml.tmx");
|
||||
// var map = ImportAndProcessMap(filePath);
|
||||
// var layer = map.Layers.OfType<TmxTileLayer>().First();
|
||||
// var actualData = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
Assert.Equal("customlayerprop2", tileLayer1.Properties[1].Name);
|
||||
Assert.Equal("2", tileLayer1.Properties[1].Value);
|
||||
}
|
||||
|
||||
// Assert.IsNull(layer.Data.Encoding);
|
||||
// Assert.IsNull(layer.Data.Compression);
|
||||
// Assert.IsTrue(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(actualData));
|
||||
// }
|
||||
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_Csv_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-csv.tmx");
|
||||
// var map = ImportAndProcessMap(filePath);
|
||||
// var layer = map.Layers.OfType<TmxTileLayer>().First();
|
||||
// var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
[Fact]
|
||||
public void TiledMapImporter_Xml_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-xml.tmx");
|
||||
var map = ImportAndProcessMap(filePath);
|
||||
var layer = map.Layers.OfType<TiledMapTileLayerContent>().First();
|
||||
var actualData = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
|
||||
// Assert.Equal("csv", layer.Data.Encoding);
|
||||
// Assert.IsNull(layer.Data.Compression);
|
||||
// Assert.IsTrue(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
// }
|
||||
Assert.Null(layer.Data.Encoding);
|
||||
Assert.Null(layer.Data.Compression);
|
||||
Assert.True(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(actualData));
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_Base64_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-base64.tmx");
|
||||
// var map = ImportAndProcessMap(filePath);
|
||||
// var layer = map.Layers.OfType<TmxTileLayer>().First();
|
||||
// var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
[Fact]
|
||||
public void TiledMapImporter_Csv_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-csv.tmx");
|
||||
var map = ImportAndProcessMap(filePath);
|
||||
var layer = map.Layers.OfType<TiledMapTileLayerContent>().First();
|
||||
var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
|
||||
// Assert.Equal("base64", layer.Data.Encoding);
|
||||
// Assert.IsNull(layer.Data.Compression);
|
||||
// Assert.IsTrue(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
// }
|
||||
Assert.Equal("csv", layer.Data.Encoding);
|
||||
Assert.Null(layer.Data.Compression);
|
||||
//Assert.True(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_Gzip_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-gzip.tmx");
|
||||
// var map = ImportAndProcessMap(filePath);
|
||||
// var layer = map.Layers.OfType<TmxTileLayer>().First();
|
||||
// var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
[Fact]
|
||||
public void TiledMapImporter_Base64_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-base64.tmx");
|
||||
var map = ImportAndProcessMap(filePath);
|
||||
var layer = map.Layers.OfType<TiledMapTileLayerContent>().First();
|
||||
var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
|
||||
// Assert.Equal("base64", layer.Data.Encoding);
|
||||
// Assert.Equal("gzip", layer.Data.Compression);
|
||||
// Assert.IsTrue(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
// }
|
||||
Assert.Equal("base64", layer.Data.Encoding);
|
||||
Assert.Null(layer.Data.Compression);
|
||||
//Assert.True(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TiledMapImporter_Gzip_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-gzip.tmx");
|
||||
var map = ImportAndProcessMap(filePath);
|
||||
var layer = map.Layers.OfType<TiledMapTileLayerContent>().First();
|
||||
var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
|
||||
Assert.Equal("base64", layer.Data.Encoding);
|
||||
Assert.Equal("gzip", layer.Data.Compression);
|
||||
//Assert.True(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
}
|
||||
|
||||
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_Zlib_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-zlib.tmx");
|
||||
// var map = ImportAndProcessMap(filePath);
|
||||
// var layer = map.Layers.OfType<TmxTileLayer>().First();
|
||||
// var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
[Fact]
|
||||
public void TiledMapImporter_Zlib_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-tileset-zlib.tmx");
|
||||
var map = ImportAndProcessMap(filePath);
|
||||
var layer = map.Layers.OfType<TiledMapTileLayerContent>().First();
|
||||
var data = layer.Data.Tiles.Select(i => i.GlobalIdentifier).ToArray();
|
||||
|
||||
// Assert.Equal("base64", layer.Data.Encoding);
|
||||
// Assert.Equal("zlib", layer.Data.Compression);
|
||||
// Assert.IsTrue(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
// }
|
||||
Assert.Equal("base64", layer.Data.Encoding);
|
||||
Assert.Equal("zlib", layer.Data.Compression);
|
||||
//Assert.True(new uint[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.SequenceEqual(data));
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
// public void TiledMapImporter_ObjectLayer_Test()
|
||||
// {
|
||||
// var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-object-layer.tmx");
|
||||
// var map = ImportAndProcessMap(filePath);
|
||||
[Fact]
|
||||
public void TiledMapImporter_ObjectLayer_Test()
|
||||
{
|
||||
var filePath = PathExtensions.GetApplicationFullPath("TestData", "test-object-layer.tmx");
|
||||
var map = ImportAndProcessMap(filePath);
|
||||
|
||||
// Assert.Equal(1, map.Layers.Count);
|
||||
// Assert.IsInstanceOf<TmxObjectLayer>(map.Layers[0]);
|
||||
// var tmxObjectGroup = map.Layers[0] as TmxObjectLayer;
|
||||
// var tmxObject = tmxObjectGroup.Objects[0];
|
||||
// var tmxPolygon = tmxObjectGroup.Objects[3].Polygon;
|
||||
// var tmxPolyline = tmxObjectGroup.Objects[4].Polyline;
|
||||
Assert.Single(map.Layers);
|
||||
Assert.IsType<TiledMapObjectLayerContent>(map.Layers[0]);
|
||||
var tmxObjectGroup = map.Layers[0] as TiledMapObjectLayerContent;
|
||||
var tmxObject = tmxObjectGroup.Objects[0];
|
||||
var tmxPolygon = tmxObjectGroup.Objects[3].Polygon;
|
||||
var tmxPolyline = tmxObjectGroup.Objects[4].Polyline;
|
||||
|
||||
// Assert.Equal("Object Layer 1", tmxObjectGroup.Name);
|
||||
// Assert.Equal(1, tmxObject.Identifier);
|
||||
// Assert.Equal(131.345f, tmxObject.X);
|
||||
// Assert.Equal(65.234f, tmxObject.Y);
|
||||
// Assert.Equal(311.111f, tmxObject.Width);
|
||||
// Assert.Equal(311.232f, tmxObject.Height);
|
||||
// Assert.Equal(1, tmxObject.Properties.Count);
|
||||
// Assert.Equal("shape", tmxObject.Properties[0].Name);
|
||||
// Assert.Equal("circle", tmxObject.Properties[0].Value);
|
||||
// Assert.NotNull(tmxObject.Ellipse);
|
||||
// Assert.IsFalse(tmxObjectGroup.Objects[1].Visible);
|
||||
// Assert.Equal(-1, tmxObjectGroup.Objects[1].GlobalIdentifier);
|
||||
// Assert.Equal(23, tmxObjectGroup.Objects[5].GlobalIdentifier);
|
||||
// Assert.Equal("rectangle", tmxObjectGroup.Objects[2].Type);
|
||||
// Assert.NotNull(tmxPolygon);
|
||||
// Assert.Equal("0,0 180,90 -8,275 -45,81 38,77", tmxPolygon.Points);
|
||||
// Assert.NotNull(tmxPolyline);
|
||||
// Assert.Equal("0,0 28,299 326,413 461,308", tmxPolyline.Points);
|
||||
// }
|
||||
Assert.Equal("Object Layer 1", tmxObjectGroup.Name);
|
||||
Assert.Equal(1, tmxObject.Identifier);
|
||||
Assert.Equal(131.345f, tmxObject.X);
|
||||
Assert.Equal(65.234f, tmxObject.Y);
|
||||
Assert.Equal(311.111f, tmxObject.Width);
|
||||
Assert.Equal(311.232f, tmxObject.Height);
|
||||
Assert.Single(tmxObject.Properties);
|
||||
Assert.Equal("shape", tmxObject.Properties[0].Name);
|
||||
Assert.Equal("circle", tmxObject.Properties[0].Value);
|
||||
Assert.NotNull(tmxObject.Ellipse);
|
||||
Assert.False(tmxObjectGroup.Objects[1].Visible);
|
||||
Assert.Equal((uint)0, tmxObjectGroup.Objects[1].GlobalIdentifier);
|
||||
Assert.Equal((uint)23, tmxObjectGroup.Objects[5].GlobalIdentifier);
|
||||
Assert.Equal("rectangle", tmxObjectGroup.Objects[2].Type);
|
||||
Assert.NotNull(tmxPolygon);
|
||||
Assert.Equal("0,0 180,90 -8,275 -45,81 38,77", tmxPolygon.Points);
|
||||
Assert.NotNull(tmxPolyline);
|
||||
Assert.Equal("0,0 28,299 326,413 461,308", tmxPolyline.Points);
|
||||
}
|
||||
|
||||
|
||||
// private static TmxMap ImportAndProcessMap(string filename)
|
||||
// {
|
||||
// var logger = Substitute.For<ContentBuildLogger>();
|
||||
// var importer = new TmxMapImporter();
|
||||
// var importerContext = Substitute.For<ContentImporterContext>();
|
||||
// importerContext.Logger.Returns(logger);
|
||||
private static TiledMapContent ImportAndProcessMap(string filename)
|
||||
{
|
||||
var logger = Substitute.For<ContentBuildLogger>();
|
||||
var importer = new TiledMapImporter();
|
||||
var importerContext = Substitute.For<ContentImporterContext>();
|
||||
importerContext.Logger.Returns(logger);
|
||||
|
||||
// var processor = new TmxMapProcessor();
|
||||
// var processorContext = Substitute.For<ContentProcessorContext>();
|
||||
// processorContext.Logger.Returns(logger);
|
||||
var processor = new TiledMapProcessor();
|
||||
var processorContext = Substitute.For<ContentProcessorContext>();
|
||||
processorContext.Logger.Returns(logger);
|
||||
|
||||
// var import = importer.Import(filename, importerContext);
|
||||
// var result = processor.Process(import, processorContext);
|
||||
var import = importer.Import(filename, importerContext);
|
||||
var result = processor.Process(import, processorContext);
|
||||
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
return result.Data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using Xunit;
|
||||
|
||||
namespace MonoGame.Extended.Tiled.Tests
|
||||
{
|
||||
public class LoadContentTests
|
||||
{
|
||||
[Fact]
|
||||
public void CanLoadContent()
|
||||
{
|
||||
Assert.True(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user