misc: chore: Move converters into a directory in Helpers. Namespace unchanged

This commit is contained in:
Evan Husted 2025-01-10 20:24:53 -06:00
parent d75ce52bd4
commit cc95e80ee9
11 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,36 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using System;
using System.Globalization;
using System.IO;
namespace Ryujinx.Ava.UI.Helpers
{
internal class BitmapArrayValueConverter : IValueConverter
{
public static BitmapArrayValueConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
switch (value)
{
case null:
return null;
case byte[] buffer when targetType == typeof(IImage):
{
MemoryStream mem = new(buffer);
return new Bitmap(mem);
}
default:
throw new NotSupportedException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}

View file

@ -0,0 +1,42 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Locale;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Ryujinx.Ava.UI.Helpers
{
internal class DownloadableContentLabelConverter : IMultiValueConverter
{
public static DownloadableContentLabelConverter Instance = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Any(it => it is UnsetValueType))
{
return BindingOperations.DoNothing;
}
if (values.Count != 2 || !targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (values is not [string label, bool isBundled])
{
return null;
}
return isBundled ? $"{LocaleManager.Instance[LocaleKeys.TitleBundledDlcLabel]} {label}" : label;
}
public object[] ConvertBack(object[] values, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View file

@ -0,0 +1,32 @@
using Avalonia.Markup.Xaml;
using FluentAvalonia.UI.Controls;
using System;
using System.Collections.Generic;
namespace Ryujinx.Ava.UI.Helpers
{
public class GlyphValueConverter : MarkupExtension
{
private readonly string _key;
private static readonly Dictionary<Glyph, string> _glyphs = new()
{
{ Glyph.List, char.ConvertFromUtf32((int)Symbol.List) },
{ Glyph.Grid, char.ConvertFromUtf32((int)Symbol.ViewAll) },
{ Glyph.Chip, char.ConvertFromUtf32(59748) },
{ Glyph.Important, char.ConvertFromUtf32((int)Symbol.Important) },
};
public GlyphValueConverter(string key)
{
_key = key;
}
public string this[string key] =>
_glyphs.TryGetValue(Enum.Parse<Glyph>(key), out var val)
? val
: string.Empty;
public override object ProvideValue(IServiceProvider serviceProvider) => this[_key];
}
}

View file

@ -0,0 +1,184 @@
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Ryujinx.Ava.UI.Helpers
{
internal class KeyValueConverter : IValueConverter
{
public static KeyValueConverter Instance = new();
private static readonly Dictionary<Key, LocaleKeys> _keysMap = new()
{
{ Key.Unknown, LocaleKeys.KeyUnknown },
{ Key.ShiftLeft, LocaleKeys.KeyShiftLeft },
{ Key.ShiftRight, LocaleKeys.KeyShiftRight },
{ Key.ControlLeft, LocaleKeys.KeyControlLeft },
{ Key.ControlRight, LocaleKeys.KeyControlRight },
{ Key.AltLeft, LocaleKeys.KeyAltLeft },
{ Key.AltRight, LocaleKeys.KeyAltRight },
{ Key.WinLeft, LocaleKeys.KeyWinLeft },
{ Key.WinRight, LocaleKeys.KeyWinRight },
{ Key.Up, LocaleKeys.KeyUp },
{ Key.Down, LocaleKeys.KeyDown },
{ Key.Left, LocaleKeys.KeyLeft },
{ Key.Right, LocaleKeys.KeyRight },
{ Key.Enter, LocaleKeys.KeyEnter },
{ Key.Escape, LocaleKeys.KeyEscape },
{ Key.Space, LocaleKeys.KeySpace },
{ Key.Tab, LocaleKeys.KeyTab },
{ Key.BackSpace, LocaleKeys.KeyBackSpace },
{ Key.Insert, LocaleKeys.KeyInsert },
{ Key.Delete, LocaleKeys.KeyDelete },
{ Key.PageUp, LocaleKeys.KeyPageUp },
{ Key.PageDown, LocaleKeys.KeyPageDown },
{ Key.Home, LocaleKeys.KeyHome },
{ Key.End, LocaleKeys.KeyEnd },
{ Key.CapsLock, LocaleKeys.KeyCapsLock },
{ Key.ScrollLock, LocaleKeys.KeyScrollLock },
{ Key.PrintScreen, LocaleKeys.KeyPrintScreen },
{ Key.Pause, LocaleKeys.KeyPause },
{ Key.NumLock, LocaleKeys.KeyNumLock },
{ Key.Clear, LocaleKeys.KeyClear },
{ Key.Keypad0, LocaleKeys.KeyKeypad0 },
{ Key.Keypad1, LocaleKeys.KeyKeypad1 },
{ Key.Keypad2, LocaleKeys.KeyKeypad2 },
{ Key.Keypad3, LocaleKeys.KeyKeypad3 },
{ Key.Keypad4, LocaleKeys.KeyKeypad4 },
{ Key.Keypad5, LocaleKeys.KeyKeypad5 },
{ Key.Keypad6, LocaleKeys.KeyKeypad6 },
{ Key.Keypad7, LocaleKeys.KeyKeypad7 },
{ Key.Keypad8, LocaleKeys.KeyKeypad8 },
{ Key.Keypad9, LocaleKeys.KeyKeypad9 },
{ Key.KeypadDivide, LocaleKeys.KeyKeypadDivide },
{ Key.KeypadMultiply, LocaleKeys.KeyKeypadMultiply },
{ Key.KeypadSubtract, LocaleKeys.KeyKeypadSubtract },
{ Key.KeypadAdd, LocaleKeys.KeyKeypadAdd },
{ Key.KeypadDecimal, LocaleKeys.KeyKeypadDecimal },
{ Key.KeypadEnter, LocaleKeys.KeyKeypadEnter },
{ Key.Number0, LocaleKeys.KeyNumber0 },
{ Key.Number1, LocaleKeys.KeyNumber1 },
{ Key.Number2, LocaleKeys.KeyNumber2 },
{ Key.Number3, LocaleKeys.KeyNumber3 },
{ Key.Number4, LocaleKeys.KeyNumber4 },
{ Key.Number5, LocaleKeys.KeyNumber5 },
{ Key.Number6, LocaleKeys.KeyNumber6 },
{ Key.Number7, LocaleKeys.KeyNumber7 },
{ Key.Number8, LocaleKeys.KeyNumber8 },
{ Key.Number9, LocaleKeys.KeyNumber9 },
{ Key.Tilde, LocaleKeys.KeyTilde },
{ Key.Grave, LocaleKeys.KeyGrave },
{ Key.Minus, LocaleKeys.KeyMinus },
{ Key.Plus, LocaleKeys.KeyPlus },
{ Key.BracketLeft, LocaleKeys.KeyBracketLeft },
{ Key.BracketRight, LocaleKeys.KeyBracketRight },
{ Key.Semicolon, LocaleKeys.KeySemicolon },
{ Key.Quote, LocaleKeys.KeyQuote },
{ Key.Comma, LocaleKeys.KeyComma },
{ Key.Period, LocaleKeys.KeyPeriod },
{ Key.Slash, LocaleKeys.KeySlash },
{ Key.BackSlash, LocaleKeys.KeyBackSlash },
{ Key.Unbound, LocaleKeys.KeyUnbound },
};
private static readonly Dictionary<GamepadInputId, LocaleKeys> _gamepadInputIdMap = new()
{
{ GamepadInputId.LeftStick, LocaleKeys.GamepadLeftStick },
{ GamepadInputId.RightStick, LocaleKeys.GamepadRightStick },
{ GamepadInputId.LeftShoulder, LocaleKeys.GamepadLeftShoulder },
{ GamepadInputId.RightShoulder, LocaleKeys.GamepadRightShoulder },
{ GamepadInputId.LeftTrigger, LocaleKeys.GamepadLeftTrigger },
{ GamepadInputId.RightTrigger, LocaleKeys.GamepadRightTrigger },
{ GamepadInputId.DpadUp, LocaleKeys.GamepadDpadUp},
{ GamepadInputId.DpadDown, LocaleKeys.GamepadDpadDown},
{ GamepadInputId.DpadLeft, LocaleKeys.GamepadDpadLeft},
{ GamepadInputId.DpadRight, LocaleKeys.GamepadDpadRight},
{ GamepadInputId.Minus, LocaleKeys.GamepadMinus},
{ GamepadInputId.Plus, LocaleKeys.GamepadPlus},
{ GamepadInputId.Guide, LocaleKeys.GamepadGuide},
{ GamepadInputId.Misc1, LocaleKeys.GamepadMisc1},
{ GamepadInputId.Paddle1, LocaleKeys.GamepadPaddle1},
{ GamepadInputId.Paddle2, LocaleKeys.GamepadPaddle2},
{ GamepadInputId.Paddle3, LocaleKeys.GamepadPaddle3},
{ GamepadInputId.Paddle4, LocaleKeys.GamepadPaddle4},
{ GamepadInputId.Touchpad, LocaleKeys.GamepadTouchpad},
{ GamepadInputId.SingleLeftTrigger0, LocaleKeys.GamepadSingleLeftTrigger0},
{ GamepadInputId.SingleRightTrigger0, LocaleKeys.GamepadSingleRightTrigger0},
{ GamepadInputId.SingleLeftTrigger1, LocaleKeys.GamepadSingleLeftTrigger1},
{ GamepadInputId.SingleRightTrigger1, LocaleKeys.GamepadSingleRightTrigger1},
{ GamepadInputId.Unbound, LocaleKeys.KeyUnbound},
};
private static readonly Dictionary<StickInputId, LocaleKeys> _stickInputIdMap = new()
{
{ StickInputId.Left, LocaleKeys.StickLeft},
{ StickInputId.Right, LocaleKeys.StickRight},
{ StickInputId.Unbound, LocaleKeys.KeyUnbound},
};
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string keyString = string.Empty;
LocaleKeys localeKey;
switch (value)
{
case Key key:
if (_keysMap.TryGetValue(key, out localeKey))
{
if (OperatingSystem.IsMacOS())
{
localeKey = localeKey switch
{
LocaleKeys.KeyControlLeft => LocaleKeys.KeyMacControlLeft,
LocaleKeys.KeyControlRight => LocaleKeys.KeyMacControlRight,
LocaleKeys.KeyAltLeft => LocaleKeys.KeyMacAltLeft,
LocaleKeys.KeyAltRight => LocaleKeys.KeyMacAltRight,
LocaleKeys.KeyWinLeft => LocaleKeys.KeyMacWinLeft,
LocaleKeys.KeyWinRight => LocaleKeys.KeyMacWinRight,
_ => localeKey
};
}
keyString = LocaleManager.Instance[localeKey];
}
else
{
keyString = key.ToString();
}
break;
case GamepadInputId gamepadInputId:
if (_gamepadInputIdMap.TryGetValue(gamepadInputId, out localeKey))
{
keyString = LocaleManager.Instance[localeKey];
}
else
{
keyString = gamepadInputId.ToString();
}
break;
case StickInputId stickInputId:
if (_stickInputIdMap.TryGetValue(stickInputId, out localeKey))
{
keyString = LocaleManager.Instance[localeKey];
}
else
{
keyString = stickInputId.ToString();
}
break;
}
return keyString;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}

View file

@ -0,0 +1,43 @@
using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Utilities.AppLibrary;
using System;
using System.Globalization;
namespace Ryujinx.Ava.UI.Helpers
{
internal class MultiplayerInfoConverter : MarkupExtension, IValueConverter
{
private static readonly MultiplayerInfoConverter _instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ApplicationData applicationData)
{
if (applicationData.PlayerCount != 0 && applicationData.GameCount != 0)
{
return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}";
}
else
{
return "";
}
}
else
{
return "";
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return _instance;
}
}
}

View file

@ -0,0 +1,28 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using Gommon;
using Ryujinx.Ava.Common.Locale;
using System;
using System.Globalization;
namespace Ryujinx.Ava.UI.Helpers
{
public class PlayabilityStatusConverter : IValueConverter
{
private static readonly Lazy<PlayabilityStatusConverter> _shared = new(() => new());
public static PlayabilityStatusConverter Shared => _shared.Value;
public object Convert(object value, Type _, object __, CultureInfo ___)
=> value.Cast<LocaleKeys>() switch
{
LocaleKeys.CompatibilityListNothing or
LocaleKeys.CompatibilityListBoots or
LocaleKeys.CompatibilityListMenus => Brushes.Red,
LocaleKeys.CompatibilityListIngame => Brushes.Yellow,
_ => Brushes.ForestGreen
};
public object ConvertBack(object value, Type _, object __, CultureInfo ___)
=> throw new NotSupportedException();
}
}

View file

@ -0,0 +1,20 @@
using Avalonia.Data.Converters;
using System;
using System.Globalization;
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
namespace Ryujinx.Ava.UI.Helpers
{
internal class TimeZoneConverter : IValueConverter
{
public static TimeZoneConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> value is TimeZone timeZone
? $"{timeZone.UtcDifference} {timeZone.Location} {timeZone.Abbreviation}"
: null;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}

View file

@ -0,0 +1,42 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Locale;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Ryujinx.Ava.UI.Helpers
{
internal class TitleUpdateLabelConverter : IMultiValueConverter
{
public static TitleUpdateLabelConverter Instance = new();
public object Convert(IList<object> values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Any(it => it is UnsetValueType))
{
return BindingOperations.DoNothing;
}
if (values.Count != 2 || !targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (values is not [string label, bool isBundled])
{
return null;
}
var key = isBundled ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel;
return LocaleManager.Instance.UpdateAndGetDynamicValue(key, label);
}
public object[] ConvertBack(object[] values, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View file

@ -0,0 +1,49 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Gommon;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using System;
using System.Globalization;
namespace Ryujinx.Ava.UI.Helpers
{
internal class XCITrimmerFileSpaceSavingsConverter : IValueConverter
{
private const long _bytesPerMB = 1024 * 1024;
public static XCITrimmerFileSpaceSavingsConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is UnsetValueType)
{
return BindingOperations.DoNothing;
}
if (!targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (value is not XCITrimmerFileModel app)
{
return null;
}
if (app.CurrentSavingsB < app.PotentialSavingsB)
{
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCICanSaveLabel, ((app.PotentialSavingsB - app.CurrentSavingsB) / _bytesPerMB).CoerceAtLeast(0));
}
else
{
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCISavingLabel, (app.CurrentSavingsB / _bytesPerMB).CoerceAtLeast(0));
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}

View file

@ -0,0 +1,46 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models;
using System;
using System.Globalization;
using static Ryujinx.Common.Utilities.XCIFileTrimmer;
namespace Ryujinx.Ava.UI.Helpers
{
internal class XCITrimmerFileStatusConverter : IValueConverter
{
public static XCITrimmerFileStatusConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is UnsetValueType)
{
return BindingOperations.DoNothing;
}
if (!targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (value is not XCITrimmerFileModel app)
{
return null;
}
return app.PercentageProgress != null ? String.Empty :
app.ProcessingOutcome != OperationOutcome.Successful && app.ProcessingOutcome != OperationOutcome.Undetermined ? LocaleManager.Instance[LocaleKeys.TitleXCIStatusFailedLabel] :
app.Trimmable & app.Untrimmable ? LocaleManager.Instance[LocaleKeys.TitleXCIStatusPartialLabel] :
app.Trimmable ? LocaleManager.Instance[LocaleKeys.TitleXCIStatusTrimmableLabel] :
app.Untrimmable ? LocaleManager.Instance[LocaleKeys.TitleXCIStatusUntrimmableLabel] :
String.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}

View file

@ -0,0 +1,42 @@
using Avalonia;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Ryujinx.Ava.Common.Models;
using System;
using System.Globalization;
using static Ryujinx.Common.Utilities.XCIFileTrimmer;
namespace Ryujinx.Ava.UI.Helpers
{
internal class XCITrimmerFileStatusDetailConverter : IValueConverter
{
public static XCITrimmerFileStatusDetailConverter Instance = new();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is UnsetValueType)
{
return BindingOperations.DoNothing;
}
if (!targetType.IsAssignableFrom(typeof(string)))
{
return null;
}
if (value is not XCITrimmerFileModel app)
{
return null;
}
return app.PercentageProgress != null ? null :
app.ProcessingOutcome != OperationOutcome.Successful && app.ProcessingOutcome != OperationOutcome.Undetermined ? app.ProcessingOutcome.ToLocalisedText() :
null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}