mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-25 23:37:11 +02:00
misc: chore: Move the windows that are shown via ContentDialogs out of Ryujinx.Ava.UI.Windows (they're not windows)
This commit is contained in:
parent
f3a9cecf72
commit
d87d3235e9
20 changed files with 45 additions and 46 deletions
|
@ -1,193 +0,0 @@
|
|||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Windows.AboutWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModel="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
MinWidth="550"
|
||||
MinHeight="260"
|
||||
MaxWidth="600"
|
||||
MaxHeight="500"
|
||||
Margin="0,-12,0,0"
|
||||
d:DesignHeight="260"
|
||||
d:DesignWidth="550"
|
||||
x:DataType="viewModel:AboutWindowViewModel"
|
||||
Focusable="True"
|
||||
mc:Ignorable="d">
|
||||
<Design.DataContext>
|
||||
<viewModel:AboutWindowViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ColumnDefinitions="Auto,Auto,*">
|
||||
<Grid
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" RowDefinitions="Auto,*,Auto">
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Spacing="10">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Spacing="10">
|
||||
<Image
|
||||
Height="90"
|
||||
Width="90"
|
||||
Source="resm:Ryujinx.Assets.UIImages.Logo_Ryujinx.png?assembly=Ryujinx"
|
||||
HorizontalAlignment="Center"
|
||||
IsHitTestVisible="True" />
|
||||
<WrapPanel
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Vertical">
|
||||
<TextBlock
|
||||
FontSize="28"
|
||||
FontWeight="Bold"
|
||||
Text="Ryujinx"
|
||||
TextAlignment="Start"
|
||||
Width="110"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBlock
|
||||
FontSize="11"
|
||||
Text="(REE-YOU-JINX)"
|
||||
TextAlignment="Start"
|
||||
Width="110"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="10"
|
||||
LineHeight="12"
|
||||
Text="{Binding Version}"
|
||||
TextAlignment="Center" />
|
||||
<Border
|
||||
Height="1"
|
||||
Margin="0,20, 0, 20"
|
||||
HorizontalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="0,1,0,0" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Spacing="10">
|
||||
<TextBlock
|
||||
Width="200"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="10"
|
||||
LineHeight="12"
|
||||
Text="{ext:Locale AboutDisclaimerMessage}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
Name="AmiiboLabel"
|
||||
Width="200"
|
||||
HorizontalAlignment="Center"
|
||||
FontSize="10"
|
||||
LineHeight="12"
|
||||
PointerPressed="AmiiboLabel_OnPointerPressed"
|
||||
Text="{ext:Locale AboutAmiiboDisclaimerMessage}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<StackPanel
|
||||
HorizontalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="10">
|
||||
<Button Name="GitHubRepoButton"
|
||||
MinWidth="30"
|
||||
MinHeight="30"
|
||||
MaxWidth="30"
|
||||
MaxHeight="30"
|
||||
Padding="8"
|
||||
Background="Transparent"
|
||||
Click="Button_OnClick"
|
||||
CornerRadius="15"
|
||||
ToolTip.Tip="{ext:Locale AboutGithubUrlTooltipMessage}">
|
||||
<Image Source="{Binding GithubLogo}" />
|
||||
</Button>
|
||||
<Button
|
||||
MinWidth="30"
|
||||
MinHeight="30"
|
||||
MaxWidth="30"
|
||||
MaxHeight="30"
|
||||
Padding="8"
|
||||
Background="Transparent"
|
||||
Click="Button_OnClick"
|
||||
CornerRadius="15"
|
||||
Tag="https://discord.gg/PEuzjrFXUA"
|
||||
ToolTip.Tip="{ext:Locale AboutDiscordUrlTooltipMessage}">
|
||||
<Image Source="{Binding DiscordLogo}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Border
|
||||
Grid.Column="1"
|
||||
Width="1"
|
||||
Margin="20,0"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||
BorderThickness="1,0,0,0" />
|
||||
<Grid
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" RowDefinitions="Auto,Auto,Auto">
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Spacing="2">
|
||||
<TextBlock
|
||||
Classes="h1"
|
||||
FontWeight="Bold"
|
||||
Text="{ext:Locale AboutRyujinxAboutTitle}" />
|
||||
<TextBlock
|
||||
Text="{ext:Locale AboutRyujinxAboutContent}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<Separator Grid.Row="1" Margin="0,20" />
|
||||
<StackPanel
|
||||
Grid.Row="2"
|
||||
Spacing="2">
|
||||
<TextBlock
|
||||
Classes="h1"
|
||||
FontWeight="Bold"
|
||||
Text="{ext:Locale AboutRyujinxMaintainersTitle}" />
|
||||
<TextBlock
|
||||
Margin="0, 0, 0, 5"
|
||||
TextWrapping="Wrap"
|
||||
Text="{Binding Developers}"/>
|
||||
<TextBlock
|
||||
Classes="h1"
|
||||
FontWeight="Bold"
|
||||
Text="{ext:Locale AboutRyujinxFormerMaintainersTitle}" />
|
||||
<TextBlock
|
||||
FontSize="11"
|
||||
Text="{Binding FormerDevelopers}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
Margin="0, 5, 0, 0"
|
||||
Padding="5"
|
||||
HorizontalAlignment="Left"
|
||||
Background="Transparent"
|
||||
Click="Button_OnClick"
|
||||
Tag="https://github.com/Ryubing/Ryujinx/graphs/contributors?type=a">
|
||||
<TextBlock
|
||||
FontSize="10"
|
||||
Text="{ext:Locale AboutRyujinxContributorsButtonHeader}"
|
||||
TextAlignment="End"
|
||||
ToolTip.Tip="{ext:Locale AboutRyujinxMaintainersContentTooltipMessage}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,57 +0,0 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System.Threading.Tasks;
|
||||
using Button = Avalonia.Controls.Button;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class AboutWindow : RyujinxControl<AboutWindowViewModel>
|
||||
{
|
||||
public AboutWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
GitHubRepoButton.Tag =
|
||||
$"https://github.com/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}";
|
||||
}
|
||||
|
||||
public static async Task Show()
|
||||
{
|
||||
using AboutWindowViewModel viewModel = new();
|
||||
|
||||
ContentDialog contentDialog = new()
|
||||
{
|
||||
PrimaryButtonText = string.Empty,
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
|
||||
Content = new AboutWindow { ViewModel = viewModel }
|
||||
};
|
||||
|
||||
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles());
|
||||
}
|
||||
|
||||
private void Button_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { Tag: string url })
|
||||
OpenHelper.OpenUrl(url);
|
||||
}
|
||||
|
||||
private void AmiiboLabel_OnPointerPressed(object sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (sender is TextBlock)
|
||||
{
|
||||
OpenHelper.OpenUrl("https://amiiboapi.com");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,198 +0,0 @@
|
|||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Windows.DownloadableContentManagerWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:models="clr-namespace:Ryujinx.Ava.Common.Models"
|
||||
Width="500"
|
||||
Height="380"
|
||||
mc:Ignorable="d"
|
||||
x:DataType="viewModels:DownloadableContentManagerViewModel"
|
||||
Focusable="True">
|
||||
<Grid RowDefinitions="Auto,Auto,*,Auto">
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Margin="0 0 0 10"
|
||||
Spacing="5"
|
||||
Orientation="Horizontal"
|
||||
IsVisible="{Binding ShowBundledContentNotice}">
|
||||
<ui:FontIcon
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
|
||||
Glyph="{helpers:GlyphValueConverter Important}" />
|
||||
<!-- NOTE: aligning to bottom for better visual alignment with glyph -->
|
||||
<TextBlock
|
||||
FontStyle="Italic"
|
||||
VerticalAlignment="Bottom"
|
||||
Text="{ext:Locale DlcWindowBundledContentNotice}" />
|
||||
</StackPanel>
|
||||
<Panel
|
||||
Margin="0 0 0 10"
|
||||
Grid.Row="1">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*">
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Text="{Binding UpdateCount}" />
|
||||
<StackPanel
|
||||
Margin="10 0"
|
||||
Grid.Column="1"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Name="EnableAllButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding EnableAll}">
|
||||
<TextBlock Text="{ext:Locale DlcManagerEnableAllButton}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="DisableAllButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding DisableAll}">
|
||||
<TextBlock Text="{ext:Locale DlcManagerDisableAllButton}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBox
|
||||
Grid.Column="2"
|
||||
MinHeight="29"
|
||||
MaxHeight="29"
|
||||
HorizontalAlignment="Stretch"
|
||||
Watermark="{ext:Locale Search}"
|
||||
Text="{Binding Search}" />
|
||||
</Grid>
|
||||
</Panel>
|
||||
<Border
|
||||
Grid.Row="2"
|
||||
Margin="0 0 0 24"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="2.5">
|
||||
<ListBox
|
||||
AutoScrollToSelectedItem="False"
|
||||
SelectionMode="Multiple, Toggle"
|
||||
Background="Transparent"
|
||||
SelectionChanged="OnSelectionChanged"
|
||||
SelectedItems="{Binding SelectedDownloadableContents, Mode=OneWay}"
|
||||
ItemsSource="{Binding Views}">
|
||||
<ListBox.DataTemplates>
|
||||
<DataTemplate
|
||||
DataType="models:DownloadableContentModel">
|
||||
<Panel Margin="10" Background="Transparent">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<Grid
|
||||
Grid.Column="0" ColumnDefinitions="*,Auto">
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="2"
|
||||
TextWrapping="Wrap"
|
||||
TextTrimming="CharacterEllipsis">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{x:Static helpers:DownloadableContentLabelConverter.Instance}">
|
||||
<Binding Path="FileName" />
|
||||
<Binding Path="IsBundled" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Margin="10 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding TitleIdStr}" />
|
||||
</Grid>
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Spacing="10"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Click="OpenLocation">
|
||||
<ui:SymbolIcon
|
||||
Symbol="OpenFolder"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Click="RemoveDLC">
|
||||
<ui:SymbolIcon
|
||||
Symbol="Cancel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</ListBox.DataTemplates>
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<Panel
|
||||
Grid.Row="3"
|
||||
HorizontalAlignment="Stretch">
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Left">
|
||||
<Button
|
||||
Name="AddButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding Add}">
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="RemoveAllButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding RemoveAll}">
|
||||
<TextBlock Text="{ext:Locale DlcManagerRemoveAllButton}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
Name="SaveButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="SaveAndClose">
|
||||
<TextBlock Text="{ext:Locale SettingsButtonSave}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="CancelButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Close">
|
||||
<TextBlock Text="{ext:Locale InputDialogCancel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,97 +0,0 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Systems.AppLibrary;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class DownloadableContentManagerWindow : UserControl
|
||||
{
|
||||
public DownloadableContentManagerViewModel ViewModel;
|
||||
|
||||
public DownloadableContentManagerWindow()
|
||||
{
|
||||
DataContext = this;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public DownloadableContentManagerWindow(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||
{
|
||||
DataContext = ViewModel = new DownloadableContentManagerViewModel(applicationLibrary, applicationData);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static async Task Show(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||
{
|
||||
ContentDialog contentDialog = new()
|
||||
{
|
||||
PrimaryButtonText = string.Empty,
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = string.Empty,
|
||||
Content = new DownloadableContentManagerWindow(applicationLibrary, applicationData),
|
||||
Title = string.Format(LocaleManager.Instance[LocaleKeys.DlcWindowTitle], applicationData.Name, applicationData.IdBaseString),
|
||||
};
|
||||
|
||||
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
|
||||
bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
|
||||
|
||||
contentDialog.Styles.Add(bottomBorder);
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
|
||||
private void SaveAndClose(object sender, RoutedEventArgs routedEventArgs)
|
||||
{
|
||||
ViewModel.Save();
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
private void RemoveDLC(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { DataContext: DownloadableContentModel dlc })
|
||||
{
|
||||
ViewModel.Remove(dlc);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenLocation(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { DataContext: DownloadableContentModel dlc })
|
||||
{
|
||||
OpenHelper.LocateFile(dlc.ContainerPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
foreach (object content in e.AddedItems)
|
||||
{
|
||||
if (content is DownloadableContentModel model)
|
||||
{
|
||||
ViewModel.Enable(model);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (object content in e.RemovedItems)
|
||||
{
|
||||
if (content is DownloadableContentModel model)
|
||||
{
|
||||
ViewModel.Disable(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
static class IconColorPicker
|
||||
{
|
||||
private const int ColorsPerLine = 64;
|
||||
private const int TotalColors = ColorsPerLine * ColorsPerLine;
|
||||
|
||||
private const int UvQuantBits = 3;
|
||||
private const int UvQuantShift = BitsPerComponent - UvQuantBits;
|
||||
|
||||
private const int SatQuantBits = 5;
|
||||
private const int SatQuantShift = BitsPerComponent - SatQuantBits;
|
||||
|
||||
private const int BitsPerComponent = 8;
|
||||
|
||||
private const int CutOffLuminosity = 64;
|
||||
|
||||
private readonly struct PaletteColor(int qck, byte r, byte g, byte b)
|
||||
{
|
||||
public int Qck => qck;
|
||||
public byte R => r;
|
||||
public byte G => g;
|
||||
public byte B => b;
|
||||
}
|
||||
|
||||
public static SKColor GetFilteredColor(SKBitmap image)
|
||||
{
|
||||
SKColor color = GetColor(image);
|
||||
|
||||
|
||||
// We don't want colors that are too dark.
|
||||
// If the color is too dark, make it brighter by reducing the range
|
||||
// and adding a constant color.
|
||||
int luminosity = GetColorApproximateLuminosity(color.Red, color.Green, color.Blue);
|
||||
if (luminosity < CutOffLuminosity)
|
||||
{
|
||||
color = new SKColor(
|
||||
(byte)Math.Min(CutOffLuminosity + color.Red, byte.MaxValue),
|
||||
(byte)Math.Min(CutOffLuminosity + color.Green, byte.MaxValue),
|
||||
(byte)Math.Min(CutOffLuminosity + color.Blue, byte.MaxValue));
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
public static SKColor GetColor(SKBitmap image)
|
||||
{
|
||||
PaletteColor[] colors = new PaletteColor[TotalColors];
|
||||
Dictionary<int, int> dominantColorBin = new();
|
||||
|
||||
SKColor[] buffer = GetBuffer(image);
|
||||
|
||||
int i = 0;
|
||||
int maxHitCount = 0;
|
||||
|
||||
for (int y = 0; y < image.Height; y++)
|
||||
{
|
||||
int yOffset = y * image.Width;
|
||||
|
||||
for (int x = 0; x < image.Width && i < TotalColors; x++)
|
||||
{
|
||||
int offset = x + yOffset;
|
||||
|
||||
SKColor pixel = buffer[offset];
|
||||
byte cr = pixel.Red;
|
||||
byte cg = pixel.Green;
|
||||
byte cb = pixel.Blue;
|
||||
|
||||
int qck = GetQuantizedColorKey(cr, cg, cb);
|
||||
|
||||
if (dominantColorBin.TryGetValue(qck, out int hitCount))
|
||||
{
|
||||
dominantColorBin[qck] = hitCount + 1;
|
||||
|
||||
if (maxHitCount < hitCount)
|
||||
{
|
||||
maxHitCount = hitCount;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dominantColorBin.Add(qck, 1);
|
||||
}
|
||||
|
||||
colors[i++] = new PaletteColor(qck, cr, cg, cb);
|
||||
}
|
||||
}
|
||||
|
||||
int highScore = -1;
|
||||
PaletteColor bestCandidate = default;
|
||||
|
||||
for (i = 0; i < TotalColors; i++)
|
||||
{
|
||||
int score = GetColorScore(dominantColorBin, maxHitCount, colors[i]);
|
||||
|
||||
if (highScore < score)
|
||||
{
|
||||
highScore = score;
|
||||
bestCandidate = colors[i];
|
||||
}
|
||||
}
|
||||
|
||||
return new SKColor(bestCandidate.R, bestCandidate.G, bestCandidate.B);
|
||||
}
|
||||
|
||||
public static SKColor[] GetBuffer(SKBitmap image)
|
||||
{
|
||||
SKColor[] pixels = new SKColor[image.Width * image.Height];
|
||||
|
||||
for (int y = 0; y < image.Height; y++)
|
||||
{
|
||||
for (int x = 0; x < image.Width; x++)
|
||||
{
|
||||
pixels[x + y * image.Width] = image.GetPixel(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
private static int GetColorScore(Dictionary<int, int> dominantColorBin, int maxHitCount, PaletteColor color)
|
||||
{
|
||||
int hitCount = dominantColorBin[color.Qck];
|
||||
int balancedHitCount = BalanceHitCount(hitCount, maxHitCount);
|
||||
int quantSat = (GetColorSaturation(color) >> SatQuantShift) << SatQuantShift;
|
||||
int value = GetColorValue(color);
|
||||
|
||||
// If the color is rarely used on the image,
|
||||
// then chances are that there's a better candidate, even if the saturation value
|
||||
// is high. By multiplying the saturation value with a weight, we can lower
|
||||
// it if the color is almost never used (hit count is low).
|
||||
int satWeighted = quantSat;
|
||||
int satWeight = balancedHitCount << 5;
|
||||
if (satWeight < 0x100)
|
||||
{
|
||||
satWeighted = (satWeighted * satWeight) >> 8;
|
||||
}
|
||||
|
||||
// Compute score from saturation and dominance of the color.
|
||||
// We prefer more vivid colors over dominant ones, so give more weight to the saturation.
|
||||
int score = ((satWeighted << 1) + balancedHitCount) * value;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
private static int GetColorSaturation(PaletteColor color)
|
||||
{
|
||||
int cMax = Math.Max(Math.Max(color.R, color.G), color.B);
|
||||
|
||||
if (cMax == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cMin = Math.Min(Math.Min(color.R, color.G), color.B);
|
||||
int delta = cMax - cMin;
|
||||
return (delta << 8) / cMax;
|
||||
}
|
||||
|
||||
private static int GetColorValue(PaletteColor color) => Math.Max(Math.Max(color.R, color.G), color.B);
|
||||
|
||||
private static int BalanceHitCount(int hitCount, int maxHitCount) => (hitCount << 8) / maxHitCount;
|
||||
|
||||
private static int GetColorApproximateLuminosity(byte r, byte g, byte b) => (r + g + b) / 3;
|
||||
|
||||
private static int GetQuantizedColorKey(byte r, byte g, byte b)
|
||||
{
|
||||
int u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
|
||||
int v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
|
||||
return (v >> UvQuantShift) | ((u >> UvQuantShift) << UvQuantBits);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
<UserControl
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
Width="500"
|
||||
Height="380"
|
||||
mc:Ignorable="d"
|
||||
x:Class="Ryujinx.Ava.UI.Windows.ModManagerWindow"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="viewModels:ModManagerViewModel"
|
||||
Focusable="True">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<Panel
|
||||
Margin="0 0 0 10"
|
||||
Grid.Row="0">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*">
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Text="{Binding ModCount}" />
|
||||
<StackPanel
|
||||
Margin="10 0"
|
||||
Grid.Column="1"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Name="EnableAllButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding EnableAll}">
|
||||
<TextBlock Text="{ext:Locale DlcManagerEnableAllButton}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="DisableAllButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding DisableAll}">
|
||||
<TextBlock Text="{ext:Locale DlcManagerDisableAllButton}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBox
|
||||
Grid.Column="2"
|
||||
MinHeight="27"
|
||||
MaxHeight="27"
|
||||
HorizontalAlignment="Stretch"
|
||||
Watermark="{ext:Locale Search}"
|
||||
Text="{Binding Search}" />
|
||||
</Grid>
|
||||
</Panel>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Margin="0 0 0 24"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="2.5">
|
||||
<ListBox
|
||||
AutoScrollToSelectedItem="False"
|
||||
SelectionMode="Multiple, Toggle"
|
||||
Background="Transparent"
|
||||
SelectionChanged="OnSelectionChanged"
|
||||
SelectedItems="{Binding SelectedMods, Mode=TwoWay}"
|
||||
ItemsSource="{Binding Views}">
|
||||
<ListBox.DataTemplates>
|
||||
<DataTemplate
|
||||
DataType="models:ModModel">
|
||||
<Panel Margin="10">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="2"
|
||||
TextWrapping="Wrap"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Text="{Binding FormattedName}" />
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Spacing="10"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
ToolTip.Tip="{Binding Path}"
|
||||
Click="OpenLocation">
|
||||
<ui:SymbolIcon
|
||||
Symbol="OpenFolder"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Click="DeleteMod">
|
||||
<ui:SymbolIcon
|
||||
Symbol="Cancel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</ListBox.DataTemplates>
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<Panel
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Stretch">
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Left">
|
||||
<Button
|
||||
Name="AddButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding Add}">
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="RemoveAllButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="DeleteAll">
|
||||
<TextBlock Text="{ext:Locale ModManagerDeleteAllButton}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
Name="SaveButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="SaveAndClose">
|
||||
<TextBlock Text="{ext:Locale SettingsButtonSave}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="CancelButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Close">
|
||||
<TextBlock Text="{ext:Locale InputDialogCancel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,140 +0,0 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.Models;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Systems.AppLibrary;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System.Threading.Tasks;
|
||||
using Button = Avalonia.Controls.Button;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class ModManagerWindow : UserControl
|
||||
{
|
||||
public readonly ModManagerViewModel ViewModel;
|
||||
|
||||
public ModManagerWindow()
|
||||
{
|
||||
DataContext = this;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public ModManagerWindow(ulong titleId, ulong titleIdBase, ApplicationLibrary applicationLibrary)
|
||||
{
|
||||
DataContext = ViewModel = new ModManagerViewModel(titleId, titleIdBase, applicationLibrary);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static async Task Show(ulong titleId, ulong titleIdBase, ApplicationLibrary appLibrary, string titleName)
|
||||
{
|
||||
ContentDialog contentDialog = new()
|
||||
{
|
||||
PrimaryButtonText = string.Empty,
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = string.Empty,
|
||||
Content = new ModManagerWindow(titleId, titleIdBase, appLibrary),
|
||||
Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowTitle], titleName, titleId.ToString("X16")),
|
||||
};
|
||||
|
||||
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
|
||||
bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
|
||||
|
||||
contentDialog.Styles.Add(bottomBorder);
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
|
||||
private void SaveAndClose(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Save();
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
private async void DeleteMod(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button)
|
||||
{
|
||||
if (button.DataContext is ModModel model)
|
||||
{
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogWarning],
|
||||
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogModManagerDeletionWarningMessage, model.Name),
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
||||
LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
|
||||
|
||||
if (result == UserResult.Yes)
|
||||
{
|
||||
ViewModel.Delete(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void DeleteAll(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
|
||||
LocaleManager.Instance[LocaleKeys.DialogWarning],
|
||||
LocaleManager.Instance[LocaleKeys.DialogModManagerDeletionAllWarningMessage],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
||||
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
||||
LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
|
||||
|
||||
if (result == UserResult.Yes)
|
||||
{
|
||||
ViewModel.DeleteAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenLocation(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button)
|
||||
{
|
||||
if (button.DataContext is ModModel model)
|
||||
{
|
||||
OpenHelper.OpenFolder(model.Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
foreach (object content in e.AddedItems)
|
||||
{
|
||||
if (content is ModModel model)
|
||||
{
|
||||
int index = ViewModel.Mods.IndexOf(model);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
ViewModel.Mods[index].Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (object content in e.RemovedItems)
|
||||
{
|
||||
if (content is ModModel model)
|
||||
{
|
||||
int index = ViewModel.Mods.IndexOf(model);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
ViewModel.Mods[index].Enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Windows.TitleUpdateWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:models="clr-namespace:Ryujinx.Ava.Common.Models"
|
||||
Width="500"
|
||||
Height="300"
|
||||
mc:Ignorable="d"
|
||||
x:DataType="viewModels:TitleUpdateViewModel"
|
||||
Focusable="True">
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Margin="0 0 0 10"
|
||||
Spacing="5"
|
||||
Orientation="Horizontal"
|
||||
IsVisible="{Binding ShowBundledContentNotice}">
|
||||
<ui:FontIcon
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
|
||||
Glyph="{helpers:GlyphValueConverter Important}" />
|
||||
<!-- NOTE: aligning to bottom for better visual alignment with glyph -->
|
||||
<TextBlock
|
||||
FontStyle="Italic"
|
||||
VerticalAlignment="Bottom"
|
||||
Text="{ext:Locale UpdateWindowBundledContentNotice}" />
|
||||
</StackPanel>
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Margin="0 0 0 24"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="2.5">
|
||||
<ListBox
|
||||
Background="Transparent"
|
||||
SelectedItem="{Binding SelectedUpdate, Mode=TwoWay}"
|
||||
ItemsSource="{Binding Views}">
|
||||
<ListBox.DataTemplates>
|
||||
<DataTemplate
|
||||
DataType="models:TitleUpdateModel">
|
||||
<Panel Margin="10">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="Wrap">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{x:Static helpers:TitleUpdateLabelConverter.Instance}">
|
||||
<Binding Path="DisplayVersion" />
|
||||
<Binding Path="IsBundled" />
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
<StackPanel
|
||||
Spacing="10"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Click="OpenLocation">
|
||||
<ui:SymbolIcon
|
||||
Symbol="OpenFolder"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="10"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Click="RemoveUpdate">
|
||||
<ui:SymbolIcon
|
||||
Symbol="Cancel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
<DataTemplate
|
||||
DataType="viewModels:TitleUpdateViewModelNoUpdate">
|
||||
<Panel
|
||||
Height="33"
|
||||
Margin="10">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
Text="{ext:Locale NoUpdate}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</ListBox.DataTemplates>
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<Panel
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Stretch">
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Left">
|
||||
<Button
|
||||
Name="AddButton"
|
||||
MinWidth="90"
|
||||
Command="{Binding Add}">
|
||||
<TextBlock Text="{ext:Locale SettingsTabGeneralAdd}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="RemoveAllButton"
|
||||
MinWidth="90"
|
||||
Click="RemoveAll">
|
||||
<TextBlock Text="{ext:Locale DlcManagerRemoveAllButton}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
Name="SaveButton"
|
||||
MinWidth="90"
|
||||
Click="Save">
|
||||
<TextBlock Text="{ext:Locale SettingsButtonSave}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="CancelButton"
|
||||
MinWidth="90"
|
||||
Click="Close">
|
||||
<TextBlock Text="{ext:Locale InputDialogCancel}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,82 +0,0 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.Systems.AppLibrary;
|
||||
using Ryujinx.Common.Helper;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class TitleUpdateWindow : UserControl
|
||||
{
|
||||
public readonly TitleUpdateViewModel ViewModel;
|
||||
|
||||
public TitleUpdateWindow()
|
||||
{
|
||||
DataContext = this;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public TitleUpdateWindow(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||
{
|
||||
DataContext = ViewModel = new TitleUpdateViewModel(applicationLibrary, applicationData);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static async Task Show(ApplicationLibrary applicationLibrary, ApplicationData applicationData)
|
||||
{
|
||||
ContentDialog contentDialog = new()
|
||||
{
|
||||
PrimaryButtonText = string.Empty,
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = string.Empty,
|
||||
Content = new TitleUpdateWindow(applicationLibrary, applicationData),
|
||||
Title = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.GameUpdateWindowHeading, applicationData.Name, applicationData.IdBaseString),
|
||||
};
|
||||
|
||||
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
|
||||
bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
|
||||
|
||||
contentDialog.Styles.Add(bottomBorder);
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
public void Save(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Save();
|
||||
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
private void OpenLocation(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { DataContext: TitleUpdateModel model })
|
||||
OpenHelper.LocateFile(model.Path);
|
||||
}
|
||||
|
||||
private void RemoveUpdate(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button { DataContext: TitleUpdateModel model })
|
||||
ViewModel.RemoveUpdate(model);
|
||||
}
|
||||
|
||||
private void RemoveAll(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.TitleUpdates.Clear();
|
||||
|
||||
ViewModel.SortUpdates();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,316 +0,0 @@
|
|||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Windows.XCITrimmerWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:models="clr-namespace:Ryujinx.Ava.Common.Models"
|
||||
Width="700"
|
||||
Height="600"
|
||||
x:DataType="viewModels:XCITrimmerViewModel"
|
||||
Focusable="True"
|
||||
mc:Ignorable="d">
|
||||
<Grid Margin="20 0 20 0" RowDefinitions="Auto,Auto,*,Auto,Auto">
|
||||
<Panel
|
||||
Margin="10 10 10 10"
|
||||
Grid.Row="0">
|
||||
<TextBlock Text="{Binding Status}" />
|
||||
</Panel>
|
||||
<Panel
|
||||
Margin="0 0 10 10"
|
||||
IsVisible="{Binding !Processing}"
|
||||
Grid.Row="1">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="10,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale CommonSort}" />
|
||||
<DropDownButton
|
||||
Width="150"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Content="{Binding SortingFieldName}">
|
||||
<DropDownButton.Flyout>
|
||||
<Flyout Placement="Bottom">
|
||||
<StackPanel
|
||||
Margin="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Orientation="Vertical">
|
||||
<StackPanel>
|
||||
<RadioButton
|
||||
Checked="Sort_Checked"
|
||||
Content="{ext:Locale XCITrimmerSortName}"
|
||||
GroupName="Sort"
|
||||
IsChecked="{Binding IsSortedByName, Mode=OneTime}"
|
||||
Tag="Name" />
|
||||
<RadioButton
|
||||
Checked="Sort_Checked"
|
||||
Content="{ext:Locale XCITrimmerSortSaved}"
|
||||
GroupName="Sort"
|
||||
IsChecked="{Binding IsSortedBySaved, Mode=OneTime}"
|
||||
Tag="Saved" />
|
||||
</StackPanel>
|
||||
<Border
|
||||
Width="60"
|
||||
Height="2"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
BorderBrush="White"
|
||||
BorderThickness="0,1,0,0">
|
||||
<Separator Height="0" HorizontalAlignment="Stretch" />
|
||||
</Border>
|
||||
<RadioButton
|
||||
Checked="Order_Checked"
|
||||
Content="{ext:Locale OrderAscending}"
|
||||
GroupName="Order"
|
||||
IsChecked="{Binding SortingAscending, Mode=OneTime}"
|
||||
Tag="Ascending" />
|
||||
<RadioButton
|
||||
Checked="Order_Checked"
|
||||
Content="{ext:Locale OrderDescending}"
|
||||
GroupName="Order"
|
||||
IsChecked="{Binding !SortingAscending, Mode=OneTime}"
|
||||
Tag="Descending" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</DropDownButton.Flyout>
|
||||
</DropDownButton>
|
||||
</StackPanel>
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
MinHeight="29"
|
||||
MaxHeight="29"
|
||||
Margin="5 0 5 0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Watermark="{ext:Locale Search}"
|
||||
Text="{Binding Search}" />
|
||||
<StackPanel
|
||||
Grid.Column="2"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Name="SelectDisplayedButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding SelectDisplayed}">
|
||||
<TextBlock Text="{ext:Locale XCITrimmerSelectDisplayed}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="DeselectDisplayedButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Command="{Binding DeselectDisplayed}">
|
||||
<TextBlock Text="{ext:Locale XCITrimmerDeselectDisplayed}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
<Border
|
||||
Grid.Row="2"
|
||||
Margin="0 0 0 10"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="2.5">
|
||||
<ListBox
|
||||
AutoScrollToSelectedItem="{Binding Processing}"
|
||||
SelectedItem="{Binding NullableProcessingApplication}"
|
||||
SelectionMode="Multiple, Toggle"
|
||||
Background="Transparent"
|
||||
SelectionChanged="OnSelectionChanged"
|
||||
SelectedItems="{Binding SelectedDisplayedXCIFiles, Mode=OneWay}"
|
||||
ItemsSource="{Binding DisplayedXCIFiles}"
|
||||
IsEnabled="{Binding !Processing}">
|
||||
<ListBox.DataTemplates>
|
||||
<DataTemplate
|
||||
DataType="models:XCITrimmerFileModel">
|
||||
<Panel Margin="10">
|
||||
<Grid ColumnDefinitions="65*,35*">
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Margin="10 0 10 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="2"
|
||||
TextWrapping="Wrap"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
Text="{Binding Name}">
|
||||
</TextBlock>
|
||||
<Grid Grid.Column="1" ColumnDefinitions="45*,55*">
|
||||
<ProgressBar
|
||||
Height="10"
|
||||
Margin="10 0 10 0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="5"
|
||||
IsVisible="{Binding $parent[UserControl].((viewModels:XCITrimmerViewModel)DataContext).Processing}"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Value="{Binding PercentageProgress}" />
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Margin="10 0 10 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileStatusConverter.Instance}}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel
|
||||
IsVisible="{Binding IsFailed}">
|
||||
<TextBlock
|
||||
Classes="h1"
|
||||
Text="{ext:Locale XCITrimmerTitleStatusFailed}" />
|
||||
<TextBlock
|
||||
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileStatusDetailConverter.Instance}}"
|
||||
MaxLines="5"
|
||||
MaxWidth="200"
|
||||
MaxHeight="100"
|
||||
TextTrimming="None"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</ToolTip.Tip>
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Margin="10 0 10 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{Binding ., Converter={x:Static helpers:XCITrimmerFileSpaceSavingsConverter.Instance}}">>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</ListBox.DataTemplates>
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<Border
|
||||
Grid.Row="3"
|
||||
Margin="0 0 0 10"
|
||||
HorizontalAlignment="Stretch"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="2.5">
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto">
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Classes="h1"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{ext:Locale XCITrimmerPotentialSavings}" />
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
Classes="h1"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{ext:Locale XCITrimmerActualSavings}" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{Binding PotentialSavings}" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
MaxLines="1"
|
||||
Text="{Binding ActualSavings}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<Panel
|
||||
Grid.Row="4"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Left">
|
||||
<Button
|
||||
Name="TrimButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Trim"
|
||||
IsEnabled="{Binding CanTrim}">
|
||||
<TextBlock Text="{ext:Locale XCITrimmerTrim}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="UntrimButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Untrim"
|
||||
IsEnabled="{Binding CanUntrim}">
|
||||
<TextBlock Text="{ext:Locale XCITrimmerUntrim}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Orientation="Horizontal"
|
||||
Spacing="10"
|
||||
HorizontalAlignment="Right">
|
||||
<Button
|
||||
Name="CancellingButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Cancel"
|
||||
IsEnabled="False">
|
||||
<Button.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="Processing" />
|
||||
<Binding Path="Cancel" />
|
||||
</MultiBinding>
|
||||
</Button.IsVisible>
|
||||
<TextBlock Text="{ext:Locale InputDialogCancelling}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="CancelButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Cancel">
|
||||
<Button.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<Binding Path="Processing" />
|
||||
<Binding Path="!Cancel" />
|
||||
</MultiBinding>
|
||||
</Button.IsVisible>
|
||||
<TextBlock Text="{ext:Locale InputDialogCancel}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="CloseButton"
|
||||
MinWidth="90"
|
||||
Margin="5"
|
||||
Click="Close"
|
||||
IsVisible="{Binding !Processing}">
|
||||
<TextBlock Text="{ext:Locale InputDialogClose}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -1,101 +0,0 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
{
|
||||
public partial class XCITrimmerWindow : UserControl
|
||||
{
|
||||
public XCITrimmerViewModel ViewModel;
|
||||
|
||||
public XCITrimmerWindow()
|
||||
{
|
||||
DataContext = this;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public XCITrimmerWindow(MainWindowViewModel mainWindowViewModel)
|
||||
{
|
||||
DataContext = ViewModel = new XCITrimmerViewModel(mainWindowViewModel);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static async Task Show()
|
||||
{
|
||||
ContentDialog contentDialog = new()
|
||||
{
|
||||
PrimaryButtonText = string.Empty,
|
||||
SecondaryButtonText = string.Empty,
|
||||
CloseButtonText = string.Empty,
|
||||
Content = new XCITrimmerWindow(RyujinxApp.MainWindow.ViewModel),
|
||||
Title = LocaleManager.Instance[LocaleKeys.XCITrimmerWindowTitle]
|
||||
};
|
||||
|
||||
Style bottomBorder = new(x => x.OfType<Grid>().Name("DialogSpace").Child().OfType<Border>());
|
||||
bottomBorder.Setters.Add(new Setter(IsVisibleProperty, false));
|
||||
|
||||
contentDialog.Styles.Add(bottomBorder);
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
|
||||
private void Trim(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.TrimSelected();
|
||||
}
|
||||
|
||||
private void Untrim(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.UntrimSelected();
|
||||
}
|
||||
|
||||
private void Close(object sender, RoutedEventArgs e)
|
||||
{
|
||||
((ContentDialog)Parent).Hide();
|
||||
}
|
||||
|
||||
private void Cancel(Object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.Cancel = true;
|
||||
}
|
||||
|
||||
public void Sort_Checked(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is RadioButton { Tag: string sortField })
|
||||
ViewModel.SortingField = Enum.Parse<XCITrimmerViewModel.SortField>(sortField);
|
||||
}
|
||||
|
||||
public void Order_Checked(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (sender is RadioButton { Tag: string sortOrder })
|
||||
ViewModel.SortingAscending = sortOrder is "Ascending";
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
foreach (object content in e.AddedItems)
|
||||
{
|
||||
if (content is XCITrimmerFileModel applicationData)
|
||||
{
|
||||
ViewModel.Select(applicationData);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (object content in e.RemovedItems)
|
||||
{
|
||||
if (content is XCITrimmerFileModel applicationData)
|
||||
{
|
||||
ViewModel.Deselect(applicationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue