Add DragDrop support for image content
This commit is contained in:
parent
022c91910c
commit
d647cf8a86
3 changed files with 136 additions and 29 deletions
|
|
@ -56,11 +56,44 @@ namespace MatterHackers.MatterControl
|
|||
using Agg.Image;
|
||||
using System.Net;
|
||||
using CustomWidgets;
|
||||
using MatterHackers.DataConverters3D;
|
||||
|
||||
public class OemProfileDictionary : Dictionary<string, Dictionary<string, PublicDevice>>
|
||||
{
|
||||
}
|
||||
|
||||
public class ContentResult
|
||||
{
|
||||
public IObject3D Object3D { get; set; }
|
||||
public Task MeshLoaded { get; set; }
|
||||
}
|
||||
|
||||
public interface IContentProvider
|
||||
{
|
||||
ContentResult CreateItem(string filePath);
|
||||
}
|
||||
|
||||
public class SimpleContentProvider : IContentProvider
|
||||
{
|
||||
public Func<string, ContentResult> Generator { get; set; }
|
||||
|
||||
public ContentResult CreateItem(string filePath)
|
||||
{
|
||||
return this.Generator(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtensionMethods
|
||||
{
|
||||
public static void Add(this Dictionary<string, IContentProvider> list, IEnumerable<string> extensions, IContentProvider provider)
|
||||
{
|
||||
foreach(var extension in extensions)
|
||||
{
|
||||
list.Add(extension, provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PublicDevice
|
||||
{
|
||||
public string DeviceToken { get; set; }
|
||||
|
|
@ -224,6 +257,8 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
public SlicePresetsWindow EditQualityPresetsWindow { get; set; }
|
||||
|
||||
public Dictionary<string, IContentProvider> SceneContentProviders = new Dictionary<string, IContentProvider>();
|
||||
|
||||
public ApplicationView MainView;
|
||||
|
||||
public event EventHandler ApplicationClosed;
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
public partial class View3DWidget : PartPreview3DWidget
|
||||
{
|
||||
private bool DoBooleanTest = false;
|
||||
private bool deferEditorTillMouseUp = false;
|
||||
|
||||
public FlowLayoutWidget doEdittingButtonsContainer;
|
||||
public UndoBuffer UndoBuffer { get; private set; } = new UndoBuffer();
|
||||
public readonly int EditButtonHeight = 44;
|
||||
|
|
@ -872,22 +874,27 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
if (AllowDragDrop())
|
||||
{
|
||||
foreach (string file in mouseEvent.DragFiles)
|
||||
{
|
||||
string extension = Path.GetExtension(file).ToLower();
|
||||
if (extension != "" && ApplicationSettings.OpenDesignFileParams.Contains(extension))
|
||||
{
|
||||
mouseEvent.AcceptDrop = true;
|
||||
}
|
||||
}
|
||||
mouseEvent.AcceptDrop = mouseEvent.DragFiles.TrueForAll(filePath => AllowFileDrop(filePath));
|
||||
|
||||
if (mouseEvent.AcceptDrop)
|
||||
{
|
||||
DragDropSource = new Object3D
|
||||
string filePath = mouseEvent.DragFiles.FirstOrDefault();
|
||||
string extensionWithoutPeriod = Path.GetExtension(filePath).Trim('.');
|
||||
|
||||
IContentProvider contentProvider;
|
||||
if (!string.IsNullOrEmpty(filePath)
|
||||
&& ApplicationController.Instance.SceneContentProviders.TryGetValue(extensionWithoutPeriod, out contentProvider))
|
||||
{
|
||||
ItemType = Object3DTypes.Model,
|
||||
Mesh = PlatonicSolids.CreateCube(10, 10, 10)
|
||||
};
|
||||
DragDropSource = contentProvider.CreateItem(filePath).Object3D;
|
||||
}
|
||||
else
|
||||
{
|
||||
DragDropSource = new Object3D
|
||||
{
|
||||
ItemType = Object3DTypes.Model,
|
||||
Mesh = PlatonicSolids.CreateCube(10, 10, 10)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -903,7 +910,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
/// Provides a View3DWidget specific drag implementation
|
||||
/// </summary>
|
||||
/// <param name="screenSpaceMousePosition">The screen space mouse position.</param>
|
||||
/// <returns>A value indicating in the DragDropSource was added to the scene</returns>
|
||||
/// <returns>A value indicating if a new item was generated for the DragDropSource and added to the scene</returns>
|
||||
public bool AltDragOver(Vector2 screenSpaceMousePosition)
|
||||
{
|
||||
if (this.HasBeenClosed)
|
||||
|
|
@ -942,6 +949,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
CurrentSelectInfo.PlaneDownHitPos = intersectInfo.hitPosition;
|
||||
CurrentSelectInfo.LastMoveDelta = Vector3.Zero;
|
||||
|
||||
this.deferEditorTillMouseUp = true;
|
||||
|
||||
// Add item to scene and select it
|
||||
Scene.ModifyChildren(children =>
|
||||
{
|
||||
|
|
@ -987,14 +996,19 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
IObject3D loadedItem = await Task.Run(() =>
|
||||
{
|
||||
return Object3D.Load(dragSource.MeshPath, progress: new DragDropLoadProgress(this, dragSource).UpdateLoadProgress);
|
||||
string extensionWithoutPeriod = Path.GetExtension(dragSource.MeshPath).Trim('.');
|
||||
if (ApplicationController.Instance.SceneContentProviders.ContainsKey(extensionWithoutPeriod))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Object3D.Load(dragSource.MeshPath, progress: new DragDropLoadProgress(this, dragSource).UpdateLoadProgress);
|
||||
}
|
||||
});
|
||||
|
||||
if (loadedItem != null)
|
||||
{
|
||||
// TODO: Changing an item in the scene has a risk of collection modified during enumeration errors. This approach works as
|
||||
// a proof of concept but needs to take the more difficult route of managing state and swapping the dragging instance with
|
||||
// the new loaded item data
|
||||
Vector3 meshGroupCenter = loadedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity).Center;
|
||||
dragSource.Mesh = loadedItem.Mesh;
|
||||
dragSource.Children.AddRange(loadedItem.Children);
|
||||
|
|
@ -1247,7 +1261,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
// the "loading" mesh with the actual file contents
|
||||
if (AltDragOver(screenSpaceMousePosition))
|
||||
{
|
||||
DragDropSource.MeshPath = mouseEvent.DragFiles.First();
|
||||
DragDropSource.MeshPath = mouseEvent.DragFiles.FirstOrDefault();
|
||||
|
||||
// Run the rest of the OnDragOver pipeline since we're starting a new thread and won't finish for an unknown time
|
||||
base.OnMouseMove(mouseEvent);
|
||||
|
|
@ -1291,10 +1305,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
else if (AllowDragDrop())
|
||||
{
|
||||
// Items need to be added to the scene
|
||||
var partsToAdd = (from droppedFileName in mouseEvent.DragFiles
|
||||
let extension = Path.GetExtension(droppedFileName).ToLower()
|
||||
where !string.IsNullOrEmpty(extension) && ApplicationSettings.OpenDesignFileParams.Contains(extension)
|
||||
select droppedFileName).ToArray();
|
||||
var partsToAdd = mouseEvent.DragFiles.Where(filePath => AllowFileDrop(filePath)).ToArray();
|
||||
|
||||
if (partsToAdd.Length > 0)
|
||||
{
|
||||
|
|
@ -1307,6 +1318,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
loadAndAddPartsToPlate(partsToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
if (deferEditorTillMouseUp)
|
||||
{
|
||||
this.deferEditorTillMouseUp = false;
|
||||
Scene_SelectionChanged(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
|
||||
|
|
@ -1520,6 +1537,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
flowToAddTo.AddChild(saveButtons);
|
||||
}
|
||||
|
||||
// Indicates if DragDrop operations should be allowed for the given file type
|
||||
private bool AllowFileDrop(string filePath)
|
||||
{
|
||||
string extension = Path.GetExtension(filePath).ToLower();
|
||||
string extensionWithoutPeriod = extension.Trim('.');
|
||||
|
||||
return !string.IsNullOrEmpty(extension)
|
||||
&& (ApplicationSettings.OpenDesignFileParams.Contains(extension) || ApplicationController.Instance.SceneContentProviders.Keys.Contains(extensionWithoutPeriod));
|
||||
}
|
||||
|
||||
// Indicates if MatterControl is in a mode that allows DragDrop
|
||||
private bool AllowDragDrop()
|
||||
{
|
||||
if ((!enterEditButtonsContainer.Visible
|
||||
|
|
@ -1753,6 +1781,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
return;
|
||||
}
|
||||
|
||||
if (deferEditorTillMouseUp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedItem = Scene.SelectedItem;
|
||||
|
||||
HashSet<IObject3DEditor> mappedEditors;
|
||||
|
|
@ -1952,13 +1985,24 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
foreach (string loadedFileName in filesToLoad)
|
||||
{
|
||||
IObject3D newItem = Object3D.Load(loadedFileName, itemCache, (double progress0To1, string processingState, out bool continueProcessing) =>
|
||||
IObject3D newItem;
|
||||
|
||||
string extension = Path.GetExtension(loadedFileName).ToLower();
|
||||
IContentProvider contentProvider;
|
||||
if (ApplicationController.Instance.SceneContentProviders.TryGetValue(extension.Trim('.'), out contentProvider))
|
||||
{
|
||||
continueProcessing = !this.HasBeenClosed;
|
||||
double ratioAvailable = (ratioPerFile * .5);
|
||||
double currentRatio = currentRatioDone + progress0To1 * ratioAvailable;
|
||||
ReportProgressChanged(currentRatio, progressMessage, out continueProcessing);
|
||||
});
|
||||
newItem = contentProvider.CreateItem(loadedFileName).Object3D;
|
||||
}
|
||||
else
|
||||
{
|
||||
newItem = Object3D.Load(loadedFileName, itemCache, (double progress0To1, string processingState, out bool continueProcessing) =>
|
||||
{
|
||||
continueProcessing = !this.HasBeenClosed;
|
||||
double ratioAvailable = (ratioPerFile * .5);
|
||||
double currentRatio = currentRatioDone + progress0To1 * ratioAvailable;
|
||||
ReportProgressChanged(currentRatio, progressMessage, out continueProcessing);
|
||||
});
|
||||
}
|
||||
|
||||
if (HasBeenClosed)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ using MatterHackers.Agg.VertexSource;
|
|||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using System.Threading.Tasks;
|
||||
using MatterHackers.MeshVisualizer;
|
||||
|
||||
namespace MatterHackers.MatterControl.PrintQueue
|
||||
{
|
||||
|
|
@ -426,15 +427,19 @@ namespace MatterHackers.MatterControl.PrintQueue
|
|||
ActionButtonLabel = "Add to Queue",
|
||||
Title = "MatterControl: Select A File"
|
||||
},
|
||||
(openParams) =>
|
||||
async (openParams) =>
|
||||
{
|
||||
if (openParams.FileNames != null)
|
||||
{
|
||||
int preAddCount = QueueData.Instance.ItemCount;
|
||||
|
||||
IContentProvider contentProvider;
|
||||
|
||||
foreach (string fileNameToLoad in openParams.FileNames)
|
||||
{
|
||||
string extension = Path.GetExtension(fileNameToLoad).ToUpper();
|
||||
string extensionWithoutPeriod = extension.ToLower().Trim('.');
|
||||
|
||||
if (extension == ".ZIP")
|
||||
{
|
||||
List<PrintItem> partFiles = ProjectFileHandler.ImportFromProjectArchive(fileNameToLoad);
|
||||
|
|
@ -446,6 +451,29 @@ namespace MatterHackers.MatterControl.PrintQueue
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (extension != "" && ApplicationController.Instance.SceneContentProviders.TryGetValue(extensionWithoutPeriod, out contentProvider))
|
||||
{
|
||||
// Generate the object
|
||||
var result = contentProvider.CreateItem(fileNameToLoad);
|
||||
|
||||
await result.MeshLoaded;
|
||||
|
||||
// Save to the library
|
||||
string fileName = Path.ChangeExtension(Path.GetRandomFileName(), ".mcx");
|
||||
string libraryPath = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, fileName);
|
||||
|
||||
var tempScene = new InteractiveScene();
|
||||
tempScene.Children.Add(result.Object3D);
|
||||
tempScene.Save(libraryPath, ApplicationDataStorage.Instance.ApplicationLibraryDataPath);
|
||||
|
||||
// Add the generated .mcx file to the queue
|
||||
QueueData.Instance.AddItem(
|
||||
new PrintItemWrapper(
|
||||
new PrintItem(
|
||||
Path.GetFileNameWithoutExtension(fileNameToLoad),
|
||||
libraryPath)));
|
||||
|
||||
}
|
||||
else if (extension != "" && ApplicationSettings.OpenDesignFileParams.Contains(extension.ToLower()))
|
||||
{
|
||||
// Only add files if they have an extension and if it's in the OpenDesignFileParams list
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue