StandardView

This commit is contained in:
DismissedLight
2024-07-02 17:07:46 +08:00
parent 64d9d04608
commit a3fb0486c2
8 changed files with 232 additions and 36 deletions

View File

@@ -12,6 +12,7 @@
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/Elevation.xaml"/>
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/ItemIcon.xaml"/>
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/Loading.xaml"/>
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/StandardView.xaml"/>
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/Card/CardBlock.xaml"/>
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/Card/CardProgressBar.xaml"/>
<ResourceDictionary Source="ms-appx:///UI/Xaml/Control/Card/HorizontalCard.xaml"/>

View File

@@ -95,6 +95,7 @@
<None Remove="UI\Xaml\Control\Card\VerticalCard.xaml" />
<None Remove="UI\Xaml\Control\Elevation.xaml" />
<None Remove="UI\Xaml\Control\ItemIcon.xaml" />
<None Remove="UI\Xaml\Control\StandardView.xaml" />
<None Remove="UI\Xaml\Control\Theme\Card.xaml" />
<None Remove="UI\Xaml\Control\Theme\Color.xaml" />
<None Remove="UI\Xaml\Control\Theme\ComboBox.xaml" />
@@ -339,6 +340,11 @@
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnablePreviewMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<Page Update="UI\Xaml\Control\StandardView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Service\Game\Automation\ScreenCapture\GameScreenCaptureDebugPreviewWindow.xaml">
<Generator>MSBuild:Compile</Generator>

View File

@@ -0,0 +1,55 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Snap.Hutao.UI.Xaml.Control;
[TemplateVisualState(Name = "Show", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Empty", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Hide", GroupName = "CommonStates")]
[DependencyProperty("EmptyContent", typeof(UIElement))]
[DependencyProperty("ShowCondition", typeof(bool), false, nameof(OnShowConditionChanged))]
[DependencyProperty("HideCondition", typeof(bool), false, nameof(OnHideConditionChanged))]
internal sealed partial class StandardView : ContentControl
{
public StandardView()
{
DefaultStyleKey = typeof(StandardView);
}
private static void OnShowConditionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is StandardView view)
{
view.UpdateState();
}
}
private static void OnHideConditionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is StandardView view)
{
view.UpdateState();
}
}
private void UpdateState()
{
if (HideCondition)
{
VisualStateManager.GoToState(this, "Hide", true);
return;
}
if (ShowCondition)
{
VisualStateManager.GoToState(this, "Show", true);
}
else
{
VisualStateManager.GoToState(this, "Empty", true);
}
}
}

View File

@@ -0,0 +1,107 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shuxc="using:Snap.Hutao.UI.Xaml.Control">
<Visibility x:Key="VisibilityVisible">Visible</Visibility>
<Visibility x:Key="VisibilityCollapsed">Collapsed</Visibility>
<CubicEase x:Key="CubicEaseFunction"/>
<Style BasedOn="{StaticResource DefaultStandardViewStyle}" TargetType="shuxc:StandardView"/>
<Style x:Key="DefaultStandardViewStyle" TargetType="shuxc:StandardView">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="shuxc:StandardView">
<Grid>
<ContentPresenter
x:Name="PartContent"
Content="{TemplateBinding Content}"
Opacity="0"
Visibility="Collapsed"/>
<ContentPresenter
x:Name="PartEmptyContent"
Content="{TemplateBinding EmptyContent}"
Opacity="0"
Visibility="Collapsed"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Show">
<Storyboard>
<DoubleAnimation
EasingFunction="{StaticResource CubicEaseFunction}"
Storyboard.TargetName="PartEmptyContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartEmptyContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityVisible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
EasingFunction="{StaticResource CubicEaseFunction}"
Storyboard.TargetName="PartContent"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.3"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Empty">
<Storyboard>
<DoubleAnimation
EasingFunction="{StaticResource CubicEaseFunction}"
Storyboard.TargetName="PartContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartEmptyContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityVisible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
EasingFunction="{StaticResource CubicEaseFunction}"
Storyboard.TargetName="PartEmptyContent"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.3"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Hide">
<Storyboard>
<DoubleAnimation
EasingFunction="{StaticResource CubicEaseFunction}"
Storyboard.TargetName="PartContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation
EasingFunction="{StaticResource CubicEaseFunction}"
Storyboard.TargetName="PartEmptyContent"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.3"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PartEmptyContent" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource VisibilityCollapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Stretch"/>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,16 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.UI.Xaml.Data;
internal static class AdvancedCollectionViewExtension
{
public static void MoveCurrentToFirstOrDefault<T>(this IAdvancedCollectionView<T> view)
where T : class
{
if (!view.MoveCurrentToFirst())
{
view.MoveCurrentTo(default);
}
}
}

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.WinUI.Collections;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data;
using System.Collections;
using System.Collections.ObjectModel;
@@ -70,7 +71,18 @@ internal interface IAdvancedCollectionView<T> : ICollectionView, IEnumerable
int IList<object>.IndexOf(object item)
{
return IndexOf((T)item);
if (item is T dataItem1)
{
return IndexOf(dataItem1);
}
// WinUI somehow pass in a FrameworkElement with DataContext as actual item
if (item is FrameworkElement { DataContext: T dataItem2 })
{
return IndexOf(dataItem2);
}
return IndexOf(default!);
}
int IndexOf(T item);
@@ -87,7 +99,7 @@ internal interface IAdvancedCollectionView<T> : ICollectionView, IEnumerable
return MoveCurrentTo((T)item);
}
bool MoveCurrentTo(T item);
bool MoveCurrentTo(T? item);
void ObserveFilterProperty(string propertyName);

View File

@@ -191,8 +191,37 @@
<shuxb:InvokeCommandOnLoadedBehavior Command="{Binding LoadCommand}"/>
</mxi:Interaction.Behaviors>
<Grid Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
<Grid Visibility="{Binding Archives.CurrentItem, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<shuxc:StandardView HideCondition="{Binding IsInitialized, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" ShowCondition="{Binding Achievements, Converter={StaticResource EmptyObjectToBoolConverter}, Mode=OneWay}">
<shuxc:StandardView.EmptyContent>
<Border
HorizontalAlignment="Center"
VerticalAlignment="Center"
cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border
MinWidth="480"
Padding="16"
Style="{ThemeResource AcrylicBorderCardStyle}">
<StackPanel>
<Image
Width="120"
Height="120"
Source="ms-appx:///Resource/Navigation/Achievement.png"/>
<TextBlock
Margin="0,16,0,0"
HorizontalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{shuxm:ResourceString Name=ViewPageAchievementAddArchiveHint}"/>
<Button
Margin="0,16,0,0"
Padding="16,8"
HorizontalAlignment="Stretch"
Command="{Binding AddArchiveCommand}"
Content="{shuxm:ResourceString Name=ViewPageAchievementAddArchive}"/>
</StackPanel>
</Border>
</Border>
</shuxc:StandardView.EmptyContent>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
@@ -370,36 +399,6 @@
</Border>
</Border>
</Grid>
</shuxc:StandardView>
<Grid Visibility="{Binding Archives.CurrentItem, Converter={StaticResource EmptyObjectToVisibilityRevertConverter}}">
<Border
HorizontalAlignment="Center"
VerticalAlignment="Center"
cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border
MinWidth="480"
Padding="16"
Style="{ThemeResource AcrylicBorderCardStyle}">
<StackPanel>
<Image
Width="120"
Height="120"
Source="ms-appx:///Resource/Navigation/Achievement.png"/>
<TextBlock
Margin="0,16,0,0"
HorizontalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{shuxm:ResourceString Name=ViewPageAchievementAddArchiveHint}"/>
<Button
Margin="0,16,0,0"
Padding="16,8"
HorizontalAlignment="Stretch"
Command="{Binding AddArchiveCommand}"
Content="{shuxm:ResourceString Name=ViewPageAchievementAddArchive}"/>
</StackPanel>
</Border>
</Border>
</Grid>
</Grid>
</shuxc:ScopedPage>

View File

@@ -227,7 +227,7 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
}
await scopeContext.TaskContext.SwitchToMainThreadAsync();
Archives.MoveCurrentToFirst();
Archives.MoveCurrentToFirstOrDefault();
}
catch (OperationCanceledException)
{