mouse simulator

This commit is contained in:
DismissedLight
2023-09-23 14:55:47 +08:00
parent ef352303e7
commit 6029acc7f1
14 changed files with 384 additions and 219 deletions

View File

@@ -1,27 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Windows.Win32.Foundation;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing;
internal static class HotKey
{
private const int DefaultId = 100000;
public static bool Register(in HWND hwnd)
{
return RegisterHotKey(hwnd, DefaultId, default, (uint)Windows.Win32.UI.Input.KeyboardAndMouse.VIRTUAL_KEY.VK_F8);
}
public static bool Unregister(in HWND hwnd)
{
return UnregisterHotKey(hwnd, DefaultId);
}
public static bool OnHotKeyPressed()
{
return true;
}
}

View File

@@ -0,0 +1,93 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Runtime.InteropServices;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Input.KeyboardAndMouse;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing.HotKey;
[SuppressMessage("", "CA1001")]
internal sealed class HotKeyController : IHotKeyController
{
private const int DefaultId = 100000;
private readonly object locker = new();
private readonly WaitCallback runMouseClickRepeatForever;
private readonly HotKeyOptions hotKeyOptions;
private volatile CancellationTokenSource? cancellationTokenSource;
public HotKeyController(IServiceProvider serviceProvider)
{
hotKeyOptions = serviceProvider.GetRequiredService<HotKeyOptions>();
runMouseClickRepeatForever = MouseClickRepeatForever;
}
public bool Register(in HWND hwnd)
{
return RegisterHotKey(hwnd, DefaultId, default, (uint)VIRTUAL_KEY.VK_F8);
}
public bool Unregister(in HWND hwnd)
{
return UnregisterHotKey(hwnd, DefaultId);
}
public void OnHotKeyPressed(in HotKeyParameter parameter)
{
if (parameter is { Key: VIRTUAL_KEY.VK_F8, Modifier: 0 })
{
lock (locker)
{
if (hotKeyOptions.IsMouseClickRepeatForeverOn)
{
cancellationTokenSource?.Cancel();
cancellationTokenSource = default;
hotKeyOptions.IsMouseClickRepeatForeverOn = false;
}
else
{
cancellationTokenSource = new();
ThreadPool.QueueUserWorkItem(runMouseClickRepeatForever, cancellationTokenSource.Token);
hotKeyOptions.IsMouseClickRepeatForeverOn = true;
}
}
}
}
private static unsafe INPUT CreateInputForMouseEvent(MOUSE_EVENT_FLAGS flags)
{
INPUT input = new() { type = INPUT_TYPE.INPUT_MOUSE, };
input.Anonymous.mi.dwFlags = flags;
return input;
}
[SuppressMessage("", "SH007")]
private unsafe void MouseClickRepeatForever(object? state)
{
CancellationToken token = (CancellationToken)state!;
// We want to use this thread for a long time
while (!token.IsCancellationRequested)
{
INPUT[] inputs =
{
CreateInputForMouseEvent(MOUSE_EVENT_FLAGS.MOUSEEVENTF_LEFTDOWN),
CreateInputForMouseEvent(MOUSE_EVENT_FLAGS.MOUSEEVENTF_LEFTUP),
};
if (SendInput(inputs.AsSpan(), sizeof(INPUT)) is 0)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError());
}
if (token.IsCancellationRequested)
{
return;
}
Thread.Sleep(Random.Shared.Next(100, 150));
}
}
}

View File

@@ -0,0 +1,18 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using System.Runtime.InteropServices;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Input.KeyboardAndMouse;
using static Windows.Win32.PInvoke;
namespace Snap.Hutao.Core.Windowing.HotKey;
[Injection(InjectAs.Singleton)]
internal sealed class HotKeyOptions : ObservableObject
{
private bool isVirtualKeyF8Pressed;
public bool IsMouseClickRepeatForeverOn { get => isVirtualKeyF8Pressed; set => SetProperty(ref isVirtualKeyF8Pressed, value); }
}

View File

@@ -0,0 +1,12 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Windows.Win32.UI.Input.KeyboardAndMouse;
namespace Snap.Hutao.Core.Windowing.HotKey;
internal readonly struct HotKeyParameter
{
public readonly ushort Modifier;
public readonly VIRTUAL_KEY Key;
}

View File

@@ -0,0 +1,14 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Windows.Win32.Foundation;
namespace Snap.Hutao.Core.Windowing.HotKey;
internal interface IHotKeyController
{
void OnHotKeyPressed(in HotKeyParameter parameter);
bool Register(in HWND hwnd);
bool Unregister(in HWND hwnd);
}

View File

@@ -33,7 +33,7 @@ internal sealed class WindowController
this.options = options;
this.serviceProvider = serviceProvider;
subclass = new(window, options);
subclass = new(window, options, serviceProvider);
InitializeCore();
}

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Microsoft.UI.Xaml;
using Snap.Hutao.Core.Windowing.HotKey;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.WindowsAndMessaging;
@@ -20,15 +21,19 @@ internal sealed class WindowSubclass : IDisposable
private readonly Window window;
private readonly WindowOptions options;
private readonly IServiceProvider serviceProvider;
private readonly IHotKeyController hotKeyController;
// We have to explicitly hold a reference to SUBCLASSPROC
private SUBCLASSPROC? windowProc;
private SUBCLASSPROC? legacyDragBarProc;
public WindowSubclass(Window window, in WindowOptions options)
public WindowSubclass(Window window, in WindowOptions options, IServiceProvider serviceProvider)
{
this.window = window;
this.options = options;
this.serviceProvider = serviceProvider;
hotKeyController = new HotKeyController(serviceProvider);
}
/// <summary>
@@ -39,7 +44,7 @@ internal sealed class WindowSubclass : IDisposable
{
windowProc = OnSubclassProcedure;
bool windowHooked = SetWindowSubclass(options.Hwnd, windowProc, WindowSubclassId, 0);
HotKey.Register(options.Hwnd);
hotKeyController.Register(options.Hwnd);
bool titleBarHooked = true;
@@ -74,7 +79,7 @@ internal sealed class WindowSubclass : IDisposable
return;
}
HotKey.Unregister(options.Hwnd);
hotKeyController.Unregister(options.Hwnd);
RemoveWindowSubclass(options.Hwnd, legacyDragBarProc, DragBarSubclassId);
legacyDragBarProc = null;
}
@@ -100,7 +105,7 @@ internal sealed class WindowSubclass : IDisposable
case WM_HOTKEY:
{
System.Diagnostics.Debug.WriteLine($"Hot key pressed, wParam: {wParam.Value}, lParam: {lParam.Value}");
hotKeyController.OnHotKeyPressed(*(HotKeyParameter*)&lParam);
break;
}
}

View File

@@ -33,6 +33,7 @@ CoWaitForMultipleObjects
// USER32
AttachThreadInput
FindWindowExW
GetCursorPos
GetDC
GetDpiForWindow
GetForegroundWindow

View File

@@ -81,6 +81,15 @@ internal sealed partial class LaunchScheme
IsOversea = true,
};
private static readonly LaunchScheme ServerGlobalChannelDefaultSubChannelDefault = new()
{
LauncherId = SdkStaticLauncherGlobalId,
Key = SdkStaticLauncherGlobalKey,
Channel = ChannelType.Default,
SubChannel = SubChannelType.Default,
IsOversea = true,
};
/// <summary>
/// 获取已知的启动方案
/// </summary>

View File

@@ -20,6 +20,149 @@
<Page.Resources>
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
<DataTemplate x:Key="AchievementGoalListTemplate" x:DataType="shva:AchievementGoalView">
<Grid Margin="0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="36"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="0"
Width="36"
Height="36"
Source="{Binding Icon}"/>
<StackPanel Grid.Column="1" Margin="12,0,0,2">
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
<TextBlock
Margin="0,2,0,0"
VerticalAlignment="Center"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding FinishDescription}"/>
<ProgressBar
Margin="0,4,0,0"
Maximum="1"
Value="{Binding FinishPercent}"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AchievementGoalGridTemplate" x:DataType="shva:AchievementGoalView">
<Border MinWidth="180" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<shci:CachedImage
Grid.Row="0"
Width="64"
Height="64"
Margin="8"
Source="{Binding Icon}"/>
<StackPanel Grid.Row="1" Margin="8,0">
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Margin="0,2,0,0"
HorizontalAlignment="Center"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding FinishDescription}"/>
<ProgressBar
Margin="0,8"
Maximum="1"
Value="{Binding FinishPercent}"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="AchievementTemplate" x:DataType="shva:AchievementView">
<Border
Margin="0,4,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Style="{StaticResource BorderCardStyle}">
<Border.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem IsEnabled="False" Text="{Binding Inner.Id}"/>
</MenuFlyout>
</Border.ContextFlyout>
<Grid MinHeight="48" Padding="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
MinWidth="0"
MinHeight="0"
Margin="8,0"
Padding="0,0,0,0"
Command="{Binding Path=DataContext.SaveAchievementCommand, Source={StaticResource BindingProxy}}"
CommandParameter="{Binding}"
IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
<Grid Grid.Column="1" Margin="8,0,0,0">
<Grid.ColumnDefinitions>
<!-- text -->
<ColumnDefinition/>
<!-- time -->
<ColumnDefinition Width="auto"/>
<!-- pic -->
<ColumnDefinition Width="auto"/>
<!-- count -->
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Inner.Title}"/>
<Border
Margin="4,0,0,0"
Padding="4,1"
VerticalAlignment="Center"
CornerRadius="2">
<Border.Background>
<SolidColorBrush Opacity="0.6" Color="{ThemeResource SystemAccentColor}"/>
</Border.Background>
<TextBlock
FontSize="10"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Inner.Version}"/>
</Border>
</StackPanel>
<TextBlock
Margin="0,2,0,0"
Style="{StaticResource SecondaryTextStyle}"
Text="{Binding Inner.Description}"
TextTrimming="CharacterEllipsis"/>
</StackPanel>
<TextBlock
Grid.Column="1"
Margin="12,0,12,0"
VerticalAlignment="Center"
Text="{Binding Time}"
Visibility="{Binding IsChecked, Converter={StaticResource BoolToVisibilityConverter}}"/>
<shci:CachedImage
Grid.Column="2"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_201}"/>
<TextBlock
Grid.Column="3"
Margin="12,0,0,0"
VerticalAlignment="Center"
Text="{Binding Inner.FinishReward.Count}"/>
</Grid>
</Grid>
</Border>
</DataTemplate>
</Page.Resources>
<mxi:Interaction.Behaviors>
@@ -118,12 +261,10 @@
Label="{shcm:ResourceString Name=ViewPageAchievementSortIncompletedItemsFirst}"/>
</CommandBar>
</Grid>
<cwc:SwitchPresenter Grid.Row="1" Value="{Binding ElementName=ItemsPanelSelector, Path=Current}">
<cwc:SwitchPresenter.ContentTransitions>
<TransitionCollection>
<ContentThemeTransition/>
</TransitionCollection>
</cwc:SwitchPresenter.ContentTransitions>
<cwc:SwitchPresenter
Grid.Row="1"
ContentTransitions="{StaticResource ContentThemeTransitions}"
Value="{Binding ElementName=ItemsPanelSelector, Path=Current}">
<cwc:Case Value="List">
<SplitView
Grid.Row="1"
@@ -133,6 +274,7 @@
PaneBackground="{x:Null}">
<SplitView.Pane>
<ListView
ItemTemplate="{StaticResource AchievementGoalListTemplate}"
ItemsSource="{Binding AchievementGoals}"
SelectedItem="{Binding SelectedAchievementGoal, Mode=TwoWay}"
SelectionMode="Single">
@@ -144,34 +286,6 @@
<Setter Property="Margin" Value="0,0,6,0"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="0,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="36"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="0"
Width="36"
Height="36"
Source="{Binding Icon}"/>
<StackPanel Grid.Column="1" Margin="12,0,0,2">
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
<TextBlock
Margin="0,2,0,0"
VerticalAlignment="Center"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding FinishDescription}"/>
<ProgressBar
Margin="0,4,0,0"
Maximum="1"
Value="{Binding FinishPercent}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</SplitView.Pane>
@@ -179,6 +293,7 @@
<ListView
Margin="8,0,0,0"
Padding="0,0,0,8"
ItemTemplate="{StaticResource AchievementTemplate}"
ItemsSource="{Binding Achievements}"
SelectionMode="None">
<ListView.ItemContainerStyle>
@@ -187,89 +302,6 @@
<Setter Property="Margin" Value="0,4,8,0"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="shva:AchievementView">
<Border
Margin="0,4,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Style="{StaticResource BorderCardStyle}">
<Border.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem IsEnabled="False" Text="{Binding Inner.Id}"/>
</MenuFlyout>
</Border.ContextFlyout>
<Grid MinHeight="48" Padding="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
MinWidth="0"
MinHeight="0"
Margin="8,0"
Padding="0,0,0,0"
Command="{Binding Path=DataContext.SaveAchievementCommand, Source={StaticResource BindingProxy}}"
CommandParameter="{Binding}"
IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
<Grid Grid.Column="1" Margin="8,0,0,0">
<Grid.ColumnDefinitions>
<!-- text -->
<ColumnDefinition/>
<!-- time -->
<ColumnDefinition Width="auto"/>
<!-- pic -->
<ColumnDefinition Width="auto"/>
<!-- count -->
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Inner.Title}"/>
<Border
Margin="4,0,0,0"
Padding="4,1"
VerticalAlignment="Center"
CornerRadius="2">
<Border.Background>
<SolidColorBrush Opacity="0.6" Color="{ThemeResource SystemAccentColor}"/>
</Border.Background>
<TextBlock
FontSize="10"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding Inner.Version}"/>
</Border>
</StackPanel>
<TextBlock
Margin="0,2,0,0"
Style="{StaticResource SecondaryTextStyle}"
Text="{Binding Inner.Description}"
TextTrimming="CharacterEllipsis"/>
</StackPanel>
<TextBlock
Grid.Column="1"
Margin="12,0,12,0"
VerticalAlignment="Center"
Text="{Binding Time}"
Visibility="{Binding IsChecked, Converter={StaticResource BoolToVisibilityConverter}}"/>
<shci:CachedImage
Grid.Column="2"
shch:FrameworkElementHelper.SquareLength="32"
Source="{StaticResource UI_ItemIcon_201}"/>
<TextBlock
Grid.Column="3"
Margin="12,0,0,0"
VerticalAlignment="Center"
Text="{Binding Inner.FinishReward.Count}"/>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</SplitView.Content>
</SplitView>
@@ -280,47 +312,13 @@
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
ItemContainerStyle="{StaticResource LargeGridViewItemStyle}"
ItemTemplate="{StaticResource AchievementGoalGridTemplate}"
ItemsSource="{Binding AchievementGoals}"
SelectedItem="{Binding SelectedAchievementGoal, Mode=TwoWay}"
SelectionMode="Single">
<mxi:Interaction.Behaviors>
<shcb:SelectedItemInViewBehavior/>
</mxi:Interaction.Behaviors>
<GridView.ItemTemplate>
<DataTemplate>
<Border MinWidth="180" Style="{StaticResource BorderCardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<shci:CachedImage
Grid.Row="0"
Width="64"
Height="64"
Margin="8"
Source="{Binding Icon}"/>
<StackPanel Grid.Row="1" Margin="8,0">
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Name}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"/>
<TextBlock
Margin="0,2,0,0"
HorizontalAlignment="Center"
Opacity="0.7"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding FinishDescription}"/>
<ProgressBar
Margin="0,8"
Maximum="1"
Value="{Binding FinishPercent}"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</cwc:Case>
</cwc:SwitchPresenter>

View File

@@ -16,6 +16,7 @@
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shvco="using:Snap.Hutao.View.Control"
xmlns:shvcp="using:Snap.Hutao.View.Card.Primitive"
xmlns:shvh="using:Snap.Hutao.ViewModel.Home"
d:DataContext="{d:DesignInstance shvh:AnnouncementViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
@@ -155,11 +156,41 @@
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</DataTemplate>
<DataTemplate x:Key="HutaoAnnouncementTemplate">
<InfoBar
Title="{Binding Title}"
Margin="0,8,0,0"
shch:InfoBarHelper.IsTextSelectionEnabled="True"
CloseButtonCommand="{Binding DismissCommand}"
CloseButtonCommandParameter="{Binding}"
IsOpen="True"
Message="{Binding Content}"
Severity="{Binding Severity}">
<StackPanel Margin="0,0,0,8" Orientation="Horizontal">
<HyperlinkButton Content="查看详情" NavigateUri="{Binding Link}"/>
<TextBlock
Margin="8,0,0,2"
VerticalAlignment="Center"
Opacity="0.7"
Text="{Binding UpdateTimeFormatted}"/>
</StackPanel>
</InfoBar>
</DataTemplate>
<DataTemplate x:Key="CardTemplate" x:DataType="shvcp:CardReference">
<ItemContainer Child="{Binding Card}">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
</ItemContainer.Resources>
</ItemContainer>
</DataTemplate>
</shc:ScopedPage.Resources>
<Grid>
<ScrollViewer Padding="0,0,0,0">
<StackPanel>
<StackPanel>
<TextBlock
Margin="16,16,16,0"
@@ -169,34 +200,13 @@
<ItemsControl
Margin="16,8,12,0"
ItemTemplate="{StaticResource HutaoAnnouncementTemplate}"
ItemsSource="{Binding HutaoAnnouncements}"
Visibility="{Binding HutaoAnnouncements.Count, Converter={StaticResource Int32ToVisibilityConverter}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<InfoBar
Title="{Binding Title}"
Margin="0,8,0,0"
shch:InfoBarHelper.IsTextSelectionEnabled="True"
CloseButtonCommand="{Binding DismissCommand}"
CloseButtonCommandParameter="{Binding}"
IsOpen="True"
Message="{Binding Content}"
Severity="{Binding Severity}">
<StackPanel Margin="0,0,0,8" Orientation="Horizontal">
<HyperlinkButton Content="查看详情" NavigateUri="{Binding Link}"/>
<TextBlock
Margin="8,0,0,2"
VerticalAlignment="Center"
Opacity="0.7"
Text="{Binding UpdateTimeFormatted}"/>
</StackPanel>
</InfoBar>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Visibility="{Binding HutaoAnnouncements.Count, Converter={StaticResource Int32ToVisibilityConverter}}"/>
<ItemsRepeater
Margin="16"
HorizontalAlignment="Stretch"
ItemTemplate="{StaticResource CardTemplate}"
ItemsSource="{Binding Cards, Mode=OneWay}">
<ItemsRepeater.Layout>
<UniformGridLayout
@@ -208,16 +218,6 @@
MinRowSpacing="12"
Orientation="Horizontal"/>
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<ItemContainer Child="{Binding Card}">
<ItemContainer.Resources>
<SolidColorBrush x:Key="ItemContainerPointerOverBackground" Color="Transparent"/>
</ItemContainer.Resources>
<!--<ContentPresenter HorizontalContentAlignment="Stretch" Content="{Binding Card}"/>-->
</ItemContainer>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</StackPanel>

View File

@@ -8,11 +8,38 @@
VerticalAlignment="Top"
mc:Ignorable="d">
<Grid x:Name="DragableGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="136"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="4,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind Title}"
TextWrapping="NoWrap"/>
<ToggleButton
Grid.Column="1"
Margin="0,0,6,0"
VerticalAlignment="Center"
IsChecked="{x:Bind HotKeyOptions.IsMouseClickRepeatForeverOn, Mode=OneWay}"
IsHitTestVisible="False"
Visibility="{x:Bind RuntimeOptions.IsElevated}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="F8"/>
<TextBlock
Grid.Column="1"
Margin="6,0,0,0"
Text="自动连点"/>
</Grid>
</ToggleButton>
</Grid>
</UserControl>

View File

@@ -3,6 +3,8 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Core;
using Snap.Hutao.Core.Windowing.HotKey;
namespace Snap.Hutao.View;
@@ -47,4 +49,16 @@ internal sealed partial class TitleView : UserControl
{
get => DragableGrid;
}
[SuppressMessage("", "CA1822")]
public RuntimeOptions RuntimeOptions
{
get => Ioc.Default.GetRequiredService<RuntimeOptions>();
}
[SuppressMessage("", "CA1822")]
public HotKeyOptions HotKeyOptions
{
get => Ioc.Default.GetRequiredService<HotKeyOptions>();
}
}

View File

@@ -22,6 +22,7 @@ internal sealed class AvatarProperty : ObservableObject, INameIcon, IAlternating
[FightProperty.FIGHT_PROP_SKILL_CD_MINUS_RATIO] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_CDReduce.png").ToUri(),
[FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_ChargeEfficiency.png").ToUri(),
[FightProperty.FIGHT_PROP_CRITICAL] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_Critical.png").ToUri(),
[FightProperty.FIGHT_PROP_CRITICAL_HURT] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_Critical_Hurt.png").ToUri(),
[FightProperty.FIGHT_PROP_CUR_ATTACK] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_CurAttack.png").ToUri(),
[FightProperty.FIGHT_PROP_CUR_DEFENSE] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_CurDefense.png").ToUri(),
[FightProperty.FIGHT_PROP_ELEMENT_MASTERY] = Web.HutaoEndpoints.StaticFile("Property", "UI_Icon_Element.png").ToUri(),