feat: 移植主页

This commit is contained in:
denglihong2007
2025-08-30 17:09:41 +08:00
parent d79e129724
commit b4a16c88f0
15 changed files with 729 additions and 51 deletions

View File

@@ -9,6 +9,7 @@
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<ResourceDictionary Source="Styles/Controls.xaml" />
<ResourceDictionary Source="ms-appx:///Controls/OpacityMaskView.xaml" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -14,22 +14,12 @@
<WindowsPackageType>None</WindowsPackageType>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<Content Remove="Assets\CRSimIcon.png" />
<Content Remove="Assets\HomeHeaderTiles\CRSim-Icon.ico" />
<Content Remove="Assets\HomeHeaderTiles\Header-Afdian.png" />
<Content Remove="Assets\HomeHeaderTiles\Header-docs.png" />
<Content Remove="Assets\HomeHeaderTiles\Header-QQ.png" />
</ItemGroup>
<ItemGroup>
<None Remove="Styles\Controls.xaml" />
<None Remove="Views\DialogContents\InputDialog.xaml" />
<None Remove="Views\StartWindow.xaml" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\LockScreenLogo.scale-200.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
@@ -51,6 +41,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="CommunityToolkit.WinUI.Animations" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
@@ -68,13 +59,18 @@
<ProjectReference Include="..\CRSim.ScreenSimulator\CRSim.ScreenSimulator.csproj" />
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\CRSimIcon.png" />
<Resource Include="Assets\HomeHeaderTiles\CRSim-Icon.ico" />
<Resource Include="Assets\HomeHeaderTiles\Header-Afdian.png" />
<Resource Include="Assets\HomeHeaderTiles\Header-docs.png" />
<Resource Include="Assets\HomeHeaderTiles\Header-QQ.png" />
</ItemGroup>
<ItemGroup>
<Page Update="Controls\HorizontalScrollContainer.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Controls\Tile.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Controls\OpacityMaskView.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Controls\HomePageHeader.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\DialogContents\TextDialog.xaml">
<SubType>Designer</SubType>
</Page>
@@ -113,18 +109,24 @@
<Content Update="Assets\CRSimIcon.ico">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\HomeHeaderTiles\GalleryHeaderImage.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\HomeHeaderTiles\Header-Afdian.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\HomeHeaderTiles\Header-docs.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\HomeHeaderTiles\Header-QQ.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Update="Assets\CRSimIcon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<Page Update="Views\StartWindow.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Update="Styles\Controls.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Views\Dialogs\InputDialog.xaml">

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="CRSim.Controls.HomePageHeader"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CRSim.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<x:String x:Key="GitHubIconPath">M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z</x:String>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<LinearGradientBrush x:Name="BackgroundGradient" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0.0" Color="#CED8E4" />
<GradientStop Offset="1.0" Color="#D5DBE3" />
</LinearGradientBrush>
<SolidColorBrush x:Key="ForegroundBrush" Color="Black" />
<x:Double x:Key="ImageOpacity">0.9</x:Double>
<LinearGradientBrush x:Key="OverlayRadialGradient" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFFFFFFF" />
<GradientStop Offset="0.75" Color="#FFFFFFFF" />
<GradientStop Offset="0.85" Color="#00FFFFFF" />
<GradientStop Offset="1" Color="#00FFFFFF" />
</LinearGradientBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="BackgroundGradient" Color="#020B20" />
<x:Double x:Key="ImageOpacity">0.8</x:Double>
<SolidColorBrush x:Key="ForegroundBrush" Color="White" />
<LinearGradientBrush x:Key="OverlayRadialGradient" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FF000000" />
<GradientStop Offset="0.75" Color="#FF000000" />
<GradientStop Offset="0.85" Color="#00000000" />
<GradientStop Offset="1" Color="#00000000" />
</LinearGradientBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="HeaderGrid" Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:OpacityMaskView
Grid.RowSpan="3"
Height="400"
VerticalAlignment="Stretch">
<local:OpacityMaskView.OpacityMask>
<Rectangle Fill="{ThemeResource OverlayRadialGradient}" />
</local:OpacityMaskView.OpacityMask>
<Grid
x:Name="ImageGrid"
Margin="0,-100,0,0"
Background="{ThemeResource BackgroundGradient}">
<Image
x:Name="HeroImage"
Opacity="{ThemeResource ImageOpacity}"
Source="/Assets/HomeHeaderTiles/GalleryHeaderImage.jpg"
Stretch="UniformToFill" />
</Grid>
</local:OpacityMaskView>
<TextBlock AutomationProperties.AutomationId="__ClickableAreaTextBlock" />
<StackPanel
Margin="36,48,0,0"
VerticalAlignment="Center"
Orientation="Vertical">
<TextBlock
x:Name="smallHeaderSubtitleText"
FontSize="18"
Foreground="{ThemeResource ForegroundBrush}"
Text="CRSim" />
<TextBlock
x:Name="smallHeaderText"
Foreground="{ThemeResource ForegroundBrush}"
Style="{StaticResource TitleLargeTextBlockStyle}"
Text="国铁信息显示模拟"
AutomationProperties.HeadingLevel="Level1" />
</StackPanel>
<local:HorizontalScrollContainer Grid.Row="2" Margin="0,56,0,0">
<local:HorizontalScrollContainer.Source>
<StackPanel Orientation="Horizontal" Spacing="12">
<local:Tile
Title="官方网站"
Description="访问我们的官网(部分地区可能访问缓慢)。"
Link="https://crsim.tech/">
<local:Tile.Source>
<Image Source="/Assets/CRSimIcon.png" />
</local:Tile.Source>
</local:Tile>
<local:Tile
Title="赞助作者"
Description="赏作者一口饭吃吧QAQ"
Link="https://afdian.com/a/CRSim">
<local:Tile.Source>
<Image Source="/Assets/HomeHeaderTiles/Header-Afdian.png" />
</local:Tile.Source>
</local:Tile>
<local:Tile
Title="开源仓库"
Description="欢迎贡献代码!当然功能样式请求和 Bug 反馈也请交到 Issue 中!"
Link="https://github.com/denglihong2007/CRSim">
<local:Tile.Source>
<Viewbox>
<PathIcon Data="{StaticResource GitHubIconPath}" Foreground="{ThemeResource TextFillColorPrimaryBrush}" />
</Viewbox>
</local:Tile.Source>
</local:Tile>
<local:Tile
Title="使用教程"
Description="一个优雅的食用或者开发教程。"
Link="https://docs.crsim.tech/">
<local:Tile.Source>
<Image Source="/Assets/HomeHeaderTiles/Header-docs.png" />
</local:Tile.Source>
</local:Tile>
<local:Tile
Title="交流鹅群"
Description="在这里分享你的使用经验与建议。或者玩玩抽象。加入暗号114514"
Link="https://qm.qq.com/q/uxCsP2veYS">
<local:Tile.Source>
<Image Source="/Assets/HomeHeaderTiles/Header-QQ.png"/>
</local:Tile.Source>
</local:Tile>
</StackPanel>
</local:HorizontalScrollContainer.Source>
</local:HorizontalScrollContainer>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,10 @@
namespace CRSim.Controls;
public sealed partial class HomePageHeader : UserControl
{
public HomePageHeader()
{
InitializeComponent();
}
}

View File

@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="CRSim.Controls.HorizontalScrollContainer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CRSim.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<Style x:Key="ScrollButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{ThemeResource FlipViewNextPreviousButtonBackground}" />
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource FlipViewNextPreviousButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
<Setter Property="FocusVisualMargin" Value="-3" />
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter
x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
AnimatedIcon.State="Normal"
AutomationProperties.AccessibilityView="Raw"
Background="{TemplateBinding Background}"
BackgroundSizing="{TemplateBinding BackgroundSizing}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter.BackgroundTransition>
<BrushTransition Duration="0:0:0.083" />
</ContentPresenter.BackgroundTransition>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBackgroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBorderBrushPointerOver}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousArrowForegroundPointerOver}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<VisualState.Setters>
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="PointerOver" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBackgroundPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousButtonBorderBrushPressed}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource FlipViewNextPreviousArrowForegroundPressed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<VisualState.Setters>
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="Pressed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushDisabled}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundDisabled}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<VisualState.Setters>
<!-- DisabledVisual Should be handled by the control, not the animated icon. -->
<Setter Target="ContentPresenter.(AnimatedIcon.State)" Value="Normal" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ScrollViewer
x:Name="scroller"
HorizontalScrollBarVisibility="Hidden"
HorizontalScrollMode="Enabled"
SizeChanged="Scroller_SizeChanged"
VerticalScrollBarVisibility="Hidden"
VerticalScrollMode="Disabled"
ViewChanging="Scroller_ViewChanging">
<Grid x:Name="ContentGrid" Margin="36,0,36,0">
<ContentPresenter Content="{x:Bind Source, Mode=OneWay}" />
</Grid>
</ScrollViewer>
<Button
x:Name="ScrollBackBtn"
Width="16"
Height="38"
Margin="8,-16,0,0"
AutomationProperties.Name="Scroll left"
Click="ScrollBackBtn_Click"
Style="{StaticResource ScrollButtonStyle}"
ToolTipService.ToolTip="Scroll left"
Visibility="Collapsed">
<FontIcon FontSize="{ThemeResource FlipViewButtonFontSize}" Glyph="&#xedd9;" />
</Button>
<Button
x:Name="ScrollForwardBtn"
Width="16"
Height="38"
Margin="0,-16,8,0"
HorizontalAlignment="Right"
AutomationProperties.Name="Scroll right"
Click="ScrollForwardBtn_Click"
Style="{StaticResource ScrollButtonStyle}"
ToolTipService.ToolTip="Scroll right">
<FontIcon FontSize="{ThemeResource FlipViewButtonFontSize}" Glyph="&#xEDDA;" />
</Button>
</Grid>
</UserControl>

View File

@@ -0,0 +1,72 @@
namespace CRSim.Controls;
public sealed partial class HorizontalScrollContainer : UserControl
{
public HorizontalScrollContainer()
{
this.InitializeComponent();
}
public object Source
{
get => (object)GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(nameof(Source), typeof(object), typeof(HorizontalScrollContainer), new PropertyMetadata(null));
private void Scroller_ViewChanging(object sender, ScrollViewerViewChangingEventArgs e)
{
if (e.FinalView.HorizontalOffset < 1)
{
ScrollBackBtn.Visibility = Visibility.Collapsed;
}
else if (e.FinalView.HorizontalOffset > 1)
{
ScrollBackBtn.Visibility = Visibility.Visible;
}
if (e.FinalView.HorizontalOffset > scroller.ScrollableWidth - 1)
{
ScrollForwardBtn.Visibility = Visibility.Collapsed;
}
else if (e.FinalView.HorizontalOffset < scroller.ScrollableWidth - 1)
{
ScrollForwardBtn.Visibility = Visibility.Visible;
}
}
private void ScrollBackBtn_Click(object sender, RoutedEventArgs e)
{
scroller.ChangeView(scroller.HorizontalOffset - scroller.ViewportWidth, null, null);
// Manually focus to ScrollForwardBtn since this button disappears after scrolling to the end.
ScrollForwardBtn.Focus(FocusState.Programmatic);
}
private void ScrollForwardBtn_Click(object sender, RoutedEventArgs e)
{
scroller.ChangeView(scroller.HorizontalOffset + scroller.ViewportWidth, null, null);
// Manually focus to ScrollBackBtn since this button disappears after scrolling to the end.
ScrollBackBtn.Focus(FocusState.Programmatic);
}
private void Scroller_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateScrollButtonsVisibility();
}
private void UpdateScrollButtonsVisibility()
{
if (scroller.ScrollableWidth > 0)
{
ScrollForwardBtn.Visibility = Visibility.Visible;
}
else
{
ScrollForwardBtn.Visibility = Visibility.Collapsed;
}
}
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CRSim.Controls">
<Style BasedOn="{StaticResource DefaultOpacityMaskViewStyle}" TargetType="local:OpacityMaskView" />
<Style x:Key="DefaultOpacityMaskViewStyle" TargetType="local:OpacityMaskView">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:OpacityMaskView">
<Grid
x:Name="PART_RootGrid"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border
x:Name="PART_MaskContainer"
Child="{TemplateBinding OpacityMask}"
IsHitTestVisible="False" />
<ContentPresenter
x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,85 @@
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Media;
using System.Numerics;
namespace CRSim.Controls;
[TemplatePart(Name = RootGridTemplateName, Type = typeof(Grid))]
[TemplatePart(Name = MaskContainerTemplateName, Type = typeof(Border))]
[TemplatePart(Name = ContentPresenterTemplateName, Type = typeof(ContentPresenter))]
public partial class OpacityMaskView : ContentControl
{
public static readonly DependencyProperty OpacityMaskProperty =
DependencyProperty.Register(nameof(OpacityMask), typeof(UIElement), typeof(OpacityMaskView), new PropertyMetadata(null, OnOpacityMaskChanged));
private const string ContentPresenterTemplateName = "PART_ContentPresenter";
private const string MaskContainerTemplateName = "PART_MaskContainer";
private const string RootGridTemplateName = "PART_RootGrid";
private readonly Compositor _compositor = CompositionTarget.GetCompositorForCurrentThread();
private CompositionBrush? _mask;
private CompositionMaskBrush? _maskBrush;
public OpacityMaskView()
{
DefaultStyleKey = typeof(OpacityMaskView);
}
public UIElement? OpacityMask
{
get => (UIElement?)GetValue(OpacityMaskProperty);
set => SetValue(OpacityMaskProperty, value);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
Grid rootGrid = (Grid)GetTemplateChild(RootGridTemplateName);
ContentPresenter contentPresenter = (ContentPresenter)GetTemplateChild(ContentPresenterTemplateName);
Border maskContainer = (Border)GetTemplateChild(MaskContainerTemplateName);
_maskBrush = _compositor.CreateMaskBrush();
_maskBrush.Source = GetVisualBrush(contentPresenter);
_mask = GetVisualBrush(maskContainer);
_maskBrush.Mask = OpacityMask is null ? null : _mask;
SpriteVisual redirectVisual = _compositor.CreateSpriteVisual();
redirectVisual.RelativeSizeAdjustment = Vector2.One;
redirectVisual.Brush = _maskBrush;
ElementCompositionPreview.SetElementChildVisual(rootGrid, redirectVisual);
}
private static CompositionBrush GetVisualBrush(UIElement element)
{
Visual visual = ElementCompositionPreview.GetElementVisual(element);
Compositor compositor = visual.Compositor;
CompositionVisualSurface visualSurface = compositor.CreateVisualSurface();
visualSurface.SourceVisual = visual;
ExpressionAnimation sourceSizeAnimation = compositor.CreateExpressionAnimation($"{nameof(visual)}.Size");
sourceSizeAnimation.SetReferenceParameter(nameof(visual), visual);
visualSurface.StartAnimation(nameof(visualSurface.SourceSize), sourceSizeAnimation);
CompositionSurfaceBrush brush = compositor.CreateSurfaceBrush(visualSurface);
visual.Opacity = 0;
return brush;
}
private static void OnOpacityMaskChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
OpacityMaskView self = (OpacityMaskView)d;
if (self._maskBrush is not { } maskBrush)
{
return;
}
UIElement? opacityMask = (UIElement?)e.NewValue;
maskBrush.Mask = opacityMask is null ? null : self._mask;
}
}

80
CRSim/Controls/Tile.xaml Normal file
View File

@@ -0,0 +1,80 @@
<UserControl
x:Class="CRSim.Controls.Tile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CRSim.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="200"
Height="190"
mc:Ignorable="d">
<Grid
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource SurfaceStrokeColorFlyoutBrush}"
CornerRadius="8">
<Grid.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="HyperlinkButtonBorderBrush" Color="{ThemeResource ControlStrokeColorDefault}" />
<SolidColorBrush x:Key="HyperlinkButtonBorderBrushPointerOver" Color="{ThemeResource ControlStrokeColorSecondary}" />
<SolidColorBrush x:Key="HyperlinkButtonBorderBrushPressed" Color="{ThemeResource ControlStrokeColorDefault}" />
<SolidColorBrush x:Key="HyperlinkButtonBorderBrushDisabled" Color="{ThemeResource ControlStrokeColorDefault}" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="HyperlinkButtonBorderBrush" Color="{ThemeResource ControlStrokeColorDefault}" />
<SolidColorBrush x:Key="HyperlinkButtonBorderBrushPointerOver" Color="{ThemeResource ControlStrokeColorSecondary}" />
<SolidColorBrush x:Key="HyperlinkButtonBorderBrushPressed" Color="{ThemeResource ControlStrokeColorDefault}" />
<SolidColorBrush x:Key="HyperlinkButtonBorderBrushDisabled" Color="{ThemeResource ControlStrokeColorDefault}" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Grid.Resources>
<HyperlinkButton
Padding="-1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
AutomationProperties.LabeledBy="{Binding ElementName=TitleText}"
CornerRadius="{StaticResource OverlayCornerRadius}"
NavigateUri="{x:Bind Link}">
<Grid
Padding="24"
VerticalAlignment="Stretch"
RowSpacing="16">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<FontIcon
Grid.RowSpan="3"
Margin="-12"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
FontSize="14"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Glyph="&#xE8A7;" />
<ContentPresenter
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="{x:Bind Source}" />
<StackPanel
Grid.Row="1"
Orientation="Vertical"
Spacing="4">
<TextBlock
x:Name="TitleText"
Foreground="{ThemeResource TextFillColorPrimaryBrush}"
Style="{StaticResource BodyStrongTextBlockStyle}"
Text="{x:Bind Title}" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind Description}" />
</StackPanel>
</Grid>
</HyperlinkButton>
</Grid>
</UserControl>

View File

@@ -0,0 +1,49 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace CRSim.Controls;
public sealed partial class Tile : UserControl
{
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register(nameof(Title), typeof(string), typeof(Tile), new PropertyMetadata(null));
public string Description
{
get { return (string)GetValue(DescriptionProperty); }
set { SetValue(DescriptionProperty, value); }
}
public static readonly DependencyProperty DescriptionProperty =
DependencyProperty.Register(nameof(Description), typeof(string), typeof(Tile), new PropertyMetadata(null));
public object Source
{
get { return (object)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(nameof(Source), typeof(object), typeof(Tile), new PropertyMetadata(null));
public string Link
{
get { return (string)GetValue(LinkProperty); }
set { SetValue(LinkProperty, value); }
}
public static readonly DependencyProperty LinkProperty =
DependencyProperty.Register(nameof(Link), typeof(string), typeof(Tile), new PropertyMetadata(null));
public Tile()
{
this.InitializeComponent();
}
}

View File

@@ -3,9 +3,29 @@
namespace CRSim.ViewModels;
public partial class DashboardPageViewModel : ObservableObject
{
[ObservableProperty]
public partial string? UpdateMessage { get; set; } = null;
public StyleManager StyleManager { get; }
public DashboardPageViewModel(StyleManager styleManager)
private readonly INetworkService _networkService;
private readonly ISettingsService _settingsService;
public DashboardPageViewModel(StyleManager styleManager,INetworkService networkService,ISettingsService settingsService)
{
StyleManager = styleManager;
_networkService = networkService;
_settingsService = settingsService;
InitializeAsync();
}
private async void InitializeAsync()
{
var url = _settingsService.GetSettings().ApiUri.Contains("47")
? "https://api.github.com/repos/denglihong2007/CRSim/releases/latest"
: "https://crsim.com.cn/api/version";
var updateInfo = await _networkService.GetUpdateAsync(url);
if (updateInfo is not null && updateInfo.Name != Assembly.GetExecutingAssembly().GetName().Version.ToString())
{
UpdateMessage = $"有新版本 {updateInfo.Name} 可用,请前往“设置”下载安装更新!";
}
}
}

View File

@@ -6,32 +6,68 @@
xmlns:local="using:CRSim.Views"
xmlns:winui="using:CommunityToolkit.WinUI"
xmlns:screensim="using:CRSim.ScreenSimulator.Views"
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:localcontrols="using:CRSim.Controls"
xmlns:converts="using:CRSim.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ScrollViewer Padding="36">
<StackPanel Orientation="Vertical">
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="活动的引导屏"/>
<Border Style="{StaticResource ListViewBorder}">
<ListView ItemsSource="{x:Bind ViewModel.StyleManager.ActiveWindows,Mode=OneWay}" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="screensim:SimulatorWindow">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{x:Bind Session.StyleName}" VerticalAlignment="Center"/>
<Button Grid.Column="2" Style="{StaticResource AccentButtonStyle}" Height="32"
<Page.Resources>
<converts:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
</Page.Resources>
<Grid>
<Grid.Resources>
<animations:ImplicitAnimationSet x:Name="ShowTransitions">
<animations:OffsetAnimation
EasingMode="EaseOut"
From="0,24,0"
To="0"
Duration="0:0:0.4" />
<animations:OpacityAnimation
EasingMode="EaseOut"
From="0"
To="1"
Duration="0:0:0.2" />
</animations:ImplicitAnimationSet>
<animations:ImplicitAnimationSet x:Name="HideTransitions">
<animations:OffsetAnimation
EasingMode="EaseOut"
From="0"
To="0,24,0"
Duration="0:0:0.2" />
<animations:OpacityAnimation
EasingMode="EaseOut"
From="1"
To="0"
Duration="0:0:0.1" />
</animations:ImplicitAnimationSet>
</Grid.Resources>
<ScrollViewer Padding="36">
<StackPanel Orientation="Vertical">
<localcontrols:HomePageHeader/>
<InfoBar Severity="Informational" IsOpen="True" Title="有可用更新" Message="{x:Bind ViewModel.UpdateMessage, Mode=OneWay}" Visibility="{x:Bind ViewModel.UpdateMessage,Converter={StaticResource NullToVisibilityConverter},Mode=OneWay}"/>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="活动的引导屏"/>
<Border Style="{StaticResource ListViewBorder}">
<ListView ItemsSource="{x:Bind ViewModel.StyleManager.ActiveWindows,Mode=OneWay}" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="screensim:SimulatorWindow">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{x:Bind Session.StyleName}" VerticalAlignment="Center"/>
<Button Grid.Column="2" Style="{StaticResource AccentButtonStyle}" Height="32"
Margin="0,0,4,0" Content="{winui:FontIcon FontSize=16, Glyph=&#xE890;}" Click="{x:Bind FoucsWindow}"/>
<Button Grid.Column="3" Height="32" Content="{winui:FontIcon FontSize=16, Glyph=&#xEA14;}" Click="{x:Bind CloseWindow}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border>
</StackPanel>
</ScrollViewer>
<Button Grid.Column="3" Height="32" Content="{winui:FontIcon FontSize=16, Glyph=&#xEA14;}" Click="{x:Bind CloseWindow}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>