feat(工具栏设置): 添加工具栏配置页面及功能实现
实现工具栏配置页面,允许用户调整工具栏按钮的顺序和可见性 包含主工具栏、画布控制和尾部按钮三个区域的配置 支持恢复默认布局功能
This commit is contained in:
@@ -2,28 +2,24 @@ using System.Windows;
|
||||
|
||||
namespace Ink_Canvas.Controls.Toolbar
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个工具栏按钮(或任意浮动栏/白板栏条目)的插件化契约。
|
||||
/// 实现类必须有无参构造函数,启动时会被 ToolbarRegistry 反射实例化。
|
||||
/// </summary>
|
||||
public interface IToolbarItem
|
||||
{
|
||||
/// <summary>稳定、唯一的 id,用于持久化用户配置。不要随便改。</summary>
|
||||
string Id { get; }
|
||||
|
||||
ToolbarSlot DefaultSlot { get; }
|
||||
|
||||
/// <summary>同一 slot 内的默认顺序,小的在前。</summary>
|
||||
int DefaultOrder { get; }
|
||||
|
||||
bool DefaultVisible { get; }
|
||||
|
||||
ToolbarInsertPosition DefaultPosition { get; }
|
||||
|
||||
/// <summary>仅当 Position 为 BeforeAnchor/AfterAnchor 时有意义,对应 XAML 里 x:Name。</summary>
|
||||
string DefaultAnchorName { get; }
|
||||
|
||||
/// <summary>构造 UI 元素并接线所有行为。</summary>
|
||||
string DisplayName { get; }
|
||||
|
||||
string MenuPanelName { get; }
|
||||
|
||||
FrameworkElement BuildView(IToolbarHost host);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace Ink_Canvas.Controls.Toolbar.Items
|
||||
public override string LocalizationKey => "FloatingBar_AreaEraser";
|
||||
public override ToolbarSlot DefaultSlot => ToolbarSlot.FloatingBarCanvasControls;
|
||||
public override int DefaultOrder => 100;
|
||||
public override string MenuPanelName => "EraserSizePanel";
|
||||
|
||||
protected override void OnClick(IToolbarHost host, object sender, MouseButtonEventArgs e)
|
||||
=> host.Window.EraserIcon_Click(sender, e);
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Ink_Canvas.Controls.Toolbar.Items
|
||||
public override string LocalizationKey => "FloatingBar_Annotate";
|
||||
public override ToolbarSlot DefaultSlot => ToolbarSlot.FloatingBarMain;
|
||||
public override int DefaultOrder => 110;
|
||||
public override string MenuPanelName => "PenPalette";
|
||||
|
||||
protected override void OnClick(IToolbarHost host, object sender, MouseButtonEventArgs e)
|
||||
=> host.Window.PenIcon_Click(sender, e);
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Ink_Canvas.Controls.Toolbar.Items
|
||||
public override string LocalizationKey => "FloatingBar_Geometry";
|
||||
public override ToolbarSlot DefaultSlot => ToolbarSlot.FloatingBarCanvasControls;
|
||||
public override int DefaultOrder => 130;
|
||||
public override string MenuPanelName => "BorderDrawShape";
|
||||
|
||||
protected override void OnClick(IToolbarHost host, object sender, MouseButtonEventArgs e)
|
||||
=> host.Window.ImageDrawShape_MouseUp(sender, e);
|
||||
|
||||
@@ -5,10 +5,6 @@ using System.Windows.Media;
|
||||
|
||||
namespace Ink_Canvas.Controls.Toolbar.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用 ToolbarImageButton 工具栏条目基类——大幅减少每个按钮的样板代码。
|
||||
/// 派生类通常只需给 Id / 本地化键 / Slot / Order / 点击处理 / Attach 回填。
|
||||
/// </summary>
|
||||
internal abstract class ToolbarImageButtonItemBase : IToolbarItem
|
||||
{
|
||||
public abstract string Id { get; }
|
||||
@@ -19,22 +15,22 @@ namespace Ink_Canvas.Controls.Toolbar.Items
|
||||
public virtual ToolbarInsertPosition DefaultPosition => ToolbarInsertPosition.Prepend;
|
||||
public virtual string DefaultAnchorName => null;
|
||||
|
||||
/// <summary>DynamicResource 名称,用于 IconBrush。默认为 null(使用控件自带前景色)。</summary>
|
||||
protected virtual string IconBrushResourceKey => null;
|
||||
public string DisplayName => Strings.GetString(LocalizationKey) ?? LocalizationKey;
|
||||
public virtual string MenuPanelName => null;
|
||||
|
||||
/// <summary>DynamicResource 名称,用于 LabelBrush(文字颜色)。默认为 null(使用控件自带前景色)。</summary>
|
||||
protected virtual string IconBrushResourceKey => null;
|
||||
protected virtual string LabelBrushResourceKey => null;
|
||||
|
||||
protected abstract void OnClick(IToolbarHost host, object sender, MouseButtonEventArgs e);
|
||||
|
||||
/// <summary>构建后调用,用于回填 MainWindow 的原命名属性(partial 扩展里的 Attach*)。可选。</summary>
|
||||
protected virtual void AfterBuild(IToolbarHost host, ToolbarImageButton view) { }
|
||||
|
||||
public FrameworkElement BuildView(IToolbarHost host)
|
||||
{
|
||||
var btn = new ToolbarImageButton
|
||||
{
|
||||
Label = Strings.GetString(LocalizationKey) ?? LocalizationKey
|
||||
Label = Strings.GetString(LocalizationKey) ?? LocalizationKey,
|
||||
Tag = "ToolbarRegistryInjected"
|
||||
};
|
||||
if (!string.IsNullOrEmpty(IconBrushResourceKey))
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Ink_Canvas.Controls.Toolbar.Items
|
||||
public override int DefaultOrder => 110;
|
||||
public override ToolbarInsertPosition DefaultPosition => ToolbarInsertPosition.AfterAnchor;
|
||||
public override string DefaultAnchorName => "FloatingBarEndSeparator";
|
||||
public override string MenuPanelName => "BorderTools";
|
||||
|
||||
protected override void OnClick(IToolbarHost host, object sender, MouseButtonEventArgs e)
|
||||
=> host.Window.SymbolIconTools_MouseUp(sender, e);
|
||||
|
||||
@@ -8,12 +8,10 @@ using System.Windows.Controls;
|
||||
|
||||
namespace Ink_Canvas.Controls.Toolbar
|
||||
{
|
||||
/// <summary>
|
||||
/// 扫描当前程序集里的 IToolbarItem 实现,按用户配置(Settings.Toolbar)排序/过滤后注入到目标容器。
|
||||
/// </summary>
|
||||
public static class ToolbarRegistry
|
||||
{
|
||||
private static List<IToolbarItem> _items;
|
||||
internal const string InjectedTag = "ToolbarRegistryInjected";
|
||||
|
||||
public static IReadOnlyList<IToolbarItem> Discover()
|
||||
{
|
||||
@@ -34,13 +32,25 @@ namespace Ink_Canvas.Controls.Toolbar
|
||||
})
|
||||
.Where(i => i != null)
|
||||
.ToList();
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: Discover 完成, 发现 {_items.Count} 个条目", LogHelper.LogType.Info);
|
||||
return _items;
|
||||
}
|
||||
|
||||
/// <summary>按 slot 分配工具栏条目到对应容器。调用者负责清空目标容器里要被接管的旧内容。</summary>
|
||||
public static void ClearInjected(Panel container)
|
||||
{
|
||||
if (container == null) return;
|
||||
var toRemove = container.Children.OfType<FrameworkElement>()
|
||||
.Where(e => e.Tag as string == InjectedTag)
|
||||
.ToList();
|
||||
foreach (var element in toRemove)
|
||||
container.Children.Remove(element);
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: ClearInjected 清除 {toRemove.Count} 个元素 [{container.Name}]", LogHelper.LogType.Info);
|
||||
}
|
||||
|
||||
public static void Populate(IToolbarHost host, IDictionary<ToolbarSlot, Panel> slots, ToolbarLayoutSettings layout)
|
||||
{
|
||||
if (host == null || slots == null) return;
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: Populate 开始", LogHelper.LogType.Info);
|
||||
if (host == null || slots == null) { LogHelper.WriteLogToFile("ToolbarRegistry: Populate host 或 slots 为空", LogHelper.LogType.Warning); return; }
|
||||
layout = layout ?? new ToolbarLayoutSettings();
|
||||
|
||||
var grouped = new Dictionary<ToolbarSlot, List<(IToolbarItem item, ToolbarItemConfig cfg)>>();
|
||||
@@ -65,18 +75,51 @@ namespace Ink_Canvas.Controls.Toolbar
|
||||
}
|
||||
list.Add((item, cfg));
|
||||
}
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 分组完成, {grouped.Count} 个 slot 有可见条目", LogHelper.LogType.Info);
|
||||
|
||||
foreach (var kv in grouped)
|
||||
{
|
||||
if (!slots.TryGetValue(kv.Key, out var container) || container == null) continue;
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 注入到 {kv.Key}, 条目数={kv.Value.Count}", LogHelper.LogType.Info);
|
||||
InjectIntoContainer(host, container, kv.Value);
|
||||
}
|
||||
|
||||
ApplyMenuVisibility(host, layout);
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: Populate 完成", LogHelper.LogType.Info);
|
||||
}
|
||||
|
||||
public static void ApplyMenuVisibility(IToolbarHost host, ToolbarLayoutSettings layout)
|
||||
{
|
||||
if (host == null || layout == null) return;
|
||||
foreach (var item in Discover())
|
||||
{
|
||||
if (string.IsNullOrEmpty(item.MenuPanelName)) continue;
|
||||
bool visible = true;
|
||||
if (layout.Items.TryGetValue(item.Id, out var cfg))
|
||||
visible = cfg.Visible;
|
||||
try
|
||||
{
|
||||
var menuElement = host.Window.FindName(item.MenuPanelName) as FrameworkElement;
|
||||
if (menuElement != null)
|
||||
{
|
||||
menuElement.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 菜单 [{item.MenuPanelName}] -> {(visible ? "Visible" : "Collapsed")}", LogHelper.LogType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 找不到菜单面板 [{item.MenuPanelName}]", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 设置菜单可见性异常 [{item.MenuPanelName}]: {ex.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void InjectIntoContainer(IToolbarHost host, Panel container,
|
||||
List<(IToolbarItem item, ToolbarItemConfig cfg)> entries)
|
||||
{
|
||||
// 按 Position 分桶,每桶内按 Order 升序。
|
||||
var prepend = entries.Where(e => e.cfg.Position == ToolbarInsertPosition.Prepend).OrderBy(e => e.cfg.Order).ToList();
|
||||
var append = entries.Where(e => e.cfg.Position == ToolbarInsertPosition.Append).OrderBy(e => e.cfg.Order).ToList();
|
||||
var before = entries.Where(e => e.cfg.Position == ToolbarInsertPosition.BeforeAnchor).ToList();
|
||||
@@ -153,9 +196,9 @@ namespace Ink_Canvas.Controls.Toolbar
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 构建 {item.Id} 失败: {ex.Message}", LogHelper.LogType.Warning);
|
||||
LogHelper.WriteLogToFile($"ToolbarRegistry: 构建 {item.Id} 失败: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", LogHelper.LogType.Error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
|
||||
@@ -264,7 +265,6 @@ namespace Ink_Canvas.Helpers
|
||||
|
||||
var sb = new Storyboard();
|
||||
|
||||
// 渐变动画
|
||||
var fadeOutAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 1,
|
||||
@@ -283,5 +283,106 @@ namespace Ink_Canvas.Helpers
|
||||
sb.Begin((FrameworkElement)element);
|
||||
}
|
||||
|
||||
public static void ShowPopupWithSlideAndFade(Popup popup, double duration = 0.15)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (popup == null)
|
||||
throw new ArgumentNullException(nameof(popup));
|
||||
|
||||
if (popup.IsOpen) return;
|
||||
|
||||
var child = popup.Child as FrameworkElement;
|
||||
if (child == null)
|
||||
{
|
||||
popup.IsOpen = true;
|
||||
return;
|
||||
}
|
||||
|
||||
child.Opacity = 0.5;
|
||||
child.RenderTransform = new TranslateTransform(0, 10);
|
||||
|
||||
popup.IsOpen = true;
|
||||
|
||||
var sb = new Storyboard();
|
||||
|
||||
var fadeInAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 0.5,
|
||||
To = 1,
|
||||
Duration = TimeSpan.FromSeconds(duration)
|
||||
};
|
||||
fadeInAnimation.EasingFunction = new CubicEase();
|
||||
Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath(UIElement.OpacityProperty));
|
||||
|
||||
var slideAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 10,
|
||||
To = 0,
|
||||
Duration = TimeSpan.FromSeconds(duration)
|
||||
};
|
||||
slideAnimation.EasingFunction = new CubicEase();
|
||||
Storyboard.SetTargetProperty(slideAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
|
||||
|
||||
sb.Children.Add(fadeInAnimation);
|
||||
sb.Children.Add(slideAnimation);
|
||||
|
||||
sb.Begin(child);
|
||||
}
|
||||
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
|
||||
}
|
||||
|
||||
public static void HidePopupWithSlideAndFade(Popup popup, double duration = 0.15)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (popup == null)
|
||||
throw new ArgumentNullException(nameof(popup));
|
||||
|
||||
if (!popup.IsOpen) return;
|
||||
|
||||
var child = popup.Child as FrameworkElement;
|
||||
if (child == null)
|
||||
{
|
||||
popup.IsOpen = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var sb = new Storyboard();
|
||||
|
||||
var fadeOutAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 1,
|
||||
To = 0,
|
||||
Duration = TimeSpan.FromSeconds(duration)
|
||||
};
|
||||
fadeOutAnimation.EasingFunction = new CubicEase();
|
||||
Storyboard.SetTargetProperty(fadeOutAnimation, new PropertyPath(UIElement.OpacityProperty));
|
||||
|
||||
var slideAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 10,
|
||||
Duration = TimeSpan.FromSeconds(duration)
|
||||
};
|
||||
slideAnimation.EasingFunction = new CubicEase();
|
||||
Storyboard.SetTargetProperty(slideAnimation, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
|
||||
|
||||
sb.Children.Add(fadeOutAnimation);
|
||||
sb.Children.Add(slideAnimation);
|
||||
|
||||
sb.Completed += (s, e) =>
|
||||
{
|
||||
popup.IsOpen = false;
|
||||
child.Opacity = 1;
|
||||
child.RenderTransform = new TranslateTransform();
|
||||
};
|
||||
|
||||
child.RenderTransform = new TranslateTransform();
|
||||
sb.Begin(child);
|
||||
}
|
||||
catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+150
-151
@@ -666,10 +666,10 @@
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 图片选中框(边框 + 四角自由缩放 + 顶部旋转手柄) -->
|
||||
<!-- 图片选择覆盖层(缩放/移动/旋转) -->
|
||||
<localControls:ImageSelectionOverlay x:Name="ImageSelectionOverlay"
|
||||
Visibility="Collapsed"
|
||||
Panel.ZIndex="1000" />
|
||||
Visibility="Collapsed"
|
||||
Panel.ZIndex="1000" />
|
||||
|
||||
</Grid>
|
||||
|
||||
@@ -1489,18 +1489,20 @@
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1"
|
||||
CornerRadius="6,6,0,0"
|
||||
Background="#2563eb" Margin="-1,-1,-1,1">
|
||||
<Canvas Height="24" ClipToBounds="True">
|
||||
<TextBlock Text="{i18n:I18n Key=Board_EraserOptions}" Canvas.Left="8" Foreground="White"
|
||||
Padding="0,5"
|
||||
FontSize="11" FontWeight="Bold"
|
||||
TextAlignment="Center" />
|
||||
<Image Margin="100,4,0,0"
|
||||
Source="/Resources/new-icons/close-white.png"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16" Width="16"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Canvas>
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{i18n:I18n Key=Board_EraserOptions}" Foreground="White"
|
||||
VerticalAlignment="Center" Grid.Column="0"
|
||||
FontSize="11" FontWeight="Bold" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.ChromeCloseContrast}"
|
||||
Foreground="White" FontSize="12"
|
||||
VerticalAlignment="Center" Grid.Column="1"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ikw:SimpleStackPanel Orientation="Horizontal" Margin="0,6,0,0"
|
||||
Spacing="2"
|
||||
@@ -1934,67 +1936,7 @@
|
||||
Label="{i18n:I18n Key=Board_Tools}"
|
||||
IconGeometry="F1 M24,24z M0,0z M3.336,1.17001C2.13975,1.17001,1.17,2.13976,1.17,3.33601L1.17,8.75101C1.17,9.94726,2.13975,10.917,3.336,10.917L8.751,10.917C9.94725,10.917,10.917,9.94726,10.917,8.75101L10.917,3.33601C10.917,2.13976,9.94725,1.17001,8.751,1.17001L3.336,1.17001z M15.249,1.17001C14.0527,1.17001,13.083,2.13976,13.083,3.33601L13.083,8.75101C13.083,9.94726,14.0527,10.917,15.249,10.917L20.664,10.917C21.8602,10.917,22.83,9.94726,22.83,8.75101L22.83,3.33601C22.83,2.13976,21.8602,1.17001,20.664,1.17001L15.249,1.17001z M3.336,13.083C2.13975,13.083,1.17,14.0528,1.17,15.249L1.17,20.664C1.17,21.8603,2.13975,22.83,3.336,22.83L8.751,22.83C9.94725,22.83,10.917,21.8603,10.917,20.664L10.917,15.249C10.917,14.0528,9.94725,13.083,8.751,13.083L3.336,13.083z M15.249,13.083C14.0527,13.083,13.083,14.0528,13.083,15.249L13.083,20.664C13.083,21.8603,14.0527,22.83,15.249,22.83L20.664,22.83C21.8602,22.83,22.83,21.8603,22.83,20.664L22.83,15.249C22.83,14.0528,21.8602,13.083,20.664,13.083L15.249,13.083z"
|
||||
ButtonMouseUp="SymbolIconTools_MouseUp" />
|
||||
<!--工具菜单-->
|
||||
<Border>
|
||||
<Grid Width="0" Margin="0,0,0,5" RenderTransformOrigin="0,1">
|
||||
<Grid.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform ScaleX="1.5" ScaleY="1.5" />
|
||||
<SkewTransform />
|
||||
<RotateTransform />
|
||||
<TranslateTransform />
|
||||
</TransformGroup>
|
||||
</Grid.RenderTransform>
|
||||
<Border ClipToBounds="True" x:Name="BoardBorderTools"
|
||||
Visibility="Collapsed"
|
||||
Margin="-80,-160,-39,50"
|
||||
CornerRadius="5" Background="{DynamicResource SettingsPageBackground}" Opacity="1"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#2563eb">
|
||||
<ikw:SimpleStackPanel Margin="-1,0,0,0">
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1"
|
||||
CornerRadius="6,6,0,0"
|
||||
Background="#2563eb" Margin="-1,-1,-1,1">
|
||||
<Grid Height="24">
|
||||
<TextBlock Text="{i18n:I18n Key=Tools_MoreFeaturesTitle}" Margin="8,0,0,0" Foreground="White"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left"
|
||||
FontSize="11" FontWeight="Bold" />
|
||||
<Image Margin="0,0,8,0"
|
||||
Source="/Resources/new-icons/close-white.png"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16" Width="16"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ikw:SimpleStackPanel Margin="10,3,10,2" Spacing="2">
|
||||
<ikw:SimpleStackPanel.Resources>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource AutoFitToolPopupLabel8}" />
|
||||
</ikw:SimpleStackPanel.Resources>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="BoardTimerToolBtn" ButtonMouseUp="ImageCountdownTimer_MouseUp" Label="{i18n:I18n Key=Tools_Timer}" />
|
||||
<controls:ToolMenuButton x:Name="BoardRandomDrawToolBtn" Visibility="Collapsed" ButtonMouseUp="SymbolIconRand_MouseUp" Label="{i18n:I18n Key=Tools_RandomDraw}" />
|
||||
<controls:ToolMenuButton x:Name="BoardSingleDrawToolBtn" Visibility="Collapsed" ButtonMouseUp="SymbolIconRandOne_MouseUp" Label="{i18n:I18n Key=Tools_SingleDraw}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="BoardSaveToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconSaveStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Save}" />
|
||||
<controls:ToolMenuButton x:Name="BoardOpenToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconOpenStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Open}" />
|
||||
<controls:ToolMenuButton x:Name="BoardReplayToolBtn" ButtonMouseUp="GridInkReplayButton_MouseUp" Label="{i18n:I18n Key=Tools_Replay}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="BoardScreenshotToolBtn" ButtonMouseUp="SymbolIconScreenshot_MouseUp" Label="{i18n:I18n Key=Tools_Screenshot}" />
|
||||
<controls:ToolMenuButton x:Name="BoardManualToolBtn" ButtonMouseUp="OperatingGuideWindowIcon_MouseUp" Label="{i18n:I18n Key=Tools_Manual}" />
|
||||
<controls:ToolMenuButton x:Name="BoardSettingsToolBtn" ButtonMouseUp="SymbolIconSettings_Click" Label="{i18n:I18n Key=Tools_Settings}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<controls:BoardToolbarButton x:Name="BoardExit"
|
||||
Position="Last"
|
||||
Label="{i18n:I18n Key=Board_Exit}"
|
||||
@@ -2006,6 +1948,59 @@
|
||||
</ikw:SimpleStackPanel>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
<Popup x:Name="BoardBorderToolsPopup"
|
||||
PlacementTarget="{Binding ElementName=BoardTools}"
|
||||
Placement="Custom"
|
||||
AllowsTransparency="True"
|
||||
StaysOpen="True"
|
||||
IsOpen="False">
|
||||
<Border x:Name="BoardBorderTools"
|
||||
CornerRadius="6" Background="{DynamicResource SettingsPageBackground}" Opacity="1"
|
||||
BorderThickness="1"
|
||||
BorderBrush="#2563eb">
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0">
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1"
|
||||
CornerRadius="4,4,0,0" ClipToBounds="True"
|
||||
Background="#2563eb">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{i18n:I18n Key=Tools_MoreFeaturesTitle}" Foreground="White"
|
||||
VerticalAlignment="Center" Grid.Column="0"
|
||||
FontSize="11" FontWeight="Bold" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.ChromeCloseContrast}"
|
||||
Foreground="White" FontSize="12"
|
||||
VerticalAlignment="Center"
|
||||
Grid.Column="1"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ikw:SimpleStackPanel Margin="10,3,10,2" Spacing="2">
|
||||
<ikw:SimpleStackPanel.Resources>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource AutoFitToolPopupLabel8}" />
|
||||
</ikw:SimpleStackPanel.Resources>
|
||||
<ikw:SimpleStackPanel Height="40" Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="BoardTimerToolBtn" ButtonMouseUp="ImageCountdownTimer_MouseUp" Label="{i18n:I18n Key=Tools_Timer}" />
|
||||
<controls:ToolMenuButton x:Name="BoardRandomDrawToolBtn" Visibility="Collapsed" ButtonMouseUp="SymbolIconRand_MouseUp" Label="{i18n:I18n Key=Tools_RandomDraw}" />
|
||||
<controls:ToolMenuButton x:Name="BoardSingleDrawToolBtn" Visibility="Collapsed" ButtonMouseUp="SymbolIconRandOne_MouseUp" Label="{i18n:I18n Key=Tools_SingleDraw}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Height="40" Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="BoardSaveToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconSaveStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Save}" />
|
||||
<controls:ToolMenuButton x:Name="BoardOpenToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconOpenStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Open}" />
|
||||
<controls:ToolMenuButton x:Name="BoardReplayToolBtn" ButtonMouseUp="GridInkReplayButton_MouseUp" Label="{i18n:I18n Key=Tools_Replay}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Height="40" Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="BoardScreenshotToolBtn" ButtonMouseUp="SymbolIconScreenshot_MouseUp" Label="{i18n:I18n Key=Tools_Screenshot}" />
|
||||
<controls:ToolMenuButton x:Name="BoardManualToolBtn" ButtonMouseUp="OperatingGuideWindowIcon_MouseUp" Label="{i18n:I18n Key=Tools_Manual}" />
|
||||
<controls:ToolMenuButton x:Name="BoardSettingsToolBtn" ButtonMouseUp="SymbolIconSettings_Click" Label="{i18n:I18n Key=Tools_Settings}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</Border>
|
||||
</Popup>
|
||||
<!-- 右下角 -->
|
||||
<Viewbox x:Name="ViewboxBlackboardRightSide" Margin="3,0,0,0" Height="55"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom">
|
||||
@@ -2395,7 +2390,7 @@
|
||||
HorizontalAlignment="Left">
|
||||
<Grid>
|
||||
<Canvas Name="FloatingbarSelectionBGCanvas" Margin="2,0,2,0">
|
||||
<Border Name="FloatingbarSelectionBG" Visibility="Hidden" Width="28" Height="34"
|
||||
<Border Name="FloatingbarSelectionBG" Visibility="Hidden" d:Visibility="Visible" Width="28" Height="34"
|
||||
Canvas.Left="28" Margin="0,-2,0,-2" Background="#153b82f6">
|
||||
<Canvas>
|
||||
<Border Canvas.Bottom="0" Canvas.Left="8" Width="12" Height="2"
|
||||
@@ -2803,22 +2798,21 @@
|
||||
</TextBlock>
|
||||
<ui:SymbolIcon Margin="0,-20,8,15" Symbol="Pin" MouseDown="Border_MouseDown" MouseUp="SymbolIconPinBorderDrawShape_MouseUp" Foreground="{DynamicResource FloatBarForeground}" HorizontalAlignment="Right"/>-->
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1"
|
||||
CornerRadius="8,8,0,0" Background="#2563eb" Margin="-1,-1,-1,0"
|
||||
Padding="1,1,1,0">
|
||||
<ikw:SimpleStackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Canvas Height="24" Width="315" ClipToBounds="True">
|
||||
<TextBlock Text="{i18n:I18n Key=Board_Shape}" Canvas.Left="8" Foreground="White"
|
||||
Padding="0,5" FontSize="11" FontWeight="Bold"
|
||||
TextAlignment="Center" />
|
||||
<Image Margin="295,3.5,0,0"
|
||||
Source="/Resources/new-icons/close-white.png"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16"
|
||||
Width="16" MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Canvas>
|
||||
</ikw:SimpleStackPanel>
|
||||
CornerRadius="6,6,0,0" Background="#2563eb" Margin="-1,-1,-1,0">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{i18n:I18n Key=Board_Shape}" Foreground="White"
|
||||
VerticalAlignment="Center" Grid.Column="0"
|
||||
FontSize="11" FontWeight="Bold" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.ChromeCloseContrast}"
|
||||
Foreground="White" FontSize="12"
|
||||
VerticalAlignment="Center" Grid.Column="1"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<ikw:SimpleStackPanel Orientation="Horizontal" Height="38" Spacing="2"
|
||||
@@ -2856,17 +2850,20 @@
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1"
|
||||
CornerRadius="6,6,0,0"
|
||||
Background="#2563eb" Margin="-1,-1,-1,1">
|
||||
<Canvas Height="24" ClipToBounds="True">
|
||||
<TextBlock Text="{i18n:I18n Key=Board_EraserOptions}" Canvas.Left="8" Foreground="White"
|
||||
Padding="0,5"
|
||||
FontSize="11" FontWeight="Bold" TextAlignment="Center" />
|
||||
<Image Margin="100,4,0,0"
|
||||
Source="/Resources/new-icons/close-white.png"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Height="16"
|
||||
Width="16" MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Canvas>
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{i18n:I18n Key=Board_EraserOptions}" Foreground="White"
|
||||
VerticalAlignment="Center" Grid.Column="0"
|
||||
FontSize="11" FontWeight="Bold" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.ChromeCloseContrast}"
|
||||
Foreground="White" FontSize="12"
|
||||
VerticalAlignment="Center" Grid.Column="1"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ikw:SimpleStackPanel Orientation="Horizontal" Margin="0,8,0,0" Spacing="2"
|
||||
VerticalAlignment="Center"
|
||||
@@ -2982,57 +2979,59 @@
|
||||
</Border>
|
||||
</Grid>
|
||||
<ikw:SimpleStackPanel x:Name="StackPanelFloatingBarEnd"
|
||||
Orientation="{Binding ElementName=StackPanelFloatingBar, Path=Orientation}">
|
||||
Orientation="{Binding ElementName=StackPanelFloatingBar, Path=Orientation}">
|
||||
<Border x:Name="FloatingBarEndSeparator" Margin="2,0,2,0" BorderBrush="#71717a" BorderThickness="1,0,0,0" />
|
||||
<!-- WhiteboardFloatingBarBtn / ToolsFloatingBarBtn / Fold_Icon 由 ToolbarRegistry 注入(AfterAnchor=FloatingBarEndSeparator) -->
|
||||
<Grid Width="0">
|
||||
<Border ClipToBounds="True" Name="BorderTools" Margin="-103,-156,-16,37"
|
||||
CornerRadius="5" Background="{DynamicResource FloatBarBackground}" Opacity="1" BorderThickness="1"
|
||||
BorderBrush="#2563eb">
|
||||
<ikw:SimpleStackPanel Margin="-1,0,0,0">
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1" Background="#2563eb" Margin="-1,-1,-1,0"
|
||||
Padding="1,1,1,0">
|
||||
<Grid Margin="6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{i18n:I18n Key=Tools_MoreFeaturesTitle}"
|
||||
Foreground="White" FontWeight="Bold"/>
|
||||
<ui:FontIcon Grid.Column="1" Icon="{x:Static ui:SegoeFluentIcons.ChromeCloseContrast}"
|
||||
Foreground="White" FontSize="12"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<!---->
|
||||
<ikw:SimpleStackPanel Margin="10,3,10,2" Spacing="2">
|
||||
<ikw:SimpleStackPanel.Resources>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource AutoFitToolPopupLabel8}" />
|
||||
</ikw:SimpleStackPanel.Resources>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="TimerToolBtn" ButtonMouseUp="ImageCountdownTimer_MouseUp" Label="{i18n:I18n Key=Tools_Timer}" />
|
||||
<controls:ToolMenuButton x:Name="RandomDrawToolBtn" ButtonMouseUp="SymbolIconRand_MouseUp" Label="{i18n:I18n Key=Tools_RandomDraw}" />
|
||||
<controls:ToolMenuButton x:Name="SingleDrawToolBtn" ButtonMouseUp="SymbolIconRandOne_MouseUp" Label="{i18n:I18n Key=Tools_SingleDraw}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="SaveToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconSaveStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Save}" />
|
||||
<controls:ToolMenuButton x:Name="OpenToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconOpenStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Open}" />
|
||||
<controls:ToolMenuButton x:Name="ReplayToolBtn" ButtonMouseUp="GridInkReplayButton_MouseUp" Label="{i18n:I18n Key=Tools_Replay}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="ScreenshotToolBtn" ButtonMouseUp="SymbolIconScreenshot_MouseUp" Label="{i18n:I18n Key=Tools_Screenshot}" />
|
||||
<controls:ToolMenuButton x:Name="ManualToolBtn" ButtonMouseUp="OperatingGuideWindowIcon_MouseUp" Label="{i18n:I18n Key=Tools_Manual}" />
|
||||
<controls:ToolMenuButton x:Name="SettingsToolBtn" ButtonMouseUp="SymbolIconSettings_Click" Label="{i18n:I18n Key=Tools_Settings}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</Border>
|
||||
<Grid Width="0" d:Visibility="Visible">
|
||||
</Grid>
|
||||
</ikw:SimpleStackPanel>
|
||||
<Border Name="BorderTools"
|
||||
Visibility="Collapsed" d:Visibility="Visible"
|
||||
Margin="-103,-156,-16,37" CornerRadius="6"
|
||||
Background="{DynamicResource FloatBarBackground}"
|
||||
BorderBrush="#2563eb" >
|
||||
<ikw:SimpleStackPanel Margin="-1">
|
||||
<Border BorderBrush="#1e3a8a" BorderThickness="0,0,0,1" CornerRadius="8,8,0,0" Background="#2563eb">
|
||||
<Grid Margin="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{i18n:I18n Key=Tools_MoreFeaturesTitle}"
|
||||
Foreground="White" FontWeight="Bold"/>
|
||||
<ui:FontIcon Grid.Column="1" Icon="{x:Static ui:SegoeFluentIcons.ChromeCloseContrast}"
|
||||
Foreground="White" FontSize="12"
|
||||
MouseDown="Border_MouseDown"
|
||||
MouseUp="CloseBordertools_MouseUp" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<!---->
|
||||
<ikw:SimpleStackPanel Margin="10,3,10,2" Spacing="2">
|
||||
<ikw:SimpleStackPanel.Resources>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource AutoFitToolPopupLabel8}" />
|
||||
</ikw:SimpleStackPanel.Resources>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="TimerToolBtn" ButtonMouseUp="ImageCountdownTimer_MouseUp" Label="{i18n:I18n Key=Tools_Timer}" />
|
||||
<controls:ToolMenuButton x:Name="RandomDrawToolBtn" ButtonMouseUp="SymbolIconRand_MouseUp" Label="{i18n:I18n Key=Tools_RandomDraw}" />
|
||||
<controls:ToolMenuButton x:Name="SingleDrawToolBtn" ButtonMouseUp="SymbolIconRandOne_MouseUp" Label="{i18n:I18n Key=Tools_SingleDraw}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="SaveToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconSaveStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Save}" />
|
||||
<controls:ToolMenuButton x:Name="OpenToolBtn" ButtonMouseDown="Border_MouseDown" ButtonMouseUp="SymbolIconOpenStrokes_MouseUp" Label="{i18n:I18n Key=Tools_Open}" />
|
||||
<controls:ToolMenuButton x:Name="ReplayToolBtn" ButtonMouseUp="GridInkReplayButton_MouseUp" Label="{i18n:I18n Key=Tools_Replay}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Margin="0,0,0,0" Height="40"
|
||||
Orientation="Horizontal">
|
||||
<controls:ToolMenuButton x:Name="ScreenshotToolBtn" ButtonMouseUp="SymbolIconScreenshot_MouseUp" Label="{i18n:I18n Key=Tools_Screenshot}" />
|
||||
<controls:ToolMenuButton x:Name="ManualToolBtn" ButtonMouseUp="OperatingGuideWindowIcon_MouseUp" Label="{i18n:I18n Key=Tools_Manual}" />
|
||||
<controls:ToolMenuButton x:Name="SettingsToolBtn" ButtonMouseUp="SymbolIconSettings_Click" Label="{i18n:I18n Key=Tools_Settings}" />
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</ikw:SimpleStackPanel>
|
||||
</Border>
|
||||
</ikw:SimpleStackPanel>
|
||||
</Grid>
|
||||
|
||||
|
||||
@@ -100,6 +100,14 @@ namespace Ink_Canvas
|
||||
*/
|
||||
InitializeComponent();
|
||||
|
||||
BoardBorderToolsPopup.CustomPopupPlacementCallback =
|
||||
(popupSize, targetSize, offset) => new[]
|
||||
{
|
||||
new CustomPopupPlacement(
|
||||
new Point((targetSize.Width - popupSize.Width) / 2, -popupSize.Height - 5),
|
||||
PopupPrimaryAxis.Vertical)
|
||||
};
|
||||
|
||||
BlackboardLeftSide.Visibility = Visibility.Collapsed;
|
||||
BlackboardCenterSide.Visibility = Visibility.Collapsed;
|
||||
BlackboardRightSide.Visibility = Visibility.Collapsed;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
AnimationsHelper.HideWithSlideAndFade(EraserSizePanel);
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(PenPalette);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardPenPalette);
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderDrawShape);
|
||||
|
||||
@@ -295,7 +295,7 @@ namespace Ink_Canvas
|
||||
private void HideSubPanelsImmediately()
|
||||
{
|
||||
BorderTools.Visibility = Visibility.Collapsed;
|
||||
BoardBorderTools.Visibility = Visibility.Collapsed;
|
||||
BoardBorderToolsPopup.IsOpen = false;
|
||||
PenPalette.Visibility = Visibility.Collapsed;
|
||||
BoardPenPalette.Visibility = Visibility.Collapsed;
|
||||
BoardEraserSizePanel.Visibility = Visibility.Collapsed;
|
||||
@@ -377,7 +377,7 @@ namespace Ink_Canvas
|
||||
internal async void HideSubPanels(string mode = null, bool autoAlignCenter = false)
|
||||
{
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(PenPalette);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardPenPalette);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardEraserSizePanel);
|
||||
@@ -1100,7 +1100,7 @@ namespace Ink_Canvas
|
||||
LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
if (Settings.RandSettings?.UseNewStyleUI == true)
|
||||
@@ -1152,7 +1152,7 @@ namespace Ink_Canvas
|
||||
private void OperatingGuideWindowIcon_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
new OperatingGuideWindow().Show();
|
||||
@@ -1172,7 +1172,7 @@ namespace Ink_Canvas
|
||||
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
// 根据设置决定使用哪个点名窗口
|
||||
@@ -1307,7 +1307,7 @@ namespace Ink_Canvas
|
||||
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
// 检查是否启用了外部点名功能
|
||||
@@ -1386,7 +1386,7 @@ namespace Ink_Canvas
|
||||
//if (lastBorderMouseDownObject != sender) return;
|
||||
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel);
|
||||
|
||||
CollapseBorderDrawShape();
|
||||
@@ -1687,10 +1687,10 @@ namespace Ink_Canvas
|
||||
/// <param name="e">鼠标按钮事件参数</param>
|
||||
internal void SymbolIconTools_MouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (BorderTools.Visibility == Visibility.Visible || BoardBorderTools.Visibility == Visibility.Visible)
|
||||
if (BorderTools.Visibility == Visibility.Visible || BoardBorderToolsPopup.IsOpen)
|
||||
{
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1702,7 +1702,7 @@ namespace Ink_Canvas
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardBorderTools);
|
||||
AnimationsHelper.ShowPopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Ink_Canvas
|
||||
if (lastBorderMouseDownObject != sender || inkCanvas.Visibility != Visibility.Visible) return;
|
||||
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
|
||||
GridNotifications.Visibility = Visibility.Collapsed;
|
||||
|
||||
@@ -917,7 +917,7 @@ namespace Ink_Canvas
|
||||
{
|
||||
if (lastBorderMouseDownObject != sender) return;
|
||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||
AnimationsHelper.HidePopupWithSlideAndFade(BoardBorderToolsPopup);
|
||||
|
||||
var openFileDialog = new OpenFileDialog();
|
||||
openFileDialog.InitialDirectory = Settings.Automation.AutoSavedStrokesLocation;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using Ink_Canvas.Controls;
|
||||
using Ink_Canvas.Controls.Toolbar;
|
||||
using Ink_Canvas.Helpers;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Controls;
|
||||
|
||||
@@ -7,8 +9,6 @@ namespace Ink_Canvas
|
||||
{
|
||||
public partial class MainWindow
|
||||
{
|
||||
// 这批属性替代了 XAML 中原有的 x:Name 自动生成字段;外部代码继续按原名访问。
|
||||
// 由对应 Toolbar Item 的 AfterBuild 回填,Populate 发生在 Window_Loaded 早期。
|
||||
internal ToolbarImageButton SymbolIconDelete { get; private set; }
|
||||
internal ToolbarImageButton Eraser_Icon { get; private set; }
|
||||
internal ToolbarImageButton EraserByStrokes_Icon { get; private set; }
|
||||
@@ -35,22 +35,46 @@ namespace Ink_Canvas
|
||||
internal void AttachToolsBtn(ToolbarImageButton btn) => ToolsFloatingBarBtn = btn;
|
||||
internal void AttachFoldIcon(ToolbarImageButton btn) => Fold_Icon = btn;
|
||||
|
||||
/// <summary>
|
||||
/// 在 Window_Loaded 早期调用:按 Settings.Toolbar 配置把插件化按钮填充到对应容器。
|
||||
/// 必须在 LoadSettings 之前,因为 LoadSettings 会访问 Cursor_Icon/Pen_Icon/Eraser_Icon 等。
|
||||
/// </summary>
|
||||
internal void InitializeToolbarPlugins()
|
||||
{
|
||||
ToolbarHost = new ToolbarHost(this);
|
||||
var slots = new Dictionary<ToolbarSlot, Panel>
|
||||
LogHelper.WriteLogToFile("MW_Toolbar: InitializeToolbarPlugins 开始", LogHelper.LogType.Info);
|
||||
try
|
||||
{
|
||||
{ ToolbarSlot.FloatingBarMain, StackPanelFloatingBar },
|
||||
{ ToolbarSlot.FloatingBarCanvasControls, StackPanelCanvasControls },
|
||||
{ ToolbarSlot.FloatingBarEnd, StackPanelFloatingBarEnd },
|
||||
{ ToolbarSlot.BlackboardLeft, BlackboardLeftSide },
|
||||
{ ToolbarSlot.BlackboardRight, BlackboardRightSide }
|
||||
};
|
||||
ToolbarRegistry.Populate(ToolbarHost, slots, Settings?.Toolbar);
|
||||
ToolbarHost = new ToolbarHost(this);
|
||||
var slots = new Dictionary<ToolbarSlot, Panel>
|
||||
{
|
||||
{ ToolbarSlot.FloatingBarMain, StackPanelFloatingBar },
|
||||
{ ToolbarSlot.FloatingBarCanvasControls, StackPanelCanvasControls },
|
||||
{ ToolbarSlot.FloatingBarEnd, StackPanelFloatingBarEnd },
|
||||
{ ToolbarSlot.BlackboardLeft, BlackboardLeftSide },
|
||||
{ ToolbarSlot.BlackboardRight, BlackboardRightSide }
|
||||
};
|
||||
ToolbarRegistry.Populate(ToolbarHost, slots, Settings?.Toolbar);
|
||||
LogHelper.WriteLogToFile("MW_Toolbar: InitializeToolbarPlugins 完成", LogHelper.LogType.Info);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"MW_Toolbar: InitializeToolbarPlugins 异常: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RebuildToolbar()
|
||||
{
|
||||
LogHelper.WriteLogToFile("MW_Toolbar: RebuildToolbar 开始", LogHelper.LogType.Info);
|
||||
try
|
||||
{
|
||||
ToolbarRegistry.ClearInjected(StackPanelFloatingBar);
|
||||
ToolbarRegistry.ClearInjected(StackPanelCanvasControls);
|
||||
ToolbarRegistry.ClearInjected(StackPanelFloatingBarEnd);
|
||||
ToolbarRegistry.ClearInjected(BlackboardLeftSide);
|
||||
ToolbarRegistry.ClearInjected(BlackboardRightSide);
|
||||
InitializeToolbarPlugins();
|
||||
LogHelper.WriteLogToFile("MW_Toolbar: RebuildToolbar 完成", LogHelper.LogType.Info);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"MW_Toolbar: RebuildToolbar 异常: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<ui:Page x:Class="Ink_Canvas.Windows.SettingsViews.Pages.ToolbarPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Ink_Canvas.Windows.SettingsViews.Pages"
|
||||
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
|
||||
xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf"
|
||||
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||
mc:Ignorable="d"
|
||||
Title="工具栏">
|
||||
|
||||
<Page.Resources>
|
||||
<Style x:Key="ToolbarItemStyle" TargetType="ListBox">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="dd:DragDrop.IsDragSource" Value="True"/>
|
||||
<Setter Property="dd:DragDrop.IsDropTarget" Value="True"/>
|
||||
<Setter Property="dd:DragDrop.UseDefaultEffectDataTemplate" Value="False"/>
|
||||
<Setter Property="dd:DragDrop.SelectDroppedItems" Value="True"/>
|
||||
<Setter Property="dd:DragDrop.DropTargetAdornerBrush" Value="#2563eb"/>
|
||||
<Setter Property="dd:DragDrop.DropHandler" Value="{Binding}"/>
|
||||
<Setter Property="ScrollViewer.PanningMode" Value="VerticalOnly"/>
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
|
||||
<Setter Property="dd:DragDrop.EffectMoveAdornerTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<Border Background="#2563eb" CornerRadius="12" Padding="16,8"
|
||||
Opacity="0.9">
|
||||
<TextBlock Text="移动" Foreground="White"
|
||||
FontSize="13" FontWeight="Medium"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="ToolbarItemTemplate">
|
||||
<Grid Height="44" Margin="0,1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text=""
|
||||
FontFamily="Segoe MDL2 Assets" FontSize="14"
|
||||
VerticalAlignment="Center" Margin="0,0,10,0" Opacity="0.45"/>
|
||||
|
||||
<TextBlock Grid.Column="1" Text="{Binding DisplayName}"
|
||||
FontSize="14" VerticalAlignment="Center"/>
|
||||
|
||||
<CheckBox Grid.Column="2" IsChecked="{Binding IsVisible, Mode=TwoWay}"
|
||||
VerticalAlignment="Center" Margin="12,0,0,0"
|
||||
ToolTip="显示或隐藏此按钮"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</Page.Resources>
|
||||
|
||||
<ScrollViewer PanningMode="VerticalFirst">
|
||||
<StackPanel Margin="59,0,59,0" MaxWidth="1000">
|
||||
|
||||
<!-- 主工具栏 -->
|
||||
<TextBlock Text="主工具栏" FontSize="16" FontWeight="Bold" Margin="0,20,0,4"/>
|
||||
<TextBlock Text="拖动调整顺序,开关控制显示。隐藏的按钮不会出现在浮动工具栏中。"
|
||||
Opacity="0.65" FontSize="12" Margin="0,0,0,8"/>
|
||||
<ListBox Name="MainItemsList" Style="{StaticResource ToolbarItemStyle}"
|
||||
ItemTemplate="{StaticResource ToolbarItemTemplate}"
|
||||
ItemsSource="{Binding MainItems}" />
|
||||
|
||||
<!-- 画布控制 -->
|
||||
<TextBlock Text="画布控制" FontSize="16" FontWeight="Bold" Margin="0,24,0,4"/>
|
||||
<TextBlock Text="批注模式下可见的工具按钮排序。"
|
||||
Opacity="0.65" FontSize="12" Margin="0,0,0,8"/>
|
||||
<ListBox Name="CanvasItemsList" Style="{StaticResource ToolbarItemStyle}"
|
||||
ItemTemplate="{StaticResource ToolbarItemTemplate}"
|
||||
ItemsSource="{Binding CanvasItems}" />
|
||||
|
||||
<!-- 尾部按钮 -->
|
||||
<TextBlock Text="尾部按钮" FontSize="16" FontWeight="Bold" Margin="0,24,0,4"/>
|
||||
<TextBlock Text="白板、工具、折叠按钮排序。"
|
||||
Opacity="0.65" FontSize="12" Margin="0,0,0,8"/>
|
||||
<ListBox Name="EndItemsList" Style="{StaticResource ToolbarItemStyle}"
|
||||
ItemTemplate="{StaticResource ToolbarItemTemplate}"
|
||||
ItemsSource="{Binding EndItems}" />
|
||||
|
||||
<Button Content="恢复默认布局" Click="ButtonReset_Click"
|
||||
Padding="20,10" HorizontalAlignment="Left" Margin="0,16,0,0"/>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</ui:Page>
|
||||
@@ -0,0 +1,232 @@
|
||||
using GongSolutions.Wpf.DragDrop;
|
||||
using Ink_Canvas.Controls.Toolbar;
|
||||
using Ink_Canvas.Helpers;
|
||||
using Ink_Canvas.Windows.SettingsViews.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Page = iNKORE.UI.WPF.Modern.Controls.Page;
|
||||
|
||||
namespace Ink_Canvas.Windows.SettingsViews.Pages
|
||||
{
|
||||
public partial class ToolbarPage : Page, IDropTarget
|
||||
{
|
||||
public class ToolbarItemViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public string Id { get; }
|
||||
public string DisplayName { get; }
|
||||
|
||||
private int _order;
|
||||
public int Order { get => _order; set { _order = value; OnPropertyChanged(nameof(Order)); } }
|
||||
|
||||
private bool _isVisible = true;
|
||||
public bool IsVisible { get => _isVisible; set { _isVisible = value; OnPropertyChanged(nameof(IsVisible)); } }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
|
||||
public ToolbarItemViewModel(string id, string displayName, int order, bool isVisible)
|
||||
{
|
||||
Id = id; DisplayName = displayName; _order = order; _isVisible = isVisible;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly string LogTag = "ToolbarPage";
|
||||
private bool _isLoaded;
|
||||
|
||||
public ObservableCollection<ToolbarItemViewModel> MainItems { get; } = new();
|
||||
public ObservableCollection<ToolbarItemViewModel> CanvasItems { get; } = new();
|
||||
public ObservableCollection<ToolbarItemViewModel> EndItems { get; } = new();
|
||||
|
||||
public ToolbarPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
Loaded += OnPageLoaded;
|
||||
}
|
||||
|
||||
private void OnPageLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try { LoadSettings(); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"{LogTag}: LoadSettings 异常: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", LogHelper.LogType.Error);
|
||||
}
|
||||
_isLoaded = true;
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
LogHelper.WriteLogToFile($"{LogTag}: LoadSettings 开始", LogHelper.LogType.Info);
|
||||
MainItems.Clear(); CanvasItems.Clear(); EndItems.Clear();
|
||||
|
||||
var layout = SettingsManager.Settings?.Toolbar ?? new ToolbarLayoutSettings();
|
||||
IReadOnlyList<IToolbarItem> discoveredItems;
|
||||
try { discoveredItems = ToolbarRegistry.Discover(); }
|
||||
catch (Exception ex) { LogHelper.WriteLogToFile($"{LogTag}: Discover 失败: {ex.Message}", LogHelper.LogType.Error); return; }
|
||||
|
||||
foreach (var item in discoveredItems)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!layout.Items.TryGetValue(item.Id, out var cfg))
|
||||
{
|
||||
cfg = new ToolbarItemConfig
|
||||
{
|
||||
Visible = item.DefaultVisible,
|
||||
Order = item.DefaultOrder,
|
||||
Slot = item.DefaultSlot,
|
||||
Position = item.DefaultPosition,
|
||||
AnchorName = item.DefaultAnchorName
|
||||
};
|
||||
}
|
||||
string displayName;
|
||||
try { displayName = item.DisplayName ?? item.Id; }
|
||||
catch { displayName = item.Id; }
|
||||
|
||||
var vm = new ToolbarItemViewModel(item.Id, displayName, cfg.Order, cfg.Visible);
|
||||
switch (cfg.Slot)
|
||||
{
|
||||
case ToolbarSlot.FloatingBarMain: MainItems.Add(vm); break;
|
||||
case ToolbarSlot.FloatingBarCanvasControls: CanvasItems.Add(vm); break;
|
||||
case ToolbarSlot.FloatingBarEnd: EndItems.Add(vm); break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"{LogTag}: 处理条目失败 [{item?.Id}]: {ex.Message}", LogHelper.LogType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
ReorderCollections();
|
||||
LogHelper.WriteLogToFile($"{LogTag}: LoadSettings 完成 Main={MainItems.Count} Canvas={CanvasItems.Count} End={EndItems.Count}", LogHelper.LogType.Info);
|
||||
}
|
||||
|
||||
private void ReorderCollections()
|
||||
{
|
||||
SortCollection(MainItems);
|
||||
SortCollection(CanvasItems);
|
||||
SortCollection(EndItems);
|
||||
}
|
||||
|
||||
private static void SortCollection(ObservableCollection<ToolbarItemViewModel> collection)
|
||||
{
|
||||
if (collection == null) return;
|
||||
var sorted = collection.OrderBy(x => x.Order).ToList();
|
||||
for (int i = 0; i < sorted.Count; i++)
|
||||
{
|
||||
var oldIndex = collection.IndexOf(sorted[i]);
|
||||
if (oldIndex != -1 && oldIndex != i)
|
||||
collection.Move(oldIndex, i);
|
||||
}
|
||||
}
|
||||
|
||||
public new void DragOver(IDropInfo dropInfo)
|
||||
{
|
||||
if (dropInfo.Data is not ToolbarItemViewModel) return;
|
||||
dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
|
||||
dropInfo.Effects = DragDropEffects.Move;
|
||||
}
|
||||
|
||||
public new void Drop(IDropInfo dropInfo)
|
||||
{
|
||||
if (dropInfo.Data is not ToolbarItemViewModel vm) return;
|
||||
if (dropInfo.TargetCollection is not ObservableCollection<ToolbarItemViewModel> target) return;
|
||||
|
||||
var oldIndex = target.IndexOf(vm);
|
||||
var newIndex = oldIndex < dropInfo.UnfilteredInsertIndex ? dropInfo.UnfilteredInsertIndex - 1 : dropInfo.UnfilteredInsertIndex;
|
||||
var finalIndex = Math.Min(newIndex >= target.Count ? target.Count - 1 : newIndex, target.Count);
|
||||
|
||||
if (!target.Contains(vm))
|
||||
{
|
||||
if (dropInfo.DragInfo.SourceCollection is ObservableCollection<ToolbarItemViewModel> source)
|
||||
source.Remove(vm);
|
||||
target.Insert(dropInfo.UnfilteredInsertIndex, vm);
|
||||
}
|
||||
else if (oldIndex != -1 && oldIndex != finalIndex)
|
||||
{
|
||||
target.Move(oldIndex, finalIndex);
|
||||
}
|
||||
|
||||
UpdateOrdersFromCollection(target);
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
private static void UpdateOrdersFromCollection(ObservableCollection<ToolbarItemViewModel> collection)
|
||||
{
|
||||
for (int i = 0; i < collection.Count; i++)
|
||||
collection[i].Order = (i + 1) * 10;
|
||||
}
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
if (!_isLoaded) return;
|
||||
try
|
||||
{
|
||||
var settings = SettingsManager.Settings;
|
||||
if (settings == null) return;
|
||||
if (settings.Toolbar == null) settings.Toolbar = new ToolbarLayoutSettings();
|
||||
var layout = settings.Toolbar;
|
||||
|
||||
foreach (var vm in MainItems.Concat(CanvasItems).Concat(EndItems))
|
||||
{
|
||||
if (!layout.Items.TryGetValue(vm.Id, out var cfg))
|
||||
{
|
||||
var item = ToolbarRegistry.Discover().FirstOrDefault(i => i.Id == vm.Id);
|
||||
cfg = new ToolbarItemConfig
|
||||
{
|
||||
Visible = item?.DefaultVisible ?? true,
|
||||
Order = item?.DefaultOrder ?? 0,
|
||||
Slot = item?.DefaultSlot ?? ToolbarSlot.FloatingBarMain,
|
||||
Position = item?.DefaultPosition ?? ToolbarInsertPosition.Prepend,
|
||||
AnchorName = item?.DefaultAnchorName
|
||||
};
|
||||
layout.Items[vm.Id] = cfg;
|
||||
}
|
||||
cfg.Visible = vm.IsVisible;
|
||||
cfg.Order = vm.Order;
|
||||
}
|
||||
|
||||
SettingsManager.SaveSettingsToFile();
|
||||
LogHelper.WriteLogToFile($"{LogTag}: 设置已保存", LogHelper.LogType.Info);
|
||||
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
|
||||
mainWindow?.RebuildToolbar();
|
||||
}
|
||||
catch (Exception ex) { LogHelper.WriteLogToFile($"{LogTag}: RebuildToolbar 异常: {ex.Message}", LogHelper.LogType.Error); }
|
||||
}));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"{LogTag}: SaveSettings 异常: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void ButtonReset_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
SettingsManager.Settings?.Toolbar?.Items.Clear();
|
||||
SettingsManager.SaveSettingsToFile();
|
||||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
try { Application.Current.Windows.OfType<MainWindow>().FirstOrDefault()?.RebuildToolbar(); }
|
||||
catch (Exception ex) { LogHelper.WriteLogToFile($"{LogTag}: Reset Rebuild 异常: {ex.Message}", LogHelper.LogType.Error); }
|
||||
}));
|
||||
LoadSettings();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.WriteLogToFile($"{LogTag}: ButtonReset 异常: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", LogHelper.LogType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +202,15 @@
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.KeyboardStandard}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem
|
||||
x:Name="ToolbarPageItem"
|
||||
Content="工具栏"
|
||||
Tag="ToolbarPage"
|
||||
ToolTipService.ToolTip="工具栏按钮排序与可见性">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Rename}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationViewItem.MenuItems>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
{ "WindowPage", typeof(WindowPage) },
|
||||
{ "AppearancePage", typeof(AppearancePage) },
|
||||
{ "HotkeyPage", typeof(HotkeyPage) },
|
||||
{ "ToolbarPage", typeof(ToolbarPage) },
|
||||
{ "UpdatePage", typeof(UpdatePage) },
|
||||
{ "ExperimentalPage", typeof(ExperimentalPage) },
|
||||
{ "AdvancedPage", typeof(AdvancedPage) },
|
||||
@@ -312,8 +313,10 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
|
||||
if (!_pages.TryGetValue(pageTag, out var cachedPage))
|
||||
{
|
||||
Ink_Canvas.Helpers.LogHelper.WriteLogToFile($"SettingsWindow: 创建页面实例 {pageTag} ({pageType.Name})", Ink_Canvas.Helpers.LogHelper.LogType.Info);
|
||||
cachedPage = Activator.CreateInstance(pageType);
|
||||
_pages.Add(pageTag, cachedPage);
|
||||
Ink_Canvas.Helpers.LogHelper.WriteLogToFile($"SettingsWindow: 页面实例 {pageTag} 创建成功", Ink_Canvas.Helpers.LogHelper.LogType.Info);
|
||||
}
|
||||
|
||||
if (cachedPage is PluginSettingsPage pluginSettingsPage && pluginInfo != null)
|
||||
@@ -325,6 +328,7 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Ink_Canvas.Helpers.LogHelper.WriteLogToFile($"SettingsWindow: 导航到 {pageTag} 异常: {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}", Ink_Canvas.Helpers.LogHelper.LogType.Error);
|
||||
MessageBox.Show($"导航到页面时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
finally
|
||||
|
||||
Reference in New Issue
Block a user