@@ -1,6 +1,4 @@
using NLog ;
using NLog.Layouts ;
using NLog.Targets ;
using SFMLRenderer ;
using Spine ;
using SpineViewer.Models ;
@@ -25,6 +23,7 @@ using System.Windows.Documents;
using System.Windows.Input ;
using System.Windows.Interop ;
using System.Windows.Media ;
using System.Windows.Threading ;
namespace SpineViewer.Views ;
@@ -36,7 +35,7 @@ public partial class MainWindow : Window
/// <summary>
/// 上一次状态文件保存路径
/// </summary>
public static readonly string Last StateFilePath = Path . Combine ( Path . GetDirectoryName ( Environment . ProcessPath ) , "last state.json" ) ;
public static readonly string User StateFilePath = Path . Combine ( Path . GetDirectoryName ( Environment . ProcessPath ) , "user state.json" ) ;
private static readonly Logger _logger = LogManager . GetCurrentClassLogger ( ) ;
@@ -46,6 +45,10 @@ public partial class MainWindow : Window
private readonly SFMLRenderWindow _wallpaperRenderWindow ;
private readonly MainWindowViewModel _vm ;
private readonly List < IDisposable > _userStateWatchers = [ ] ;
private DispatcherTimer _saveUserStateTimer ;
private readonly TimeSpan _saveTimerDelay = TimeSpan . FromSeconds ( 3 ) ;
public MainWindow ( )
{
InitializeComponent ( ) ;
@@ -104,79 +107,6 @@ public partial class MainWindow : Window
LogManager . ReconfigExistingLoggers ( ) ;
}
private void LoadLastState ( )
{
if ( JsonHelper . Deserialize < LastStateModel > ( LastStateFilePath , out var m , true ) )
{
Left = m . WindowLeft ;
Top = m . WindowTop ;
Width = m . WindowWidth ;
Height = m . WindowHeight ;
if ( m . WindowState = = WindowState . Maximized )
{
WindowState = WindowState . Maximized ;
}
else
{
WindowState = WindowState . Normal ;
}
_rootGrid . ColumnDefinitions [ 0 ] . Width = new ( m . RootGridCol0Width , GridUnitType . Star ) ;
_rootGrid . ColumnDefinitions [ 2 ] . Width = new ( m . RootGridCol2Width , GridUnitType . Star ) ;
_modelListGrid . RowDefinitions [ 0 ] . Height = new ( m . ModelListRow0Height , GridUnitType . Star ) ;
_modelListGrid . RowDefinitions [ 2 ] . Height = new ( m . ModelListRow2Height , GridUnitType . Star ) ;
_explorerGrid . RowDefinitions [ 0 ] . Height = new ( m . ExplorerGridRow0Height , GridUnitType . Star ) ;
_explorerGrid . RowDefinitions [ 2 ] . Height = new ( m . ExplorerGridRow2Height , GridUnitType . Star ) ;
_rightPanelGrid . RowDefinitions [ 0 ] . Height = new ( m . RightPanelGridRow0Height , GridUnitType . Star ) ;
_rightPanelGrid . RowDefinitions [ 2 ] . Height = new ( m . RightPanelGridRow2Height , GridUnitType . Star ) ;
_vm . SFMLRendererViewModel . SetResolution ( m . ResolutionX , m . ResolutionY ) ;
_vm . SFMLRendererViewModel . MaxFps = m . MaxFps ;
_vm . SFMLRendererViewModel . Speed = m . Speed ;
_vm . SFMLRendererViewModel . ShowAxis = m . ShowAxis ;
_vm . SFMLRendererViewModel . BackgroundColor = m . BackgroundColor ;
_vm . SFMLRendererViewModel . BackgroundImageMode = m . BackgroundImageMode ;
}
}
private void SaveLastState ( )
{
var rb = RestoreBounds ;
var m = new LastStateModel ( )
{
WindowLeft = rb . Left ,
WindowTop = rb . Top ,
WindowWidth = rb . Width ,
WindowHeight = rb . Height ,
WindowState = WindowState ,
RootGridCol0Width = _rootGrid . ColumnDefinitions [ 0 ] . Width . Value ,
RootGridCol2Width = _rootGrid . ColumnDefinitions [ 2 ] . Width . Value ,
ModelListRow0Height = _modelListGrid . RowDefinitions [ 0 ] . Height . Value ,
ModelListRow2Height = _modelListGrid . RowDefinitions [ 2 ] . Height . Value ,
ExplorerGridRow0Height = _explorerGrid . RowDefinitions [ 0 ] . Height . Value ,
ExplorerGridRow2Height = _explorerGrid . RowDefinitions [ 2 ] . Height . Value ,
RightPanelGridRow0Height = _rightPanelGrid . RowDefinitions [ 0 ] . Height . Value ,
RightPanelGridRow2Height = _rightPanelGrid . RowDefinitions [ 2 ] . Height . Value ,
ResolutionX = _vm . SFMLRendererViewModel . ResolutionX ,
ResolutionY = _vm . SFMLRendererViewModel . ResolutionY ,
MaxFps = _vm . SFMLRendererViewModel . MaxFps ,
Speed = _vm . SFMLRendererViewModel . Speed ,
ShowAxis = _vm . SFMLRendererViewModel . ShowAxis ,
BackgroundColor = _vm . SFMLRendererViewModel . BackgroundColor ,
BackgroundImageMode = _vm . SFMLRendererViewModel . BackgroundImageMode ,
} ;
JsonHelper . Serialize ( m , LastStateFilePath ) ;
}
#region MainWindow 事 件 处 理
private void MainWindow_SourceInitialized ( object? sender , EventArgs e )
@@ -206,7 +136,29 @@ public partial class MainWindow : Window
// 加载首选项
_vm . PreferenceViewModel . LoadPreference ( ) ;
LoadLastState ( ) ;
// 还原上一次用户历史状态
LoadUserState ( ) ;
// 添加用户状态监听器
_userStateWatchers . Add ( PropertyWatcher . Watch ( this , MainWindow . WidthProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( this , MainWindow . HeightProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( this , MainWindow . LeftProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( this , MainWindow . TopProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( this , MainWindow . WindowStateProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _rootGrid . ColumnDefinitions [ 0 ] , ColumnDefinition . WidthProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _rootGrid . ColumnDefinitions [ 2 ] , ColumnDefinition . WidthProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _modelListGrid . RowDefinitions [ 0 ] , RowDefinition . HeightProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _modelListGrid . RowDefinitions [ 2 ] , RowDefinition . HeightProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _explorerGrid . RowDefinitions [ 0 ] , RowDefinition . HeightProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _explorerGrid . RowDefinitions [ 2 ] , RowDefinition . HeightProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _rightPanelGrid . RowDefinitions [ 0 ] , RowDefinition . HeightProperty , DelayedSaveUserState ) ) ;
_userStateWatchers . Add ( PropertyWatcher . Watch ( _rightPanelGrid . RowDefinitions [ 2 ] , RowDefinition . HeightProperty , DelayedSaveUserState ) ) ;
_vm . SFMLRendererViewModel . PropertyChanged + = SFMLRendererUserStateChanged ;
}
private void MainWindow_ContentRendered ( object? sender , EventArgs e )
@@ -246,7 +198,14 @@ public partial class MainWindow : Window
}
}
SaveLastState ( ) ;
// 保存当前用户状态
SaveUserState ( ) ;
// 撤除所有状态监听器
_vm . SFMLRendererViewModel . PropertyChanged - = SFMLRendererUserStateChanged ;
foreach ( var w in _userStateWatchers ) w . Dispose ( ) ;
_userStateWatchers . Clear ( ) ;
_vm . SFMLRendererViewModel . StopRender ( ) ;
}
@@ -255,6 +214,118 @@ public partial class MainWindow : Window
}
private void LoadUserState ( )
{
if ( JsonHelper . Deserialize < UserStateModel > ( UserStateFilePath , out var m , true ) )
{
Left = m . WindowLeft ;
Top = m . WindowTop ;
Width = m . WindowWidth ;
Height = m . WindowHeight ;
if ( m . WindowState = = WindowState . Maximized )
{
WindowState = WindowState . Maximized ;
}
else
{
WindowState = WindowState . Normal ;
}
_rootGrid . ColumnDefinitions [ 0 ] . Width = new ( m . RootGridCol0Width , GridUnitType . Star ) ;
_rootGrid . ColumnDefinitions [ 2 ] . Width = new ( m . RootGridCol2Width , GridUnitType . Star ) ;
_modelListGrid . RowDefinitions [ 0 ] . Height = new ( m . ModelListRow0Height , GridUnitType . Star ) ;
_modelListGrid . RowDefinitions [ 2 ] . Height = new ( m . ModelListRow2Height , GridUnitType . Star ) ;
_explorerGrid . RowDefinitions [ 0 ] . Height = new ( m . ExplorerGridRow0Height , GridUnitType . Star ) ;
_explorerGrid . RowDefinitions [ 2 ] . Height = new ( m . ExplorerGridRow2Height , GridUnitType . Star ) ;
_rightPanelGrid . RowDefinitions [ 0 ] . Height = new ( m . RightPanelGridRow0Height , GridUnitType . Star ) ;
_rightPanelGrid . RowDefinitions [ 2 ] . Height = new ( m . RightPanelGridRow2Height , GridUnitType . Star ) ;
_vm . SFMLRendererViewModel . SetResolution ( m . ResolutionX , m . ResolutionY ) ;
_vm . SFMLRendererViewModel . MaxFps = m . MaxFps ;
_vm . SFMLRendererViewModel . Speed = m . Speed ;
_vm . SFMLRendererViewModel . ShowAxis = m . ShowAxis ;
_vm . SFMLRendererViewModel . BackgroundColor = m . BackgroundColor ;
_vm . SFMLRendererViewModel . BackgroundImageMode = m . BackgroundImageMode ;
}
}
private void SaveUserState ( )
{
var rb = RestoreBounds ;
var m = new UserStateModel ( )
{
WindowLeft = rb . Left ,
WindowTop = rb . Top ,
WindowWidth = rb . Width ,
WindowHeight = rb . Height ,
WindowState = WindowState ,
RootGridCol0Width = _rootGrid . ColumnDefinitions [ 0 ] . Width . Value ,
RootGridCol2Width = _rootGrid . ColumnDefinitions [ 2 ] . Width . Value ,
ModelListRow0Height = _modelListGrid . RowDefinitions [ 0 ] . Height . Value ,
ModelListRow2Height = _modelListGrid . RowDefinitions [ 2 ] . Height . Value ,
ExplorerGridRow0Height = _explorerGrid . RowDefinitions [ 0 ] . Height . Value ,
ExplorerGridRow2Height = _explorerGrid . RowDefinitions [ 2 ] . Height . Value ,
RightPanelGridRow0Height = _rightPanelGrid . RowDefinitions [ 0 ] . Height . Value ,
RightPanelGridRow2Height = _rightPanelGrid . RowDefinitions [ 2 ] . Height . Value ,
ResolutionX = _vm . SFMLRendererViewModel . ResolutionX ,
ResolutionY = _vm . SFMLRendererViewModel . ResolutionY ,
MaxFps = _vm . SFMLRendererViewModel . MaxFps ,
Speed = _vm . SFMLRendererViewModel . Speed ,
ShowAxis = _vm . SFMLRendererViewModel . ShowAxis ,
BackgroundColor = _vm . SFMLRendererViewModel . BackgroundColor ,
BackgroundImageMode = _vm . SFMLRendererViewModel . BackgroundImageMode ,
} ;
JsonHelper . Serialize ( m , UserStateFilePath ) ;
}
/// <summary>
/// <see cref="SaveUserState"/> 的延时版本, 避免一次性大量执行
/// </summary>
private void DelayedSaveUserState ( )
{
// 第一次调用时创建定时器
if ( _saveUserStateTimer = = null )
{
_saveUserStateTimer = new ( ) { Interval = _saveTimerDelay } ;
_saveUserStateTimer . Tick + = ( s , e ) = >
{
_saveUserStateTimer . Stop ( ) ;
SaveUserState ( ) ;
} ;
}
// 每次触发都重置间隔和计时
_saveUserStateTimer . Stop ( ) ;
_saveUserStateTimer . Start ( ) ;
}
private void SFMLRendererUserStateChanged ( object? sender , PropertyChangedEventArgs e )
{
switch ( e . PropertyName )
{
case nameof ( SFMLRendererViewModel . ResolutionX ) :
case nameof ( SFMLRendererViewModel . ResolutionY ) :
case nameof ( SFMLRendererViewModel . MaxFps ) :
case nameof ( SFMLRendererViewModel . Speed ) :
case nameof ( SFMLRendererViewModel . ShowAxis ) :
case nameof ( SFMLRendererViewModel . BackgroundColor ) :
case nameof ( SFMLRendererViewModel . BackgroundImageMode ) :
DelayedSaveUserState ( ) ;
break ;
default :
break ;
}
}
#endregion
#region ColorPicker 弹 窗 事 件 处 理
@@ -741,6 +812,8 @@ public partial class MainWindow : Window
_logger . Warn ( "Warn" ) ;
_logger . Error ( "Error" ) ;
_logger . Fatal ( "Fatal" ) ;
var _tabContentHost = ( ContentPresenter ? ) _mainTabControl . Template . FindName ( "PART_SelectedContentHost" , _mainTabControl ) ;
_mainTabControl . Visibility = Visibility . Collapsed ;
return ;
#endif
}