Files
better-genshin-impact/BetterGenshinImpact/View/MaskWindow.xaml
辉鸭蛋 4e24701b1d feat(界面): 实现遮罩窗口布局的相对比例定位
添加相对比例定位功能,将遮罩窗口中的状态列表和日志文本框从绝对坐标改为基于窗口宽高的比例坐标
新增OverlayRelativeOrAbsoluteConverter转换器处理坐标转换
修改相关视图模型和配置以支持比例定位
2026-01-17 22:07:27 +08:00

421 lines
24 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Window x:Class="BetterGenshinImpact.View.MaskWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:viewModel="clr-namespace:BetterGenshinImpact.ViewModel"
xmlns:platform="clr-namespace:BetterGenshinImpact.Platform.Wine"
xmlns:overlay="clr-namespace:BetterGenshinImpact.View.Controls.Overlay"
xmlns:converters="clr-namespace:BetterGenshinImpact.View.Converters"
Title="MaskWindow"
Width="500"
Height="800"
d:DesignWidth="1920"
d:DesignHeight="1080"
AllowsTransparency="True"
FontFamily="{DynamicResource TextThemeFontFamily}"
ShowActivated="False"
Focusable="False"
ShowInTaskbar="False"
Topmost="True"
WindowStyle="None"
mc:Ignorable="d">
<Window.DataContext>
<viewModel:MaskWindowViewModel />
</Window.DataContext>
<b:Interaction.Triggers>
<b:EventTrigger EventName="Loaded">
<b:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding}" />
</b:EventTrigger>
<b:EventTrigger EventName="SizeChanged">
<b:InvokeCommandAction Command="{Binding WindowSizeChangedCommand}" PassEventArgsToCommand="True" />
</b:EventTrigger>
</b:Interaction.Triggers>
<Window.Background>
<SolidColorBrush Opacity="0.00001" Color="Transparent" />
</Window.Background>
<Window.Style>
<Style TargetType="Window">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/View/Controls/Overlay/AdjustableOverlayItemStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<converters:OverlayRelativeOrAbsoluteConverter x:Key="OverlayRelativeOrAbsoluteConverter" />
</ResourceDictionary>
</Window.Resources>
<AdornerDecorator ClipToBounds="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="23*" />
<ColumnDefinition Width="250*" />
<ColumnDefinition Width="1392*" />
<ColumnDefinition Width="178*" />
<ColumnDefinition Width="57*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1020*" />
<RowDefinition Height="33*" />
<RowDefinition Height="22*" />
<RowDefinition Height="5*" />
</Grid.RowDefinitions>
<Canvas Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="6"
ClipToBounds="True">
<overlay:AdjustableOverlayItem x:Name="StatusWrapper"
Padding="4,2"
Background="#00000000"
BorderBrush="#33000000"
BorderThickness="0"
MinWidth="160"
MinHeight="24"
IsEditEnabled="{Binding Config.MaskWindowConfig.OverlayLayoutEditEnabled}"
LayoutKey="StatusList"
Visibility="{Binding Config.MaskWindowConfig.ShowStatus, Converter={StaticResource BooleanToVisibilityConverter}}">
<Canvas.Left>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.StatusListLeftRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualWidth" />
</MultiBinding>
</Canvas.Left>
<Canvas.Top>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.StatusListTopRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualHeight" />
</MultiBinding>
</Canvas.Top>
<overlay:AdjustableOverlayItem.Width>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.StatusListWidthRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualWidth" />
</MultiBinding>
</overlay:AdjustableOverlayItem.Width>
<overlay:AdjustableOverlayItem.Height>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.StatusListHeightRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualHeight" />
</MultiBinding>
</overlay:AdjustableOverlayItem.Height>
<b:Interaction.Triggers>
<b:EventTrigger EventName="LayoutCommitted">
<b:InvokeCommandAction Command="{Binding OverlayLayoutCommittedCommand}" PassEventArgsToCommand="True" />
</b:EventTrigger>
<b:EventTrigger EventName="PreviewMouseRightButtonDown">
<b:InvokeCommandAction Command="{Binding ExitOverlayLayoutEditModeCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
<overlay:AdjustableOverlayItem.Effect>
<DropShadowEffect Opacity="0.4" BlurRadius="4" ShadowDepth="0" Color="LightGray" />
</overlay:AdjustableOverlayItem.Effect>
<ui:ListView ItemsSource="{Binding StatusList}"
Background="Transparent"
BorderThickness="0"
d:ItemsSource="{d:SampleData}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Focusable" Value="False" />
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="0,0,8,0" />
</Style>
</StackPanel.Resources>
<TextBlock FontFamily="{StaticResource FgiIconFontFamily}"
FontSize="12"
Text="{Binding Name}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="LightGray"
Opacity="{Binding DataContext.Config.MaskWindowConfig.TextOpacity, RelativeSource={RelativeSource AncestorType=Window}}" />
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled}" Value="True">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="LightGreen"
Opacity="{Binding DataContext.Config.MaskWindowConfig.TextOpacity, RelativeSource={RelativeSource AncestorType=Window}}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ui:ListView>
</overlay:AdjustableOverlayItem>
<overlay:AdjustableOverlayItem x:Name="LogTextBoxWrapper"
Padding="0"
Background="#00000000"
BorderBrush="#33000000"
BorderThickness="0"
MinWidth="240"
MinHeight="80"
IsEditEnabled="{Binding Config.MaskWindowConfig.OverlayLayoutEditEnabled}"
LayoutKey="LogTextBox"
Visibility="{Binding Config.MaskWindowConfig.ShowLogBox, Converter={StaticResource BooleanToVisibilityConverter}}">
<Canvas.Left>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.LogTextBoxLeftRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualWidth" />
</MultiBinding>
</Canvas.Left>
<Canvas.Top>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.LogTextBoxTopRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualHeight" />
</MultiBinding>
</Canvas.Top>
<overlay:AdjustableOverlayItem.Width>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.LogTextBoxWidthRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualWidth" />
</MultiBinding>
</overlay:AdjustableOverlayItem.Width>
<overlay:AdjustableOverlayItem.Height>
<MultiBinding Converter="{StaticResource OverlayRelativeOrAbsoluteConverter}">
<Binding Path="Config.MaskWindowConfig.LogTextBoxHeightRatio" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="ActualHeight" />
</MultiBinding>
</overlay:AdjustableOverlayItem.Height>
<b:Interaction.Triggers>
<b:EventTrigger EventName="LayoutCommitted">
<b:InvokeCommandAction Command="{Binding OverlayLayoutCommittedCommand}" PassEventArgsToCommand="True" />
</b:EventTrigger>
<b:EventTrigger EventName="PreviewMouseRightButtonDown">
<b:InvokeCommandAction Command="{Binding ExitOverlayLayoutEditModeCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
<overlay:AdjustableOverlayItem.Effect>
<DropShadowEffect Opacity="0.4" BlurRadius="4" ShadowDepth="0" />
</overlay:AdjustableOverlayItem.Effect>
<RichTextBox x:Name="LogTextBox"
Padding="0,5,0,0"
Background="Transparent"
BorderThickness="0"
FontFamily="Cascadia Mono, Consolas, Courier New, monospace, /Resources/Fonts/MiSans-Regular.ttf#MiSans"
FontSize="12"
IsHitTestVisible="False"
VerticalScrollBarVisibility="Hidden"
Opacity="{Binding Config.MaskWindowConfig.TextOpacity}">
<RichTextBox.Foreground>
<SolidColorBrush Color="LightGray" />
</RichTextBox.Foreground>
<d:FlowDocument FontFamily="{Binding FontFamily, ElementName=LogTextBox}" FontSize="{Binding FontSize, ElementName=LogTextBox}">
<Paragraph>
<Run>[00:00:00 INF] 更好的原神</Run>
<LineBreak />
<Run>[00:00:00 INF] 遮罩窗口已启动游戏大小1920x1080素材缩放1.00DPI缩放1</Run>
<LineBreak />
<Run>[00:00:01 INF] Never gonna give you up</Run>
<LineBreak />
<Run>[00:00:01 INF] Never gonna let you down</Run>
</Paragraph>
</d:FlowDocument>
</RichTextBox>
</overlay:AdjustableOverlayItem>
</Canvas>
<Grid Grid.Row="0"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="6"
IsHitTestVisible="False"
Panel.ZIndex="999"
Visibility="{Binding Config.MaskWindowConfig.OverlayLayoutEditEnabled, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="当前处于编辑模式"
FontSize="72"
FontWeight="DemiBold"
Foreground="#CCFFFFFF"
HorizontalAlignment="Center">
<TextBlock.Effect>
<DropShadowEffect Opacity="0.8" BlurRadius="10" ShadowDepth="0" />
</TextBlock.Effect>
</TextBlock>
<TextBlock Text="可以调整日志框、状态栏控件的位置和大小"
Margin="0,8,0,0"
FontSize="22"
FontWeight="SemiBold"
Foreground="#CCFFFFFF"
HorizontalAlignment="Center">
<TextBlock.Effect>
<DropShadowEffect Opacity="0.8" BlurRadius="10" ShadowDepth="0" />
</TextBlock.Effect>
</TextBlock>
<TextBlock Text="右键相关控件可退出编辑状态"
Margin="0,8,0,0"
FontSize="22"
FontWeight="SemiBold"
Foreground="#CCFFFFFF"
HorizontalAlignment="Center">
<TextBlock.Effect>
<DropShadowEffect Opacity="0.8" BlurRadius="10" ShadowDepth="0" />
</TextBlock.Effect>
</TextBlock>
</StackPanel>
</Grid>
<!-- uid遮盖 -->
<Rectangle Grid.Column="4"
Grid.Row="2"
Fill="White"
IsHitTestVisible="False"
Visibility="{Binding Config.MaskWindowConfig.UidCoverEnabled, Converter={StaticResource BooleanToVisibilityConverter}}" />
<!-- 方位 -->
<Viewbox Grid.Column="2" Grid.Row="0"
IsHitTestVisible="False"
HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid Width="250" Height="250"
Visibility="{Binding Config.MaskWindowConfig.DirectionsEnabled, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.Effect>
<DropShadowEffect Opacity="0.4" BlurRadius="8" ShadowDepth="0" />
</Grid.Effect>
<TextBlock Grid.Column="0"
Grid.Row="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="-24,0,0,0"
FontSize="34"
FontStretch="Medium"
FontWeight="DemiBold"
Text="西">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="{Binding Config.MaskWindowConfig.TextOpacity}" />
</TextBlock.Foreground>
</TextBlock>
<TextBlock Grid.Column="2"
Grid.Row="4"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,0,-24"
FontSize="34"
FontStretch="Medium"
FontWeight="DemiBold"
Text="南">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="{Binding Config.MaskWindowConfig.TextOpacity}" />
</TextBlock.Foreground>
</TextBlock>
<TextBlock Grid.Column="4"
Grid.Row="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,0,-24,0"
FontSize="34"
FontStretch="Medium"
FontWeight="DemiBold"
Text="东">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="{Binding Config.MaskWindowConfig.TextOpacity}" />
</TextBlock.Foreground>
</TextBlock>
<TextBlock Grid.Column="2"
Grid.Row="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="0,-24,0,0"
FontSize="34"
FontStretch="Medium"
FontWeight="DemiBold"
Text="北">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="{Binding Config.MaskWindowConfig.TextOpacity}" />
</TextBlock.Foreground>
</TextBlock>
</Grid>
</Viewbox>
<!-- 展示FPS -->
<Border Margin="4,4,0,0"
Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
HorizontalAlignment="Left" VerticalAlignment="Top"
Background="#00000000"
CornerRadius="4"
Opacity="0.5"
IsHitTestVisible="False"
Visibility="{Binding Config.MaskWindowConfig.ShowFps, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{StaticResource DigitalThemeFontFamily}"
FontSize="16"
Text="{Binding Fps}">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="{Binding Config.MaskWindowConfig.TextOpacity}" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<!-- 用于支持wine -->
<Border Grid.Row="0" Grid.Column="0"
Grid.RowSpan="4" Grid.ColumnSpan="6"
IsHitTestVisible="False">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static platform:WinePlatformAddon.IsRunningOnWine}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="Background" Value="#11000000"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Grid>
</AdornerDecorator>
</Window>