增加背景图案选项
This commit is contained in:
@@ -33,6 +33,8 @@ namespace SpineViewer.Models
|
|||||||
public float Speed { get; set; } = 1f;
|
public float Speed { get; set; } = 1f;
|
||||||
public bool ShowAxis { get; set; } = true;
|
public bool ShowAxis { get; set; } = true;
|
||||||
public Color BackgroundColor { get; set; } = Color.FromRgb(105, 105, 105);
|
public Color BackgroundColor { get; set; } = Color.FromRgb(105, 105, 105);
|
||||||
|
public string BackgroundImagePath { get; set; }
|
||||||
|
public Stretch BackgroundImageMode { get; set; } = Stretch.Uniform;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,8 @@
|
|||||||
<s:String x:Key="Str_RenderSelectedOnly">Render Selected Only</s:String>
|
<s:String x:Key="Str_RenderSelectedOnly">Render Selected Only</s:String>
|
||||||
<s:String x:Key="Str_ShowAxis">Show Axis</s:String>
|
<s:String x:Key="Str_ShowAxis">Show Axis</s:String>
|
||||||
<s:String x:Key="Str_BackgroundColor">Background Color</s:String>
|
<s:String x:Key="Str_BackgroundColor">Background Color</s:String>
|
||||||
<s:String x:Key="Str_BackgroundImage">Background Image</s:String>
|
<s:String x:Key="Str_BackgroundImagePath">Background Image Path</s:String>
|
||||||
|
<s:String x:Key="Str_BackgroundImageMode">Background Image Mode</s:String>
|
||||||
|
|
||||||
<!-- 渲染画面按钮组 -->
|
<!-- 渲染画面按钮组 -->
|
||||||
<s:String x:Key="Str_StopTooltip">Stop</s:String>
|
<s:String x:Key="Str_StopTooltip">Stop</s:String>
|
||||||
|
|||||||
@@ -121,7 +121,8 @@
|
|||||||
<s:String x:Key="Str_RenderSelectedOnly">選択のみレンダリング</s:String>
|
<s:String x:Key="Str_RenderSelectedOnly">選択のみレンダリング</s:String>
|
||||||
<s:String x:Key="Str_ShowAxis">座標軸を表示</s:String>
|
<s:String x:Key="Str_ShowAxis">座標軸を表示</s:String>
|
||||||
<s:String x:Key="Str_BackgroundColor">背景色</s:String>
|
<s:String x:Key="Str_BackgroundColor">背景色</s:String>
|
||||||
<s:String x:Key="Str_BackgroundImage">背景画像</s:String>
|
<s:String x:Key="Str_BackgroundImagePath">背景画像のパス</s:String>
|
||||||
|
<s:String x:Key="Str_BackgroundImageMode">背景画像のモード</s:String>
|
||||||
|
|
||||||
<!-- 渲染画面按钮组 -->
|
<!-- 渲染画面按钮组 -->
|
||||||
<s:String x:Key="Str_StopTooltip">停止</s:String>
|
<s:String x:Key="Str_StopTooltip">停止</s:String>
|
||||||
|
|||||||
@@ -121,7 +121,8 @@
|
|||||||
<s:String x:Key="Str_RenderSelectedOnly">仅渲染选中</s:String>
|
<s:String x:Key="Str_RenderSelectedOnly">仅渲染选中</s:String>
|
||||||
<s:String x:Key="Str_ShowAxis">显示坐标轴</s:String>
|
<s:String x:Key="Str_ShowAxis">显示坐标轴</s:String>
|
||||||
<s:String x:Key="Str_BackgroundColor">背景颜色</s:String>
|
<s:String x:Key="Str_BackgroundColor">背景颜色</s:String>
|
||||||
<s:String x:Key="Str_BackgroundImage">背景图片</s:String>
|
<s:String x:Key="Str_BackgroundImagePath">背景图片路径</s:String>
|
||||||
|
<s:String x:Key="Str_BackgroundImageMode">背景图片模式</s:String>
|
||||||
|
|
||||||
<!-- 渲染画面按钮组 -->
|
<!-- 渲染画面按钮组 -->
|
||||||
<s:String x:Key="Str_StopTooltip">停止</s:String>
|
<s:String x:Key="Str_StopTooltip">停止</s:String>
|
||||||
|
|||||||
@@ -90,6 +90,22 @@ namespace SpineViewer.Services
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool ShowOpenSFMLImageDialog(out string? fileName, string initialDirectory = "")
|
||||||
|
{
|
||||||
|
var dialog = new OpenFileDialog()
|
||||||
|
{
|
||||||
|
InitialDirectory = initialDirectory,
|
||||||
|
Filter = "SFML Image|*.png;*.jpg;*.jpeg;*.bmp;*.tga|All|*.*"
|
||||||
|
};
|
||||||
|
if (dialog.ShowDialog() is true)
|
||||||
|
{
|
||||||
|
fileName = dialog.FileName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
fileName = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool ShowOpenJsonDialog(out string? fileName, string initialDirectory = "")
|
public static bool ShowOpenJsonDialog(out string? fileName, string initialDirectory = "")
|
||||||
{
|
{
|
||||||
var dialog = new OpenFileDialog()
|
var dialog = new OpenFileDialog()
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ using SpineViewer.Services;
|
|||||||
using SpineViewer.Utils;
|
using SpineViewer.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -23,6 +25,8 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
{
|
{
|
||||||
public class SFMLRendererViewModel : ObservableObject
|
public class SFMLRendererViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
|
public ImmutableArray<Stretch> StretchOptions { get; } = Enum.GetValues<Stretch>().ToImmutableArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日志器
|
/// 日志器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -69,6 +73,13 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
private float _forwardDelta = 0;
|
private float _forwardDelta = 0;
|
||||||
private readonly object _forwardDeltaLock = new();
|
private readonly object _forwardDeltaLock = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 背景图片
|
||||||
|
/// </summary>
|
||||||
|
private SFML.Graphics.Sprite? _backgroundImageSprite; // XXX: 暂时未使用 Dispose 释放
|
||||||
|
private SFML.Graphics.Texture? _backgroundImageTexture; // XXX: 暂时未使用 Dispose 释放
|
||||||
|
private readonly object _bgLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 临时变量, 记录拖放世界源点
|
/// 临时变量, 记录拖放世界源点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -169,6 +180,62 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
}
|
}
|
||||||
private SFML.Graphics.Color _backgroundColor = new(105, 105, 105);
|
private SFML.Graphics.Color _backgroundColor = new(105, 105, 105);
|
||||||
|
|
||||||
|
public string BackgroundImagePath
|
||||||
|
{
|
||||||
|
get => _backgroundImagePath;
|
||||||
|
set => SetProperty(_backgroundImagePath, value, v =>
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(v))
|
||||||
|
{
|
||||||
|
lock (_bgLock)
|
||||||
|
{
|
||||||
|
_backgroundImageSprite?.Dispose();
|
||||||
|
_backgroundImageTexture?.Dispose();
|
||||||
|
_backgroundImageTexture = null;
|
||||||
|
_backgroundImageSprite = null;
|
||||||
|
}
|
||||||
|
_backgroundImagePath = v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!File.Exists(v))
|
||||||
|
{
|
||||||
|
_logger.Warn("Omit non-existed background image path, {0}", v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SFML.Graphics.Texture tex = null;
|
||||||
|
SFML.Graphics.Sprite sprite = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tex = new(v);
|
||||||
|
sprite = new(tex) { Origin = new(tex.Size.X / 2f, tex.Size.Y / 2f) };
|
||||||
|
lock (_bgLock)
|
||||||
|
{
|
||||||
|
_backgroundImageSprite?.Dispose();
|
||||||
|
_backgroundImageTexture?.Dispose();
|
||||||
|
_backgroundImageTexture = tex;
|
||||||
|
_backgroundImageSprite = sprite;
|
||||||
|
}
|
||||||
|
_backgroundImagePath = v;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
sprite?.Dispose();
|
||||||
|
tex?.Dispose();
|
||||||
|
_logger.Error("Failed to load background image from path: {0}, {1}", v, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private string _backgroundImagePath;
|
||||||
|
|
||||||
|
public Stretch BackgroundImageMode
|
||||||
|
{
|
||||||
|
get => _backgroundImageMode;
|
||||||
|
set => SetProperty(ref _backgroundImageMode, value);
|
||||||
|
}
|
||||||
|
private Stretch _backgroundImageMode = Stretch.Uniform;
|
||||||
|
|
||||||
public bool RenderSelectedOnly
|
public bool RenderSelectedOnly
|
||||||
{
|
{
|
||||||
get => _renderSelectedOnly;
|
get => _renderSelectedOnly;
|
||||||
@@ -189,6 +256,14 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
}
|
}
|
||||||
private bool _isUpdating = true;
|
private bool _isUpdating = true;
|
||||||
|
|
||||||
|
public RelayCommand Cmd_SelectBackgroundImage => _cmd_SelectBackgroundImage ??= new(() =>
|
||||||
|
{
|
||||||
|
if (!DialogService.ShowOpenSFMLImageDialog(out var fileName))
|
||||||
|
return;
|
||||||
|
BackgroundImagePath = fileName;
|
||||||
|
});
|
||||||
|
private RelayCommand? _cmd_SelectBackgroundImage;
|
||||||
|
|
||||||
public RelayCommand Cmd_Stop => _cmd_Stop ??= new(() =>
|
public RelayCommand Cmd_Stop => _cmd_Stop ??= new(() =>
|
||||||
{
|
{
|
||||||
IsUpdating = false;
|
IsUpdating = false;
|
||||||
@@ -386,6 +461,38 @@ namespace SpineViewer.ViewModels.MainWindow
|
|||||||
|
|
||||||
_renderer.Clear(_backgroundColor);
|
_renderer.Clear(_backgroundColor);
|
||||||
|
|
||||||
|
// 渲染背景
|
||||||
|
lock (_bgLock)
|
||||||
|
{
|
||||||
|
if (_backgroundImageSprite is not null)
|
||||||
|
{
|
||||||
|
using var view = _renderer.GetView();
|
||||||
|
var bg = _backgroundImageSprite;
|
||||||
|
var viewSize = view.Size;
|
||||||
|
var bgSize = bg.Texture.Size;
|
||||||
|
var scaleX = Math.Abs(viewSize.X / bgSize.X);
|
||||||
|
var scaleY = Math.Abs(viewSize.Y / bgSize.Y);
|
||||||
|
var signX = Math.Sign(viewSize.X);
|
||||||
|
var signY = Math.Sign(viewSize.Y);
|
||||||
|
if (_backgroundImageMode == Stretch.None)
|
||||||
|
{
|
||||||
|
scaleX = scaleY = 1f / _renderer.Zoom;
|
||||||
|
}
|
||||||
|
else if (_backgroundImageMode == Stretch.Uniform)
|
||||||
|
{
|
||||||
|
scaleX = scaleY = Math.Min(scaleX, scaleY);
|
||||||
|
}
|
||||||
|
else if (_backgroundImageMode == Stretch.UniformToFill)
|
||||||
|
{
|
||||||
|
scaleX = scaleY = Math.Max(scaleX, scaleY);
|
||||||
|
}
|
||||||
|
bg.Scale = new(signX * scaleX, signY * scaleY);
|
||||||
|
bg.Position = view.Center;
|
||||||
|
bg.Rotation = view.Rotation;
|
||||||
|
_renderer.Draw(bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_showAxis)
|
if (_showAxis)
|
||||||
{
|
{
|
||||||
// 画一个很长的坐标轴, 用 1e9 比较合适
|
// 画一个很长的坐标轴, 用 1e9 比较合适
|
||||||
|
|||||||
@@ -727,6 +727,8 @@
|
|||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- 水平分辨率 -->
|
<!-- 水平分辨率 -->
|
||||||
@@ -780,7 +782,15 @@
|
|||||||
<TextBox Grid.Row="12" Grid.Column="1" Text="{Binding BackgroundColor}" ToolTip="#AARRGGBB"/>
|
<TextBox Grid.Row="12" Grid.Column="1" Text="{Binding BackgroundColor}" ToolTip="#AARRGGBB"/>
|
||||||
|
|
||||||
<!-- 背景图案 -->
|
<!-- 背景图案 -->
|
||||||
|
<Label Grid.Row="13" Grid.Column="0" Content="{DynamicResource Str_BackgroundImagePath}"/>
|
||||||
|
<DockPanel Grid.Row="13" Grid.Column="1" >
|
||||||
|
<Button DockPanel.Dock="Right" Content="..." Command="{Binding Cmd_SelectBackgroundImage}"/>
|
||||||
|
<TextBox Text="{Binding BackgroundImagePath}"/>
|
||||||
|
</DockPanel>
|
||||||
|
|
||||||
<!-- 背景图案模式 -->
|
<!-- 背景图案模式 -->
|
||||||
|
<Label Grid.Row="14" Grid.Column="0" Content="{DynamicResource Str_BackgroundImageMode}"/>
|
||||||
|
<ComboBox Grid.Row="14" Grid.Column="1" SelectedValue="{Binding BackgroundImageMode}" ItemsSource="{Binding StretchOptions}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ public partial class MainWindow : Window
|
|||||||
_vm.SFMLRendererViewModel.Speed = m.Speed;
|
_vm.SFMLRendererViewModel.Speed = m.Speed;
|
||||||
_vm.SFMLRendererViewModel.ShowAxis = m.ShowAxis;
|
_vm.SFMLRendererViewModel.ShowAxis = m.ShowAxis;
|
||||||
_vm.SFMLRendererViewModel.BackgroundColor = m.BackgroundColor;
|
_vm.SFMLRendererViewModel.BackgroundColor = m.BackgroundColor;
|
||||||
|
_vm.SFMLRendererViewModel.BackgroundImagePath = m.BackgroundImagePath;
|
||||||
|
_vm.SFMLRendererViewModel.BackgroundImageMode = m.BackgroundImageMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +183,8 @@ public partial class MainWindow : Window
|
|||||||
Speed = _vm.SFMLRendererViewModel.Speed,
|
Speed = _vm.SFMLRendererViewModel.Speed,
|
||||||
ShowAxis = _vm.SFMLRendererViewModel.ShowAxis,
|
ShowAxis = _vm.SFMLRendererViewModel.ShowAxis,
|
||||||
BackgroundColor = _vm.SFMLRendererViewModel.BackgroundColor,
|
BackgroundColor = _vm.SFMLRendererViewModel.BackgroundColor,
|
||||||
|
BackgroundImagePath = _vm.SFMLRendererViewModel.BackgroundImagePath,
|
||||||
|
BackgroundImageMode = _vm.SFMLRendererViewModel.BackgroundImageMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
JsonHelper.Serialize(m, LastStateFilePath);
|
JsonHelper.Serialize(m, LastStateFilePath);
|
||||||
@@ -596,5 +600,4 @@ public partial class MainWindow : Window
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user