mattercontrol/PrintQueue/PrintQueueItem.cs
2014-01-29 19:09:30 -08:00

431 lines
17 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Threading;
using System.IO;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.VertexSource;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.VectorMath;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.PrintLibrary;
using MatterHackers.Localizations;
using MatterHackers.PolygonMesh;
namespace MatterHackers.MatterControl.PrintQueue
{
public class PrintQueueItem : GuiWidget
{
public PrintItemWrapper PrintItemWrapper { get; set; }
public RGBA_Bytes WidgetTextColor;
public RGBA_Bytes WidgetBackgroundColor;
public bool isActivePrint = false;
public bool isSelectedItem = false;
public bool isHoverItem = false;
TextWidget partLabel;
TextWidget partStatus;
FlowLayoutWidget editControls;
LinkButtonFactory linkButtonFactory = new LinkButtonFactory();
public PrintQueueItem(PrintItemWrapper printItem)
{
this.PrintItemWrapper = printItem;
ConstructPrintQueueItem();
}
public PrintQueueItem(string displayName, string fileLocation)
{
PrintItem printItem = new PrintItem();
printItem.Name = displayName;
printItem.FileLocation = fileLocation;
this.PrintItemWrapper = new PrintItemWrapper(printItem);
ConstructPrintQueueItem();
}
public void ConstructPrintQueueItem()
{
linkButtonFactory.fontSize = 10;
linkButtonFactory.textColor = RGBA_Bytes.Black;
WidgetTextColor = RGBA_Bytes.Black;
WidgetBackgroundColor = RGBA_Bytes.White;
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
SetDisplayAttributes();
FlowLayoutWidget topToBottomLayout = new FlowLayoutWidget(FlowDirection.TopToBottom);
topToBottomLayout.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;
FlowLayoutWidget topContentsFlowLayout = new FlowLayoutWidget(FlowDirection.LeftToRight);
topContentsFlowLayout.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;
{
FlowLayoutWidget leftColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
leftColumn.VAnchor = VAnchor.ParentTop | Agg.UI.VAnchor.FitToChildren;
{
PartThumbnailWidget thumbnailWidget = new PartThumbnailWidget(PrintItemWrapper, "part_icon_transparent_40x40.png", "building_thumbnail_40x40.png", new Vector2(50, 50));
leftColumn.AddChild(thumbnailWidget);
}
FlowLayoutWidget middleColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
middleColumn.VAnchor = VAnchor.ParentTop | Agg.UI.VAnchor.FitToChildren;
middleColumn.HAnchor = HAnchor.ParentLeftRight;// | Agg.UI.HAnchor.FitToChildren;
middleColumn.Padding = new BorderDouble(8);
middleColumn.Margin = new BorderDouble(10,0);
{
string labelName = textInfo.ToTitleCase(PrintItemWrapper.Name);
labelName = labelName.Replace('_', ' ');
partLabel = new TextWidget(labelName, pointSize: 14);
partLabel.TextColor = WidgetTextColor;
partLabel.MinimumSize = new Vector2(1, 16);
string partStatusLblTxt = new LocalizedString ("Status").Translated;
string partStatusLblTxtTest = new LocalizedString ("Queued to Print").Translated;
string partStatusLblTxtFull = string.Format("{0}: {1}", partStatusLblTxt,partStatusLblTxtTest);
partStatus = new TextWidget(partStatusLblTxtFull, pointSize: 10);
partStatus.AutoExpandBoundsToText = true;
partStatus.TextColor = WidgetTextColor;
partStatus.MinimumSize = new Vector2(50, 12);
middleColumn.AddChild(partLabel);
middleColumn.AddChild(partStatus);
}
CreateEditControls();
topContentsFlowLayout.AddChild(leftColumn);
topContentsFlowLayout.AddChild(middleColumn);
topContentsFlowLayout.AddChild(editControls);
editControls.Visible = false;
}
topToBottomLayout.AddChild(topContentsFlowLayout);
this.AddChild(topToBottomLayout);
AddHandlers();
}
private void CreateEditControls()
{
editControls = new FlowLayoutWidget();
editControls.Margin = new BorderDouble(right: 10);
editControls.VAnchor = Agg.UI.VAnchor.FitToChildren | Agg.UI.VAnchor.ParentCenter;
{
FlowLayoutWidget layoutLeftToRight = new FlowLayoutWidget();
linkButtonFactory.margin = new BorderDouble(3);
// view button
{
Button viewLink = linkButtonFactory.Generate(new LocalizedString("View").Translated);
viewLink.Click += (sender, e) =>
{
string pathAndFile = PrintItemWrapper.FileLocation;
if (File.Exists(pathAndFile))
{
new PartPreviewMainWindow(PrintItemWrapper);
}
else
{
ShowCantFindFileMessage(PrintItemWrapper);
}
};
layoutLeftToRight.AddChild(viewLink);
}
// copy button
{
Button copyLink = linkButtonFactory.Generate(new LocalizedString("Copy").Translated);
copyLink.Click += (sender, e) =>
{
CreateCopyInQueue();
};
layoutLeftToRight.AddChild(copyLink);
}
// add to library button
{
if (this.PrintItemWrapper.PrintItem.PrintItemCollectionID == PrintLibraryListControl.Instance.LibraryCollection.Id)
{
//rightColumnOptions.AddChild(new TextWidget("Libary Item"));
}
}
// the export menu
{
Button exportLink = linkButtonFactory.Generate(new LocalizedString("Export").Translated);
exportLink.Click += (sender, e) =>
{
ExportQueueItemWindow exportingWindow = new ExportQueueItemWindow(this);
exportingWindow.ShowAsSystemWindow();
};
layoutLeftToRight.AddChild(exportLink);
}
// spacer
{
layoutLeftToRight.AddChild(new GuiWidget(10, 10));
}
// delete button
{
Button deleteLink = linkButtonFactory.Generate(new LocalizedString("Remove").Translated);
deleteLink.Click += (sender, e) =>
{
DeletePartFromQueue();
};
layoutLeftToRight.AddChild(deleteLink);
}
// push off to the right the rest spacer
{
GuiWidget spaceFiller = new GuiWidget(10, 10);
//layoutLeftToRight.AddChild(spaceFiller);
}
// up and down buttons
{
FlowLayoutWidget topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);
// move up one button
{
Button moveUp = linkButtonFactory.Generate(" ^ ");
moveUp.Click += (sender, e) =>
{
int thisIndexInQueue = PrintQueueControl.Instance.GetIndex(PrintItemWrapper);
PrintQueueControl.Instance.SwapItemsDurringUiAction(thisIndexInQueue, thisIndexInQueue - 1);
};
topToBottom.AddChild(moveUp);
}
// move down one button
{
Button moveDown = linkButtonFactory.Generate(" v ");
moveDown.Click += (sender, e) =>
{
int thisIndexInQueue = PrintQueueControl.Instance.GetIndex(PrintItemWrapper);
PrintQueueControl.Instance.SwapItemsDurringUiAction(thisIndexInQueue, thisIndexInQueue + 1);
};
topToBottom.AddChild(moveDown);
}
// don't add this yet as we don't have icons for it and it should probably be drag and drop anyway
//layoutLeftToRight.AddChild(topToBottom);
}
// now add the layout to the edit controls bar
editControls.AddChild(layoutLeftToRight);
}
}
public override void OnClosed(EventArgs e)
{
if (unregisterEvents != null)
{
unregisterEvents(this, null);
}
base.OnClosed(e);
}
event EventHandler unregisterEvents;
void AddHandlers()
{
ActiveTheme.Instance.ThemeChanged.RegisterEvent(onThemeChanged, ref unregisterEvents);
PrintItemWrapper.SlicingOutputMessage += PrintItem_SlicingOutputMessage;
MouseEnterBounds += new EventHandler(PrintQueueItem_MouseEnterBounds);
MouseLeaveBounds += new EventHandler(PrintQueueItem_MouseLeaveBounds);
}
void PrintItem_SlicingOutputMessage(object sender, EventArgs e)
{
StringEventArgs message = e as StringEventArgs;
partStatus.Text = string.Format("Status: {0}", message.Data);
}
void SetDisplayAttributes()
{
this.VAnchor = Agg.UI.VAnchor.FitToChildren;
this.HAnchor = Agg.UI.HAnchor.ParentLeftRight | Agg.UI.HAnchor.FitToChildren;
this.Height = 50;
this.BackgroundColor = this.WidgetBackgroundColor;
this.Padding = new BorderDouble(0);
this.Margin = new BorderDouble(6,0,6,6);
}
void PrintQueueItem_MouseLeaveBounds(object sender, EventArgs e)
{
editControls.Visible = false;
}
void PrintQueueItem_MouseEnterBounds(object sender, EventArgs e)
{
editControls.Visible = true;
}
class PartToAddToQueue
{
internal string Name;
internal string FileLocation;
internal int insertAfterIndex;
internal PartToAddToQueue(string name, string fileLocation, int insertAfterIndex)
{
this.Name = name;
this.FileLocation = fileLocation;
this.insertAfterIndex = insertAfterIndex;
}
}
void AddPartToQueue(object state)
{
PartToAddToQueue partToAddToQueue = (PartToAddToQueue)state;
PrintQueueItem queueItem = new PrintQueueItem(partToAddToQueue.Name, partToAddToQueue.FileLocation);
PrintQueueControl.Instance.AddChild(queueItem, partToAddToQueue.insertAfterIndex);
}
public void CreateCopyInQueue()
{
int thisIndexInQueue = PrintQueueControl.Instance.GetIndex(PrintItemWrapper);
if (thisIndexInQueue != -1)
{
string applicationDataPath = ApplicationDataStorage.Instance.ApplicationUserDataPath;
string stagingFolder = Path.Combine(applicationDataPath, "data", "temp", "stl");
if (!Directory.Exists(stagingFolder))
{
Directory.CreateDirectory(stagingFolder);
}
string newCopyFilename;
int infiniteBlocker = 0;
do
{
newCopyFilename = Path.Combine(stagingFolder, Path.ChangeExtension(Path.GetRandomFileName(), "stl"));
newCopyFilename = Path.GetFullPath(newCopyFilename);
infiniteBlocker++;
} while (File.Exists(newCopyFilename) && infiniteBlocker < 100);
File.Copy(PrintItemWrapper.FileLocation, newCopyFilename);
string newName = PrintItemWrapper.Name;
if (!newName.Contains(" - copy"))
{
newName += " - copy";
}
else
{
int index = newName.LastIndexOf(" - copy");
newName = newName.Substring(0, index) + " - copy";
}
int copyNumber = 2;
string testName = newName;
string[] itemNames = PrintQueueControl.Instance.GetItemNames();
// figure out if we have a copy already and increment the number if we do
while (true)
{
if (itemNames.Contains(testName))
{
testName = string.Format("{0} {1}", newName, copyNumber);
copyNumber++;
}
else
{
break;
}
}
newName = testName;
UiThread.RunOnIdle(AddPartToQueue, new PartToAddToQueue(newName, newCopyFilename, thisIndexInQueue + 1));
}
}
public void DeletePartFromQueue()
{
int thisIndexInQueue = PrintQueueControl.Instance.GetIndex(PrintItemWrapper);
PrintQueueControl.Instance.RemoveIndex(thisIndexInQueue);
}
public static void ShowCantFindFileMessage(PrintItemWrapper printItem)
{
UiThread.RunOnIdle((state) =>
{
string maxLengthName = printItem.FileLocation;
int maxLength = 43;
if (maxLengthName.Length > maxLength)
{
string start = maxLengthName.Substring(0, 15) + "...";
int amountRemaining = (maxLength - start.Length);
string end = maxLengthName.Substring(maxLengthName.Length - amountRemaining, amountRemaining);
maxLengthName = start + end;
}
string message = String.Format("Oops! Could not find this file:\n'{0}'\n\nWould you like to remove it from the queue?", maxLengthName);
if (StyledMessageBox.ShowMessageBox(message, "Item not found", StyledMessageBox.MessageType.YES_NO))
{
PrintQueueControl.Instance.RemoveIndex(PrintQueueControl.Instance.GetIndex(printItem));
}
});
}
private void onThemeChanged(object sender, EventArgs e)
{
if (this.isActivePrint)
{
//Set background and text color to new theme
this.BackgroundColor = ActiveTheme.Instance.PrimaryAccentColor;
this.partLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
this.partStatus.TextColor = ActiveTheme.Instance.PrimaryTextColor;
this.Invalidate();
}
}
public void SetTextColors(RGBA_Bytes color)
{
this.partLabel.TextColor = color;
this.partStatus.TextColor = color;
editControls.SendToChildren(new ChangeTextColorEventArgs(color));
}
public override void OnDraw(Graphics2D graphics2D)
{
base.OnDraw(graphics2D);
if (this.isActivePrint)
{
//RectangleDouble Bounds = LocalBounds;
//RoundedRect rectBorder = new RoundedRect(Bounds, 0);
this.BackgroundColor = ActiveTheme.Instance.SecondaryAccentColor;
SetTextColors(ActiveTheme.Instance.PrimaryTextColor);
//graphics2D.Render(new Stroke(rectBorder, 4), ActiveTheme.Instance.SecondaryAccentColor);
}
else if (this.isHoverItem)
{
RectangleDouble Bounds = LocalBounds;
RoundedRect rectBorder = new RoundedRect(Bounds, 0);
this.BackgroundColor = RGBA_Bytes.White;
SetTextColors(RGBA_Bytes.Black);
graphics2D.Render(new Stroke(rectBorder, 3), ActiveTheme.Instance.SecondaryAccentColor);
}
else
{
this.BackgroundColor = RGBA_Bytes.White;
SetTextColors(RGBA_Bytes.Black);
}
}
}
}