Add per workspace library context

- Add WrappedLibraryContainer for per workspace containers
  (support for printer specific containers)
- Issue MatterHackers/MCCentral#4710
All printers and parts share the same library view
This commit is contained in:
John Lewin 2018-12-12 17:12:06 -08:00
parent aaa335f8c4
commit a22866abcf
12 changed files with 290 additions and 39 deletions

View file

@ -3178,7 +3178,7 @@ If you experience adhesion problems, please re-run leveling."
LoadMC();
}
};
void LoadMC()
{
ReportStartupProgress(0.02, "First draw->RunOnIdle");

View file

@ -27,6 +27,8 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using MatterHackers.MatterControl.Library;
using Newtonsoft.Json;
namespace MatterHackers.MatterControl
@ -39,6 +41,9 @@ namespace MatterHackers.MatterControl
{
}
[JsonIgnore]
public ILibraryContext LibraryView { get; set; }
public PartWorkspace(PrinterConfig printer)
: this (printer.Bed)
{
@ -48,6 +53,18 @@ namespace MatterHackers.MatterControl
public PartWorkspace(BedConfig bedConfig)
{
// Create a new library context for the SaveAs view
this.LibraryView = new LibraryConfig()
{
ActiveContainer = new WrappedLibraryContainer(ApplicationController.Instance.Library.RootLibaryContainer)
{
ExtraContainers = new List<ILibraryContainerLink>()
{
new FileSystemContainer.DirectoryContainerLink(@"c:\temp")
}
}
};
_sceneContext = bedConfig;
Name = _sceneContext.EditContext?.SourceItem?.Name ?? "Unknown";
}

View file

@ -0,0 +1,95 @@
/*
Copyright (c) 2018, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
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.Linq;
using System.Threading.Tasks;
using MatterHackers.Agg.Image;
using MatterHackers.MatterControl.Library;
namespace MatterHackers.MatterControl
{
public class WrappedLibraryContainer : ILibraryContainer
{
private ILibraryContainer _libraryContainer;
public WrappedLibraryContainer(ILibraryContainer libraryContainer)
{
_libraryContainer = libraryContainer;
}
public List<ILibraryContainerLink> ExtraContainers { get; set; } = new List<ILibraryContainerLink>();
public string ID => _libraryContainer.ID;
public string Name => _libraryContainer.Name;
public string StatusMessage => _libraryContainer.StatusMessage;
public bool IsProtected => _libraryContainer.IsProtected;
public Type DefaultView => _libraryContainer.DefaultView;
public List<ILibraryContainerLink> ChildContainers => this.ExtraContainers.Concat(_libraryContainer.ChildContainers).ToList();
public List<ILibraryItem> Items => _libraryContainer.Items;
public ILibraryContainer Parent { get => _libraryContainer.Parent; set => _libraryContainer.Parent = value; }
public string KeywordFilter { get => _libraryContainer.KeywordFilter; set => _libraryContainer.KeywordFilter = value; }
public event EventHandler ContentChanged;
public void Activate()
{
_libraryContainer.Activate();
}
public void Deactivate()
{
_libraryContainer.Deactivate();
}
public void Dispose()
{
_libraryContainer.Dispose();
}
public Task<ImageBuffer> GetThumbnail(ILibraryItem item, int width, int height)
{
return _libraryContainer.GetThumbnail(item, width, height);
}
public void Load()
{
_libraryContainer.Load();
}
}
}

View file

@ -54,16 +54,6 @@ namespace MatterHackers.MatterControl.Library
() => new SqliteLibraryContainer(rootLibraryCollection.Id)));
}
this.ChildContainers.Add(
new DynamicContainerLink(
() => "Calibration Parts".Localize(),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "folder_20x20.png")),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "folder.png")),
() => new CalibrationPartsContainer())
{
IsReadOnly = true
});
this.ChildContainers.Add(
new DynamicContainerLink(
() => "Primitives".Localize(),

View file

@ -0,0 +1,70 @@
/*
Copyright (c) 2018, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using System.IO;
using MatterHackers.Agg.Platform;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.SlicerConfiguration;
namespace MatterHackers.MatterControl.Library
{
public class OpenPrintersContainer : LibraryContainer
{
public OpenPrintersContainer()
{
this.ChildContainers = new List<ILibraryContainerLink>();
this.Items = new List<ILibraryItem>();
this.Name = "Printers".Localize();
}
public override void Load()
{
this.Items.Clear();
this.ChildContainers.Clear();
foreach(var printer in ApplicationController.Instance.ActivePrinters)
{
this.ChildContainers.Add(
new DynamicContainerLink(
() => printer.Settings.GetValue(SettingsKey.printer_name),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "sd_20x20.png")),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "sd_folder.png")),
() => new PrinterContainer(printer),
() =>
{
return printer.Settings.GetValue<bool>(SettingsKey.has_sd_card_reader);
})
{
IsReadOnly = true
});
}
}
}
}

View file

@ -0,0 +1,84 @@
/*
Copyright (c) 2018, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using System.IO;
using MatterHackers.Agg.Platform;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.SlicerConfiguration;
namespace MatterHackers.MatterControl.Library
{
// Printer specific containers
public class PrinterContainer : LibraryContainer
{
private PrinterConfig printer;
public PrinterContainer(PrinterConfig printer)
{
this.printer = printer;
this.ChildContainers = new List<ILibraryContainerLink>();
this.Items = new List<ILibraryItem>();
this.Name = "Printers".Localize();
}
public override void Load()
{
this.Items.Clear();
this.ChildContainers.Clear();
this.ChildContainers.Add(
new DynamicContainerLink(
() => "SD Card".Localize(),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "sd_20x20.png")),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "sd_folder.png")),
() => new SDCardContainer(printer),
() =>
{
return printer.Settings.GetValue<bool>(SettingsKey.has_sd_card_reader);
})
{
IsReadOnly = true
});
this.ChildContainers.Add(
new DynamicContainerLink(
() => "Calibration Parts".Localize(),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "folder_20x20.png")),
AggContext.StaticData.LoadIcon(Path.Combine("Library", "folder.png")),
() => new CalibrationPartsContainer())
{
IsReadOnly = true
});
// TODO: An enumerable list of serialized container paths (or some other markup) to construct for this printer
// printer.Settings.GetValue(SettingsKey.library_containers);
}
}
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2017, John Lewin
Copyright (c) 2018, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -32,7 +32,6 @@ using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
@ -45,8 +44,6 @@ namespace MatterHackers.MatterControl.Library
{
private bool gotBeginFileList;
private EventHandler unregisterEvents;
private PrinterConfig printer;
private AutoResetEvent autoResetEvent;
@ -56,7 +53,7 @@ namespace MatterHackers.MatterControl.Library
this.ChildContainers = new List<ILibraryContainerLink>();
this.Items = new List<ILibraryItem>();
this.Name = "SD Card".Localize();
this.printer = printer;
void CommunicationStateChanged(object s, EventArgs e)
{
switch (printer.Connection.CommunicationState)
@ -150,8 +147,6 @@ namespace MatterHackers.MatterControl.Library
public override void Dispose()
{
unregisterEvents?.Invoke(this, null);
// Ensure released
autoResetEvent?.Set();
}

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
private OverflowBar navBar;
private GuiWidget searchButton;
public PrintLibraryWidget(MainViewWidget mainViewWidget, ThemeConfig theme, PopupMenuButton popupMenuButton)
public PrintLibraryWidget(MainViewWidget mainViewWidget, PartWorkspace workspace, ThemeConfig theme, PopupMenuButton popupMenuButton)
{
this.theme = theme;
this.mainViewWidget = mainViewWidget;
@ -70,9 +70,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
var allControls = new FlowLayoutWidget(FlowDirection.TopToBottom);
var libaryContext = ApplicationController.Instance.Library;
libraryView = new LibraryListView(libaryContext, theme)
libraryView = new LibraryListView(workspace.LibraryView, workspace.Printer, theme)
{
Name = "LibraryView",
// Drop containers if ShowContainers != 1
@ -251,7 +249,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
return popupMenu;
};
breadCrumbWidget = new FolderBreadCrumbWidget(libaryContext, theme);
breadCrumbWidget = new FolderBreadCrumbWidget(workspace.LibraryView, theme);
navBar.AddChild(breadCrumbWidget);
var searchPanel = new SearchInputBox(theme)

View file

@ -383,7 +383,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// Create and switch to new printer tab
if (activePrinter?.Settings.PrinterSelected == true)
{
tabControl.ActiveTab = this.CreatePrinterTab(activePrinter, theme);
tabControl.ActiveTab = this.CreatePrinterTab(e.Workspace, theme);
}
else
{
@ -493,8 +493,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public ChromeTabs TabControl => tabControl;
private ChromeTab CreatePrinterTab(PrinterConfig printer, ThemeConfig theme)
private ChromeTab CreatePrinterTab(PartWorkspace workspace, ThemeConfig theme)
{
var printer = workspace.Printer;
// Printer page is in fixed position
var tab1 = tabControl.AllTabs.FirstOrDefault();
@ -514,7 +515,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
printer.Settings.GetValue(SettingsKey.printer_name),
printer.Settings.GetValue(SettingsKey.printer_name),
tabControl,
new PrinterTabPage(printer, theme, "unused_tab_title"),
new PrinterTabPage(workspace, theme, "unused_tab_title"),
theme,
tabImageUrl: ApplicationController.Instance.GetFavIconUrl(oemName: printer.Settings.GetValue(SettingsKey.make)))
{
@ -585,7 +586,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
workspace.Name,
workspace.Name,
tabControl,
new PartTabPage(null, workspace.SceneContext, theme, ""),
new PartTabPage(workspace, theme, ""),
theme,
AggContext.StaticData.LoadIcon("cube.png", 16, 16, theme.InvertIcons))
{

View file

@ -47,7 +47,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
internal View3DWidget view3DWidget;
internal BedConfig sceneContext;
internal PrinterConfig printer;
protected PartWorkspace workspace;
protected ViewControls3D viewControls3D;
protected ThemeConfig theme;
protected GuiWidget view3DContainer;
@ -55,14 +55,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
protected FlowLayoutWidget leftToRight;
protected LibraryListView favoritesBar;
public PartTabPage(PrinterConfig printer, BedConfig sceneContext, ThemeConfig theme, string tabTitle)
public PartTabPage(PartWorkspace workspace, ThemeConfig theme, string tabTitle)
: base (tabTitle)
{
this.sceneContext = sceneContext;
this.sceneContext = workspace.SceneContext;
this.theme = theme;
this.BackgroundColor = theme.BackgroundColor;
this.Padding = 0;
this.printer = printer;
this.printer = workspace.Printer;
this.workspace = workspace;
bool isPrinterType = this is PrinterTabPage;
@ -72,7 +73,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
VAnchor = VAnchor.Stretch
};
viewControls3D = new ViewControls3D(sceneContext, theme, sceneContext.Scene.UndoBuffer, isPrinterType, !(this is PrinterTabPage))
viewControls3D = new ViewControls3D(workspace, theme, sceneContext.Scene.UndoBuffer, isPrinterType, !(this is PrinterTabPage))
{
VAnchor = VAnchor.Top | VAnchor.Fit,
HAnchor = HAnchor.Left | HAnchor.Stretch,

View file

@ -54,8 +54,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private DockingTabControl sideBar;
private SliceSettingsWidget sliceSettingsWidget;
public PrinterTabPage(PrinterConfig printer, ThemeConfig theme, string tabTitle)
: base(printer, printer.Bed, theme, tabTitle)
public PrinterTabPage(PartWorkspace workspace, ThemeConfig theme, string tabTitle)
: base(workspace, theme, tabTitle)
{
gcodeOptions = sceneContext.RendererOptions;

View file

@ -43,7 +43,6 @@ using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.Library;
using MatterHackers.MatterControl.PrintLibrary;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow
@ -87,7 +86,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private View3DWidget view3DWidget;
private BedConfig sceneContext;
private PartWorkspace workspace;
private ViewControls3DButtons activeTransformState = ViewControls3DButtons.PartSelect;
private List<(GuiWidget button, SceneSelectionOperation operation)> operationButtons;
private MainViewWidget mainViewWidget = null;
@ -282,7 +281,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
}
public ViewControls3D(BedConfig sceneContext, ThemeConfig theme, UndoBuffer undoBuffer, bool isPrinterType, bool showPrintButton)
public ViewControls3D(PartWorkspace workspace, ThemeConfig theme, UndoBuffer undoBuffer, bool isPrinterType, bool showPrintButton)
: base(theme)
{
this.theme = theme;
@ -293,7 +292,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
this.IsPrinterMode = isPrinterType;
this.sceneContext = sceneContext;
this.sceneContext = workspace.SceneContext;
this.workspace = workspace;
string iconPath;
@ -604,7 +604,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var systemWindow = this.Parents<SystemWindow>().FirstOrDefault();
var printLibraryWidget = new PrintLibraryWidget(mainViewWidget, theme, libraryPopup)
var printLibraryWidget = new PrintLibraryWidget(mainViewWidget, workspace, theme, libraryPopup)
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Absolute,