|
@@ -23,6 +23,7 @@ using PixiEditor.Models.Handlers;
|
|
|
using PixiEditor.Models.IO;
|
|
|
using PixiEditor.Models.Layers;
|
|
|
using Drawie.Numerics;
|
|
|
+using PixiEditor.ChangeableDocument.Changeables.Interfaces;
|
|
|
using PixiEditor.Helpers;
|
|
|
using PixiEditor.UI.Common.Fonts;
|
|
|
using PixiEditor.UI.Common.Localization;
|
|
@@ -249,6 +250,55 @@ internal class LayersViewModel : SubViewModel<ViewModelMain>
|
|
|
return member is IVectorLayerHandler;
|
|
|
}
|
|
|
|
|
|
+ [Evaluator.CanExecute("PixiEditor.Layer.AnySelectedMemberIsVectorLayer",
|
|
|
+ nameof(DocumentManagerViewModel.ActiveDocument), nameof(DocumentViewModel.SelectedStructureMember))]
|
|
|
+ public bool AnySelectedMemberIsVectorLayer(object property)
|
|
|
+ {
|
|
|
+ var members = Owner.DocumentManagerSubViewModel.ActiveDocument?.ExtractSelectedLayers();
|
|
|
+
|
|
|
+ if (members is null || members.Count == 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
|
|
|
+ if (doc is null)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ foreach (var member in members)
|
|
|
+ {
|
|
|
+ var handler = doc.StructureHelper.Find(member);
|
|
|
+ if (handler is IVectorLayerHandler)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ [Evaluator.CanExecute("PixiEditor.Layer.AnySelectedLayerIsRasterizable",
|
|
|
+ nameof(DocumentManagerViewModel.ActiveDocument), nameof(DocumentViewModel.SelectedStructureMember))]
|
|
|
+ public bool AnySelectedMemberIsRasterizable(object property)
|
|
|
+ {
|
|
|
+ var members = Owner.DocumentManagerSubViewModel.ActiveDocument?.ExtractSelectedLayers();
|
|
|
+
|
|
|
+ if (members is null || members.Count == 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
|
|
|
+ if (doc is null)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ foreach (var member in members)
|
|
|
+ {
|
|
|
+ var handler = doc.StructureHelper.Find(member);
|
|
|
+ if (handler is ILayerHandler && handler is not IRasterLayerHandler)
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
[Evaluator.CanExecute("PixiEditor.Layer.SelectedMemberIsSelectedText",
|
|
|
nameof(DocumentManagerViewModel.ActiveDocument), nameof(DocumentViewModel.SelectedStructureMember))]
|
|
@@ -563,56 +613,78 @@ internal class LayersViewModel : SubViewModel<ViewModelMain>
|
|
|
}
|
|
|
|
|
|
[Command.Basic("PixiEditor.Layer.Rasterize", "RASTERIZE_ACTIVE_LAYER", "RASTERIZE_ACTIVE_LAYER_DESCRIPTIVE",
|
|
|
- CanExecute = "PixiEditor.Layer.SelectedLayerIsRasterizable",
|
|
|
+ CanExecute = "PixiEditor.Layer.AnySelectedLayerIsRasterizable",
|
|
|
Icon = PixiPerfectIcons.LowResCircle, MenuItemPath = "LAYER/VECTOR/RASTERIZE_ACTIVE_LAYER",
|
|
|
AnalyticsTrack = true)]
|
|
|
public void RasterizeActiveLayer()
|
|
|
{
|
|
|
var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
|
|
|
- var member = doc?.SelectedStructureMember;
|
|
|
- if (member is null)
|
|
|
+ var selectedMembers = doc.ExtractSelectedLayers();
|
|
|
+ if (selectedMembers.Count == 0)
|
|
|
return;
|
|
|
|
|
|
- doc!.Operations.Rasterize(member.Id);
|
|
|
+ var block = doc.Operations.StartChangeBlock();
|
|
|
+
|
|
|
+ foreach (var member in selectedMembers)
|
|
|
+ {
|
|
|
+ doc!.Operations.Rasterize(member);
|
|
|
+ }
|
|
|
+
|
|
|
+ block.Dispose();
|
|
|
}
|
|
|
|
|
|
[Command.Basic("PixiEditor.Layer.ConvertToCurve", "CONVERT_TO_CURVE", "CONVERT_TO_CURVE_DESCRIPTIVE",
|
|
|
- CanExecute = "PixiEditor.Layer.SelectedMemberIsVectorLayer",
|
|
|
+ CanExecute = "PixiEditor.Layer.AnySelectedMemberIsVectorLayer",
|
|
|
MenuItemPath = "LAYER/VECTOR/CONVERT_TO_CURVE", AnalyticsTrack = true)]
|
|
|
- public void ConvertActiveLayerToCurve()
|
|
|
+ public void ConvertActiveLayersToCurve()
|
|
|
{
|
|
|
var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
|
|
|
- var member = doc?.SelectedStructureMember;
|
|
|
- if (member is null)
|
|
|
+ var selectedMembers = doc.ExtractSelectedLayers();
|
|
|
+ if (selectedMembers.Count == 0)
|
|
|
return;
|
|
|
|
|
|
- doc!.Operations.ConvertToCurve(member.Id);
|
|
|
+ var block = doc.Operations.StartChangeBlock();
|
|
|
+
|
|
|
+ foreach (var member in selectedMembers)
|
|
|
+ {
|
|
|
+ doc!.Operations.ConvertToCurve(member);
|
|
|
+ }
|
|
|
+
|
|
|
+ block.Dispose();
|
|
|
}
|
|
|
|
|
|
[Command.Basic("PixiEditor.Layer.SeparateShapes", "SEPARATE_SHAPES", "SEPARATE_SHAPES_DESCRIPTIVE",
|
|
|
- CanExecute = "PixiEditor.Layer.SelectedMemberIsVectorLayer",
|
|
|
+ CanExecute = "PixiEditor.Layer.AnySelectedMemberIsVectorLayer",
|
|
|
MenuItemPath = "LAYER/VECTOR/SEPARATE_SHAPES", AnalyticsTrack = true)]
|
|
|
public void SeparateShapes()
|
|
|
{
|
|
|
var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
|
|
|
- var member = doc?.SelectedStructureMember;
|
|
|
- if (member is null)
|
|
|
+ var selectedMembers = doc.ExtractSelectedLayers();
|
|
|
+ if (selectedMembers.Count == 0)
|
|
|
return;
|
|
|
|
|
|
- doc!.Operations.SeparateShapes(member.Id);
|
|
|
+ var block = doc.Operations.StartChangeBlock();
|
|
|
+
|
|
|
+ foreach (var member in selectedMembers)
|
|
|
+ {
|
|
|
+ doc!.Operations.SeparateShapes(member);
|
|
|
+ }
|
|
|
+
|
|
|
+ block.Dispose();
|
|
|
}
|
|
|
|
|
|
[Command.Basic("PixiEditor.Layer.ExtractSelectedText", "EXTRACT_SELECTED_TEXT", "EXTRACT_SELECTED_TEXT_DESCRIPTIVE",
|
|
|
CanExecute = "PixiEditor.Layer.SelectedMemberIsSelectedText",
|
|
|
Key = Key.X, Modifiers = KeyModifiers.Control | KeyModifiers.Shift,
|
|
|
Parameter = false,
|
|
|
- ShortcutContexts = [ typeof(ViewportWindowViewModel), typeof(TextOverlay)],
|
|
|
+ ShortcutContexts = [typeof(ViewportWindowViewModel), typeof(TextOverlay)],
|
|
|
MenuItemPath = "LAYER/TEXT/EXTRACT_SELECTED_TEXT", AnalyticsTrack = true)]
|
|
|
- [Command.Basic("PixiEditor.Layer.ExtractSelectedCharacters", "EXTRACT_SELECTED_CHARACTERS", "EXTRACT_SELECTED_CHARACTERS_DESCRIPTIVE",
|
|
|
+ [Command.Basic("PixiEditor.Layer.ExtractSelectedCharacters", "EXTRACT_SELECTED_CHARACTERS",
|
|
|
+ "EXTRACT_SELECTED_CHARACTERS_DESCRIPTIVE",
|
|
|
CanExecute = "PixiEditor.Layer.SelectedMemberIsSelectedText",
|
|
|
Key = Key.X, Modifiers = KeyModifiers.Control | KeyModifiers.Shift | KeyModifiers.Alt,
|
|
|
Parameter = true,
|
|
|
- ShortcutContexts = [ typeof(ViewportWindowViewModel), typeof(TextOverlay)],
|
|
|
+ ShortcutContexts = [typeof(ViewportWindowViewModel), typeof(TextOverlay)],
|
|
|
MenuItemPath = "LAYER/TEXT/EXTRACT_SELECTED_CHARACTERS", AnalyticsTrack = true)]
|
|
|
public void ExtractSelectedText(bool extractEachCharacter)
|
|
|
{
|