diff --git a/src/Myra/Graphics2D/TextureAtlases/TextureRegionAtlas.cs b/src/Myra/Graphics2D/TextureAtlases/TextureRegionAtlas.cs
index 6c966bf9..2729e86d 100644
--- a/src/Myra/Graphics2D/TextureAtlases/TextureRegionAtlas.cs
+++ b/src/Myra/Graphics2D/TextureAtlases/TextureRegionAtlas.cs
@@ -103,18 +103,7 @@ public string ToXml()
///
public static TextureRegionAtlas Load(string data, Func textureGetter)
{
- bool isXml;
- try
- {
- var xDoc = XDocument.Parse(data);
- isXml = true;
- }
- catch (Exception)
- {
- isXml = false;
- }
-
- if (isXml)
+ if (data.StartsWith("<") && data.EndsWith(">"))
{
return FromXml(data, textureGetter);
}
diff --git a/src/Myra/Graphics2D/UI/ComboBox.cs b/src/Myra/Graphics2D/UI/ComboBox.cs
index c1b5be38..55a091f0 100644
--- a/src/Myra/Graphics2D/UI/ComboBox.cs
+++ b/src/Myra/Graphics2D/UI/ComboBox.cs
@@ -196,7 +196,10 @@ internal void UpdateSelectedItem()
{
InternalChild.Text = item.Text;
InternalChild.TextColor = item.Color ?? _listBox.ListBoxStyle.ListItemStyle.LabelStyle.TextColor;
- ((ImageTextButton)item.Widget).IsPressed = true;
+ if (item.Widget != null)
+ {
+ ((ImageTextButton)item.Widget).IsPressed = true;
+ }
}
else
{
diff --git a/src/Myra/Graphics2D/UI/ImageTextButton.cs b/src/Myra/Graphics2D/UI/ImageTextButton.cs
index a0cf5f72..90213dba 100644
--- a/src/Myra/Graphics2D/UI/ImageTextButton.cs
+++ b/src/Myra/Graphics2D/UI/ImageTextButton.cs
@@ -29,6 +29,21 @@ public enum TextPositionEnum
private readonly Label _label;
private TextPositionEnum _textPosition;
+
+ private string _l18nText;
+ public string L18nTextKey
+ {
+ get
+ {
+ return _l18nText;
+ }
+ set
+ {
+ _l18nText = value;
+ Text = Project.Localize?.Invoke(value) ?? value;
+ }
+ }
+
[Category("Appearance")]
[DefaultValue(null)]
public string Text
diff --git a/src/Myra/Graphics2D/UI/Label.cs b/src/Myra/Graphics2D/UI/Label.cs
index b8361228..ef736257 100644
--- a/src/Myra/Graphics2D/UI/Label.cs
+++ b/src/Myra/Graphics2D/UI/Label.cs
@@ -44,6 +44,20 @@ public int VerticalSpacing
}
}
+ private string _l18nText;
+ public string L18nTextKey
+ {
+ get
+ {
+ return _l18nText;
+ }
+ set
+ {
+ _l18nText = value;
+ Text = Project.Localize?.Invoke(value) ?? value;
+ }
+ }
+
[Category("Appearance")]
[DefaultValue(null)]
public string Text
diff --git a/src/Myra/Graphics2D/UI/Project.cs b/src/Myra/Graphics2D/UI/Project.cs
index e2161ab1..971a77e3 100644
--- a/src/Myra/Graphics2D/UI/Project.cs
+++ b/src/Myra/Graphics2D/UI/Project.cs
@@ -18,391 +18,425 @@
namespace Myra.Graphics2D.UI
{
- public class ExportOptions
- {
- public string Namespace { get; set; }
- public string Class { get; set; }
- public string OutputPath { get; set; }
- public string TemplateDesigner { get; set; }
- public string TemplateMain { get; set; }
- }
-
- public class Project
- {
- public const string ProportionName = "Proportion";
- public const string DefaultProportionName = "DefaultProportion";
- public const string DefaultColumnProportionName = "DefaultColumnProportion";
- public const string DefaultRowProportionName = "DefaultRowProportion";
+ public class ExportOptions
+ {
+ public string Namespace { get; set; }
+ public string Class { get; set; }
+ public string OutputPath { get; set; }
+ public string TemplateDesigner { get; set; }
+ public string TemplateMain { get; set; }
+ }
+
+ public class Project
+ {
+ public const string ProportionName = "Proportion";
+ public const string DefaultProportionName = "DefaultProportion";
+ public const string DefaultColumnProportionName = "DefaultColumnProportion";
+ public const string DefaultRowProportionName = "DefaultRowProportion";
+
+ public static Func Localize = null;
private static readonly Dictionary LegacyClassNames = new Dictionary();
- private readonly ExportOptions _exportOptions = new ExportOptions();
-
- [Browsable(false)]
- public ExportOptions ExportOptions
- {
- get { return _exportOptions; }
- }
-
- [Browsable(false)]
- [Content]
- public Widget Root { get; set; }
-
- [Browsable(false)]
- public string StylesheetPath
- {
- get; set;
- }
-
- [Browsable(false)]
- [XmlIgnore]
- public Stylesheet Stylesheet { get; set; }
-
- static Project()
- {
- LegacyClassNames["Button"] = "ImageTextButton";
- LegacyClassNames["VerticalBox"] = "VerticalStackPanel";
- LegacyClassNames["HorizontalBox"] = "HorizontalStackPanel";
- LegacyClassNames["TextField"] = "TextBox";
- LegacyClassNames["TextBlock"] = "Label";
- LegacyClassNames["ScrollPane"] = "ScrollViewer";
- }
-
- public Project()
+ private readonly ExportOptions _exportOptions = new ExportOptions();
+ private readonly List _diagnostics = new List();
+
+ [Browsable(false)]
+ public ExportOptions ExportOptions
+ {
+ get { return _exportOptions; }
+ }
+
+ [Browsable(false)]
+ [Content]
+ public Widget Root { get; set; }
+
+ [Browsable(false)]
+ public string StylesheetPath
+ {
+ get; set;
+ }
+
+ [Browsable(false)]
+ [XmlIgnore]
+ public Stylesheet Stylesheet { get; set; }
+
+ [Browsable(false)]
+ [XmlIgnore]
+ public List Diagnostics
+ {
+ get { return _diagnostics; }
+ }
+
+ static Project()
+ {
+ LegacyClassNames["Button"] = "ImageTextButton";
+ LegacyClassNames["VerticalBox"] = "VerticalStackPanel";
+ LegacyClassNames["HorizontalBox"] = "HorizontalStackPanel";
+ LegacyClassNames["TextField"] = "TextBox";
+ LegacyClassNames["TextBlock"] = "Label";
+ LegacyClassNames["ScrollPane"] = "ScrollViewer";
+ }
+
+ public Project()
+ {
+ Stylesheet = Stylesheet.Current;
+ _diagnostics = new List();
+ }
+
+ public static bool IsProportionName(string s)
+ {
+ return s.EndsWith(ProportionName) ||
+ s.EndsWith(DefaultProportionName) ||
+ s.EndsWith(DefaultColumnProportionName) ||
+ s.EndsWith(DefaultRowProportionName);
+ }
+
+ public static bool ShouldSerializeProperty(Stylesheet stylesheet, object o, PropertyInfo p)
+ {
+ var asWidget = o as Widget;
+ if (asWidget != null && asWidget.Parent != null && asWidget.Parent is Grid)
+ {
+ var container = asWidget.Parent.Parent;
+ if (container != null &&
+ (container is StackPanel || container is SplitPane) &&
+ (p.Name == "GridRow" || p.Name == "GridColumn"))
+ {
+ // Skip serializing auto-assigned GridRow/GridColumn for SplitPane and Box containers
+ return false;
+ }
+ }
+
+ var asGrid = o as Grid;
+ if (asGrid != null)
+ {
+ var value = p.GetValue(o);
+ if ((p.Name == DefaultColumnProportionName || p.Name == DefaultRowProportionName) &&
+ value == Proportion.GridDefault)
+ {
+ return false;
+ }
+ }
+
+ var asBox = o as StackPanel;
+ if (asBox != null)
+ {
+ var value = p.GetValue(o);
+ if (p.Name == DefaultProportionName && value == Proportion.StackPanelDefault)
+ {
+ return false;
+ }
+ }
+
+ if (SaveContext.HasDefaultValue(o, p))
+ {
+ return false;
+ }
+
+ if (asWidget != null && HasStylesheetValue(asWidget, p, stylesheet))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool ShouldSerializeProperty(object o, PropertyInfo p)
+ {
+ return ShouldSerializeProperty(Stylesheet, o, p);
+ }
+
+ internal static SaveContext CreateSaveContext(Stylesheet stylesheet)
+ {
+ return new SaveContext
+ {
+ ShouldSerializeProperty = (o, p) => ShouldSerializeProperty(stylesheet, o, p)
+ };
+ }
+
+ internal SaveContext CreateSaveContext()
+ {
+ return CreateSaveContext(Stylesheet);
+ }
+
+ internal static LoadContext CreateLoadContext(IAssetManager assetManager, Stylesheet stylesheet)
+ {
+ Func resourceGetter = (t, name) =>
+ {
+ if (t == typeof(IBrush))
+ {
+ return new SolidBrush(name);
+ }
+ else if (t == typeof(IImage))
+ {
+ return assetManager.Load(name);
+ }
+ else if (t == typeof(SpriteFontBase))
+ {
+ return assetManager.Load(name);
+ }
+
+ throw new Exception(string.Format("Type {0} isn't supported", t.Name));
+ };
+
+ return new LoadContext
+ {
+ Namespaces = new[]
+ {
+ typeof(Widget).Namespace,
+ typeof(PropertyGrid).Namespace,
+ },
+ LegacyClassNames = LegacyClassNames,
+ ObjectCreator = (t, el) => CreateItem(t, el, stylesheet),
+ ResourceGetter = resourceGetter
+ };
+ }
+
+ internal LoadContext CreateLoadContext(IAssetManager assetManager)
+ {
+ return CreateLoadContext(assetManager, Stylesheet);
+ }
+
+ public string Save()
+ {
+ var saveContext = CreateSaveContext();
+ var root = saveContext.Save(this);
+
+ var xDoc = new XDocument(root);
+
+ return xDoc.ToString();
+ }
+
+ public static Project LoadFromXml(XDocument xDoc, IAssetManager assetManager, Stylesheet stylesheet, T handler) where T : class
{
- Stylesheet = Stylesheet.Current;
- }
-
- public static bool IsProportionName(string s)
- {
- return s.EndsWith(ProportionName) ||
- s.EndsWith(DefaultProportionName) ||
- s.EndsWith(DefaultColumnProportionName) ||
- s.EndsWith(DefaultRowProportionName);
- }
-
- public static bool ShouldSerializeProperty(Stylesheet stylesheet, object o, PropertyInfo p)
- {
- var asWidget = o as Widget;
- if (asWidget != null && asWidget.Parent != null && asWidget.Parent is Grid)
- {
- var container = asWidget.Parent.Parent;
- if (container != null &&
- (container is StackPanel || container is SplitPane) &&
- (p.Name == "GridRow" || p.Name == "GridColumn"))
- {
- // Skip serializing auto-assigned GridRow/GridColumn for SplitPane and Box containers
- return false;
- }
- }
-
- var asGrid = o as Grid;
- if (asGrid != null)
- {
- var value = p.GetValue(o);
- if ((p.Name == DefaultColumnProportionName || p.Name == DefaultRowProportionName) &&
- value == Proportion.GridDefault)
- {
- return false;
- }
- }
-
- var asBox = o as StackPanel;
- if (asBox != null)
- {
- var value = p.GetValue(o);
- if (p.Name == DefaultProportionName && value == Proportion.StackPanelDefault)
- {
- return false;
- }
- }
-
- if (SaveContext.HasDefaultValue(o, p))
- {
- return false;
- }
-
- if(asWidget != null && HasStylesheetValue(asWidget, p, stylesheet))
- {
- return false;
- }
-
- return true;
- }
-
- public bool ShouldSerializeProperty(object o, PropertyInfo p)
- {
- return ShouldSerializeProperty(Stylesheet, o, p);
- }
-
- internal static SaveContext CreateSaveContext(Stylesheet stylesheet)
- {
- return new SaveContext
+ var result = new Project
{
- ShouldSerializeProperty = (o, p) => ShouldSerializeProperty(stylesheet, o, p)
+ Stylesheet = stylesheet
};
- }
- internal SaveContext CreateSaveContext()
- {
- return CreateSaveContext(Stylesheet);
- }
+ var loadContext = result.CreateLoadContext(assetManager);
- internal static LoadContext CreateLoadContext(IAssetManager assetManager, Stylesheet stylesheet)
- {
- Func resourceGetter = (t, name) =>
- {
- if (t == typeof(IBrush))
- {
- return new SolidBrush(name);
- }
- else if (t == typeof(IImage))
- {
- return assetManager.Load(name);
- }
- else if (t == typeof(SpriteFontBase))
- {
- return assetManager.Load(name);
- }
-
- throw new Exception(string.Format("Type {0} isn't supported", t.Name));
- };
+ loadContext.Load(result, xDoc.Root, (d) => result.Diagnostics.Add(d), handler);
- return new LoadContext
- {
- Namespaces = new[]
- {
- typeof(Widget).Namespace,
- typeof(PropertyGrid).Namespace,
- },
- LegacyClassNames = LegacyClassNames,
- ObjectCreator = (t, el) => CreateItem(t, el, stylesheet),
- ResourceGetter = resourceGetter
- };
- }
+ return result;
+ }
- internal LoadContext CreateLoadContext(IAssetManager assetManager)
+ public static Project LoadFromXml(string data, IAssetManager assetManager, Stylesheet stylesheet, T handler) where T : class
{
- return CreateLoadContext(assetManager, Stylesheet);
+ return LoadFromXml(XDocument.Parse(data), assetManager, stylesheet, handler);
}
- public string Save()
+ public static Project LoadFromXml(string data, T handler) where T : class
{
- var saveContext = CreateSaveContext();
- var root = saveContext.Save(this);
-
- var xDoc = new XDocument(root);
-
- return xDoc.ToString();
+ return LoadFromXml(data, null, Stylesheet.Current, handler);
}
public static Project LoadFromXml(XDocument xDoc, IAssetManager assetManager, Stylesheet stylesheet)
{
- var result = new Project
- {
- Stylesheet = stylesheet
- };
-
- var loadContext = result.CreateLoadContext(assetManager);
- loadContext.Load(result, xDoc.Root);
-
- return result;
+ return LoadFromXml