diff --git a/SpineViewer/Utils/BackgroundColorToForegroundColor.cs b/SpineViewer/Utils/BackgroundColorToForegroundColor.cs
new file mode 100644
index 0000000..620da2c
--- /dev/null
+++ b/SpineViewer/Utils/BackgroundColorToForegroundColor.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media;
+
+namespace SpineViewer.Utils
+{
+ public class BackgroundToForegroundConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var color = Colors.White;
+ if (value is SolidColorBrush brush)
+ {
+ color = brush.Color;
+ }
+ else if (value is Color c)
+ {
+ color = c;
+ }
+
+ if (color.A < 128)
+ return Brushes.Black;
+
+ // 计算亮度 (使用标准加权公式)
+ double brightness = (0.299 * color.R + 0.587 * color.G + 0.114 * color.B) / 255.0;
+ return brightness < 0.5 ? Brushes.White : Brushes.Black;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs b/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs
index c11b986..fb2f532 100644
--- a/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs
+++ b/SpineViewer/ViewModels/Exporters/FFmpegVideoExporterViewModel.cs
@@ -25,15 +25,14 @@ namespace SpineViewer.ViewModels.Exporters
get => _format;
set
{
- if (SetProperty(ref _format, value))
- {
- OnPropertyChanged(nameof(EnableParamLoop));
- OnPropertyChanged(nameof(EnableParamQuality));
- OnPropertyChanged(nameof(EnableParamLossless));
- OnPropertyChanged(nameof(EnableParamApngPred));
- OnPropertyChanged(nameof(EnableParamCrf));
- OnPropertyChanged(nameof(EnableParamProfile));
- }
+ if (!SetProperty(ref _format, value))
+ return;
+ OnPropertyChanged(nameof(EnableParamLoop));
+ OnPropertyChanged(nameof(EnableParamQuality));
+ OnPropertyChanged(nameof(EnableParamLossless));
+ OnPropertyChanged(nameof(EnableParamApngPred));
+ OnPropertyChanged(nameof(EnableParamCrf));
+ OnPropertyChanged(nameof(EnableParamProfile));
}
}
protected FFmpegVideoExporter.VideoFormat _format = FFmpegVideoExporter.VideoFormat.Mp4;
diff --git a/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs b/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs
index 590b0fe..7a4041a 100644
--- a/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs
+++ b/SpineViewer/ViewModels/MainWindow/SFMLRendererViewModel.cs
@@ -47,11 +47,6 @@ namespace SpineViewer.ViewModels.MainWindow
///
private readonly SFML.Graphics.VertexArray _selectedBackgroundVertices = new(SFML.Graphics.PrimitiveType.Quads, 4); // XXX: 暂时未使用 Dispose 释放
- ///
- /// 预览画面坐标轴颜色
- ///
- private static readonly SFML.Graphics.Color _axisColor = new(220, 220, 220);
-
///
/// 坐标轴顶点缓冲区
///
@@ -178,10 +173,21 @@ namespace SpineViewer.ViewModels.MainWindow
public Color BackgroundColor
{
get => Color.FromRgb(_backgroundColor.R, _backgroundColor.G, _backgroundColor.B);
- set => SetProperty(BackgroundColor, value, v => _backgroundColor = new(value.R, value.G, value.B));
+ set
+ {
+ if (!SetProperty(BackgroundColor, value, v => _backgroundColor = new(value.R, value.G, value.B)))
+ return;
+ var b = (0.299 * value.R + 0.587 * value.G + 0.114 * value.B) / 255.0;
+ _axisColor = b < 0.5 ? SFML.Graphics.Color.White : SFML.Graphics.Color.Black;
+ }
}
private SFML.Graphics.Color _backgroundColor = new(105, 105, 105);
+ ///
+ /// 预览画面坐标轴颜色
+ ///
+ private SFML.Graphics.Color _axisColor = SFML.Graphics.Color.White;
+
public string BackgroundImagePath
{
get => _backgroundImagePath;
diff --git a/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml b/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml
index 58336f6..b0ffb83 100644
--- a/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml
+++ b/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml
@@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:SpineViewer.Views.ExporterDialogs"
+ xmlns:utils="clr-namespace:SpineViewer.Utils"
xmlns:exporters="clr-namespace:SpineViewer.ViewModels.Exporters"
d:DataContext="{d:DesignInstance Type=exporters:CustomFFmpegExporterViewModel}"
mc:Ignorable="d"
@@ -13,6 +14,9 @@
Height="800"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
+
+
+
@@ -105,12 +109,20 @@
-
diff --git a/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml.cs b/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml.cs
index 3b0efd3..7eceb61 100644
--- a/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml.cs
+++ b/SpineViewer/Views/ExporterDialogs/CustomFFmpegExporterDialog.xaml.cs
@@ -44,7 +44,20 @@ namespace SpineViewer.Views.ExporterDialogs
private void ButtonPickColor_Click(object sender, RoutedEventArgs e)
{
+ _colorPopup.IsOpen = !_colorPopup.IsOpen;
+ }
+ private void ColorPicker_Confirmed(object sender, HandyControl.Data.FunctionEventArgs e)
+ {
+ _colorPopup.IsOpen = false;
+ var color = e.Info;
+ var vm = (BaseExporterViewModel)DataContext;
+ vm.BackgroundColor = color;
+ }
+
+ private void ColorPicker_Canceled(object sender, EventArgs e)
+ {
+ _colorPopup.IsOpen = false;
}
}
}
diff --git a/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml b/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml
index eb05e59..721a10b 100644
--- a/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml
+++ b/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml
@@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:SpineViewer.Views.ExporterDialogs"
+ xmlns:utils="clr-namespace:SpineViewer.Utils"
xmlns:vmexp="clr-namespace:SpineViewer.ViewModels.Exporters"
d:DataContext="{d:DesignInstance Type=vmexp:FFmpegVideoExporterViewModel}"
mc:Ignorable="d"
@@ -13,6 +14,9 @@
Height="750"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
+
+
+
@@ -105,12 +109,20 @@
-
+
+
+
+
+
+
-
+
diff --git a/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml.cs b/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml.cs
index 2192200..5528eb2 100644
--- a/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml.cs
+++ b/SpineViewer/Views/ExporterDialogs/FFmpegVideoExporterDialog.xaml.cs
@@ -44,7 +44,20 @@ namespace SpineViewer.Views.ExporterDialogs
private void ButtonPickColor_Click(object sender, RoutedEventArgs e)
{
+ _colorPopup.IsOpen = !_colorPopup.IsOpen;
+ }
+ private void ColorPicker_Confirmed(object sender, HandyControl.Data.FunctionEventArgs e)
+ {
+ _colorPopup.IsOpen = false;
+ var color = e.Info;
+ var vm = (BaseExporterViewModel)DataContext;
+ vm.BackgroundColor = color;
+ }
+
+ private void ColorPicker_Canceled(object sender, EventArgs e)
+ {
+ _colorPopup.IsOpen = false;
}
}
}
diff --git a/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml b/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml
index f46556f..0c54cac 100644
--- a/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml
+++ b/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml
@@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:SpineViewer.Views"
+ xmlns:utils="clr-namespace:SpineViewer.Utils"
xmlns:vmexp="clr-namespace:SpineViewer.ViewModels.Exporters"
d:DataContext="{d:DesignInstance Type=vmexp:FrameExporterViewModel}"
mc:Ignorable="d"
@@ -13,6 +14,9 @@
Height="480"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
+
+
+
@@ -105,12 +109,20 @@
-
+
+
+
+
+
+
-
+
diff --git a/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml.cs b/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml.cs
index 217d2e7..5fb3c65 100644
--- a/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml.cs
+++ b/SpineViewer/Views/ExporterDialogs/FrameExporterDialog.xaml.cs
@@ -44,7 +44,20 @@ namespace SpineViewer.Views.ExporterDialogs
private void ButtonPickColor_Click(object sender, RoutedEventArgs e)
{
-
+ _colorPopup.IsOpen = !_colorPopup.IsOpen;
+ }
+
+ private void ColorPicker_Confirmed(object sender, HandyControl.Data.FunctionEventArgs e)
+ {
+ _colorPopup.IsOpen = false;
+ var color = e.Info;
+ var vm = (BaseExporterViewModel)DataContext;
+ vm.BackgroundColor = color;
+ }
+
+ private void ColorPicker_Canceled(object sender, EventArgs e)
+ {
+ _colorPopup.IsOpen = false;
}
}
}
diff --git a/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml b/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml
index b08c19e..34ff9c7 100644
--- a/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml
+++ b/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml
@@ -5,6 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:SpineViewer.Views"
+ xmlns:utils="clr-namespace:SpineViewer.Utils"
xmlns:vmexp="clr-namespace:SpineViewer.ViewModels.Exporters"
d:DataContext="{d:DesignInstance Type=vmexp:FrameSequenceExporterViewModel}"
mc:Ignorable="d"
@@ -13,6 +14,9 @@
Height="550"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner">
+
+
+
@@ -105,12 +109,20 @@
-
+
+
+
+
+
+
-
+
diff --git a/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml.cs b/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml.cs
index 0aa157f..6c6590e 100644
--- a/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml.cs
+++ b/SpineViewer/Views/ExporterDialogs/FrameSequenceExporterDialog.xaml.cs
@@ -44,7 +44,20 @@ namespace SpineViewer.Views.ExporterDialogs
private void ButtonPickColor_Click(object sender, RoutedEventArgs e)
{
+ _colorPopup.IsOpen = !_colorPopup.IsOpen;
+ }
+ private void ColorPicker_Confirmed(object sender, HandyControl.Data.FunctionEventArgs e)
+ {
+ _colorPopup.IsOpen = false;
+ var color = e.Info;
+ var vm = (BaseExporterViewModel)DataContext;
+ vm.BackgroundColor = color;
+ }
+
+ private void ColorPicker_Canceled(object sender, EventArgs e)
+ {
+ _colorPopup.IsOpen = false;
}
}
}
diff --git a/SpineViewer/Views/MainWindow.xaml b/SpineViewer/Views/MainWindow.xaml
index 7984959..cbac603 100644
--- a/SpineViewer/Views/MainWindow.xaml
+++ b/SpineViewer/Views/MainWindow.xaml
@@ -37,6 +37,7 @@
+
@@ -941,7 +942,22 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SpineViewer/Views/MainWindow.xaml.cs b/SpineViewer/Views/MainWindow.xaml.cs
index 0b30d54..ddeca6d 100644
--- a/SpineViewer/Views/MainWindow.xaml.cs
+++ b/SpineViewer/Views/MainWindow.xaml.cs
@@ -8,6 +8,7 @@ using SpineViewer.Natives;
using SpineViewer.Resources;
using SpineViewer.Services;
using SpineViewer.Utils;
+using SpineViewer.ViewModels.Exporters;
using SpineViewer.ViewModels.MainWindow;
using System.Collections.Specialized;
using System.ComponentModel;
@@ -253,6 +254,28 @@ public partial class MainWindow : Window
#endregion
+ #region ColorPicker 弹窗事件处理
+
+ private void ButtonPickColor_Click(object sender, RoutedEventArgs e)
+ {
+ _colorPopup.IsOpen = !_colorPopup.IsOpen;
+ }
+
+ private void ColorPicker_Confirmed(object sender, HandyControl.Data.FunctionEventArgs e)
+ {
+ _colorPopup.IsOpen = false;
+ var color = e.Info;
+ var vm = ((MainWindowViewModel)DataContext).SFMLRendererViewModel;
+ vm.BackgroundColor = color;
+ }
+
+ private void ColorPicker_Canceled(object sender, EventArgs e)
+ {
+ _colorPopup.IsOpen = false;
+ }
+
+ #endregion
+
#region ViewModel PropertyChanged 事件处理
private void SFMLRendererViewModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
@@ -709,11 +732,10 @@ public partial class MainWindow : Window
private void DebugMenuItem_Click(object sender, RoutedEventArgs e)
{
#if DEBUG
- var a = _rootGrid.ColumnDefinitions[0].Width;
- var b = _rootGrid.ColumnDefinitions[1].Width;
- var c = _rootGrid.ColumnDefinitions[2].Width;
- Debug.WriteLine(a);
- Debug.WriteLine(_rootGrid.ColumnDefinitions[0].Width.IsStar);
+
+ var res = HandyControl.Controls.Dialog.Show();
+
+ return;
#endif
}
}
\ No newline at end of file