Merge pull request #5013 from larsbrubaker/master

Improving open library behavior
This commit is contained in:
Lars Brubaker 2021-03-22 08:22:30 -07:00 committed by GitHub
commit fbccc9b68b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 299 additions and 203 deletions

View file

@ -919,7 +919,7 @@ namespace MatterHackers.MatterControl
new EditContext() new EditContext()
{ {
ContentStore = historyContainer, ContentStore = historyContainer,
SourceItem = historyContainer.NewPlatingItem() SourceItem = historyContainer.NewPlatingItem(onlyPrinter.Bed.Scene)
}); });
UiThread.RunOnIdle(() => UiThread.RunOnIdle(() =>
@ -1488,7 +1488,7 @@ namespace MatterHackers.MatterControl
await workspace.SceneContext.LoadContent(new EditContext() await workspace.SceneContext.LoadContent(new EditContext()
{ {
ContentStore = history, ContentStore = history,
SourceItem = history.NewPlatingItem() SourceItem = history.NewPlatingItem(workspace.SceneContext.Scene)
}); });
if (workspace.Printer != null) if (workspace.Printer != null)
@ -1644,7 +1644,7 @@ namespace MatterHackers.MatterControl
new EditContext() new EditContext()
{ {
ContentStore = history, ContentStore = history,
SourceItem = history.NewPlatingItem() SourceItem = history.NewPlatingItem(workspace.SceneContext.Scene)
}); });
ApplicationController.Instance.MainTabKey = workspace.Name; ApplicationController.Instance.MainTabKey = workspace.Name;

View file

@ -195,7 +195,7 @@ namespace MatterHackers.MatterControl
new EditContext() new EditContext()
{ {
ContentStore = historyContainer, ContentStore = historyContainer,
SourceItem = historyContainer.NewPlatingItem() SourceItem = historyContainer.NewPlatingItem(this.Scene)
}); });
} }
@ -296,19 +296,6 @@ namespace MatterHackers.MatterControl
} }
} }
/// <summary>
/// Loads content to the bed and prepares edit/persistence context for use
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</placeholder></returns>
public async Task LoadPlateFromHistory()
{
await this.LoadContent(new EditContext()
{
ContentStore = historyContainer,
SourceItem = historyContainer.GetLastPlateOrNew()
});
}
public async Task StashAndPrintGCode(ILibraryItem libraryItem) public async Task StashAndPrintGCode(ILibraryItem libraryItem)
{ {
// Clear plate // Clear plate

View file

@ -52,7 +52,7 @@ namespace MatterHackers.MatterControl
/// </summary> /// </summary>
public IContentStore ContentStore { get; set; } public IContentStore ContentStore { get; set; }
public string SourceFilePath { get; private set; } public string SourceFilePath { get; set; }
public bool FreezeGCode { get; set; } public bool FreezeGCode { get; set; }

View file

@ -82,8 +82,6 @@ namespace MatterHackers.MatterControl
Task LoadLibraryContent(ILibraryItem libraryItem); Task LoadLibraryContent(ILibraryItem libraryItem);
Task LoadPlateFromHistory();
Task SaveChanges(IProgress<ProgressStatus> progress, CancellationToken cancellationToken); Task SaveChanges(IProgress<ProgressStatus> progress, CancellationToken cancellationToken);
// TODO: Isolate printer specifics from ISceneContext // TODO: Isolate printer specifics from ISceneContext

View file

@ -86,11 +86,6 @@ namespace MatterHackers.MatterControl.DesignTools
[DescriptionImage("https://lh3.googleusercontent.com/h-s2FyBKO5etYDr_9YSLtGmGmQTcmSGMu4p0mRqX4_7Z62Ndn2QRLoFICC6X9scbhr1EP29RiYRj4EmhLMUwiNTAG-PIiFbzI_jAses")] [DescriptionImage("https://lh3.googleusercontent.com/h-s2FyBKO5etYDr_9YSLtGmGmQTcmSGMu4p0mRqX4_7Z62Ndn2QRLoFICC6X9scbhr1EP29RiYRj4EmhLMUwiNTAG-PIiFbzI_jAses")]
public BendDirections BendDirection { get; set; } = BendDirections.Bend_Up; public BendDirections BendDirection { get; set; } = BendDirections.Bend_Up;
[Range(3, 360, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
[Description("Ensures the rotated part has a minimum number of sides per complete rotation")]
[DescriptionImage("https://lh3.googleusercontent.com/p9MyKu3AFP55PnobUKZQPqf6iAx11GzXyX-25f1ddrUnfCt8KFGd1YtHOR5HqfO0mhlX2ZVciZV4Yn0Kzfm43SErOS_xzgsESTu9scux")]
public double MinSidesPerRotation { get; set; } = 30;
[Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}.")] [Range(0, 100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
[Description("Where to start the bend as a percent from the left side")] [Description("Where to start the bend as a percent from the left side")]
[DescriptionImage("https://lh3.googleusercontent.com/eOeWjr98uz_E924PnNaXrasepv15nWEuvhqH-jbaQyvrOVdX5MHXF00HdZQGC8NLpJc9ok1sToMtyPx1wnnDgFwTTGA5MjoMFu612AY1")] [DescriptionImage("https://lh3.googleusercontent.com/eOeWjr98uz_E924PnNaXrasepv15nWEuvhqH-jbaQyvrOVdX5MHXF00HdZQGC8NLpJc9ok1sToMtyPx1wnnDgFwTTGA5MjoMFu612AY1")]
@ -100,6 +95,11 @@ namespace MatterHackers.MatterControl.DesignTools
[Description("Split the mesh so it has enough geometry to create a smooth curve")] [Description("Split the mesh so it has enough geometry to create a smooth curve")]
public bool SplitMesh { get; set; } = true; public bool SplitMesh { get; set; } = true;
[Range(3, 360, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
[Description("Ensures the rotated part has a minimum number of sides per complete rotation")]
[DescriptionImage("https://lh3.googleusercontent.com/p9MyKu3AFP55PnobUKZQPqf6iAx11GzXyX-25f1ddrUnfCt8KFGd1YtHOR5HqfO0mhlX2ZVciZV4Yn0Kzfm43SErOS_xzgsESTu9scux")]
public double MinSidesPerRotation { get; set; } = 30;
public void DrawEditor(Object3DControlsLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e) public void DrawEditor(Object3DControlsLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e)
{ {
var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox(); var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox();
@ -302,6 +302,7 @@ namespace MatterHackers.MatterControl.DesignTools
{ {
change.SetRowVisible(nameof(Diameter), () => BendType == BendTypes.Diameter); change.SetRowVisible(nameof(Diameter), () => BendType == BendTypes.Diameter);
change.SetRowVisible(nameof(Angle), () => BendType == BendTypes.Angle); change.SetRowVisible(nameof(Angle), () => BendType == BendTypes.Angle);
change.SetRowVisible(nameof(MinSidesPerRotation), () => SplitMesh);
} }
} }
} }

View file

@ -27,21 +27,9 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project. either expressed or implied, of the FreeBSD Project.
*/ */
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using CsvHelper;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI; using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets; using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.Library; using MatterHackers.MatterControl.Library;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PrintHistory namespace MatterHackers.MatterControl.PrintHistory
{ {

View file

@ -53,6 +53,11 @@ namespace MatterHackers.MatterControl.Library
Task<IObject3D> GetObject3D(Action<double, string> reportProgress); Task<IObject3D> GetObject3D(Action<double, string> reportProgress);
} }
public interface IAssetPath
{
string AssetPath { get; }
}
public interface ILibraryAssetStream : ILibraryAsset public interface ILibraryAssetStream : ILibraryAsset
{ {
/// <summary> /// <summary>

View file

@ -254,18 +254,18 @@ namespace MatterHackers.MatterControl.Library
public override void Remove(IEnumerable<ILibraryItem> items) public override void Remove(IEnumerable<ILibraryItem> items)
{ {
// Removing content from the filesystem can have devastating effects - open a shell window allowing the customer make changes as they seem fit
if (AggContext.OperatingSystem == OSType.Windows) if (AggContext.OperatingSystem == OSType.Windows)
{ {
if (items.Count() == 1 foreach (var item in items)
&& items.FirstOrDefault() is FileSystemFileItem fileItem)
{ {
Process.Start("explorer.exe", $"/select, \"{fileItem.Path}\""); if (item is FileSystemItem fileItem
} && File.Exists(fileItem.Path))
else {
{ File.Delete(fileItem.Path);
Process.Start(this.FullPath); }
} }
this.ReloadContent();
} }
} }
@ -354,7 +354,7 @@ namespace MatterHackers.MatterControl.Library
public class DirectoryContainerLink : FileSystemItem, ILibraryContainerLink public class DirectoryContainerLink : FileSystemItem, ILibraryContainerLink
{ {
public DirectoryContainerLink(string path) public DirectoryContainerLink(string path)
: base(path) : base(path, null)
{ {
} }

View file

@ -35,8 +35,8 @@ namespace MatterHackers.MatterControl.Library
{ {
public class FileSystemFileItem : FileSystemItem, ILibraryAssetStream public class FileSystemFileItem : FileSystemItem, ILibraryAssetStream
{ {
public FileSystemFileItem(string path) public FileSystemFileItem(string path, Func<FileSystemItem, string> getFirstSaveName = null)
: base(path) : base(path, getFirstSaveName)
{ {
var fileInfo = new FileInfo(path); var fileInfo = new FileInfo(path);
if (fileInfo.Exists) if (fileInfo.Exists)

View file

@ -27,9 +27,9 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project. either expressed or implied, of the FreeBSD Project.
*/ */
using MatterHackers.Agg;
using System; using System;
using System.IO; using System.IO;
using MatterHackers.Agg;
namespace MatterHackers.MatterControl.Library namespace MatterHackers.MatterControl.Library
{ {
@ -40,9 +40,12 @@ namespace MatterHackers.MatterControl.Library
{ {
private string fileName; private string fileName;
public FileSystemItem(string path) private Func<FileSystemItem, string> getFirstSaveName;
public FileSystemItem(string path, Func<FileSystemItem, string> getFirstSaveName = null)
{ {
this.Path = path; this.Path = path;
this.getFirstSaveName = getFirstSaveName;
var type = GetType(); var type = GetType();
@ -102,6 +105,25 @@ namespace MatterHackers.MatterControl.Library
} }
} }
public string Path { get; set; } private string _path;
public string Path
{
get
{
if (getFirstSaveName != null)
{
var newPath = getFirstSaveName(this);
if (!string.IsNullOrEmpty(newPath))
{
getFirstSaveName = null;
_path = newPath;
}
}
return _path;
}
set => _path = value;
}
} }
} }

View file

@ -62,10 +62,6 @@ namespace MatterHackers.MatterControl.Library
}; };
} }
public int PageSize { get; set; } = 25;
public event EventHandler<ItemChangedEventArgs> ItemContentChanged;
public override bool AllowAction(ContainerActions containerActions) public override bool AllowAction(ContainerActions containerActions)
{ {
switch(containerActions) switch(containerActions)
@ -82,44 +78,50 @@ namespace MatterHackers.MatterControl.Library
} }
} }
// PrintItems projected onto FileSystemFileItem internal ILibraryItem NewPlatingItem(InteractiveScene scene)
public override void Load()
{
// Select the 25 most recent files and project onto FileSystemItems
if (Directory.Exists(this.FullPath))
{
var recentFiles = new DirectoryInfo(this.FullPath).GetFiles("*.mcx").OrderByDescending(f => f.LastWriteTime);
Items = recentFiles.Where(f => f.Length > 215).Select(f => new FileSystemFileItem(f.FullName)).ToList<ILibraryItem>();
}
}
internal ILibraryItem NewPlatingItem()
{ {
string now = "Workspace " + DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss"); string now = "Workspace " + DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss");
string mcxPath = Path.Combine(this.FullPath, now + ".mcx"); string mcxPath = Path.Combine(this.FullPath, now + ".mcx");
File.WriteAllText(mcxPath, new Object3D().ToJson()); File.WriteAllText(mcxPath, new Object3D().ToJson());
return new FileSystemFileItem(mcxPath); return new FileSystemFileItem(mcxPath, (fileItem) =>
}
public ILibraryItem GetLastPlateOrNew()
{
// Find the last used bed plate mcx
var directoryInfo = new DirectoryInfo(ApplicationDataStorage.Instance.PlatingDirectory);
var firstFile = directoryInfo.GetFileSystemInfos("*.mcx").OrderByDescending(fl => fl.LastWriteTime).FirstOrDefault();
// Set as the current item - should be restored as the Active scene in the MeshViewer
if (firstFile != null)
{ {
return new FileSystemFileItem(firstFile.FullName); // Find the names of stuff in the scene
} if (scene.Children.Any())
{
// Otherwise generate a new plating item // Create a reasonable name
return this.NewPlatingItem(); var baseName = scene.Children.First().Name;
var newName = baseName;
// Make sure the name is unique on disk
var count = 1;
while (File.Exists(Path.Combine(this.FullPath, newName + ".mcx")))
{
newName = baseName + $" ({count++})";
}
// return the new name
var filename = Path.Combine(this.FullPath, newName + ".mcx");
if (File.Exists(filename))
{
File.Move(mcxPath, filename);
}
// change the path in the workspaces
// w.SceneContext.EditContext?.SourceFilePath
var workspace = ApplicationController.Instance.Workspaces.Where(w => w.SceneContext.EditContext?.SourceFilePath == mcxPath).FirstOrDefault();
if (workspace != null)
{
workspace.SceneContext.EditContext.SourceFilePath = filename;
}
fileItem.Name = newName;
fileItem.Path = filename;
return filename;
}
return null;
});
} }
public void SetThumbnail(ILibraryItem item, int width, int height, ImageBuffer imageBuffer) public override void SetThumbnail(ILibraryItem item, int width, int height, ImageBuffer imageBuffer)
{ {
} }
} }

View file

@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.InteropServices.WindowsRuntime;
@ -777,27 +778,54 @@ namespace MatterHackers.MatterControl.PrintLibrary
}); });
} }
// Open menu item menuActions.Add(new MenuSeparator("Open"));
// open menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem) menuActions.Add(new LibraryAction(ActionScope.ListItem)
{ {
Title = "Open".Localize(), Title = "Open".Localize(),
Icon = StaticData.Instance.LoadIcon("cube.png", 16, 16, theme.InvertIcons), Icon = StaticData.Instance.LoadIcon("cube.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) => Action = (selectedLibraryItems, listView) =>
{ {
if (listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink))) listView.SelectedItems.FirstOrDefault()?.OnDoubleClick();
{
ApplicationController.Instance.OpenIntoNewTab(selectedLibraryItems);
}
else
{
// open the folder
listView.SelectedItems.First().OnDoubleClick();
}
}, },
IsEnabled = (selectedListItems, listView) => IsEnabled = (selectedListItems, listView) =>
{ {
// Singleselect // Single select
return listView.SelectedItems.Count == 1; var only1 = listView.SelectedItems.Count == 1;
// mcx only - disallow containers and protected items
var isAsset = selectedListItems.FirstOrDefault()?.Model is ILibraryItem libraryItem
&& !(libraryItem is ILibraryContainer) // containers are also items
&& !libraryItem.IsProtected
// and we can only edit it if it is an mcx (can't edit stls)
&& libraryItem is ILibraryAsset asset && asset.ContentType == "mcx";
// Check if it is writeable
var writableContainer = !libraryContext.ActiveContainer.IsProtected
&& libraryContext.ActiveContainer is ILibraryWritableContainer;
var isFolder = listView.SelectedItems.FirstOrDefault()?.Model is DynamicContainerLink;
return only1 && ((isAsset && writableContainer) || isFolder);
}
});
// Open a copy menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem)
{
Title = "Open a copy".Localize(),
Icon = StaticData.Instance.LoadIcon("cube_add.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) =>
{
ApplicationController.Instance.OpenIntoNewTab(selectedLibraryItems);
},
IsEnabled = (selectedListItems, listView) =>
{
var isFolder = listView.SelectedItems.FirstOrDefault()?.Model is DynamicContainerLink;
return listView.SelectedItems.Count == 1
&& (listView.SelectedItems.FirstOrDefault().Container is ILibraryContainerLink
|| listView.SelectedItems.FirstOrDefault().Container is ILibraryContainer)
&& !isFolder;
} }
}); });
@ -830,61 +858,69 @@ namespace MatterHackers.MatterControl.PrintLibrary
} }
ApplicationController.Instance.BlinkTab( ApplicationController.Instance.BlinkTab(
ApplicationController.Instance.MainView.TabControl.AllTabs.FirstOrDefault(t => t.TabContent is PrinterTabPage)); ApplicationController.Instance.MainView.TabControl.AllTabs.FirstOrDefault(t => t.TabContent is PartTabPage));
}, },
IsEnabled = (selectedListItems, listView) => IsEnabled = (selectedListItems, listView) =>
{ {
var isFolder = listView.SelectedItems.FirstOrDefault()?.Model is DynamicContainerLink;
// Multiselect - disallow containers, require View3DWidget context // Multiselect - disallow containers, require View3DWidget context
return ApplicationController.Instance.DragDropData.View3DWidget != null return ApplicationController.Instance.DragDropData.View3DWidget != null
&& listView.SelectedItems.Any() && listView.SelectedItems.Any()
&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink)); && listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink))
&& !isFolder
&& ApplicationController.Instance.MainView.TabControl.AllTabs.Any(t => t.TabContent is PartTabPage);
} }
}); });
// edit menu item menuActions.Add(new MenuSeparator("Export"));
// export menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem) menuActions.Add(new LibraryAction(ActionScope.ListItem)
{ {
Title = "Edit".Localize(), Title = "Export".Localize(),
Action = async (selectedLibraryItems, listView) => Icon = StaticData.Instance.LoadIcon("cube_export.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) =>
{ {
if (selectedLibraryItems.FirstOrDefault() is ILibraryItem firstItem ApplicationController.Instance.ExportLibraryItems(libraryView.SelectedItems.Select(item => item.Model));
&& libraryContext.ActiveContainer is ILibraryWritableContainer writableContainer)
{
var workspace = new PartWorkspace(new BedConfig(ApplicationController.Instance.Library.PlatingHistory))
{
Name = firstItem.Name,
};
ApplicationController.Instance.Workspaces.Add(workspace);
var tab = mainViewWidget.CreatePartTab(workspace);
mainViewWidget.TabControl.ActiveTab = tab;
// Load content after UI widgets to support progress notification during acquire/load
await workspace.SceneContext.LoadContent(
new EditContext()
{
ContentStore = writableContainer,
SourceItem = firstItem
});
}
}, },
IsEnabled = (selectedListItems, listView) => IsEnabled = (selectedListItems, listView) =>
{ {
// Singleselect, WritableContainer, mcx only - disallow containers and protected items // Multiselect - disallow containers
return listView.SelectedItems.Any()
&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink));
},
});
// share menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem)
{
Title = "Share".Localize() + "...",
Icon = StaticData.Instance.LoadIcon("share.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) =>
{
// Previously - shareFromLibraryButton_Click
// TODO: Should be rewritten to Register from cloudlibrary, include logic to add to library as needed
ApplicationController.Instance.ShareLibraryItem(libraryView.SelectedItems.Select(i => i.Model).FirstOrDefault());
},
IsEnabled = (selectedListItems, listView) =>
{
// Singleselect - disallow containers and protected items
return listView.SelectedItems.Count == 1 return listView.SelectedItems.Count == 1
&& selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem && selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem
&& listView.ActiveContainer.GetType().Name.IndexOf("Cloud", StringComparison.OrdinalIgnoreCase) >= 0
&& !(firstItem is ILibraryContainer) && !(firstItem is ILibraryContainer)
&& !firstItem.IsProtected && !firstItem.IsProtected;
&& firstItem is ILibraryAsset asset && asset.ContentType == "mcx"
&& libraryContext.ActiveContainer is ILibraryWritableContainer;
} }
}); });
menuActions.Add(new MenuSeparator("Rename"));
// rename menu item // rename menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem) menuActions.Add(new LibraryAction(ActionScope.ListItem)
{ {
Title = "Rename".Localize(), Title = "Rename".Localize(),
Icon = StaticData.Instance.LoadIcon("icon_edit.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) => Action = (selectedLibraryItems, listView) =>
{ {
if (libraryView.SelectedItems.Count == 1) if (libraryView.SelectedItems.Count == 1)
@ -961,10 +997,51 @@ namespace MatterHackers.MatterControl.PrintLibrary
} }
}); });
// show on disk menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem)
{
Title = "Show in Explorer".Localize(),
// Icon = StaticData.Instance.LoadIcon("remove.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) =>
{
if (AggContext.OperatingSystem == OSType.Windows)
{
if (AggContext.OperatingSystem == OSType.Windows
&& listView.SelectedItems.Count() == 1)
{
if (listView.SelectedItems.FirstOrDefault().Model is FileSystemFileItem fileItem)
{
Process.Start("explorer.exe", $"/select, \"{fileItem.Path}\"");
}
else if (listView.SelectedItems.FirstOrDefault().Model is FileSystemContainer.DirectoryContainerLink container)
{
Process.Start("explorer.exe", $"/select, \"{container.Path}\"");
}
else if (listView.SelectedItems.FirstOrDefault().Model is LocalZipContainerLink zipContainer)
{
Process.Start("explorer.exe", $"/select, \"{zipContainer.Path}\"");
}
}
}
},
IsEnabled = (selectedListItems, listView) =>
{
if (AggContext.OperatingSystem == OSType.Windows
&& listView.SelectedItems.Count() == 1
&& listView.SelectedItems.FirstOrDefault().Model is FileSystemItem)
{
return true;
}
return false;
}
});
// remove menu item // remove menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem) menuActions.Add(new LibraryAction(ActionScope.ListItem)
{ {
Title = "Remove".Localize(), Title = "Remove".Localize(),
Icon = StaticData.Instance.LoadIcon("remove.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) => Action = (selectedLibraryItems, listView) =>
{ {
// Previously - deleteFromLibraryButton_Click // Previously - deleteFromLibraryButton_Click
@ -975,27 +1052,19 @@ namespace MatterHackers.MatterControl.PrintLibrary
{ {
if (libraryView.ActiveContainer is ILibraryWritableContainer container) if (libraryView.ActiveContainer is ILibraryWritableContainer container)
{ {
if (container is FileSystemContainer) StyledMessageBox.ShowMessageBox(
{ (doDelete) =>
container.Remove(libraryItems); {
libraryView.SelectedItems.Clear(); if (doDelete)
}
else
{
StyledMessageBox.ShowMessageBox(
(doDelete) =>
{ {
if (doDelete) container.Remove(libraryItems);
{ libraryView.SelectedItems.Clear();
container.Remove(libraryItems); }
libraryView.SelectedItems.Clear(); },
} "Are you sure you want to remove the currently selected items?".Localize(),
}, "Remove Items?".Localize(),
"Are you sure you want to remove the currently selected items?".Localize(), StyledMessageBox.MessageType.YES_NO,
"Remove Items?".Localize(), "Remove".Localize());
StyledMessageBox.MessageType.YES_NO,
"Remove".Localize());
}
} }
} }
}, },
@ -1008,47 +1077,6 @@ namespace MatterHackers.MatterControl.PrintLibrary
} }
}); });
menuActions.Add(new MenuSeparator("Export"));
// export menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem)
{
Title = "Export".Localize(),
Icon = StaticData.Instance.LoadIcon("cube_export.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) =>
{
ApplicationController.Instance.ExportLibraryItems(libraryView.SelectedItems.Select(item => item.Model));
},
IsEnabled = (selectedListItems, listView) =>
{
// Multiselect - disallow containers
return listView.SelectedItems.Any()
&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink));
},
});
// share menu item
menuActions.Add(new LibraryAction(ActionScope.ListItem)
{
Title = "Share".Localize() + "...",
Icon = StaticData.Instance.LoadIcon("share.png", 16, 16, theme.InvertIcons),
Action = (selectedLibraryItems, listView) =>
{
// Previously - shareFromLibraryButton_Click
// TODO: Should be rewritten to Register from cloudlibrary, include logic to add to library as needed
ApplicationController.Instance.ShareLibraryItem(libraryView.SelectedItems.Select(i => i.Model).FirstOrDefault());
},
IsEnabled = (selectedListItems, listView) =>
{
// Singleselect - disallow containers and protected items
return listView.SelectedItems.Count == 1
&& selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem
&& listView.ActiveContainer.GetType().Name.IndexOf("Cloud", StringComparison.OrdinalIgnoreCase) >= 0
&& !(firstItem is ILibraryContainer)
&& !firstItem.IsProtected;
}
});
// Extension point - RegisteredLibraryActions not defined in this file/assembly can insert here via this named token // Extension point - RegisteredLibraryActions not defined in this file/assembly can insert here via this named token
menuActions.AddRange(ApplicationController.Instance.RegisteredLibraryActions("StandardLibraryOperations")); menuActions.AddRange(ApplicationController.Instance.RegisteredLibraryActions("StandardLibraryOperations"));

View file

@ -30,6 +30,7 @@ either expressed or implied, of the FreeBSD Project.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using MatterHackers.Agg; using MatterHackers.Agg;
@ -475,7 +476,55 @@ namespace MatterHackers.MatterControl.CustomWidgets
{ {
if (this.DoubleClickAction == DoubleClickActions.PreviewItem) if (this.DoubleClickAction == DoubleClickActions.PreviewItem)
{ {
ApplicationController.Instance.OpenIntoNewTab(new[] { itemModel }); if (itemModel is ILibraryAsset asset && asset.ContentType == "mcx"
&& itemModel is ILibraryItem firstItem
&& this.ActiveContainer is ILibraryWritableContainer writableContainer)
{
var mainViewWidget = ApplicationController.Instance.MainView;
// check if it is already open
foreach (var openWorkspace in ApplicationController.Instance.Workspaces)
{
if (openWorkspace.SceneContext.EditContext.SourceFilePath == asset.AssetPath
|| (openWorkspace.SceneContext.EditContext.SourceItem is IAssetPath cloudItem
&& cloudItem.AssetPath == asset.AssetPath))
{
foreach (var tab in mainViewWidget.TabControl.AllTabs)
{
if (tab.TabContent is PartTabPage tabContent
&& (tabContent.sceneContext.EditContext.SourceFilePath == asset.AssetPath
|| (tabContent.sceneContext.EditContext.SourceItem is IAssetPath cloudItem2
&& cloudItem2.AssetPath == asset.AssetPath)))
{
mainViewWidget.TabControl.ActiveTab = tab;
return;
}
}
}
}
var workspace = new PartWorkspace(new BedConfig(ApplicationController.Instance.Library.PlatingHistory))
{
Name = firstItem.Name,
};
ApplicationController.Instance.Workspaces.Add(workspace);
var partTab = mainViewWidget.CreatePartTab(workspace);
mainViewWidget.TabControl.ActiveTab = partTab;
// Load content after UI widgets to support progress notification during acquire/load
await workspace.SceneContext.LoadContent(
new EditContext()
{
ContentStore = writableContainer,
SourceItem = firstItem
});
}
else
{
ApplicationController.Instance.OpenIntoNewTab(new[] { itemModel });
}
} }
else else
{ {

View file

@ -749,24 +749,38 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var menuTheme = ApplicationController.Instance.MenuTheme; var menuTheme = ApplicationController.Instance.MenuTheme;
var popupMenu = new PopupMenu(menuTheme); var popupMenu = new PopupMenu(menuTheme);
if (printer != null) var renameMenuItem = popupMenu.CreateMenuItem("Rename".Localize());
renameMenuItem.Click += (s, e) =>
{ {
var renameMenuItem = popupMenu.CreateMenuItem("Rename".Localize()); var currentName = "";
renameMenuItem.Click += (s, e) => if (printer != null)
{ {
DialogWindow.Show( printer.Settings.GetValue(SettingsKey.printer_name);
new InputBoxPage( }
"Rename Item".Localize(), else // design tab
"Name".Localize(), {
printer.Settings.GetValue(SettingsKey.printer_name), currentName = "Design";
"Enter New Name Here".Localize(), }
"Rename".Localize(),
(newName) => DialogWindow.Show(
new InputBoxPage(
"Rename Item".Localize(),
"Name".Localize(),
currentName,
"Enter New Name Here".Localize(),
"Rename".Localize(),
(newName) =>
{
if (printer != null)
{ {
printer.Settings.SetValue(SettingsKey.printer_name, newName); printer.Settings.SetValue(SettingsKey.printer_name, newName);
})); }
}; else
} {
// do something with design tab
}
}));
};
var moveButtons = new FlowLayoutWidget(); var moveButtons = new FlowLayoutWidget();
@ -828,7 +842,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
new EditContext() new EditContext()
{ {
ContentStore = ApplicationController.Instance.Library.PlatingHistory, ContentStore = ApplicationController.Instance.Library.PlatingHistory,
SourceItem = history.NewPlatingItem() SourceItem = history.NewPlatingItem(workspace.SceneContext.Scene)
}); });
ApplicationController.Instance.Workspaces.Add(workspace); ApplicationController.Instance.Workspaces.Add(workspace);

View file

@ -57,6 +57,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
private bool deferEditorTillMouseUp = false; private bool deferEditorTillMouseUp = false;
public float ZoomDelta { get; set; } = 0.2f;
public int EditButtonHeight { get; set; } = 44; public int EditButtonHeight { get; set; } = 44;
public Matrix4X4 TransformOnMouseDown { get; private set; } = Matrix4X4.Identity; public Matrix4X4 TransformOnMouseDown { get; private set; } = Matrix4X4.Identity;