-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Created layout preset library dialog (#375)
- Loading branch information
Showing
29 changed files
with
895 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace AnnoDesigner.Core.Layout.Presets | ||
{ | ||
public interface IPresetLayout | ||
{ | ||
public MultilangInfo Name { get; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace AnnoDesigner.Core.Layout.Presets | ||
{ | ||
public class LayoutPresetInfo | ||
{ | ||
public MultilangInfo Name { get; set; } | ||
|
||
public MultilangInfo Description { get; set; } | ||
|
||
public string Author { get; set; } | ||
|
||
public string AuthorContact { get; set; } | ||
|
||
public LayoutPresetInfo() { } | ||
|
||
public LayoutPresetInfo(string name) | ||
{ | ||
Name = name; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Newtonsoft.Json; | ||
|
||
namespace AnnoDesigner.Core.Layout.Presets | ||
{ | ||
[JsonConverter(typeof(MultilangInfoConverter))] | ||
public class MultilangInfo | ||
{ | ||
private class MultilangInfoConverter : JsonConverter<MultilangInfo> | ||
{ | ||
public override MultilangInfo ReadJson(JsonReader reader, Type objectType, MultilangInfo existingValue, bool hasExistingValue, JsonSerializer serializer) | ||
{ | ||
switch (reader.TokenType) | ||
{ | ||
case JsonToken.String: | ||
return reader.Value as string; | ||
case JsonToken.StartObject: | ||
return serializer.Deserialize<Dictionary<string, string>>(reader); | ||
default: | ||
throw new JsonSerializationException($"Unexpected token during deserialization of {nameof(MultilangInfo)}"); | ||
} | ||
} | ||
|
||
public override void WriteJson(JsonWriter writer, MultilangInfo value, JsonSerializer serializer) | ||
{ | ||
serializer.Serialize(writer, (object)value.Default ?? value.Translations); | ||
} | ||
} | ||
|
||
private Dictionary<string, string> Translations { get; set; } | ||
|
||
private string Default { get; set; } | ||
|
||
public string this[string language] | ||
{ | ||
set | ||
{ | ||
Translations ??= new Dictionary<string, string>(); | ||
Translations[language] = value; | ||
} | ||
} | ||
|
||
public string Translate(string language) | ||
{ | ||
return Default ?? ( | ||
Translations.TryGetValue(language, out var translation) | ||
? translation | ||
: Translations.Count > 0 | ||
? $"{Translations.FirstOrDefault().Value} ({Translations.FirstOrDefault().Key})" | ||
: string.Empty | ||
); | ||
} | ||
|
||
public static implicit operator MultilangInfo(string value) | ||
{ | ||
return new MultilangInfo() | ||
{ | ||
Default = value | ||
}; | ||
} | ||
|
||
public static implicit operator MultilangInfo(Dictionary<string, string> value) | ||
{ | ||
return new MultilangInfo() | ||
{ | ||
Translations = value | ||
}; | ||
} | ||
|
||
public static explicit operator string(MultilangInfo info) | ||
{ | ||
var first = info.Translations.FirstOrDefault(); | ||
return info.Default ?? (info.Translations.Count > 0 ? $"{first.Value} ({first.Key})" : string.Empty); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System.Collections.Generic; | ||
using System.Windows.Media; | ||
using AnnoDesigner.Core.Layout.Models; | ||
|
||
namespace AnnoDesigner.Core.Layout.Presets | ||
{ | ||
public class PresetLayout : IPresetLayout | ||
{ | ||
public MultilangInfo Name => Info.Name; | ||
|
||
public LayoutPresetInfo Info { get; set; } | ||
|
||
public string Author { get; set; } | ||
|
||
public string AuthorContact { get; set; } | ||
|
||
public LayoutFile Layout { get; set; } | ||
|
||
public List<ImageSource> Images { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace AnnoDesigner.Core.Layout.Presets | ||
{ | ||
public class PresetLayoutDirectory : IPresetLayout | ||
{ | ||
public MultilangInfo Name { get; set; } | ||
|
||
public List<IPresetLayout> Presets { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.IO.Abstractions; | ||
using System.IO.Compression; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using System.Windows.Media; | ||
using System.Windows.Media.Imaging; | ||
using AnnoDesigner.Core.Layout.Models; | ||
using Newtonsoft.Json; | ||
using NLog; | ||
|
||
namespace AnnoDesigner.Core.Layout.Presets | ||
{ | ||
public class PresetLayoutLoader | ||
{ | ||
private readonly IFileSystem _fileSystem; | ||
private static readonly Logger Logger = LogManager.GetLogger(nameof(PresetLayoutLoader)); | ||
|
||
public Func<LayoutFile, ImageSource> RenderLayoutToImage { get; set; } | ||
public PresetLayoutLoader(Func<LayoutFile, ImageSource> renderLayoutToImage, IFileSystem fileSystem = null) | ||
{ | ||
RenderLayoutToImage = renderLayoutToImage; | ||
_fileSystem = fileSystem ?? new FileSystem(); | ||
} | ||
|
||
public async Task<List<IPresetLayout>> LoadAsync(string rootDirectory) | ||
{ | ||
var data = await LoadDirectoryAsync(rootDirectory); | ||
|
||
return data.Presets; | ||
} | ||
|
||
private async Task<PresetLayoutDirectory> LoadDirectoryAsync(string directory) | ||
{ | ||
var subdirectories = await Task.WhenAll(_fileSystem.Directory.GetDirectories(directory).Select(LoadDirectoryAsync)); | ||
var layouts = await Task.WhenAll(_fileSystem.Directory.GetFiles(directory, "*.zip").Select(LoadLayout)); | ||
return new PresetLayoutDirectory() | ||
{ | ||
Name = _fileSystem.Path.GetFileName(directory), | ||
Presets = subdirectories.Cast<IPresetLayout>().Concat(layouts.Where(f => f != null)).ToList() | ||
}; | ||
} | ||
|
||
private async Task<PresetLayout> LoadLayout(string file) | ||
{ | ||
try | ||
{ | ||
using var zipFile = ZipFile.OpenRead(file); | ||
using var layoutFile = zipFile.GetEntry("layout.ad").Open(); | ||
using var infoFile = zipFile.GetEntry("info.json")?.Open() ?? Stream.Null; | ||
using var infoStream = new StreamReader(infoFile); | ||
|
||
var layout = await new LayoutLoader().LoadLayoutAsync(layoutFile, true); | ||
if (layout != null) | ||
{ | ||
var info = JsonConvert.DeserializeObject<LayoutPresetInfo>(await infoStream.ReadToEndAsync()) ?? new LayoutPresetInfo(_fileSystem.Path.GetFileNameWithoutExtension(file)); | ||
var images = new List<ImageSource>() | ||
{ | ||
RenderLayoutToImage(layout) | ||
}; | ||
|
||
foreach (var item in zipFile.Entries) | ||
{ | ||
using var stream = item.Open(); | ||
switch (_fileSystem.Path.GetExtension(item.FullName).ToLowerInvariant()) | ||
{ | ||
case ".png": | ||
case ".jpg": | ||
case ".jpeg": | ||
await Task.Yield(); | ||
|
||
var imageStream = new MemoryStream(); | ||
stream.CopyTo(imageStream); | ||
var image = new BitmapImage(); | ||
image.BeginInit(); | ||
image.StreamSource = imageStream; | ||
image.EndInit(); | ||
image.Freeze(); | ||
images.Add(image); | ||
break; | ||
} | ||
} | ||
|
||
return new PresetLayout() | ||
{ | ||
Info = info, | ||
Layout = layout, | ||
Images = images | ||
}; | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Warn(e, $"Failed to parse loadout preset {file}"); | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System; | ||
using System.Globalization; | ||
using System.Windows.Data; | ||
|
||
namespace AnnoDesigner.Converters | ||
{ | ||
[ValueConversion(typeof(object), typeof(object))] | ||
public class ReferenceToValueConverter : IValueConverter | ||
{ | ||
public object NullValue { get; set; } | ||
|
||
public object NotNullValue { get; set; } | ||
|
||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
return value == null ? NullValue : NotNullValue; | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Window x:Class="AnnoDesigner.ImageWindow" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
mc:Ignorable="d" | ||
Title="ImageWindow" Height="600" Width="800"> | ||
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> | ||
<Canvas Width="{Binding ActualWidth, ElementName=image}" Height="{Binding ActualHeight, ElementName=image}"> | ||
<Canvas.Background> | ||
<VisualBrush> | ||
<VisualBrush.Visual> | ||
<Image Source="{Binding .}" x:Name="image"/> | ||
</VisualBrush.Visual> | ||
</VisualBrush> | ||
</Canvas.Background> | ||
</Canvas> | ||
</ScrollViewer> | ||
</Window> |
Oops, something went wrong.