Skip to content

Commit

Permalink
Edit mode
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusz-kierepka-hl committed Jan 19, 2025
1 parent 76c0472 commit fe0d2c3
Show file tree
Hide file tree
Showing 12 changed files with 542 additions and 222 deletions.
1 change: 1 addition & 0 deletions .idea/.idea.ChatAAC/.idea/avalonia.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions ChatAAC/Converters/Base64ToBitmapConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Globalization;
using System.IO;
using Avalonia.Data.Converters;
using Avalonia.Media.Imaging;

namespace ChatAAC.Converters;

public class Base64ToBitmapConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not string base64String || string.IsNullOrEmpty(base64String))
return null; // fallback if there's no valid base64
try
{
// Convert the base64 string to a byte array
var imageBytes = System.Convert.FromBase64String(base64String);

// Use a MemoryStream to create a Bitmap
using var ms = new MemoryStream(imageBytes);
var bmp = new Bitmap(ms);
return bmp;
}
catch
{
// If the string is invalid base64, or decoding fails, return null
}
return null; // fallback if there's no valid base64
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// Typically not needed for a one-way binding
return null;
}
}
81 changes: 40 additions & 41 deletions ChatAAC/Converters/ContrastForegroundBrushConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,47 @@
using Avalonia.Data.Converters;
using Avalonia.Media;

namespace ChatAAC.Converters
namespace ChatAAC.Converters;

/// <summary>
/// Returns a brush with a contrasting color (white or black)
/// compared to the given background color.
/// </summary>
public class ContrastForegroundBrushConverter : IValueConverter
{
/// <summary>
/// Returns a brush with a contrasting color (white or black)
/// compared to the given background color.
/// </summary>
public class ContrastForegroundBrushConverter : IValueConverter
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not SolidColorBrush backgroundBrush) return Brushes.Black; // fallback
var color = backgroundBrush.Color;

// Compute luminance (0..1)
var luminance = ComputeRelativeLuminance(color);

// If the background is dark, return White, else Black
return luminance < 0.5 ? Brushes.White : Brushes.Black;
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not SolidColorBrush backgroundBrush) return Brushes.Black; // fallback
var color = backgroundBrush.Color;

// Compute luminance (0..1)
var luminance = ComputeRelativeLuminance(color);

// If the background is dark, return White, else Black
return luminance < 0.5 ? Brushes.White : Brushes.Black;
}

public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
// Usually one-way binding, so no need to convert back
return null!;
}

private static double ComputeRelativeLuminance(Color color)
{
// Standard formula for relative luminance (from W3C):
// https://www.w3.org/TR/WCAG20/#relativeluminancedef
// R, G, B are in [0..1].
var r = color.R / 255.0;
var g = color.G / 255.0;
var b = color.B / 255.0;

// Apply gamma correction
r = (r <= 0.03928) ? (r / 12.92) : Math.Pow((r + 0.055) / 1.055, 2.4);
g = (g <= 0.03928) ? (g / 12.92) : Math.Pow((g + 0.055) / 1.055, 2.4);
b = (b <= 0.03928) ? (b / 12.92) : Math.Pow((b + 0.055) / 1.055, 2.4);

// 0.2126 R + 0.7152 G + 0.0722 B
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
// Usually one-way binding, so no need to convert back
return null!;
}

private static double ComputeRelativeLuminance(Color color)
{
// Standard formula for relative luminance (from W3C):
// https://www.w3.org/TR/WCAG20/#relativeluminancedef
// R, G, B are in [0..1].
var r = color.R / 255.0;
var g = color.G / 255.0;
var b = color.B / 255.0;

// Apply gamma correction
r = (r <= 0.03928) ? (r / 12.92) : Math.Pow((r + 0.055) / 1.055, 2.4);
g = (g <= 0.03928) ? (g / 12.92) : Math.Pow((g + 0.055) / 1.055, 2.4);
b = (b <= 0.03928) ? (b / 12.92) : Math.Pow((b + 0.055) / 1.055, 2.4);

// 0.2126 R + 0.7152 G + 0.0722 B
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
}
10 changes: 10 additions & 0 deletions ChatAAC/Services/BoardLoaderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,14 @@ private string SanitizeEntryName(string entryName)

return Path.Combine(sanitizedSegments);
}

public async Task SaveObfFileAsync(string filePath, ObfFile obfFile)
{
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var json = JsonSerializer.Serialize(obfFile, options);
await File.WriteAllTextAsync(filePath, json);
}
}
110 changes: 110 additions & 0 deletions ChatAAC/ViewModels/AddImageViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using ReactiveUI;
using System.Reactive;
using ChatAAC.Models.Obf;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;

namespace ChatAAC.ViewModels;

public class AddImageViewModel : ReactiveObject
{
private string _id = "";
private string _url = "";
private string _dataUrl = "";
private string _path = "";
private string _contentType = "image/png";
private int _width;
private int _height;

public bool IsConfirmed { get; private set; }

public ReactiveCommand<Unit, Unit> ConfirmCommand { get; }
public ReactiveCommand<Unit, Unit> CancelCommand { get; }

public AddImageViewModel()
{
ConfirmCommand = ReactiveCommand.Create(Confirm);
CancelCommand = ReactiveCommand.Create(Cancel);
}

#region Properties
public string Id
{
get => _id;
set => this.RaiseAndSetIfChanged(ref _id, value);
}

public string Url
{
get => _url;
set => this.RaiseAndSetIfChanged(ref _url, value);
}

public string DataUrl
{
get => _dataUrl;
set => this.RaiseAndSetIfChanged(ref _dataUrl, value);
}

public string Path
{
get => _path;
set => this.RaiseAndSetIfChanged(ref _path, value);
}

public string ContentType
{
get => _contentType;
set => this.RaiseAndSetIfChanged(ref _contentType, value);
}

public int Width
{
get => _width;
set => this.RaiseAndSetIfChanged(ref _width, value);
}

public int Height
{
get => _height;
set => this.RaiseAndSetIfChanged(ref _height, value);
}
#endregion

private void Confirm()
{
IsConfirmed = true;
CloseWindow();
}

private void Cancel()
{
IsConfirmed = false;
CloseWindow();
}

private void CloseWindow()
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.Windows[^1].Close();
}
}

/// <summary>
/// Creates a new Image object from the user inputs.
/// </summary>
public Image CreateImage()
{
return new Image
{
Id = _id,
Url = _url,
DataUrl = _dataUrl,
Path = _path,
ContentType = _contentType,
Width = _width,
Height = _height
};
}
}
Loading

0 comments on commit fe0d2c3

Please sign in to comment.