2018-10-07 11:36:52 -07:00
|
|
|
|
/*
|
2019-04-10 07:10:18 -07:00
|
|
|
|
Copyright (c) 2019, John Lewin
|
2018-10-07 11:36:52 -07:00
|
|
|
|
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.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
using MatterHackers.Agg;
|
|
|
|
|
|
using MatterHackers.Agg.Platform;
|
|
|
|
|
|
using MatterHackers.Agg.UI;
|
|
|
|
|
|
using MatterHackers.Localizations;
|
|
|
|
|
|
using MatterHackers.MatterControl.CustomWidgets;
|
|
|
|
|
|
using MatterHackers.MatterControl.Library;
|
|
|
|
|
|
using MatterHackers.MatterControl.PartPreviewWindow;
|
|
|
|
|
|
using MatterHackers.MatterControl.PrinterCommunication;
|
|
|
|
|
|
using MatterHackers.MatterControl.PrintQueue;
|
|
|
|
|
|
using static MatterHackers.MatterControl.PrintLibrary.PrintLibraryWidget;
|
|
|
|
|
|
|
|
|
|
|
|
namespace MatterHackers.MatterControl.PrintLibrary
|
|
|
|
|
|
{
|
|
|
|
|
|
public class LibraryWidget : GuiWidget
|
|
|
|
|
|
{
|
|
|
|
|
|
private FlowLayoutWidget buttonPanel;
|
2018-12-12 18:13:22 -08:00
|
|
|
|
private ILibraryContext libraryContext;
|
2018-10-24 21:20:56 -07:00
|
|
|
|
private LibraryListView libraryView;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
private GuiWidget providerMessageContainer;
|
|
|
|
|
|
private TextWidget providerMessageWidget;
|
|
|
|
|
|
|
2018-10-24 21:10:39 -07:00
|
|
|
|
private List<LibraryAction> menuActions = new List<LibraryAction>();
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
private FolderBreadCrumbWidget breadCrumbWidget;
|
|
|
|
|
|
private GuiWidget searchInput;
|
|
|
|
|
|
private ILibraryContainer searchContainer;
|
|
|
|
|
|
|
2018-10-30 14:02:50 -07:00
|
|
|
|
private MainViewWidget mainViewWidget;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
private ThemeConfig theme;
|
|
|
|
|
|
private OverflowBar navBar;
|
|
|
|
|
|
private GuiWidget searchButton;
|
2018-11-15 12:13:27 -08:00
|
|
|
|
private TreeView libraryTreeView;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2020-07-22 08:05:39 -07:00
|
|
|
|
public bool ShowContainers { get; private set; }
|
|
|
|
|
|
|
2018-10-30 14:02:50 -07:00
|
|
|
|
public LibraryWidget(MainViewWidget mainViewWidget, ThemeConfig theme)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
this.theme = theme;
|
2018-10-30 14:02:50 -07:00
|
|
|
|
this.mainViewWidget = mainViewWidget;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
this.Padding = 0;
|
|
|
|
|
|
this.AnchorAll();
|
|
|
|
|
|
|
|
|
|
|
|
var allControls = new FlowLayoutWidget(FlowDirection.TopToBottom);
|
|
|
|
|
|
|
2018-12-12 18:13:22 -08:00
|
|
|
|
libraryContext = ApplicationController.Instance.LibraryTabContext;
|
2018-11-07 17:49:58 -08:00
|
|
|
|
|
|
|
|
|
|
libraryView = new LibraryListView(libraryContext, theme)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Name = "LibraryView",
|
|
|
|
|
|
// Drop containers if ShowContainers != 1
|
2018-11-03 09:50:09 -07:00
|
|
|
|
BackgroundColor = theme.BackgroundColor,
|
2018-11-02 22:02:05 -07:00
|
|
|
|
Border = new BorderDouble(top: 1),
|
|
|
|
|
|
DoubleClickAction = LibraryListView.DoubleClickActions.PreviewItem
|
2018-10-07 11:36:52 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
navBar = new OverflowBar(theme)
|
|
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Stretch,
|
|
|
|
|
|
VAnchor = VAnchor.Fit,
|
|
|
|
|
|
};
|
|
|
|
|
|
allControls.AddChild(navBar);
|
|
|
|
|
|
theme.ApplyBottomBorder(navBar);
|
|
|
|
|
|
|
2018-11-07 17:49:58 -08:00
|
|
|
|
breadCrumbWidget = new FolderBreadCrumbWidget(libraryContext, theme);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
navBar.AddChild(breadCrumbWidget);
|
|
|
|
|
|
|
2020-07-18 13:48:38 -07:00
|
|
|
|
var searchPanel = new TextEditWithInlineCancel(theme)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Visible = false,
|
|
|
|
|
|
Margin = new BorderDouble(10, 0, 5, 0),
|
|
|
|
|
|
};
|
2020-07-18 13:48:38 -07:00
|
|
|
|
searchPanel.TextEditWidget.ActualTextEditWidget.EnterPressed += (s, e) =>
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
this.PerformSearch();
|
|
|
|
|
|
};
|
|
|
|
|
|
searchPanel.ResetButton.Click += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
breadCrumbWidget.Visible = true;
|
|
|
|
|
|
searchPanel.Visible = false;
|
|
|
|
|
|
|
2020-07-18 13:48:38 -07:00
|
|
|
|
searchPanel.TextEditWidget.Text = "";
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
this.ClearSearch();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Store a reference to the input field
|
2020-07-18 13:48:38 -07:00
|
|
|
|
this.searchInput = searchPanel.TextEditWidget;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
navBar.AddChild(searchPanel);
|
|
|
|
|
|
|
|
|
|
|
|
searchButton = theme.CreateSearchButton();
|
|
|
|
|
|
searchButton.Enabled = false;
|
|
|
|
|
|
searchButton.Name = "Search Library Button";
|
|
|
|
|
|
searchButton.Click += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (searchPanel.Visible)
|
|
|
|
|
|
{
|
|
|
|
|
|
PerformSearch();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-12-12 18:13:22 -08:00
|
|
|
|
searchContainer = libraryContext.ActiveContainer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
breadCrumbWidget.Visible = false;
|
|
|
|
|
|
searchPanel.Visible = true;
|
|
|
|
|
|
searchInput.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
navBar.AddChild(searchButton);
|
|
|
|
|
|
|
|
|
|
|
|
PopupMenuButton viewOptionsButton;
|
|
|
|
|
|
|
|
|
|
|
|
navBar.AddChild(
|
|
|
|
|
|
viewOptionsButton = new PopupMenuButton(
|
|
|
|
|
|
new ImageWidget(AggContext.StaticData.LoadIcon("fa-sort_16.png", 32, 32, theme.InvertIcons))
|
|
|
|
|
|
{
|
|
|
|
|
|
//VAnchor = VAnchor.Center
|
|
|
|
|
|
},
|
|
|
|
|
|
theme)
|
|
|
|
|
|
{
|
|
|
|
|
|
AlignToRightEdge = true,
|
|
|
|
|
|
Name = "Print Library View Options"
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
viewOptionsButton.DynamicPopupContent = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme);
|
|
|
|
|
|
|
|
|
|
|
|
var siblingList = new List<GuiWidget>();
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"Date Created".Localize(),
|
2019-06-19 12:02:46 -07:00
|
|
|
|
() => libraryView.ActiveSort.HasFlag(SortKey.CreatedDate),
|
|
|
|
|
|
(v) => libraryView.ActiveSort = SortKey.CreatedDate,
|
2018-10-07 11:36:52 -07:00
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"Date Modified".Localize(),
|
2019-06-19 12:02:46 -07:00
|
|
|
|
() => libraryView.ActiveSort.HasFlag(SortKey.ModifiedDate),
|
|
|
|
|
|
(v) => libraryView.ActiveSort = SortKey.ModifiedDate,
|
2018-10-07 11:36:52 -07:00
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"Name".Localize(),
|
2019-06-19 12:02:46 -07:00
|
|
|
|
() => libraryView.ActiveSort.HasFlag(SortKey.Name),
|
|
|
|
|
|
(v) => libraryView.ActiveSort = SortKey.Name,
|
2018-10-07 11:36:52 -07:00
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
2018-10-24 21:13:10 -07:00
|
|
|
|
popupMenu.CreateSeparator();
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
siblingList = new List<GuiWidget>();
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"Ascending".Localize(),
|
|
|
|
|
|
() => libraryView.Ascending,
|
|
|
|
|
|
(v) => libraryView.Ascending = true,
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"Descending".Localize(),
|
|
|
|
|
|
() => !libraryView.Ascending,
|
|
|
|
|
|
(v) => libraryView.Ascending = false,
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
return popupMenu;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
PopupMenuButton viewMenuButton;
|
|
|
|
|
|
|
|
|
|
|
|
navBar.AddChild(
|
|
|
|
|
|
viewMenuButton = new PopupMenuButton(
|
|
|
|
|
|
new ImageWidget(AggContext.StaticData.LoadIcon("mi-view-list_10.png", 32, 32, theme.InvertIcons))
|
|
|
|
|
|
{
|
|
|
|
|
|
//VAnchor = VAnchor.Center
|
|
|
|
|
|
},
|
|
|
|
|
|
theme)
|
|
|
|
|
|
{
|
|
|
|
|
|
AlignToRightEdge = true
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
viewMenuButton.DynamicPopupContent = () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var popupMenu = new PopupMenu(ApplicationController.Instance.MenuTheme);
|
|
|
|
|
|
|
|
|
|
|
|
var listView = this.libraryView;
|
|
|
|
|
|
|
|
|
|
|
|
var siblingList = new List<GuiWidget>();
|
|
|
|
|
|
|
2020-07-22 08:05:39 -07:00
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"Show Folders".Localize(),
|
|
|
|
|
|
() => this.ShowContainers,
|
|
|
|
|
|
(isChecked) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
this.ShowContainers = isChecked;
|
|
|
|
|
|
listView.Reload().ConfigureAwait(false);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateSeparator();
|
|
|
|
|
|
|
2018-10-07 11:36:52 -07:00
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"View List".Localize(),
|
|
|
|
|
|
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.RowListView,
|
|
|
|
|
|
(isChecked) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.RowListView;
|
|
|
|
|
|
listView.ListContentView = new RowListView(theme);
|
|
|
|
|
|
listView.Reload().ConfigureAwait(false);
|
|
|
|
|
|
},
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"View XSmall Icons".Localize(),
|
|
|
|
|
|
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView18,
|
|
|
|
|
|
(isChecked) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView18;
|
|
|
|
|
|
listView.ListContentView = new IconListView(theme, 18);
|
|
|
|
|
|
listView.Reload().ConfigureAwait(false);
|
|
|
|
|
|
},
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"View Small Icons".Localize(),
|
|
|
|
|
|
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView70,
|
|
|
|
|
|
(isChecked) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView70;
|
|
|
|
|
|
listView.ListContentView = new IconListView(theme, 70);
|
|
|
|
|
|
listView.Reload().ConfigureAwait(false);
|
|
|
|
|
|
},
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"View Icons".Localize(),
|
|
|
|
|
|
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView,
|
|
|
|
|
|
(isChecked) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView;
|
|
|
|
|
|
listView.ListContentView = new IconListView(theme);
|
|
|
|
|
|
listView.Reload().ConfigureAwait(false);
|
|
|
|
|
|
},
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
popupMenu.CreateBoolMenuItem(
|
|
|
|
|
|
"View Large Icons".Localize(),
|
|
|
|
|
|
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView256,
|
|
|
|
|
|
(isChecked) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView256;
|
|
|
|
|
|
listView.ListContentView = new IconListView(theme, 256);
|
|
|
|
|
|
listView.Reload().ConfigureAwait(false);
|
|
|
|
|
|
},
|
|
|
|
|
|
useRadioStyle: true,
|
|
|
|
|
|
siblingRadioButtonList: siblingList);
|
|
|
|
|
|
|
|
|
|
|
|
return popupMenu;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var horizontalSplitter = new Splitter()
|
|
|
|
|
|
{
|
|
|
|
|
|
SplitterDistance = UserSettings.Instance.LibraryViewWidth,
|
|
|
|
|
|
SplitterSize = theme.SplitterWidth,
|
|
|
|
|
|
SplitterBackground = theme.SplitterBackground
|
|
|
|
|
|
};
|
|
|
|
|
|
horizontalSplitter.AnchorAll();
|
|
|
|
|
|
|
|
|
|
|
|
horizontalSplitter.DistanceChanged += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
UserSettings.Instance.LibraryViewWidth = horizontalSplitter.SplitterDistance;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
allControls.AddChild(horizontalSplitter);
|
|
|
|
|
|
|
2018-11-15 12:13:27 -08:00
|
|
|
|
libraryTreeView = new TreeView(theme)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-10-19 11:58:07 -07:00
|
|
|
|
HAnchor = HAnchor.Stretch,
|
2018-10-07 11:36:52 -07:00
|
|
|
|
VAnchor = VAnchor.Stretch,
|
|
|
|
|
|
Margin = 5
|
|
|
|
|
|
};
|
2018-11-15 12:13:27 -08:00
|
|
|
|
libraryTreeView.AfterSelect += async (s, e) =>
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-11-15 12:13:27 -08:00
|
|
|
|
if (libraryTreeView.SelectedNode is ContainerTreeNode treeNode)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
if (!treeNode.ContainerAcquired)
|
|
|
|
|
|
{
|
|
|
|
|
|
await this.EnsureExpanded(treeNode.Tag as ILibraryItem, treeNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (treeNode.ContainerAcquired)
|
|
|
|
|
|
{
|
2018-12-12 18:13:22 -08:00
|
|
|
|
libraryContext.ActiveContainer = treeNode.Container;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2018-11-15 12:13:27 -08:00
|
|
|
|
horizontalSplitter.Panel1.AddChild(libraryTreeView);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
var rootColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
|
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Fit,
|
|
|
|
|
|
VAnchor = VAnchor.Fit,
|
|
|
|
|
|
Margin = new BorderDouble(left: 10)
|
|
|
|
|
|
};
|
2018-11-15 12:13:27 -08:00
|
|
|
|
libraryTreeView.AddChild(rootColumn);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-11-07 17:49:58 -08:00
|
|
|
|
if (AppContext.IsLoading)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-11-07 17:49:58 -08:00
|
|
|
|
ApplicationController.StartupActions.Add(new ApplicationController.StartupAction()
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-11-07 17:49:58 -08:00
|
|
|
|
Title = "Initializing Library".Localize(),
|
|
|
|
|
|
Priority = 0,
|
|
|
|
|
|
Action = () =>
|
2018-11-01 09:36:58 -07:00
|
|
|
|
{
|
2018-11-07 17:49:58 -08:00
|
|
|
|
this.LoadRootLibraryNodes(rootColumn);
|
2018-11-01 09:36:58 -07:00
|
|
|
|
}
|
2018-11-07 17:49:58 -08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
this.LoadRootLibraryNodes(rootColumn);
|
|
|
|
|
|
}
|
2018-11-01 09:36:58 -07:00
|
|
|
|
|
2018-10-07 11:36:52 -07:00
|
|
|
|
horizontalSplitter.Panel2.AddChild(libraryView);
|
|
|
|
|
|
|
|
|
|
|
|
buttonPanel = new FlowLayoutWidget()
|
|
|
|
|
|
{
|
|
|
|
|
|
HAnchor = HAnchor.Stretch,
|
|
|
|
|
|
Padding = theme.ToolbarPadding,
|
|
|
|
|
|
};
|
|
|
|
|
|
AddLibraryButtonElements();
|
|
|
|
|
|
allControls.AddChild(buttonPanel);
|
|
|
|
|
|
|
|
|
|
|
|
allControls.AnchorAll();
|
|
|
|
|
|
|
|
|
|
|
|
this.AddChild(allControls);
|
2019-04-10 07:10:18 -07:00
|
|
|
|
|
|
|
|
|
|
// Register listeners
|
|
|
|
|
|
libraryView.SelectedItems.CollectionChanged += SelectedItems_CollectionChanged;
|
|
|
|
|
|
libraryContext.ContainerChanged += Library_ContainerChanged;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-07 17:49:58 -08:00
|
|
|
|
private void LoadRootLibraryNodes(FlowLayoutWidget rootColumn)
|
|
|
|
|
|
{
|
2018-12-12 18:13:22 -08:00
|
|
|
|
var rootLibraryContainer = this.GetRootContainer();
|
2018-11-07 17:49:58 -08:00
|
|
|
|
|
2018-12-12 18:13:22 -08:00
|
|
|
|
foreach (var libraryContainerLink in rootLibraryContainer.ChildContainers.OrderBy(t => t.Name))
|
2018-11-07 17:49:58 -08:00
|
|
|
|
{
|
2018-11-15 12:13:27 -08:00
|
|
|
|
if (libraryContainerLink.IsVisible)
|
|
|
|
|
|
{
|
|
|
|
|
|
var rootNode = this.CreateTreeNode(libraryContainerLink, rootLibraryContainer);
|
|
|
|
|
|
rootNode.TreeView = libraryTreeView;
|
2018-11-07 17:49:58 -08:00
|
|
|
|
|
2018-11-15 12:13:27 -08:00
|
|
|
|
rootColumn.AddChild(rootNode);
|
|
|
|
|
|
}
|
2018-11-07 17:49:58 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-12 18:13:22 -08:00
|
|
|
|
private ILibraryContainer GetRootContainer()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Walk up to the root node
|
|
|
|
|
|
var context = libraryContext.ActiveContainer;
|
|
|
|
|
|
while (context.Parent != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
context = context.Parent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return context;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-07 11:36:52 -07:00
|
|
|
|
private async Task GetExpansionItems(ILibraryItem containerItem, ContainerTreeNode treeNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (containerItem is ILibraryContainerLink containerLink)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// Container items
|
|
|
|
|
|
var container = await containerLink.GetContainer(null);
|
|
|
|
|
|
if (container != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Run(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
container.Load();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2018-11-07 17:52:08 -08:00
|
|
|
|
if (treeNode is ContainerTreeNode containerNode)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-11-07 17:52:08 -08:00
|
|
|
|
container.Parent = containerNode.ParentContainer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var childContainer in container.ChildContainers)
|
|
|
|
|
|
{
|
2018-11-07 17:52:08 -08:00
|
|
|
|
treeNode.Nodes.Add(CreateTreeNode(childContainer, container));
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
treeNode.Container = container;
|
|
|
|
|
|
|
|
|
|
|
|
treeNode.AlwaysExpandable = treeNode.Nodes.Count > 0;
|
|
|
|
|
|
treeNode.Expandable = treeNode.Nodes.Count > 0;
|
|
|
|
|
|
treeNode.Expanded = treeNode.Nodes.Count > 0;
|
|
|
|
|
|
|
|
|
|
|
|
treeNode.Invalidate();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-07 17:49:58 -08:00
|
|
|
|
private TreeNode CreateTreeNode(ILibraryItem containerItem, ILibraryContainer parentContainer)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-11-07 17:49:58 -08:00
|
|
|
|
var treeNode = new ContainerTreeNode(theme, parentContainer)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Text = containerItem.Name,
|
|
|
|
|
|
Tag = containerItem,
|
|
|
|
|
|
AlwaysExpandable = true
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
ApplicationController.Instance.Library.LoadItemThumbnail(
|
|
|
|
|
|
(icon) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
treeNode.Image = icon.SetPreMultiply();
|
|
|
|
|
|
},
|
|
|
|
|
|
null,
|
|
|
|
|
|
containerItem,
|
|
|
|
|
|
null,
|
|
|
|
|
|
16,
|
|
|
|
|
|
16,
|
|
|
|
|
|
theme).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
|
|
treeNode.ExpandedChanged += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
this.EnsureExpanded(containerItem, treeNode).ConfigureAwait(false);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return treeNode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task EnsureExpanded(ILibraryItem libraryItem, ContainerTreeNode treeNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!treeNode.ContainerAcquired)
|
|
|
|
|
|
{
|
|
|
|
|
|
await GetExpansionItems(libraryItem, treeNode).ConfigureAwait(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void PerformSearch()
|
|
|
|
|
|
{
|
|
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
2018-12-24 12:39:01 -08:00
|
|
|
|
if (libraryContext.ActiveContainer.CustomSearch is ICustomSearch customSearch)
|
2018-12-21 18:35:59 -08:00
|
|
|
|
{
|
|
|
|
|
|
// Do custom search
|
|
|
|
|
|
customSearch.ApplyFilter(searchInput.Text.Trim(), libraryContext);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Do basic filtering
|
|
|
|
|
|
// filter the view with a predicate, applying the active sort
|
|
|
|
|
|
libraryView.ApplyFilter(searchInput.Text.Trim());
|
|
|
|
|
|
}
|
2018-10-07 11:36:52 -07:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ClearSearch()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (searchContainer == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
2018-12-21 18:35:59 -08:00
|
|
|
|
if (libraryContext.ActiveContainer.CustomSearch is ICustomSearch customSearch)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Clear custom search
|
|
|
|
|
|
customSearch.ClearFilter();
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-12-21 18:35:59 -08:00
|
|
|
|
// Restore the original ActiveContainer before search started - some containers may change context
|
|
|
|
|
|
libraryContext.ActiveContainer = searchContainer;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Clear basic filtering
|
|
|
|
|
|
libraryView.ClearFilter();
|
|
|
|
|
|
}
|
2019-02-26 22:56:21 -08:00
|
|
|
|
|
2018-10-07 11:36:52 -07:00
|
|
|
|
searchContainer = null;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SelectedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in libraryView.Items)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.ViewWidget.IsSelected = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (e.OldItems != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in e.OldItems.OfType<ListViewItem>())
|
|
|
|
|
|
{
|
|
|
|
|
|
item.ViewWidget.IsSelected = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (e.NewItems != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in e.NewItems.OfType<ListViewItem>())
|
|
|
|
|
|
{
|
|
|
|
|
|
item.ViewWidget.IsSelected = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Library_ContainerChanged(object sender, ContainerChangedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Release
|
|
|
|
|
|
if (e.PreviousContainer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
e.PreviousContainer.ContentChanged -= UpdateStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var activeContainer = this.libraryView.ActiveContainer;
|
|
|
|
|
|
|
|
|
|
|
|
bool containerSupportsEdits = activeContainer is ILibraryWritableContainer;
|
|
|
|
|
|
|
2018-11-15 12:13:27 -08:00
|
|
|
|
var owningNode = libraryTreeView.SelectedNode?.Parents<ContainerTreeNode>().Where(p => p.Container == activeContainer).FirstOrDefault();
|
2018-10-07 11:36:52 -07:00
|
|
|
|
if (owningNode != null)
|
|
|
|
|
|
{
|
2018-11-15 12:13:27 -08:00
|
|
|
|
libraryTreeView.SelectedNode = owningNode;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-21 18:35:59 -08:00
|
|
|
|
//searchInput.Text = activeContainer.KeywordFilter;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
breadCrumbWidget.SetContainer(activeContainer);
|
|
|
|
|
|
|
|
|
|
|
|
activeContainer.ContentChanged += UpdateStatus;
|
|
|
|
|
|
|
|
|
|
|
|
searchButton.Enabled = activeContainer.Parent != null;
|
|
|
|
|
|
|
|
|
|
|
|
UpdateStatus(null, null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateStatus(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
string message = this.libraryView.ActiveContainer?.StatusMessage;
|
|
|
|
|
|
if (!string.IsNullOrEmpty(message))
|
|
|
|
|
|
{
|
|
|
|
|
|
providerMessageWidget.Text = message;
|
|
|
|
|
|
providerMessageContainer.Visible = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
providerMessageContainer.Visible = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void AddLibraryButtonElements()
|
|
|
|
|
|
{
|
|
|
|
|
|
buttonPanel.RemoveAllChildren();
|
|
|
|
|
|
|
|
|
|
|
|
// add in the message widget
|
|
|
|
|
|
providerMessageContainer = new GuiWidget()
|
|
|
|
|
|
{
|
|
|
|
|
|
VAnchor = VAnchor.Fit | VAnchor.Top,
|
|
|
|
|
|
HAnchor = HAnchor.Stretch,
|
|
|
|
|
|
Visible = false,
|
|
|
|
|
|
};
|
|
|
|
|
|
buttonPanel.AddChild(providerMessageContainer, -1);
|
|
|
|
|
|
|
|
|
|
|
|
providerMessageWidget = new TextWidget("")
|
|
|
|
|
|
{
|
|
|
|
|
|
PointSize = 8,
|
|
|
|
|
|
HAnchor = HAnchor.Right,
|
|
|
|
|
|
VAnchor = VAnchor.Bottom,
|
2018-10-13 17:58:54 -07:00
|
|
|
|
TextColor = theme.BorderColor,
|
2018-10-07 11:36:52 -07:00
|
|
|
|
Margin = new BorderDouble(6),
|
|
|
|
|
|
AutoExpandBoundsToText = true,
|
|
|
|
|
|
};
|
|
|
|
|
|
providerMessageContainer.AddChild(providerMessageWidget);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-12 18:13:22 -08:00
|
|
|
|
public static void CreateMenuActions(LibraryListView libraryView, List<LibraryAction> menuActions, ILibraryContext libraryContext, MainViewWidget mainViewWidget, ThemeConfig theme, bool allowPrint)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListView)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("cube.png", 16, 16, ApplicationController.Instance.MenuTheme.InvertIcons),
|
|
|
|
|
|
Title = "Add".Localize(),
|
|
|
|
|
|
ToolTipText = "Add an.stl, .obj, .amf, .gcode or.zip file to the Library".Localize(),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
AggContext.FileDialogs.OpenFileDialog(
|
|
|
|
|
|
new OpenFileDialogParams(ApplicationSettings.OpenPrintableFileParams, multiSelect: true),
|
|
|
|
|
|
(openParams) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (openParams.FileNames != null)
|
|
|
|
|
|
{
|
2018-10-14 12:06:51 -07:00
|
|
|
|
var writableContainer = libraryView.ActiveContainer as ILibraryWritableContainer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
if (writableContainer != null
|
|
|
|
|
|
&& openParams.FileNames.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
writableContainer.Add(openParams.FileNames.Select(f => new FileSystemFileItem(f)));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
2018-10-14 12:06:51 -07:00
|
|
|
|
IsEnabled = (s, l) => libraryView.ActiveContainer is ILibraryWritableContainer
|
2018-10-07 11:36:52 -07:00
|
|
|
|
});
|
|
|
|
|
|
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListView)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2020-07-24 14:03:45 -07:00
|
|
|
|
Title = "Create Folder...".Localize(),
|
2018-10-07 11:36:52 -07:00
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("fa-folder-new_16.png", 16, 16, ApplicationController.Instance.MenuTheme.InvertIcons),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
DialogWindow.Show(
|
|
|
|
|
|
new InputBoxPage(
|
|
|
|
|
|
"Create Folder".Localize(),
|
|
|
|
|
|
"Folder Name".Localize(),
|
|
|
|
|
|
"",
|
|
|
|
|
|
"Enter New Name Here".Localize(),
|
|
|
|
|
|
"Create".Localize(),
|
|
|
|
|
|
(newName) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!string.IsNullOrEmpty(newName)
|
2018-10-14 12:06:51 -07:00
|
|
|
|
&& libraryView.ActiveContainer is ILibraryWritableContainer writableContainer)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
writableContainer.Add(new[]
|
|
|
|
|
|
{
|
|
|
|
|
|
new CreateFolderItem() { Name = newName }
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}));
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (s, l) =>
|
|
|
|
|
|
{
|
2018-10-14 12:06:51 -07:00
|
|
|
|
return libraryView.ActiveContainer is ILibraryWritableContainer writableContainer
|
2018-10-07 11:36:52 -07:00
|
|
|
|
&& writableContainer?.AllowAction(ContainerActions.AddContainers) == true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2020-07-24 18:20:53 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListView)
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Enter Share Code...".Localize(),
|
|
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("enter-code.png", 16, 16, theme.InvertIcons),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Implementation already does RunOnIdle
|
|
|
|
|
|
ApplicationController.Instance.EnterShareCode?.Invoke();
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (s, l) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return l.ActiveContainer.CollectionKeyName == "sharedwithme";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2018-10-17 14:59:08 -07:00
|
|
|
|
if (allowPrint)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-10-17 14:59:08 -07:00
|
|
|
|
Title = "Print".Localize(),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
2018-10-17 17:22:24 -07:00
|
|
|
|
// TODO: Sort out the right way to have an ActivePrinter context that looks and behaves correctly
|
|
|
|
|
|
var activeContext = ApplicationController.Instance.DragDropData;
|
2018-11-12 07:43:28 -08:00
|
|
|
|
var printer = activeContext.View3DWidget.Printer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-10-17 14:59:08 -07:00
|
|
|
|
switch (selectedLibraryItems.FirstOrDefault())
|
|
|
|
|
|
{
|
|
|
|
|
|
case SDCardFileItem sdcardItem:
|
2019-01-17 17:03:25 -08:00
|
|
|
|
// TODO: Confirm SD printing?
|
|
|
|
|
|
// TODO: Need to rewrite library menu item validation can write one off validations like below so we don't end up here
|
|
|
|
|
|
// - ActiveSliceSettings.Instance.GetValue<bool>(SettingsKey.has_sd_card_reader)
|
|
|
|
|
|
printer.Connection.StartSdCardPrint(sdcardItem.Name.ToLower());
|
2018-10-17 14:59:08 -07:00
|
|
|
|
break;
|
|
|
|
|
|
case FileSystemFileItem fileItem when Path.GetExtension(fileItem.FileName).IndexOf(".gco", StringComparison.OrdinalIgnoreCase) == 0:
|
|
|
|
|
|
if (printer != null)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-10-17 14:59:08 -07:00
|
|
|
|
UiThread.RunOnIdle(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
await printer.Bed.StashAndPrintGCode(fileItem);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-10-17 14:59:08 -07:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2020-07-24 18:20:53 -07:00
|
|
|
|
// TODO: Otherwise add the selected items to the plate and print the plate?
|
2018-10-07 11:36:52 -07:00
|
|
|
|
if (printer != null)
|
|
|
|
|
|
{
|
2018-10-17 14:59:08 -07:00
|
|
|
|
UiThread.RunOnIdle(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
await printer.Bed.StashAndPrint(selectedLibraryItems);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
2018-11-12 07:43:28 -08:00
|
|
|
|
var communicationState = ApplicationController.Instance.DragDropData?.View3DWidget?.Printer?.Connection.CommunicationState;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-10-21 11:52:05 -07:00
|
|
|
|
// Singleselect - disallow containers
|
|
|
|
|
|
return listView.SelectedItems.Count == 1
|
|
|
|
|
|
&& selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem
|
|
|
|
|
|
&& !(firstItem is ILibraryContainer)
|
|
|
|
|
|
&& (communicationState == CommunicationStates.Connected
|
2020-07-24 18:20:53 -07:00
|
|
|
|
|| communicationState == CommunicationStates.FinishedPrint)
|
|
|
|
|
|
&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink));
|
2018-10-17 14:59:08 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-10-19 17:44:39 -07:00
|
|
|
|
// Open menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-19 17:44:39 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Open".Localize(),
|
|
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("cube.png", 16, 16, theme.InvertIcons),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
2020-07-24 18:20:53 -07:00
|
|
|
|
if (listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink)))
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.OpenIntoNewTab(selectedLibraryItems);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// open the folder
|
|
|
|
|
|
listView.SelectedItems.First().OnDoubleClick();
|
|
|
|
|
|
}
|
2018-10-19 17:44:39 -07:00
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
2020-07-24 18:20:53 -07:00
|
|
|
|
// Singleselect
|
|
|
|
|
|
return listView.SelectedItems.Count == 1;
|
2018-10-19 17:44:39 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2020-07-24 18:20:53 -07:00
|
|
|
|
// Share with me
|
|
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Enter Share Code...".Localize(),
|
|
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("enter-code.png", 16, 16, theme.InvertIcons),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
UiThread.RunOnIdle(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Implementation already does RunOnIdle
|
|
|
|
|
|
ApplicationController.Instance.EnterShareCode?.Invoke();
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (s, l) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return s.First()
|
|
|
|
|
|
.ViewWidget
|
|
|
|
|
|
.Descendants()
|
|
|
|
|
|
.Where(i => i.Name != null && i.Name.Contains("Shared with Me"))
|
|
|
|
|
|
.Any();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-10-07 11:36:52 -07:00
|
|
|
|
// edit menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-10-12 17:25:00 -07:00
|
|
|
|
Title = "Add to Bed".Localize(),
|
2018-10-14 12:52:18 -07:00
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("bed_add.png", 16, 16, theme.InvertIcons),
|
2018-10-07 11:36:52 -07:00
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var activeContext = ApplicationController.Instance.DragDropData;
|
2018-11-12 07:43:28 -08:00
|
|
|
|
var printer = activeContext.View3DWidget.Printer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
if (listView.SelectedItems.Count == 1 &&
|
|
|
|
|
|
selectedLibraryItems.FirstOrDefault() is ILibraryAssetStream assetStream
|
|
|
|
|
|
&& assetStream.ContentType == "gcode")
|
|
|
|
|
|
{
|
|
|
|
|
|
// Change loaded scene to new context
|
|
|
|
|
|
printer.Bed.LoadContent(
|
|
|
|
|
|
new EditContext()
|
|
|
|
|
|
{
|
|
|
|
|
|
SourceItem = assetStream,
|
|
|
|
|
|
// No content store for GCode
|
|
|
|
|
|
ContentStore = null
|
|
|
|
|
|
}).ConfigureAwait(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
activeContext.SceneContext.AddToPlate(selectedLibraryItems);
|
|
|
|
|
|
}
|
2018-10-21 11:52:05 -07:00
|
|
|
|
|
2018-10-22 14:15:29 -07:00
|
|
|
|
ApplicationController.Instance.BlinkTab(
|
2018-10-30 14:02:50 -07:00
|
|
|
|
ApplicationController.Instance.MainView.TabControl.AllTabs.FirstOrDefault(t => t.TabContent is PrinterTabPage));
|
2018-10-07 11:36:52 -07:00
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Multiselect - disallow containers, require View3DWidget context
|
|
|
|
|
|
return ApplicationController.Instance.DragDropData.View3DWidget != null
|
|
|
|
|
|
&& listView.SelectedItems.Any()
|
2018-10-24 07:59:49 -07:00
|
|
|
|
&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink));
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// edit menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Edit".Localize(),
|
|
|
|
|
|
Action = async (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (selectedLibraryItems.FirstOrDefault() is ILibraryItem firstItem
|
2018-12-12 18:13:22 -08:00
|
|
|
|
&& libraryContext.ActiveContainer is ILibraryWritableContainer writableContainer)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-12-07 18:41:32 -08:00
|
|
|
|
var workspace = new PartWorkspace(new BedConfig(ApplicationController.Instance.Library.PlatingHistory))
|
2018-10-15 20:08:15 -07:00
|
|
|
|
{
|
|
|
|
|
|
Name = firstItem.Name,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
ApplicationController.Instance.Workspaces.Add(workspace);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-11-01 15:37:16 -07:00
|
|
|
|
var tab = mainViewWidget.CreatePartTab(workspace);
|
|
|
|
|
|
mainViewWidget.TabControl.ActiveTab = tab;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
// Load content after UI widgets to support progress notification during acquire/load
|
2018-10-15 20:08:15 -07:00
|
|
|
|
await workspace.SceneContext.LoadContent(
|
2018-10-07 11:36:52 -07:00
|
|
|
|
new EditContext()
|
|
|
|
|
|
{
|
|
|
|
|
|
ContentStore = writableContainer,
|
|
|
|
|
|
SourceItem = firstItem
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Singleselect, WritableContainer, mcx only - disallow containers and protected items
|
|
|
|
|
|
return listView.SelectedItems.Count == 1
|
|
|
|
|
|
&& selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem
|
|
|
|
|
|
&& !(firstItem is ILibraryContainer)
|
|
|
|
|
|
&& !firstItem.IsProtected
|
|
|
|
|
|
&& firstItem is ILibraryAsset asset && asset.ContentType == "mcx"
|
2018-12-12 18:13:22 -08:00
|
|
|
|
&& libraryContext.ActiveContainer is ILibraryWritableContainer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// rename menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Rename".Localize(),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (libraryView.SelectedItems.Count == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
var selectedItem = libraryView.SelectedItems.FirstOrDefault();
|
|
|
|
|
|
if (selectedItem == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DialogWindow.Show(
|
|
|
|
|
|
new InputBoxPage(
|
|
|
|
|
|
"Rename Item".Localize(),
|
|
|
|
|
|
"Name".Localize(),
|
|
|
|
|
|
selectedItem.Model.Name,
|
|
|
|
|
|
"Enter New Name Here".Localize(),
|
|
|
|
|
|
"Rename".Localize(),
|
|
|
|
|
|
(newName) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var model = libraryView.SelectedItems.FirstOrDefault()?.Model;
|
|
|
|
|
|
if (model != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = libraryView.ActiveContainer as ILibraryWritableContainer;
|
|
|
|
|
|
if (container != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
container.Rename(model, newName);
|
|
|
|
|
|
libraryView.SelectedItems.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Singleselect, WritableContainer - disallow protected items
|
|
|
|
|
|
return listView.SelectedItems.Count == 1
|
|
|
|
|
|
&& selectedListItems.FirstOrDefault()?.Model is ILibraryItem firstItem
|
|
|
|
|
|
&& !firstItem.IsProtected
|
2018-12-12 18:13:22 -08:00
|
|
|
|
&& libraryContext.ActiveContainer is ILibraryWritableContainer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// move menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Move".Localize(),
|
|
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var partItems = selectedLibraryItems.Where(item => item is ILibraryAssetStream || item is ILibraryContainerLink);
|
|
|
|
|
|
if (partItems.Any()
|
|
|
|
|
|
&& libraryView.ActiveContainer is ILibraryWritableContainer sourceContainer)
|
|
|
|
|
|
{
|
|
|
|
|
|
DialogWindow.Show(new MoveItemPage((newName, destinationContainer) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
destinationContainer.Move(partItems, sourceContainer);
|
|
|
|
|
|
|
|
|
|
|
|
// Discover if item was moved to an already loaded and now stale view on an ancestor and force reload
|
2018-12-12 18:13:22 -08:00
|
|
|
|
var openParent = libraryContext.ActiveContainer.Ancestors().FirstOrDefault(c => c.ID == destinationContainer.ID);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
if (openParent != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO: Consider changing this brute force approach to instead mark as dirty and allow Activate base method to reload if dirty
|
|
|
|
|
|
Task.Run(() => openParent.Load());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
libraryView.SelectedItems.Clear();
|
|
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Multiselect, WritableContainer - disallow protected
|
|
|
|
|
|
return listView.SelectedItems.Any()
|
|
|
|
|
|
&& listView.SelectedItems.All(i => !i.Model.IsProtected
|
2018-12-12 18:13:22 -08:00
|
|
|
|
&& libraryContext.ActiveContainer is ILibraryWritableContainer);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// remove menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Remove".Localize(),
|
2018-10-14 12:06:51 -07:00
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
2018-11-29 13:41:24 -08:00
|
|
|
|
// Previously - deleteFromLibraryButton_Click
|
2018-10-14 12:06:51 -07:00
|
|
|
|
|
|
|
|
|
|
// ask before remove
|
|
|
|
|
|
var libraryItems = libraryView.SelectedItems.Select(p => p.Model);
|
|
|
|
|
|
if (libraryItems.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (libraryView.ActiveContainer is ILibraryWritableContainer container)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (container is FileSystemContainer)
|
|
|
|
|
|
{
|
|
|
|
|
|
container.Remove(libraryItems);
|
|
|
|
|
|
libraryView.SelectedItems.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
StyledMessageBox.ShowMessageBox(
|
|
|
|
|
|
(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());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2018-10-07 11:36:52 -07:00
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Multiselect, WritableContainer - disallow protected
|
|
|
|
|
|
return listView.SelectedItems.Any()
|
|
|
|
|
|
&& listView.SelectedItems.All(i => !i.Model.IsProtected
|
2018-12-12 18:13:22 -08:00
|
|
|
|
&& libraryContext.ActiveContainer is ILibraryWritableContainer);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
menuActions.Add(new MenuSeparator("Export"));
|
|
|
|
|
|
|
|
|
|
|
|
// export menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Export".Localize(),
|
2018-10-14 12:52:18 -07:00
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("cube_export.png", 16, 16, theme.InvertIcons),
|
2018-10-14 12:06:51 -07:00
|
|
|
|
Action = (selectedLibraryItems, listView) =>
|
|
|
|
|
|
{
|
2018-11-12 09:32:08 -08:00
|
|
|
|
ApplicationController.Instance.ExportLibraryItems(libraryView.SelectedItems.Select(item => item.Model));
|
2018-10-14 12:06:51 -07:00
|
|
|
|
},
|
2018-10-07 11:36:52 -07:00
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Multiselect - disallow containers
|
|
|
|
|
|
return listView.SelectedItems.Any()
|
|
|
|
|
|
&& listView.SelectedItems.All(i => !(i.Model is ILibraryContainerLink));
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// share menu item
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Share".Localize(),
|
2020-07-24 18:20:53 -07:00
|
|
|
|
Icon = AggContext.StaticData.LoadIcon("share.png", 16, 16, theme.InvertIcons),
|
2018-10-14 12:06:51 -07:00
|
|
|
|
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());
|
|
|
|
|
|
},
|
2018-10-07 11:36:52 -07:00
|
|
|
|
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"));
|
|
|
|
|
|
|
|
|
|
|
|
menuActions.Add(new MenuSeparator("Other"));
|
|
|
|
|
|
|
2018-12-15 09:44:06 -08:00
|
|
|
|
foreach(var extension in ApplicationController.Instance.Library.MenuExtensions)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
2018-12-15 09:44:06 -08:00
|
|
|
|
menuActions.Add(extension);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-24 21:10:39 -07:00
|
|
|
|
menuActions.Add(new LibraryAction(ActionScope.ListItem)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
Title = "Open Package".Localize(),
|
2019-02-26 22:56:21 -08:00
|
|
|
|
Action = async (selectedItems, listView) =>
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
var firstItem = selectedItems.First();
|
|
|
|
|
|
|
|
|
|
|
|
if (firstItem is ILibraryAsset libraryAsset)
|
|
|
|
|
|
{
|
2019-02-26 22:56:21 -08:00
|
|
|
|
var object3D = await libraryAsset.CreateContent(null);
|
|
|
|
|
|
|
|
|
|
|
|
var container = new McxContainer(object3D);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
container.Load();
|
|
|
|
|
|
|
2018-12-12 18:13:22 -08:00
|
|
|
|
container.Parent = libraryContext.ActiveContainer;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
2018-12-12 18:13:22 -08:00
|
|
|
|
libraryContext.ActiveContainer = container;
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
IsEnabled = (selectedListItems, listView) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
return listView.SelectedItems.Count == 1
|
|
|
|
|
|
&& selectedListItems.FirstOrDefault()?.Model is ILibraryAsset libraryAsset
|
|
|
|
|
|
&& libraryAsset.ContentType == "mcx";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
libraryView.MenuActions = menuActions;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnClosed(EventArgs e)
|
|
|
|
|
|
{
|
2019-04-10 07:10:18 -07:00
|
|
|
|
// Unregister listeners
|
|
|
|
|
|
libraryView.SelectedItems.CollectionChanged -= SelectedItems_CollectionChanged;
|
|
|
|
|
|
libraryContext.ContainerChanged -= Library_ContainerChanged;
|
|
|
|
|
|
if (libraryView.ActiveContainer != null)
|
2018-10-07 11:36:52 -07:00
|
|
|
|
{
|
|
|
|
|
|
libraryView.ActiveContainer.ContentChanged -= UpdateStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-11-20 16:39:20 -08:00
|
|
|
|
mainViewWidget = null;
|
|
|
|
|
|
|
2018-10-07 11:36:52 -07:00
|
|
|
|
base.OnClosed(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnMouseMove(MouseEventArgs mouseEvent)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y)
|
|
|
|
|
|
&& mouseEvent.DragFiles?.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (libraryView?.ActiveContainer.IsProtected == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Allow drag-drop if IsLoadable or extension == '.zip'
|
|
|
|
|
|
mouseEvent.AcceptDrop = mouseEvent.DragFiles?.Count > 0
|
|
|
|
|
|
&& mouseEvent.DragFiles.TrueForAll(filePath => ApplicationController.Instance.IsLoadableFile(filePath)
|
|
|
|
|
|
|| (Path.GetExtension(filePath) is string extension
|
2019-01-03 21:43:35 -08:00
|
|
|
|
&& string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
|
|| filePath.StartsWith("http", StringComparison.OrdinalIgnoreCase));
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
base.OnMouseMove(mouseEvent);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnMouseUp(MouseEventArgs mouseEvent)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO: Does this fire when .AcceptDrop is false? Looks like it should
|
|
|
|
|
|
if (mouseEvent.DragFiles?.Count > 0
|
|
|
|
|
|
&& libraryView?.ActiveContainer.IsProtected == false)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = libraryView.ActiveContainer as ILibraryWritableContainer;
|
|
|
|
|
|
container?.Add(mouseEvent.DragFiles.Select(f => new FileSystemFileItem(f)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
base.OnMouseUp(mouseEvent);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void OnLoad(EventArgs args)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Defer creating menu items until plugins have loaded
|
2018-12-12 18:13:22 -08:00
|
|
|
|
LibraryWidget.CreateMenuActions(libraryView, menuActions, libraryContext, mainViewWidget, theme, allowPrint: false);
|
2018-10-07 11:36:52 -07:00
|
|
|
|
|
|
|
|
|
|
navBar.OverflowButton.Name = "Print Library Overflow Menu";
|
|
|
|
|
|
navBar.ExtendOverflowMenu = (popupMenu) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Create menu items in the DropList for each element in this.menuActions
|
|
|
|
|
|
foreach (var menuAction in menuActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (menuAction is MenuSeparator)
|
|
|
|
|
|
{
|
2018-10-24 21:13:10 -07:00
|
|
|
|
popupMenu.CreateSeparator();
|
2018-10-07 11:36:52 -07:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var menuItem = popupMenu.CreateMenuItem(menuAction.Title, menuAction.Icon);
|
|
|
|
|
|
menuItem.Name = $"{menuAction.Title} Menu Item";
|
|
|
|
|
|
menuItem.Enabled = menuAction.Action != null && menuAction.IsEnabled(libraryView.SelectedItems, libraryView);
|
|
|
|
|
|
menuItem.Click += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
menuAction.Action?.Invoke(libraryView.SelectedItems.Select(i => i.Model), libraryView);
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
base.OnLoad(args);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|