Merge pull request #5013 from larsbrubaker/master
Improving open library behavior
This commit is contained in:
commit
fbccc9b68b
15 changed files with 299 additions and 203 deletions
|
|
@ -919,7 +919,7 @@ namespace MatterHackers.MatterControl
|
|||
new EditContext()
|
||||
{
|
||||
ContentStore = historyContainer,
|
||||
SourceItem = historyContainer.NewPlatingItem()
|
||||
SourceItem = historyContainer.NewPlatingItem(onlyPrinter.Bed.Scene)
|
||||
});
|
||||
|
||||
UiThread.RunOnIdle(() =>
|
||||
|
|
@ -1488,7 +1488,7 @@ namespace MatterHackers.MatterControl
|
|||
await workspace.SceneContext.LoadContent(new EditContext()
|
||||
{
|
||||
ContentStore = history,
|
||||
SourceItem = history.NewPlatingItem()
|
||||
SourceItem = history.NewPlatingItem(workspace.SceneContext.Scene)
|
||||
});
|
||||
|
||||
if (workspace.Printer != null)
|
||||
|
|
@ -1644,7 +1644,7 @@ namespace MatterHackers.MatterControl
|
|||
new EditContext()
|
||||
{
|
||||
ContentStore = history,
|
||||
SourceItem = history.NewPlatingItem()
|
||||
SourceItem = history.NewPlatingItem(workspace.SceneContext.Scene)
|
||||
});
|
||||
|
||||
ApplicationController.Instance.MainTabKey = workspace.Name;
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ namespace MatterHackers.MatterControl
|
|||
new EditContext()
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Clear plate
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace MatterHackers.MatterControl
|
|||
/// </summary>
|
||||
public IContentStore ContentStore { get; set; }
|
||||
|
||||
public string SourceFilePath { get; private set; }
|
||||
public string SourceFilePath { get; set; }
|
||||
|
||||
public bool FreezeGCode { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -82,8 +82,6 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
Task LoadLibraryContent(ILibraryItem libraryItem);
|
||||
|
||||
Task LoadPlateFromHistory();
|
||||
|
||||
Task SaveChanges(IProgress<ProgressStatus> progress, CancellationToken cancellationToken);
|
||||
|
||||
// TODO: Isolate printer specifics from ISceneContext
|
||||
|
|
|
|||
|
|
@ -86,11 +86,6 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
[DescriptionImage("https://lh3.googleusercontent.com/h-s2FyBKO5etYDr_9YSLtGmGmQTcmSGMu4p0mRqX4_7Z62Ndn2QRLoFICC6X9scbhr1EP29RiYRj4EmhLMUwiNTAG-PIiFbzI_jAses")]
|
||||
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}.")]
|
||||
[Description("Where to start the bend as a percent from the left side")]
|
||||
[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")]
|
||||
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)
|
||||
{
|
||||
var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox();
|
||||
|
|
@ -302,6 +302,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
{
|
||||
change.SetRowVisible(nameof(Diameter), () => BendType == BendTypes.Diameter);
|
||||
change.SetRowVisible(nameof(Angle), () => BendType == BendTypes.Angle);
|
||||
change.SetRowVisible(nameof(MinSidesPerRotation), () => SplitMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,21 +27,9 @@ of the authors and should not be interpreted as representing official policies,
|
|||
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.Localizations;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.MatterControl.DataStorage;
|
||||
using MatterHackers.MatterControl.Library;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl.PrintHistory
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ namespace MatterHackers.MatterControl.Library
|
|||
Task<IObject3D> GetObject3D(Action<double, string> reportProgress);
|
||||
}
|
||||
|
||||
public interface IAssetPath
|
||||
{
|
||||
string AssetPath { get; }
|
||||
}
|
||||
|
||||
public interface ILibraryAssetStream : ILibraryAsset
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -254,18 +254,18 @@ namespace MatterHackers.MatterControl.Library
|
|||
|
||||
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 (items.Count() == 1
|
||||
&& items.FirstOrDefault() is FileSystemFileItem fileItem)
|
||||
foreach (var item in items)
|
||||
{
|
||||
Process.Start("explorer.exe", $"/select, \"{fileItem.Path}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
Process.Start(this.FullPath);
|
||||
if (item is FileSystemItem fileItem
|
||||
&& File.Exists(fileItem.Path))
|
||||
{
|
||||
File.Delete(fileItem.Path);
|
||||
}
|
||||
}
|
||||
|
||||
this.ReloadContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -354,7 +354,7 @@ namespace MatterHackers.MatterControl.Library
|
|||
public class DirectoryContainerLink : FileSystemItem, ILibraryContainerLink
|
||||
{
|
||||
public DirectoryContainerLink(string path)
|
||||
: base(path)
|
||||
: base(path, null)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ namespace MatterHackers.MatterControl.Library
|
|||
{
|
||||
public class FileSystemFileItem : FileSystemItem, ILibraryAssetStream
|
||||
{
|
||||
public FileSystemFileItem(string path)
|
||||
: base(path)
|
||||
public FileSystemFileItem(string path, Func<FileSystemItem, string> getFirstSaveName = null)
|
||||
: base(path, getFirstSaveName)
|
||||
{
|
||||
var fileInfo = new FileInfo(path);
|
||||
if (fileInfo.Exists)
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using MatterHackers.Agg;
|
||||
using System;
|
||||
using System.IO;
|
||||
using MatterHackers.Agg;
|
||||
|
||||
namespace MatterHackers.MatterControl.Library
|
||||
{
|
||||
|
|
@ -40,9 +40,12 @@ namespace MatterHackers.MatterControl.Library
|
|||
{
|
||||
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.getFirstSaveName = getFirstSaveName;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
switch(containerActions)
|
||||
|
|
@ -82,44 +78,50 @@ namespace MatterHackers.MatterControl.Library
|
|||
}
|
||||
}
|
||||
|
||||
// PrintItems projected onto FileSystemFileItem
|
||||
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()
|
||||
internal ILibraryItem NewPlatingItem(InteractiveScene scene)
|
||||
{
|
||||
string now = "Workspace " + DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss");
|
||||
string mcxPath = Path.Combine(this.FullPath, now + ".mcx");
|
||||
|
||||
File.WriteAllText(mcxPath, new Object3D().ToJson());
|
||||
|
||||
return new FileSystemFileItem(mcxPath);
|
||||
}
|
||||
|
||||
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(mcxPath, (fileItem) =>
|
||||
{
|
||||
return new FileSystemFileItem(firstFile.FullName);
|
||||
}
|
||||
|
||||
// Otherwise generate a new plating item
|
||||
return this.NewPlatingItem();
|
||||
// Find the names of stuff in the scene
|
||||
if (scene.Children.Any())
|
||||
{
|
||||
// Create a reasonable name
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ either expressed or implied, of the FreeBSD Project.
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
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)
|
||||
{
|
||||
Title = "Open".Localize(),
|
||||
Icon = StaticData.Instance.LoadIcon("cube.png", 16, 16, theme.InvertIcons),
|
||||
Action = (selectedLibraryItems, listView) =>
|
||||
{
|
||||
if (listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink)))
|
||||
{
|
||||
ApplicationController.Instance.OpenIntoNewTab(selectedLibraryItems);
|
||||
}
|
||||
else
|
||||
{
|
||||
// open the folder
|
||||
listView.SelectedItems.First().OnDoubleClick();
|
||||
}
|
||||
listView.SelectedItems.FirstOrDefault()?.OnDoubleClick();
|
||||
},
|
||||
IsEnabled = (selectedListItems, listView) =>
|
||||
{
|
||||
// Singleselect
|
||||
return listView.SelectedItems.Count == 1;
|
||||
// Single select
|
||||
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.MainView.TabControl.AllTabs.FirstOrDefault(t => t.TabContent is PrinterTabPage));
|
||||
ApplicationController.Instance.MainView.TabControl.AllTabs.FirstOrDefault(t => t.TabContent is PartTabPage));
|
||||
},
|
||||
IsEnabled = (selectedListItems, listView) =>
|
||||
{
|
||||
var isFolder = listView.SelectedItems.FirstOrDefault()?.Model is DynamicContainerLink;
|
||||
|
||||
// Multiselect - disallow containers, require View3DWidget context
|
||||
return ApplicationController.Instance.DragDropData.View3DWidget != null
|
||||
&& 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)
|
||||
{
|
||||
Title = "Edit".Localize(),
|
||||
Action = async (selectedLibraryItems, listView) =>
|
||||
Title = "Export".Localize(),
|
||||
Icon = StaticData.Instance.LoadIcon("cube_export.png", 16, 16, theme.InvertIcons),
|
||||
Action = (selectedLibraryItems, listView) =>
|
||||
{
|
||||
if (selectedLibraryItems.FirstOrDefault() is ILibraryItem firstItem
|
||||
&& 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
|
||||
});
|
||||
}
|
||||
ApplicationController.Instance.ExportLibraryItems(libraryView.SelectedItems.Select(item => item.Model));
|
||||
},
|
||||
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
|
||||
&& selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem
|
||||
&& listView.ActiveContainer.GetType().Name.IndexOf("Cloud", StringComparison.OrdinalIgnoreCase) >= 0
|
||||
&& !(firstItem is ILibraryContainer)
|
||||
&& !firstItem.IsProtected
|
||||
&& firstItem is ILibraryAsset asset && asset.ContentType == "mcx"
|
||||
&& libraryContext.ActiveContainer is ILibraryWritableContainer;
|
||||
&& !firstItem.IsProtected;
|
||||
}
|
||||
});
|
||||
|
||||
menuActions.Add(new MenuSeparator("Rename"));
|
||||
|
||||
// rename menu item
|
||||
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
||||
{
|
||||
Title = "Rename".Localize(),
|
||||
Icon = StaticData.Instance.LoadIcon("icon_edit.png", 16, 16, theme.InvertIcons),
|
||||
Action = (selectedLibraryItems, listView) =>
|
||||
{
|
||||
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
|
||||
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
||||
{
|
||||
Title = "Remove".Localize(),
|
||||
Icon = StaticData.Instance.LoadIcon("remove.png", 16, 16, theme.InvertIcons),
|
||||
Action = (selectedLibraryItems, listView) =>
|
||||
{
|
||||
// Previously - deleteFromLibraryButton_Click
|
||||
|
|
@ -975,27 +1052,19 @@ namespace MatterHackers.MatterControl.PrintLibrary
|
|||
{
|
||||
if (libraryView.ActiveContainer is ILibraryWritableContainer container)
|
||||
{
|
||||
if (container is FileSystemContainer)
|
||||
{
|
||||
container.Remove(libraryItems);
|
||||
libraryView.SelectedItems.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
StyledMessageBox.ShowMessageBox(
|
||||
(doDelete) =>
|
||||
StyledMessageBox.ShowMessageBox(
|
||||
(doDelete) =>
|
||||
{
|
||||
if (doDelete)
|
||||
{
|
||||
if (doDelete)
|
||||
{
|
||||
container.Remove(libraryItems);
|
||||
libraryView.SelectedItems.Clear();
|
||||
}
|
||||
},
|
||||
"Are you sure you want to remove the currently selected items?".Localize(),
|
||||
"Remove Items?".Localize(),
|
||||
StyledMessageBox.MessageType.YES_NO,
|
||||
"Remove".Localize());
|
||||
}
|
||||
container.Remove(libraryItems);
|
||||
libraryView.SelectedItems.Clear();
|
||||
}
|
||||
},
|
||||
"Are you sure you want to remove the currently selected items?".Localize(),
|
||||
"Remove Items?".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
|
||||
menuActions.AddRange(ApplicationController.Instance.RegisteredLibraryActions("StandardLibraryOperations"));
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ either expressed or implied, of the FreeBSD Project.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MatterHackers.Agg;
|
||||
|
|
@ -475,7 +476,55 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -749,24 +749,38 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
var menuTheme = ApplicationController.Instance.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());
|
||||
renameMenuItem.Click += (s, e) =>
|
||||
var currentName = "";
|
||||
if (printer != null)
|
||||
{
|
||||
DialogWindow.Show(
|
||||
new InputBoxPage(
|
||||
"Rename Item".Localize(),
|
||||
"Name".Localize(),
|
||||
printer.Settings.GetValue(SettingsKey.printer_name),
|
||||
"Enter New Name Here".Localize(),
|
||||
"Rename".Localize(),
|
||||
(newName) =>
|
||||
printer.Settings.GetValue(SettingsKey.printer_name);
|
||||
}
|
||||
else // design tab
|
||||
{
|
||||
currentName = "Design";
|
||||
}
|
||||
|
||||
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);
|
||||
}));
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do something with design tab
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
var moveButtons = new FlowLayoutWidget();
|
||||
|
||||
|
|
@ -828,7 +842,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
new EditContext()
|
||||
{
|
||||
ContentStore = ApplicationController.Instance.Library.PlatingHistory,
|
||||
SourceItem = history.NewPlatingItem()
|
||||
SourceItem = history.NewPlatingItem(workspace.SceneContext.Scene)
|
||||
});
|
||||
|
||||
ApplicationController.Instance.Workspaces.Add(workspace);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
private bool deferEditorTillMouseUp = false;
|
||||
|
||||
public float ZoomDelta { get; set; } = 0.2f;
|
||||
|
||||
public int EditButtonHeight { get; set; } = 44;
|
||||
|
||||
public Matrix4X4 TransformOnMouseDown { get; private set; } = Matrix4X4.Identity;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue