Framework changed to WPF

Only the basic window frame is implemented.
Adjusted the structure of resource files.
This commit is contained in:
2022-09-29 21:56:43 +08:00
parent 346a68ddb4
commit a055dc5299
128 changed files with 48325 additions and 63581 deletions

View File

@@ -0,0 +1,407 @@
<Window
x:Class="GrasscutterTools.Windows.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:GrasscutterTools.Properties"
Title="{x:Static p:Resources.GrasscutterTools}"
Width="940"
Height="500"
MinWidth="940"
MinHeight="500"
d:DataContext="{Binding RelativeSource={RelativeSource Self}}"
Background="{StaticResource WindowBackgroundBrush}"
Icon="/Resources/IconGrasscutter.ico"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Window.Resources>
<Style x:Key="MenuItemStyle" TargetType="{x:Type RadioButton}">
<Setter Property="Foreground" Value="#DDDDDD" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Height" Value="40" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="16,4,16,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border
x:Name="BorderBlack"
Background="{TemplateBinding Background}"
CornerRadius="4">
<ContentControl
x:Name="LblContent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BorderBlack" Property="Background" Value="{StaticResource HoverBrush}" />
<Setter TargetName="LblContent" Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="BorderBlack" Property="Background" Value="{StaticResource NormalBorderBrush}" />
<Setter TargetName="LblContent" Property="Foreground" Value="White" />
<Setter Property="Cursor" Value="Arrow" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<DockPanel>
<DockPanel Width="200" DockPanel.Dock="Left">
<!-- Logo -->
<Image
x:Name="ImgLogo"
Width="60"
Height="60"
Margin="8"
HorizontalAlignment="Center"
VerticalAlignment="Top"
DockPanel.Dock="Bottom"
Source="/Resources/IconGrasscutter.png" />
<!-- 左侧,菜单栏 -->
<ScrollViewer>
<StackPanel x:Name="SPMenu" Grid.Column="0">
<RadioButton
x:Name="RadHome"
Content="Home"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadCustom"
Content="Custom"
Cursor="Hand"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadArtifact"
Content="Artifact"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadGive"
Content="Give"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadSpawn"
Content="Spawn"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadQuests"
Content="Quests"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadStats"
Content="Stats"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadTools"
Content="Tools"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadScenes"
Content="Scenes"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadDungeons"
Content="Dungeons"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadManage"
Content="Manage"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadOpenCommand"
Content="Open Command"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadAbout"
Content="About"
Style="{StaticResource MenuItemStyle}" />
<RadioButton
x:Name="RadSettings"
Content="Settings"
Style="{StaticResource MenuItemStyle}" />
</StackPanel>
</ScrollViewer>
</DockPanel>
<!-- 右侧,列表栏 -->
<DockPanel
x:Name="DockListBar"
Width="250"
d:Visibility="Visible"
DockPanel.Dock="Right"
Visibility="Collapsed">
<!-- 顶部,搜索栏 -->
<Grid Margin="4" DockPanel.Dock="Top">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<!-- 搜索框 -->
<TextBox
x:Name="TxtSearch"
d:Text="Filter"
TextChanged="TxtSearch_TextChanged" />
<!-- 清除搜索内容图标按钮 -->
<Button
x:Name="BtnClearFilter"
Width="10"
Height="10"
Margin="0,0,5,0"
HorizontalAlignment="Right"
d:Visibility="Visible"
Click="BtnClearFilter_Click"
Cursor="Hand"
Foreground="{DynamicResource GlyphBrush}"
Visibility="Hidden">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="GridBG" Background="Transparent">
<Line
x:Name="L1"
Stroke="{TemplateBinding Foreground}"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
StrokeThickness="2"
X1="0"
X2="10"
Y1="0"
Y2="10" />
<Line
x:Name="L2"
Stroke="{TemplateBinding Foreground}"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
StrokeThickness="2"
X1="10"
X2="0"
Y1="0"
Y2="10" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="L1" Property="Stroke" Value="{DynamicResource TextBrush}" />
<Setter TargetName="L2" Property="Stroke" Value="{DynamicResource TextBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<!-- 分类按钮 -->
<Button
x:Name="BtnCategory"
Grid.Column="1"
Width="16"
Height="16"
Margin="4,0,0,0"
HorizontalAlignment="Right"
d:Visibility="Visible"
Click="BtnCategory_Click"
Cursor="Hand"
Foreground="{DynamicResource GlyphBrush}"
Visibility="Collapsed">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="GridBG" Background="Transparent">
<Line
x:Name="L1"
Stroke="{TemplateBinding Foreground}"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
StrokeThickness="2"
X1="1"
X2="15"
Y1="3"
Y2="3" />
<Line
x:Name="L2"
Stroke="{TemplateBinding Foreground}"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
StrokeThickness="2"
X1="1"
X2="12"
Y1="8"
Y2="8" />
<Line
x:Name="L3"
Stroke="{TemplateBinding Foreground}"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
StrokeThickness="2"
X1="1"
X2="9"
Y1="13"
Y2="13" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="L1" Property="Stroke" Value="{DynamicResource TextBrush}" />
<Setter TargetName="L2" Property="Stroke" Value="{DynamicResource TextBrush}" />
<Setter TargetName="L3" Property="Stroke" Value="{DynamicResource TextBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<!-- 分类弹窗 -->
<Popup
x:Name="MenuCategories"
Placement="Right"
PlacementTarget="{Binding ElementName=BtnCategory}"
StaysOpen="False">
<GroupBox Padding="8" Header="Category">
<StackPanel x:Name="SPCategories">
<CheckBox
x:Name="ChkAllCategory"
Checked="ChkAllCategory_Checked"
Content="All"
Unchecked="ChkAllCategory_Unchecked" />
</StackPanel>
</GroupBox>
</Popup>
</Grid>
</Grid>
<!-- 列表 -->
<DataGrid
x:Name="ListShared"
d:ItemsSource="{d:SampleData ItemCount=10}"
AutoGenerateColumns="False"
Background="{StaticResource ControlBackgroundBrush}"
CanUserResizeColumns="False"
CanUserResizeRows="False"
ColumnHeaderHeight="0"
Foreground="{StaticResource TextBrush}"
IsReadOnly="True"
RowBackground="{StaticResource NormalBrush}"
RowHeaderWidth="0"
SelectionMode="Single"
SelectionUnit="FullRow">
<DataGrid.Columns>
<DataGridTextColumn
Width="*"
Binding="{Binding}"
Header="Item" />
</DataGrid.Columns>
<!--<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander
Background="#FF112255"
BorderBrush="#FF002255"
BorderThickness="1,1,1,5"
Foreground="#FFEEEEEE"
IsExpanded="True">
<Expander.Header>
<DockPanel>
<TextBlock
Width="100"
Margin="5,0,0,0"
FontWeight="Bold"
Text="{Binding Path=Name}" />
<TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>-->
</DataGrid>
</DockPanel>
<!-- 底部,命令栏 -->
<GroupBox
x:Name="GrpCommandBar"
Padding="8,4,8,0"
VerticalAlignment="Center"
d:Visibility="Visible"
DockPanel.Dock="Bottom"
Header="Command (Press and hold Ctrl to run automatically)"
Visibility="Collapsed">
<DockPanel>
<!-- 命令栏 -->
<DockPanel DockPanel.Dock="Top">
<!-- 运行按钮 -->
<Button
x:Name="BtnRun"
Padding="8,0"
Click="BtnRun_Click"
Content="Run(F5)"
DockPanel.Dock="Left" />
<!-- 自动复制开关 -->
<CheckBox
x:Name="ChkAuto"
Margin="4"
VerticalAlignment="Center"
Content="Auto"
DockPanel.Dock="Right" />
<!-- 复制按钮 -->
<Button
x:Name="BtnCopy"
Padding="8,0"
Content="Copy"
DockPanel.Dock="Right" />
<!-- 命令输入框 -->
<TextBox
x:Name="TxtCommand"
Margin="4"
FontSize="14"
MaxLines="1" />
</DockPanel>
<!-- 命令执行记录 -->
<TextBox
x:Name="TxtCommandLog"
Height="150"
Margin="4"
d:Visibility="Visible"
FontSize="14"
IsReadOnly="True"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto"
Visibility="Collapsed" />
</DockPanel>
</GroupBox>
<!-- 页面内容 -->
<Frame
x:Name="FrameContent"
Background="{StaticResource LightBrush}"
NavigationUIVisibility="Hidden" />
</DockPanel>
</Window>

View File

@@ -0,0 +1,364 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using GrasscutterTools.Events;
using GrasscutterTools.Game;
using GrasscutterTools.Interfaces;
using GrasscutterTools.Models;
using GrasscutterTools.Pages;
namespace GrasscutterTools.Windows
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private readonly double MinHeightDefault;
#region - -
/// <summary>
/// 是否显示右侧列表栏
/// </summary>
private bool IsShowList
{
get => DockListBar.Visibility == Visibility.Visible;
set => DockListBar.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
}
/// <summary>
/// 是否显示底部命令栏
/// </summary>
private bool IsShowCommand
{
get => GrpCommandBar.Visibility == Visibility.Visible;
set => GrpCommandBar.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
}
#endregion
#region - -
/// <summary>
/// 窗体构造函数
/// </summary>
public MainWindow()
{
InitializeComponent();
MinHeightDefault = MinHeight;
//GameData.LoadResources();
// 初始化菜单项选中事件
foreach (RadioButton btn in SPMenu.Children)
{
btn.Checked += OnPageSelected;
}
// 默认选中首页
RadHome.IsChecked = true;
}
#endregion
#region - -
/// <summary>
/// 页面导航选中时触发
/// </summary>
private void OnPageSelected(object sender, RoutedEventArgs e)
{
var btn = sender as RadioButton;
if (btn.Tag != null)
{
ShowPage(btn.Tag as Page);
return;
}
// 创建页面
Page page = null;
// 首页
if (btn == RadHome)
{
page = new PageHome();
}
else if (btn == RadCustom)
{
}
else if (btn == RadArtifact)
{
}
else if (btn == RadGive)
{
page = new PageGive();
}
else if (btn == RadSpawn)
{
}
else if (btn == RadQuests)
{
}
else if (btn == RadStats)
{
}
else if (btn == RadTools)
{
page = new PageTools();
}
else if (btn == RadScenes)
{
}
else if (btn == RadManage)
{
}
else if (btn == RadOpenCommand)
{
}
else if (btn == RadAbout)
{
}
else if (btn == RadSettings)
{
}
else
{
// TODO
}
if (page is IPageCommand t)
t.CommandGenerated += OnCommandGenerated;
if (page != null)
{
btn.Tag = page;
ShowPage(page);
}
}
/// <summary>
/// 显示页面
/// </summary>
/// <param name="page">页面</param>
private void ShowPage(Page page)
{
IsShowCommand = page is IPageCommand;
if (page is IPageListProvider provider)
{
ListView = new ListCollectionView(provider.ListSource);
// 清理分类
if (SPCategories.Children.Count > 1)
SPCategories.Children.RemoveRange(1, SPCategories.Children.Count-1);
// 默认选中全部
ChkAllCategory.IsChecked = true;
// 判断是否包含分类
if (provider.CanGroup)
{
// 显示分类按钮
BtnCategory.Visibility = Visibility.Visible;
foreach (var category in provider.Categories)
{
// 添加类别复选框
var chkCategory = new CheckBox
{
IsChecked = true,
Content = category,
Margin = new Thickness(0, 4, 0, 0),
};
chkCategory.Checked += OnCategoryChecked;
chkCategory.Unchecked += OnCategoryUnchecked;
SPCategories.Children.Add(chkCategory);
}
}
else
{
BtnCategory.Visibility = Visibility.Collapsed;
}
ListView.Filter += OnListFilter;
//cvsList.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
ListShared.ItemsSource = ListView;
IsShowList = true;
}
else
{
IsShowList = false;
}
FrameContent.Content = page;
}
#endregion
#region - -
/// <summary>
/// 列表视图,用于过滤
/// </summary>
ListCollectionView ListView;
/// <summary>
/// 列表选中项改变时触发
/// </summary>
private void OnListItemSelected(object sender, SelectionChangedEventArgs e)
{
if (ListShared.SelectedItem != null && FrameContent.Content is IPageListProvider page)
page.OnListItemSelected(ListShared.SelectedItem as GameItem);
}
/// <summary>
/// 列表过滤器
/// </summary>
private bool OnListFilter(object e)
{
if (ChkAllCategory.IsChecked != true && SPCategories.Children.Count > 1)
{
var item = e as GameItem;
for (int i = 1; i < SPCategories.Children.Count; i++)
{
var chk = SPCategories.Children[i] as CheckBox;
if ((string)chk.Content == item.Category)
{
if (chk.IsChecked == true)
break;
else
return false;
}
}
}
if (string.IsNullOrEmpty(TxtSearch.Text))
return true;
else
return e.ToString().IndexOf(TxtSearch.Text, StringComparison.OrdinalIgnoreCase) >= 0;
}
#region -- --
private void BtnCategory_Click(object sender, RoutedEventArgs e)
{
MenuCategories.IsOpen = true;
}
private bool IsInternalChanges = false;
/// <summary>
/// 全选类别勾选时触发
/// </summary>
private void ChkAllCategory_Checked(object sender, RoutedEventArgs e)
{
CheckAll(true);
}
/// <summary>
/// 全选类别取消勾选时触发
/// </summary>
private void ChkAllCategory_Unchecked(object sender, RoutedEventArgs e)
{
CheckAll(false);
}
private void CheckAll(bool isChecked)
{
IsInternalChanges = true;
foreach (CheckBox chk in SPCategories.Children)
chk.IsChecked = isChecked;
IsInternalChanges = false;
ListView.Refresh();
}
private void OnCategoryChecked(object sender, RoutedEventArgs e)
{
if (!IsInternalChanges) ListView.Refresh();
}
private void OnCategoryUnchecked(object sender, RoutedEventArgs e)
{
if (!IsInternalChanges) ListView.Refresh();
}
#endregion
#region -- --
/// <summary>
/// 搜索框文本改变时触发
/// </summary>
private void TxtSearch_TextChanged(object sender, TextChangedEventArgs e)
{
ListView.Refresh();
if (string.IsNullOrEmpty(TxtSearch.Text))
BtnClearFilter.Visibility = Visibility.Hidden;
else
BtnClearFilter.Visibility = Visibility.Visible;
}
/// <summary>
/// 清除搜索框文本按钮点击时触发
/// </summary>
private void BtnClearFilter_Click(object sender, RoutedEventArgs e)
{
TxtSearch.Clear();
}
#endregion
#endregion
#region - -
/// <summary>
/// 运行命令时触发
/// </summary>
private void BtnRun_Click(object sender, RoutedEventArgs e)
{
// 测试展开运行记录
MinHeight = MinHeightDefault + TxtCommandLog.Height;
TxtCommandLog.Visibility = Visibility.Visible;
}
/// <summary>
/// 命令生成时触发
/// </summary>
private void OnCommandGenerated(object sender, CommandGeneratedEventArgs e)
{
TxtCommand.Text = e.Command;
// TODO
}
#endregion
}
}