gamefiltres

This commit is contained in:
rmbgame
2021-04-20 23:35:16 +08:00
parent bb1bf1eb63
commit 5b006b28ff
11 changed files with 475 additions and 60 deletions
+33
View File
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace System
{
@@ -32,5 +34,36 @@ namespace System
}
public static int ConvertToInt32<TEnum>(TEnum value) where TEnum : Enum => ConvertToEnum<int, TEnum>(value);
/// <summary>
/// 返回指定枚举值的描述(通过
/// <see cref="System.ComponentModel.DescriptionAttribute"/> 指定)。
/// 如果没有指定描述,则返回枚举常数的名称,没有找到枚举常数则返回枚举值。
/// </summary>
/// <param name="value">要获取描述的枚举值。</param>
/// <returns>指定枚举值的描述。</returns>
public static string? GetDescription<TEnum>(this TEnum value) where TEnum : struct, Enum
{
Type enumType = value.GetType();
// 获取枚举常数名称。
string name = Enum.GetName(enumType, value);
if (name != null)
{
// 获取枚举字段。
FieldInfo fieldInfo = enumType.GetField(name);
if (fieldInfo != null)
{
if (Attribute.GetCustomAttribute(fieldInfo,
typeof(DescriptionAttribute), false) is DescriptionAttribute description)
{
if (description != null)
{
return description.Description;
}
}
}
}
return null;
}
}
}
@@ -10,22 +10,25 @@ namespace System.Application.Converters
{
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
public override object? ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
if (null != value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
if (null != fi)
if (value.GetType().IsEnum)
{
var attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
FieldInfo fi = value.GetType().GetField(value.ToString());
return ((attributes.Length > 0) && (!string.IsNullOrEmpty(attributes[0].Description)))
? attributes[0].Description
: value.ToString();
if (null != fi)
{
var attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return ((attributes.Length > 0) && (!string.IsNullOrEmpty(attributes[0].Description)))
? attributes[0].Description
: value.ToString();
}
}
}
@@ -1,4 +1,5 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:resx="clr-namespace:System.Application.UI.Resx;assembly=System.Application.SteamTools.Client.Desktop"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<Border Padding="20" Background="Green">
@@ -16,9 +17,15 @@
<Thickness x:Key="TextControlBorderThemeThickness">0,0,0,2</Thickness>
<Thickness x:Key="TextControlBorderThemeThicknessFocused">0,0,0,2</Thickness>
<Thickness x:Key="TextControlThemePadding">15,10,15,8</Thickness>
<ContextMenu x:Key="DefaultTextBoxContextMenu" x:Name="TextBoxContextMenu">
<MenuItem x:Name="TextBoxContextMenuCutItem" Header="{ReflectionBinding Path=Res.Cut,Mode=OneWay,Source={x:Static resx:R.Current}}" Command="{Binding $parent[TextBox].Cut}" IsEnabled="{Binding $parent[TextBox].CanCut}" InputGesture="{x:Static TextBox.CutGesture}" />
<MenuItem x:Name="TextBoxContextMenuCopyItem" Header="{ReflectionBinding Path=Res.Copy,Mode=OneWay,Source={x:Static resx:R.Current}}" Command="{Binding $parent[TextBox].Copy}" IsEnabled="{Binding $parent[TextBox].CanCopy}" InputGesture="{x:Static TextBox.CopyGesture}"/>
<MenuItem x:Name="TextBoxContextMenuPasteItem" Header="{ReflectionBinding Path=Res.Paste,Mode=OneWay,Source={x:Static resx:R.Current}}" Command="{Binding $parent[TextBox].Paste}" IsEnabled="{Binding $parent[TextBox].CanPaste}" InputGesture="{x:Static TextBox.PasteGesture}"/>
</ContextMenu>
</Styles.Resources>
<Style Selector="TextBox">
<Setter Property="ContextMenu" Value="{StaticResource DefaultTextBoxContextMenu}" />
<Setter Property="Template">
<ControlTemplate>
<DockPanel>
@@ -5,13 +5,13 @@
xmlns:vm="clr-namespace:System.Application.UI.ViewModels;assembly=System.Application.SteamTools.Client.Desktop"
xmlns:service="clr-namespace:System.Application.Services;assembly=System.Application.SteamTools.Client.Desktop"
xmlns:controls="using:System.Application.UI.Views.Controls"
mc:Ignorable="d"
d:DesignWidth="300"
d:DesignHeight="50"
mc:Ignorable="d"
d:DesignWidth="300"
d:DesignHeight="50"
Margin="0 0 0 20"
x:DataType="vm:MainWindowViewModel"
x:CompileBindings="True"
Background="Transparent"
Background="Transparent"
IsVisible="{Binding Source={x:Static service:ToastService.Current},Path=IsVisible,Mode=OneWay}"
x:Class="System.Application.UI.Views.Controls.ToastMessage">
<UserControl.Styles>
@@ -24,7 +24,7 @@
</Transitions>
</Setter>
</Style>
<Style Selector="controls|ToastMessage[IsVisible=true]">
<Style.Animations>
<Animation Duration="0:0:0.25" Easing="QuadraticEaseIn" FillMode="Forward">
@@ -69,7 +69,7 @@
</Style.Animations>
</Style>
</UserControl.Styles>
<Border Background="{DynamicResource InactiveBackgroundBrushKey}" Padding="20 0 10 0">
<StackPanel Orientation="Horizontal">
<PathIcon Data="{StaticResource InfoDrawing}"
@@ -80,8 +80,12 @@
<Border Padding="10">
<TextBlock Text="{Binding Source={x:Static service:ToastService.Current},Path=Message,Mode=OneWay}" FontSize="14" Foreground="{DynamicResource HighlightForegroundColorKey}" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="WrapWithOverflow" MaxWidth="780"/>
</Border>
<Button Width="40" Height="40" Background="Transparent" Command="{ReflectionBinding Source={x:Static service:ToastService.Current},Path=CloseBtn_Click}" Cursor="Hand">
<PathIcon Data="{DynamicResource CloseDrawing}" Width="12"></PathIcon>
<Button Width="40" Height="40"
Background="Transparent"
VerticalContentAlignment="Center"
Command="{ReflectionBinding Source={x:Static service:ToastService.Current},Path=CloseBtn_Click}"
Cursor="Hand">
<PathIcon Data="{DynamicResource CloseDrawing}" Width="12" Height="12"></PathIcon>
</Button>
</StackPanel>
</Border>
@@ -67,19 +67,19 @@
<PathIcon Width="20" Height="20" Data="{StaticResource RefreshDrawing}" />
</Button>
<ToggleButton x:Name="typebutton"
VerticalAlignment="Center"
MinWidth="200"
<ToggleButton x:Name="typebutton"
VerticalAlignment="Center"
MinWidth="200"
IsChecked="{Binding IsOpenFilter,Mode=TwoWay}">
<DockPanel>
<TextBlock Text="游戏和软件"></TextBlock>
<PathIcon
HorizontalAlignment="Right"
Data="{StaticResource ChevronDownDrawing}"
<PathIcon
HorizontalAlignment="Right"
Data="{StaticResource ChevronDownDrawing}"
Width="16"></PathIcon>
</DockPanel>
</ToggleButton>
<Popup
<Popup
IsOpen="{Binding IsOpenFilter,Mode=TwoWay, FallbackValue=False}"
StaysOpen="False" Width="201"
PlacementMode="Bottom"
@@ -87,16 +87,28 @@
HorizontalOffset="-2.5"
IsLightDismissEnabled="True">
<Border Background="Black" Width="{Binding $parent.Width}" Height="200">
<!--<ItemsControl Items="{Binding GameFilters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<CheckBox IsChecked="{Binding Enable}"></CheckBox>
<TextBlock Text="{Binding Name}"></TextBlock>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>-->
<ScrollViewer Padding="10 5">
<ItemsControl Items="{Binding AppTypeFiltres}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<CheckBox IsChecked="{Binding Enable}"
VerticalAlignment="Center">
<WrapPanel>
<TextBlock Text="{Binding Name_Localiza}"
VerticalAlignment="Center"/>
<TextBlock Margin="5 0 0 0"
Text="{Binding Count}"
VerticalAlignment="Center"
FontSize="12"
Foreground="{DynamicResource InactiveForegroundBrushKey}"/>
</WrapPanel>
</CheckBox>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
</Popup>
</StackPanel>
@@ -0,0 +1,76 @@
using ReactiveUI;
using System;
using System.Application.UI.Resx;
using System.Collections.Generic;
using System.Text;
namespace System.Application.Models
{
public class EnumModel : ReactiveObject
{
public static List<EnumModel<E>> GetEnumModels<E>() where E : struct, Enum
{
var list = new List<EnumModel<E>>();
foreach (var key in Enum.GetNames(typeof(E)))
{
list.Add(new EnumModel<E>(key, Enum.Parse<E>(key)));
}
return list;
}
}
public class EnumModel<T> : ReactiveObject where T : struct, Enum
{
public EnumModel() { }
public EnumModel(string name, T value)
{
Name = name;
Value = value;
}
private string? _Name;
public string? Name
{
get => _Name;
set => this.RaiseAndSetIfChanged(ref _Name, value);
}
public string? Description
{
get => Enum2.GetDescription<T>(Value);
}
public string? Name_Localiza
{
get => string.IsNullOrEmpty(Description)
? AppResources.ResourceManager.GetString(Name, AppResources.Culture)
: AppResources.ResourceManager.GetString(Description, AppResources.Culture);
}
private T _Value;
public T Value
{
get => _Value;
set => this.RaiseAndSetIfChanged(ref _Value, value);
}
private bool _Enable;
public bool Enable
{
get => _Enable;
set => this.RaiseAndSetIfChanged(ref _Enable, value);
}
/// <summary>
/// 枚举作为type时统计集合数量
/// </summary>
private int _Count;
public int Count
{
get => _Count;
set => this.RaiseAndSetIfChanged(ref _Count, value);
}
}
}
@@ -4,66 +4,68 @@ namespace System.Application.Models
{
public enum SteamAppType : byte
{
[Description("未知")]
[Description("SteamAppType_Unknown")]
Unknown = 0,
[Description("游戏")]
[Description("SteamAppType_Game")]
Game = 1,
[Description("软件")]
[Description("SteamAppType_Application")]
Application = 2,
[Description("工具")]
[Description("SteamAppType_Tool")]
Tool = 3,
[Description("Demo")]
[Description("SteamAppType_Demo")]
Demo = 4,
[Description("预告视频")]
[Description("SteamAppType_Media")]
Media = 5,
[Description("DLC")]
[Description("SteamAppType_DLC")]
DLC = 6,
[Description("指南")]
[Description("SteamAppType_Guide")]
Guide = 7,
[Description("驱动")]
[Description("SteamAppType_Driver")]
Driver = 8,
[Description("隐藏软件")]
[Description("SteamAppType_Config")]
Config = 9,
[Description("硬件")]
[Description("SteamAppType_Hardware")]
Hardware = 10,
[Description("授权")]
[Description("SteamAppType_Franchise")]
Franchise = 11,
[Description("视频")]
[Description("SteamAppType_Video")]
Video = 12,
[Description("插件")]
[Description("SteamAppType_Plugin")]
Plugin = 13,
[Description("原声音轨")]
[Description("SteamAppType_Music")]
Music = 14,
[Description("影视集")]
[Description("SteamAppType_Series")]
Series = 15,
[Description("快捷方式")]
[Description("SteamAppType_Shortcut")]
Shortcut = 16,
[Description("仓库")]
[Description("SteamAppType_DepotOnly")]
DepotOnly = 17,
[Description("SteamAppType_Mod")]
Mod = 18,
}
#if DEBUG
[Obsolete("use SteamAppType", true)]
public enum SteamAppTypeEnum
public enum SteamAppTypeEnum : byte
{
/// <summary>
/// Unknown
+198
View File
@@ -456,6 +456,24 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 复制 的本地化字符串。
/// </summary>
public static string Copy {
get {
return ResourceManager.GetString("Copy", resourceCulture);
}
}
/// <summary>
/// 查找类似 剪切 的本地化字符串。
/// </summary>
public static string Cut {
get {
return ResourceManager.GetString("Cut", resourceCulture);
}
}
/// <summary>
/// 查找类似 账号注销 的本地化字符串。
/// </summary>
@@ -1177,6 +1195,15 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 粘贴 的本地化字符串。
/// </summary>
public static string Paste {
get {
return ResourceManager.GetString("Paste", resourceCulture);
}
}
/// <summary>
/// 查找类似 请输入昵称 的本地化字符串。
/// </summary>
@@ -1475,6 +1502,177 @@ namespace System.Application.UI.Resx {
}
}
/// <summary>
/// 查找类似 软件 的本地化字符串。
/// </summary>
public static string SteamAppType_Application {
get {
return ResourceManager.GetString("SteamAppType_Application", resourceCulture);
}
}
/// <summary>
/// 查找类似 配置 的本地化字符串。
/// </summary>
public static string SteamAppType_Config {
get {
return ResourceManager.GetString("SteamAppType_Config", resourceCulture);
}
}
/// <summary>
/// 查找类似 Demo 的本地化字符串。
/// </summary>
public static string SteamAppType_Demo {
get {
return ResourceManager.GetString("SteamAppType_Demo", resourceCulture);
}
}
/// <summary>
/// 查找类似 仓库 的本地化字符串。
/// </summary>
public static string SteamAppType_DepotOnly {
get {
return ResourceManager.GetString("SteamAppType_DepotOnly", resourceCulture);
}
}
/// <summary>
/// 查找类似 DLC 的本地化字符串。
/// </summary>
public static string SteamAppType_DLC {
get {
return ResourceManager.GetString("SteamAppType_DLC", resourceCulture);
}
}
/// <summary>
/// 查找类似 驱动 的本地化字符串。
/// </summary>
public static string SteamAppType_Driver {
get {
return ResourceManager.GetString("SteamAppType_Driver", resourceCulture);
}
}
/// <summary>
/// 查找类似 授权 的本地化字符串。
/// </summary>
public static string SteamAppType_Franchise {
get {
return ResourceManager.GetString("SteamAppType_Franchise", resourceCulture);
}
}
/// <summary>
/// 查找类似 游戏 的本地化字符串。
/// </summary>
public static string SteamAppType_Game {
get {
return ResourceManager.GetString("SteamAppType_Game", resourceCulture);
}
}
/// <summary>
/// 查找类似 指南 的本地化字符串。
/// </summary>
public static string SteamAppType_Guide {
get {
return ResourceManager.GetString("SteamAppType_Guide", resourceCulture);
}
}
/// <summary>
/// 查找类似 硬件 的本地化字符串。
/// </summary>
public static string SteamAppType_Hardware {
get {
return ResourceManager.GetString("SteamAppType_Hardware", resourceCulture);
}
}
/// <summary>
/// 查找类似 预告视频 的本地化字符串。
/// </summary>
public static string SteamAppType_Media {
get {
return ResourceManager.GetString("SteamAppType_Media", resourceCulture);
}
}
/// <summary>
/// 查找类似 模组 的本地化字符串。
/// </summary>
public static string SteamAppType_Mod {
get {
return ResourceManager.GetString("SteamAppType_Mod", resourceCulture);
}
}
/// <summary>
/// 查找类似 原声音轨 的本地化字符串。
/// </summary>
public static string SteamAppType_Music {
get {
return ResourceManager.GetString("SteamAppType_Music", resourceCulture);
}
}
/// <summary>
/// 查找类似 插件 的本地化字符串。
/// </summary>
public static string SteamAppType_Plugin {
get {
return ResourceManager.GetString("SteamAppType_Plugin", resourceCulture);
}
}
/// <summary>
/// 查找类似 影视集 的本地化字符串。
/// </summary>
public static string SteamAppType_Series {
get {
return ResourceManager.GetString("SteamAppType_Series", resourceCulture);
}
}
/// <summary>
/// 查找类似 快捷方式 的本地化字符串。
/// </summary>
public static string SteamAppType_Shortcut {
get {
return ResourceManager.GetString("SteamAppType_Shortcut", resourceCulture);
}
}
/// <summary>
/// 查找类似 工具 的本地化字符串。
/// </summary>
public static string SteamAppType_Tool {
get {
return ResourceManager.GetString("SteamAppType_Tool", resourceCulture);
}
}
/// <summary>
/// 查找类似 未知 的本地化字符串。
/// </summary>
public static string SteamAppType_Unknown {
get {
return ResourceManager.GetString("SteamAppType_Unknown", resourceCulture);
}
}
/// <summary>
/// 查找类似 视频 的本地化字符串。
/// </summary>
public static string SteamAppType_Video {
get {
return ResourceManager.GetString("SteamAppType_Video", resourceCulture);
}
}
/// <summary>
/// 查找类似 {0}成功 的本地化字符串。
/// </summary>
@@ -250,6 +250,12 @@
<data name="Continue" xml:space="preserve">
<value>继续</value>
</data>
<data name="Copy" xml:space="preserve">
<value>复制</value>
</data>
<data name="Cut" xml:space="preserve">
<value>剪切</value>
</data>
<data name="DelAccount" xml:space="preserve">
<value>账号注销</value>
</data>
@@ -493,6 +499,9 @@
<data name="OtherGamePlaform" xml:space="preserve">
<value>其它平台</value>
</data>
<data name="Paste" xml:space="preserve">
<value>粘贴</value>
</data>
<data name="PleaseEnterNickName" xml:space="preserve">
<value>请输入昵称</value>
</data>
@@ -581,6 +590,63 @@
<data name="SteamAccount" xml:space="preserve">
<value>Steam 账号</value>
</data>
<data name="SteamAppType_Application" xml:space="preserve">
<value>软件</value>
</data>
<data name="SteamAppType_Config" xml:space="preserve">
<value>配置</value>
</data>
<data name="SteamAppType_Demo" xml:space="preserve">
<value>Demo</value>
</data>
<data name="SteamAppType_DepotOnly" xml:space="preserve">
<value>仓库</value>
</data>
<data name="SteamAppType_DLC" xml:space="preserve">
<value>DLC</value>
</data>
<data name="SteamAppType_Driver" xml:space="preserve">
<value>驱动</value>
</data>
<data name="SteamAppType_Franchise" xml:space="preserve">
<value>授权</value>
</data>
<data name="SteamAppType_Game" xml:space="preserve">
<value>游戏</value>
</data>
<data name="SteamAppType_Guide" xml:space="preserve">
<value>指南</value>
</data>
<data name="SteamAppType_Hardware" xml:space="preserve">
<value>硬件</value>
</data>
<data name="SteamAppType_Media" xml:space="preserve">
<value>预告视频</value>
</data>
<data name="SteamAppType_Mod" xml:space="preserve">
<value>模组</value>
</data>
<data name="SteamAppType_Music" xml:space="preserve">
<value>原声音轨</value>
</data>
<data name="SteamAppType_Plugin" xml:space="preserve">
<value>插件</value>
</data>
<data name="SteamAppType_Series" xml:space="preserve">
<value>影视集</value>
</data>
<data name="SteamAppType_Shortcut" xml:space="preserve">
<value>快捷方式</value>
</data>
<data name="SteamAppType_Tool" xml:space="preserve">
<value>工具</value>
</data>
<data name="SteamAppType_Unknown" xml:space="preserve">
<value>未知</value>
</data>
<data name="SteamAppType_Video" xml:space="preserve">
<value>视频</value>
</data>
<data name="Steam_ImageCodeTip" xml:space="preserve">
<value>输入图中验证码</value>
</data>
+1
View File
@@ -85,6 +85,7 @@ namespace System.Application.UI.Resx
AppResources.Culture = string.IsNullOrWhiteSpace(cultureName) ?
DefaultCurrentUICulture :
CultureInfo.GetCultureInfo(Languages.SingleOrDefault(x => x.Key == cultureName).Key);
CultureInfo.CurrentUICulture = AppResources.Culture;
mAcceptLanguage = GetAcceptLanguageCore();
mLanguage = GetLanguageCore();
Current.Res = new AppResources();
@@ -23,6 +23,7 @@ namespace System.Application.UI.ViewModels
public GameListPageViewModel()
{
IconKey = nameof(GameListPageViewModel).Replace("ViewModel", "Svg");
AppTypeFiltres = EnumModel.GetEnumModels<SteamAppType>();
}
private readonly Subject<Unit> updateSource = new();
@@ -73,12 +74,14 @@ namespace System.Application.UI.ViewModels
public bool IsSteamAppsEmpty => !SteamApps.Any_Nullable();
public IReadOnlyCollection<EnumModel<SteamAppType>> AppTypeFiltres { get; set; }
internal override void Initialize()
{
updateSource
.Do(_ => IsReloading = true)
.SelectMany(x => UpdateAsync())
.Do(_ => IsReloading = false)
this.updateSource
.Do(_ => this.IsReloading = true)
.SelectMany(x => this.UpdateAsync())
.Do(_ => this.IsReloading = false)
.Subscribe()
.AddTo(this);
@@ -114,15 +117,25 @@ namespace System.Application.UI.ViewModels
{
var list = SteamConnectService.Current.SteamApps?.Where(x => Predicate(x)).OrderBy(x => x.Name).ToList();
if (list.Any_Nullable())
SteamApps = list;
this.SteamApps = list;
else
SteamApps = null;
this.SteamApps = null;
});
}
public void Update()
{
updateSource.OnNext(Unit.Default);
this.updateSource.OnNext(Unit.Default);
this.CalcTypeCount();
}
public void CalcTypeCount()
{
if (SteamConnectService.Current.SteamApps.Any_Nullable())
foreach (var item in AppTypeFiltres)
{
item.Count = SteamConnectService.Current.SteamApps.Count(s => s.Type == item.Value);
}
}
public void AppClick(SteamApp app)