diff --git a/ChatAAC/ChatAAC.csproj b/ChatAAC/ChatAAC.csproj index 4d9f633..d63810a 100644 --- a/ChatAAC/ChatAAC.csproj +++ b/ChatAAC/ChatAAC.csproj @@ -20,10 +20,14 @@ + + + + @@ -32,6 +36,7 @@ + diff --git a/ChatAAC/Converters/BooleanToClassConverter.cs b/ChatAAC/Converters/BooleanToClassConverter.cs new file mode 100644 index 0000000..5694cf0 --- /dev/null +++ b/ChatAAC/Converters/BooleanToClassConverter.cs @@ -0,0 +1,20 @@ +// BooleanToClassConverter.cs +using Avalonia.Data.Converters; +using System; +using System.Globalization; + +namespace ChatAAC.Converters +{ + public class BooleanToClassConverter : IValueConverter + { + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return value != null ? "symbol action" : "symbol"; + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/ChatAAC/Converters/ColorConverter.cs b/ChatAAC/Converters/ColorConverter.cs new file mode 100644 index 0000000..de8ca3c --- /dev/null +++ b/ChatAAC/Converters/ColorConverter.cs @@ -0,0 +1,24 @@ +using System; +using System.Globalization; +using System.Linq; +using Avalonia.Data.Converters; +using Avalonia.Media; + +namespace ChatAAC.Converters; + +public class ColorConverter : IValueConverter +{ + public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is not string colorString) return Colors.Transparent; + var rgb = colorString.Split(['(', ',', ')'], StringSplitOptions.RemoveEmptyEntries) + .Skip(1) // Skip "rgb" + .Select(int.Parse).ToList(); + return Color.FromArgb(255, (byte)rgb[0], (byte)rgb[1], (byte)rgb[2]); + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/ChatAAC/Converters/StringToBitmapConverter.cs b/ChatAAC/Converters/StringToBitmapConverter.cs index 4cc1e40..2e08ac7 100644 --- a/ChatAAC/Converters/StringToBitmapConverter.cs +++ b/ChatAAC/Converters/StringToBitmapConverter.cs @@ -1,26 +1,60 @@ +using Avalonia; using Avalonia.Data.Converters; using Avalonia.Media.Imaging; using System; using System.Globalization; using System.IO; +using SkiaSharp; +using Svg.Skia; namespace ChatAAC.Converters; public class StringToBitmapConverter : IValueConverter { - public static StringToBitmapConverter Instance = new StringToBitmapConverter(); - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is not string path || !File.Exists(path)) return null; try { - return new Bitmap(path); + // Zakładając, że ścieżka wskazuje na plik SVG + if (!path.EndsWith(".svg", StringComparison.OrdinalIgnoreCase)) return new Bitmap(path); + using var stream = File.OpenRead(path); + + using var svg = new SKSvg(); + svg.Load(stream); + + if (svg.Picture == null) return null; + + // Ustawienie docelowego rozmiaru obrazu + const int targetWidth = 250; + const int targetHeight = 250; + + // Obliczanie skali, aby zachować proporcje obrazu + float scaleX = targetWidth / svg.Picture.CullRect.Width; + float scaleY = targetHeight / svg.Picture.CullRect.Height; + float scale = Math.Min(scaleX, scaleY); + + // Tworzenie i skalowanie bitmapy + var scaledSize = new SKImageInfo(targetWidth, targetHeight); + using var bitmap = new SKBitmap(scaledSize); + using var canvas = new SKCanvas(bitmap); + canvas.Clear(SKColors.Transparent); + + var matrix = SKMatrix.CreateScale(scale, scale); + canvas.DrawPicture(svg.Picture, ref matrix); + canvas.Flush(); + + // Konwersja SKBitmap na Bitmapę Avalonii + using var image = SKImage.FromBitmap(bitmap); + using var data = image.Encode(SKEncodedImageFormat.Png, 100); + using var ms = new MemoryStream(); + data.SaveTo(ms); + ms.Seek(0, SeekOrigin.Begin); + return new Bitmap(ms); } catch (Exception ex) { - Console.WriteLine($"Błąd podczas tworzenia Bitmap z {path}: {ex.Message}"); - // Możesz zwrócić domyślny obraz lub null + Console.WriteLine($"Błąd podczas tworzenia Bitmap z SVG: {ex.Message}"); return null; } } diff --git a/ChatAAC/Helpers/ButtonStyleHelper.cs b/ChatAAC/Helpers/ButtonStyleHelper.cs new file mode 100644 index 0000000..6f2c9f0 --- /dev/null +++ b/ChatAAC/Helpers/ButtonStyleHelper.cs @@ -0,0 +1,59 @@ +using Avalonia; +using Avalonia.Controls; +using System; + +namespace ChatAAC.Helpers +{ + public static class ButtonStyleHelper + { + public static readonly AttachedProperty ActionProperty = + AvaloniaProperty.RegisterAttached("LoadBoard", typeof(ButtonStyleHelper)); + + public static object GetAction(Button button) + { + return button.GetValue(ActionProperty); + } + + public static void SetAction(Button button, object? value) + { + button.SetValue(ActionProperty!, value); + UpdateButtonClasses(button, value); + } + + private static void UpdateButtonClasses(Button button, object? actionValue) + { + if (actionValue is not null) + { + button.Classes.Add("action"); + } + else + { + button.Classes.Remove("action"); + } + + if (!button.Classes.Contains("symbol")) + { + button.Classes.Add("symbol"); + } + } + + static ButtonStyleHelper() + { + ActionProperty.Changed.Subscribe(new AnonymousObserver>( + e => + { + if (e.Sender is Button button) + { + UpdateButtonClasses(button, e.NewValue.Value); + } + })); + } + } + + internal class AnonymousObserver(Action onNext) : IObserver + { + public void OnCompleted() { } + public void OnError(Exception error) { } + public void OnNext(T value) => onNext(value); + } +} \ No newline at end of file diff --git a/ChatAAC/Models/Obf/Button.cs b/ChatAAC/Models/Obf/Button.cs index c309b21..a68447d 100644 --- a/ChatAAC/Models/Obf/Button.cs +++ b/ChatAAC/Models/Obf/Button.cs @@ -5,7 +5,7 @@ namespace ChatAAC.Models.Obf; // Class for Button public class Button { - [JsonPropertyName("id")] public string Id { get; set; } = string.Empty; + [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("label")] public string Label { get; set; } = string.Empty; @@ -17,7 +17,36 @@ public class Button [JsonPropertyName("vocalization")] public string Vocalization { get; set; } = string.Empty; - [JsonPropertyName("load_board")] public LoadBoard LoadBoard { get; set; } = new(); + [JsonPropertyName("load_board")] public LoadBoard? LoadBoard { get; set; } [JsonPropertyName("action")] public string Action { get; set; } = string.Empty; + + [JsonIgnore] public Image? Image { get; set; } + + private const int ImageWidth = 260; + private const int ImageHeight = 290; + + [JsonIgnore] + public int Width + { + get + { + var width = Image?.Width + 10; + if (width <= 10) width = 90; + if (width > ImageWidth) width = ImageWidth; + return width ?? ImageWidth; + } + } + + [JsonIgnore] + public int Height + { + get + { + var height = Image?.Height + 30; + if (height <= 30) height = 110; + if (height > ImageHeight) height = ImageHeight; + return height ?? ImageHeight; + } + } } \ No newline at end of file diff --git a/ChatAAC/Models/Obf/ExtCoughDropSettings.cs b/ChatAAC/Models/Obf/ExtCoughDropSettings.cs new file mode 100644 index 0000000..1487211 --- /dev/null +++ b/ChatAAC/Models/Obf/ExtCoughDropSettings.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace ChatAAC.Models.Obf; + +public class ExtCoughDropSettings +{ + [JsonPropertyName("private")] + public bool Private { get; set; } + + [JsonPropertyName("key")] public string Key { get; set; } = string.Empty; + + [JsonPropertyName("word_suggestions")] + public bool WordSuggestions { get; set; } +} \ No newline at end of file diff --git a/ChatAAC/Models/Obf/Grid.cs b/ChatAAC/Models/Obf/Grid.cs index 6584e8c..f35ad1c 100644 --- a/ChatAAC/Models/Obf/Grid.cs +++ b/ChatAAC/Models/Obf/Grid.cs @@ -9,5 +9,5 @@ public class Grid [JsonPropertyName("columns")] public int Columns { get; set; } - [JsonPropertyName("order")] public List> Order { get; set; } = new(); + [JsonPropertyName("order")] public List> Order { get; set; } = new(); } \ No newline at end of file diff --git a/ChatAAC/Models/Obf/Image.cs b/ChatAAC/Models/Obf/Image.cs index b1cd4e0..c380503 100644 --- a/ChatAAC/Models/Obf/Image.cs +++ b/ChatAAC/Models/Obf/Image.cs @@ -1,6 +1,7 @@ using System.Text.Json.Serialization; namespace ChatAAC.Models.Obf; + // Class for Image public class Image { @@ -8,6 +9,7 @@ public class Image [JsonPropertyName("url")] public string Url { get; set; } = string.Empty; + [JsonPropertyName("data_url")] public string DataUrl { get; set; } = string.Empty; [JsonPropertyName("data")] public string Data { get; set; } = string.Empty; [JsonPropertyName("content_type")] public string ContentType { get; set; } = string.Empty; @@ -15,4 +17,10 @@ public class Image [JsonPropertyName("width")] public int Width { get; set; } [JsonPropertyName("height")] public int Height { get; set; } + + [JsonPropertyName("license")] public License License { get; set; } = new(); + + [JsonPropertyName("path")] public string Path { get; set; } = string.Empty; + + [JsonIgnore] public string ImagePath { get; set; } = string.Empty; } \ No newline at end of file diff --git a/ChatAAC/Models/Obf/License.cs b/ChatAAC/Models/Obf/License.cs new file mode 100644 index 0000000..1964d5c --- /dev/null +++ b/ChatAAC/Models/Obf/License.cs @@ -0,0 +1,14 @@ +using System.Text.Json.Serialization; + +namespace ChatAAC.Models.Obf; + +public class License +{ + [JsonPropertyName("type")] public string Type { get; set; } = string.Empty; + + [JsonPropertyName("copyright_notice_url")] public string CopyrightNoticeUrl { get; set; } = string.Empty; + + [JsonPropertyName("author_name")] public string AuthorName { get; set; } = string.Empty; + + [JsonPropertyName("author_url")] public string AuthorUrl { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/ChatAAC/Models/Obf/Manifest.cs b/ChatAAC/Models/Obf/Manifest.cs new file mode 100644 index 0000000..66824d2 --- /dev/null +++ b/ChatAAC/Models/Obf/Manifest.cs @@ -0,0 +1,12 @@ +using System.Text.Json.Serialization; + +namespace ChatAAC.Models.Obf; + +public class Manifest +{ + [JsonPropertyName("format")] public string Format { get; set; } = string.Empty; + + [JsonPropertyName("root")] public string Root { get; set; } = string.Empty; + + [JsonPropertyName("paths")] public Paths Paths { get; set; } = new(); +} \ No newline at end of file diff --git a/ChatAAC/Models/Obf/ObfFile.cs b/ChatAAC/Models/Obf/ObfFile.cs index fa56280..4bdf400 100644 --- a/ChatAAC/Models/Obf/ObfFile.cs +++ b/ChatAAC/Models/Obf/ObfFile.cs @@ -8,6 +8,8 @@ public class ObfFile { [JsonPropertyName("format")] public string Format { get; set; } = string.Empty; + [JsonPropertyName("license")] public License License { get; set; } = new(); + [JsonPropertyName("id")] public string Id { get; set; } = string.Empty; [JsonPropertyName("locale")] public string Locale { get; set; } = string.Empty; @@ -17,10 +19,17 @@ public class ObfFile [JsonPropertyName("description_html")] public string DescriptionHtml { get; set; } = string.Empty; [JsonPropertyName("grid")] public Grid Grid { get; set; } = new(); - [JsonPropertyName("buttons")] public List - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + + - - - - - + + + + + - + + - - - - + + + + -