Made the clear cache code do something usefull again
Removed dead code related to HTML widget
This commit is contained in:
parent
01f3b3bc45
commit
c44d820dbd
12 changed files with 32 additions and 1450 deletions
|
|
@ -202,7 +202,7 @@ namespace MatterHackers.MatterControl
|
|||
clearCacheLink.Cursor = Cursors.Hand;
|
||||
clearCacheLink.Click += (s, e) => UiThread.RunOnIdle(() =>
|
||||
{
|
||||
CacheDirectory.DeleteCacheData(0);
|
||||
CacheDirectory.DeleteCacheData();
|
||||
});
|
||||
contentRow.AddChild(clearCacheLink);
|
||||
|
||||
|
|
|
|||
|
|
@ -39,79 +39,53 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
public static class CacheDirectory
|
||||
{
|
||||
public static void DeleteCacheData(int daysOldToDelete)
|
||||
public static void DeleteCacheData()
|
||||
{
|
||||
// TODO: Enable once the cache mechanism is scene graph aware
|
||||
return;
|
||||
var basePath = ApplicationDataStorage.ApplicationUserDataPath;
|
||||
CleanDirectory(Path.Combine(basePath, "updates"), 30, new List<string>() { ".EXE" });
|
||||
|
||||
// delete everything in the GCodeOutputPath
|
||||
// AppData\Local\MatterControl\data\gcode
|
||||
// delete everything in the temp data that is not in use
|
||||
// AppData\Local\MatterControl\data\temp
|
||||
// plateImages
|
||||
// project-assembly
|
||||
// project-extract
|
||||
// stl
|
||||
// delete all unreferenced models in Library
|
||||
// AppData\Local\MatterControl\Library
|
||||
// delete all old update downloads
|
||||
// AppData\updates
|
||||
CleanDirectory(Path.Combine(basePath, "data", "temp", "gcode"), 30, new List<string>() { ".GCODE", ".INI" });
|
||||
CleanDirectory(Path.Combine(basePath, "data", "gcode"), 30, new List<string>() { ".GCODE" });
|
||||
|
||||
// start cleaning out unused data
|
||||
// MatterControl\data\gcode
|
||||
HashSet<string> referencedFilePaths = new HashSet<string>();
|
||||
CleanDirectory(ApplicationDataStorage.Instance.GCodeOutputPath, referencedFilePaths, daysOldToDelete);
|
||||
|
||||
string userDataPath = ApplicationDataStorage.ApplicationUserDataPath;
|
||||
RemoveDirectory(Path.Combine(userDataPath, "updates"));
|
||||
HashSet<string> filesToKeep = new HashSet<string>();
|
||||
|
||||
// Get a list of all the stl and amf files referenced in the queue.
|
||||
foreach (PrintItemWrapper printItem in QueueData.Instance.PrintItems)
|
||||
{
|
||||
string fileLocation = printItem.FileLocation;
|
||||
if (!referencedFilePaths.Contains(fileLocation))
|
||||
if (!filesToKeep.Contains(fileLocation))
|
||||
{
|
||||
referencedFilePaths.Add(fileLocation);
|
||||
referencedFilePaths.Add(GetImageFileName(printItem));
|
||||
filesToKeep.Add(fileLocation);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Why exclude PrintItemCollectionID == 0 items from these results
|
||||
var allPrintItems = Datastore.Instance.dbSQLite.Query<PrintItem>("SELECT * FROM PrintItem WHERE PrintItemCollectionID != 0;");
|
||||
var allPrintItems = Datastore.Instance.dbSQLite.Query<PrintItem>("SELECT * FROM PrintItem;");
|
||||
|
||||
// Add in all the stl and amf files referenced in the library.
|
||||
foreach (PrintItem printItem in allPrintItems)
|
||||
{
|
||||
var printItemWrapper = new PrintItemWrapper(printItem);
|
||||
if (!referencedFilePaths.Contains(printItem.FileLocation))
|
||||
if (!filesToKeep.Contains(printItem.FileLocation))
|
||||
{
|
||||
referencedFilePaths.Add(printItem.FileLocation);
|
||||
referencedFilePaths.Add(GetImageFileName(printItemWrapper));
|
||||
filesToKeep.Add(printItem.FileLocation);
|
||||
}
|
||||
}
|
||||
|
||||
// If the count is less than 0 then we have never run and we need to populate the library and queue still. So don't delete anything yet.
|
||||
if (referencedFilePaths.Count > 0)
|
||||
{
|
||||
CleanDirectory(userDataPath, referencedFilePaths, daysOldToDelete);
|
||||
}
|
||||
CleanDirectory(Path.Combine(basePath, "data", "temp", "amf_to_stl"), 1, new List<string>() { ".STL" }, filesToKeep);
|
||||
}
|
||||
|
||||
private static readonly Point2D BigRenderSize = new Point2D(460, 460);
|
||||
|
||||
private static readonly string ThumbnailsPath = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "temp", "thumbnails");
|
||||
|
||||
private static HashSet<string> folderNamesToPreserve = new HashSet<string>()
|
||||
{
|
||||
"profiles",
|
||||
};
|
||||
|
||||
private static int CleanDirectory(string path, HashSet<string> referencedFilePaths, int daysOldToDelete)
|
||||
private static int CleanDirectory(string path, int daysOldToDelete, List<string> extensionsToDelete, HashSet<string> filesToKeep = null)
|
||||
{
|
||||
int contentCount = 0;
|
||||
foreach (string directory in Directory.EnumerateDirectories(path))
|
||||
{
|
||||
int directoryContentCount = CleanDirectory(directory, referencedFilePaths, daysOldToDelete);
|
||||
int directoryContentCount = CleanDirectory(directory, daysOldToDelete, extensionsToDelete, filesToKeep);
|
||||
if (directoryContentCount == 0
|
||||
&& !folderNamesToPreserve.Contains(Path.GetFileName(directory)))
|
||||
{
|
||||
|
|
@ -134,79 +108,28 @@ namespace MatterHackers.MatterControl
|
|||
foreach (string file in Directory.EnumerateFiles(path, "*.*"))
|
||||
{
|
||||
bool fileIsNew = new FileInfo(file).LastAccessTime > DateTime.Now.AddDays(-daysOldToDelete);
|
||||
bool forceKeep = filesToKeep != null && filesToKeep.Contains(file);
|
||||
|
||||
switch (Path.GetExtension(file).ToUpper())
|
||||
if (fileIsNew
|
||||
|| forceKeep
|
||||
|| !extensionsToDelete.Contains(Path.GetExtension(file).ToUpper()))
|
||||
{
|
||||
case ".STL":
|
||||
case ".AMF":
|
||||
case ".GCODE":
|
||||
case ".PNG":
|
||||
case ".TGA":
|
||||
if (referencedFilePaths.Contains(file)
|
||||
|| fileIsNew)
|
||||
{
|
||||
contentCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
GuiWidget.BreakInDebugger();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ".JSON":
|
||||
// may want to clean these up eventually
|
||||
contentCount++; // if we delete these we should not increment this
|
||||
break;
|
||||
|
||||
default:
|
||||
// we have something in the directory that we are not going to delete
|
||||
contentCount++;
|
||||
break;
|
||||
contentCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
GuiWidget.BreakInDebugger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return contentCount;
|
||||
}
|
||||
|
||||
private static void RemoveDirectory(string directoryToRemove)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(directoryToRemove))
|
||||
{
|
||||
Directory.Delete(directoryToRemove, true);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
GuiWidget.BreakInDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetImageFileName(PrintItemWrapper item)
|
||||
{
|
||||
return GetImageFileName(item.FileHashCode);
|
||||
}
|
||||
|
||||
private static string GetImageFileName(string stlHashCode)
|
||||
{
|
||||
string imageFileName = Path.Combine(ThumbnailsPath, "{0}_{1}x{2}.png".FormatWith(stlHashCode, BigRenderSize.x, BigRenderSize.y));
|
||||
|
||||
string folderToSavePrintsTo = Path.GetDirectoryName(imageFileName);
|
||||
|
||||
if (!Directory.Exists(folderToSavePrintsTo))
|
||||
{
|
||||
Directory.CreateDirectory(folderToSavePrintsTo);
|
||||
}
|
||||
|
||||
return imageFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014, Lars Brubaker
|
||||
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 MatterHackers.Agg;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace MatterHackers.MatterControl.HtmlParsing
|
||||
{
|
||||
public class ElementState
|
||||
{
|
||||
internal AlignType alignment;
|
||||
|
||||
internal List<string> classes = new List<string>();
|
||||
|
||||
internal string href;
|
||||
internal string id;
|
||||
internal double pointSize = 12;
|
||||
internal Point2D sizeFixed = new Point2D();
|
||||
internal Point2D sizePercent = new Point2D();
|
||||
internal string src;
|
||||
internal string typeName;
|
||||
|
||||
internal VerticalAlignType verticalAlignment;
|
||||
|
||||
private const string getFirstNumber = @"[0-9]+";
|
||||
|
||||
private static readonly Regex getFirstNumberRegex = new Regex(getFirstNumber, RegexOptions.Compiled);
|
||||
|
||||
internal ElementState()
|
||||
{
|
||||
}
|
||||
|
||||
internal ElementState(ElementState copy)
|
||||
{
|
||||
alignment = copy.alignment;
|
||||
verticalAlignment = copy.verticalAlignment;
|
||||
pointSize = copy.pointSize;
|
||||
href = copy.href;
|
||||
// not part of the ongoing state
|
||||
//heightPercent = copy.heightPercent;
|
||||
}
|
||||
|
||||
public enum AlignType { none, center };
|
||||
|
||||
public enum VerticalAlignType { none, top };
|
||||
|
||||
public AlignType Alignment { get { return alignment; } }
|
||||
|
||||
public List<string> Classes { get { return classes; } }
|
||||
|
||||
public string Href { get { return href; } }
|
||||
public string Id { get { return id; } }
|
||||
public double PointSize { get { return pointSize; } }
|
||||
public Point2D SizeFixed { get { return sizeFixed; } }
|
||||
public Point2D SizePercent { get { return sizePercent; } }
|
||||
public string TypeName { get { return typeName; } }
|
||||
|
||||
public VerticalAlignType VerticalAlignment { get { return verticalAlignment; } }
|
||||
|
||||
public void ParseStyleContent(string styleContent)
|
||||
{
|
||||
string[] splitOnSemi = styleContent.Split(';');
|
||||
for (int i = 0; i < splitOnSemi.Length; i++)
|
||||
{
|
||||
if (splitOnSemi[i].Length > 0 && splitOnSemi[i].Contains(":"))
|
||||
{
|
||||
string[] splitOnColon = splitOnSemi[i].Split(':');
|
||||
string attribute = splitOnColon[0].Trim();
|
||||
string value = splitOnColon[1];
|
||||
switch (attribute)
|
||||
{
|
||||
case "cursor":
|
||||
break;
|
||||
|
||||
case "display":
|
||||
break;
|
||||
|
||||
case "float":
|
||||
Console.WriteLine("Not Implemented");
|
||||
break;
|
||||
|
||||
case "font-size":
|
||||
this.pointSize = GetFirstInt(value);
|
||||
break;
|
||||
|
||||
case "font-weight":
|
||||
break;
|
||||
|
||||
case "height":
|
||||
if (value.Contains("%"))
|
||||
{
|
||||
this.sizePercent = new Point2D(this.SizePercent.x, GetFirstInt(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.sizeFixed = new Point2D(this.SizeFixed.x, GetFirstInt(value));
|
||||
}
|
||||
break;
|
||||
|
||||
case "margin":
|
||||
break;
|
||||
|
||||
case "margin-right":
|
||||
case "margin-left":
|
||||
break;
|
||||
|
||||
case "width":
|
||||
if (value.Contains("%"))
|
||||
{
|
||||
this.sizePercent = new Point2D(GetFirstInt(value), this.SizePercent.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.sizeFixed = new Point2D(GetFirstInt(value), this.SizePercent.y);
|
||||
}
|
||||
break;
|
||||
|
||||
case "text-align":
|
||||
this.alignment = (ElementState.AlignType)Enum.Parse(typeof(ElementState.AlignType), value);
|
||||
break;
|
||||
|
||||
case "text-decoration":
|
||||
break;
|
||||
|
||||
case "vertical-align":
|
||||
this.verticalAlignment = (ElementState.VerticalAlignType)Enum.Parse(typeof(ElementState.VerticalAlignType), value);
|
||||
break;
|
||||
|
||||
case "overflow":
|
||||
break;
|
||||
|
||||
case "padding":
|
||||
break;
|
||||
|
||||
case "'": // the ending single quote
|
||||
break;
|
||||
|
||||
case "color":
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetFirstInt(string input)
|
||||
{
|
||||
Match match = getFirstNumberRegex.Match(input);
|
||||
int start = match.Index;
|
||||
int length = match.Length;
|
||||
return int.Parse(input.Substring(start, length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014, Lars Brubaker
|
||||
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.Text.RegularExpressions;
|
||||
|
||||
namespace MatterHackers.MatterControl.HtmlParsing
|
||||
{
|
||||
public class HtmlParser
|
||||
{
|
||||
private const string typeNameEnd = @"[ >]";
|
||||
private static readonly Regex typeNameEndRegex = new Regex(typeNameEnd, RegexOptions.Compiled);
|
||||
private static List<string> voidElements = new List<string>() { "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" };
|
||||
private Stack<ElementState> elementQueue = new Stack<ElementState>();
|
||||
|
||||
public ElementState CurrentElementState { get { return elementQueue.Peek(); } }
|
||||
|
||||
public static string UrlDecode(string htmlContent)
|
||||
{
|
||||
string decoded = htmlContent.Replace("™", "™");
|
||||
decoded = decoded.Replace(" ", " ");
|
||||
decoded = decoded.Replace("©", "©");
|
||||
|
||||
return decoded;
|
||||
}
|
||||
public void ParseHtml(string htmlContent, Action<HtmlParser, string> addContentFunction, Action<HtmlParser, string> closeContentFunction)
|
||||
{
|
||||
elementQueue.Push(new ElementState());
|
||||
|
||||
int currentPosition = 0;
|
||||
while (currentPosition < htmlContent.Length)
|
||||
{
|
||||
int openPosition = htmlContent.IndexOf('<', currentPosition);
|
||||
if (openPosition == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
int closePosition = htmlContent.IndexOf('>', openPosition);
|
||||
if (htmlContent[openPosition + 1] == '/')
|
||||
{
|
||||
closeContentFunction(this, null);
|
||||
elementQueue.Pop();
|
||||
|
||||
// get any content that is after this close but before the next open or close
|
||||
int nextOpenPosition = htmlContent.IndexOf('<', closePosition);
|
||||
if (nextOpenPosition > closePosition + 1)
|
||||
{
|
||||
string contentBetweenInsideAndEnd = htmlContent.Substring(closePosition + 1, nextOpenPosition - (closePosition + 1));
|
||||
addContentFunction(this, contentBetweenInsideAndEnd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseTypeContent(openPosition, closePosition, htmlContent);
|
||||
|
||||
int endOfName = typeNameEndRegex.Match(htmlContent, openPosition + 1).Index;
|
||||
elementQueue.Peek().typeName = htmlContent.Substring(openPosition + 1, endOfName - (openPosition + 1));
|
||||
|
||||
int nextOpenPosition = htmlContent.IndexOf('<', closePosition);
|
||||
if (closePosition + 1 < htmlContent.Length
|
||||
&& nextOpenPosition != -1)
|
||||
{
|
||||
string content = htmlContent.Substring(closePosition + 1, nextOpenPosition - closePosition - 1);
|
||||
addContentFunction(this, content);
|
||||
}
|
||||
|
||||
if (voidElements.Contains(elementQueue.Peek().typeName))
|
||||
{
|
||||
closeContentFunction(this, null);
|
||||
elementQueue.Pop();
|
||||
|
||||
// get any content that is after this close but before the next open or close
|
||||
int nextOpenPosition2 = htmlContent.IndexOf('<', closePosition);
|
||||
if (nextOpenPosition2 > closePosition + 1)
|
||||
{
|
||||
string contentBetweenInsideAndEnd = htmlContent.Substring(closePosition + 1, nextOpenPosition2 - (closePosition + 1));
|
||||
addContentFunction(this, contentBetweenInsideAndEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
currentPosition = closePosition + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int SetEndAtCharacter(string content, int currentEndIndex, char characterToSkipTo)
|
||||
{
|
||||
// look for the character to skip to
|
||||
int characterToSkipToIndex = content.IndexOf(characterToSkipTo, currentEndIndex);
|
||||
if (characterToSkipToIndex == -1)
|
||||
{
|
||||
// there is no character to skip to
|
||||
currentEndIndex = content.Length - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// move the end past the character to skip to
|
||||
currentEndIndex = Math.Min(characterToSkipToIndex + 1, content.Length - 1);
|
||||
}
|
||||
return currentEndIndex;
|
||||
}
|
||||
|
||||
private static string[] SplitOnSpacesNotInQuotes(string content)
|
||||
{
|
||||
List<string> output = new List<string>();
|
||||
|
||||
int currentStartIndex = 0;
|
||||
int currentEndIndex = 0;
|
||||
|
||||
int nextSpaceIndex = content.IndexOf(' ', currentEndIndex);
|
||||
bool hasMoreSpaces = nextSpaceIndex != -1;
|
||||
|
||||
while (hasMoreSpaces)
|
||||
{
|
||||
int nextSingleQuoteIndex = content.IndexOf('\'', currentEndIndex);
|
||||
int nextDoubleQuoteIndex = content.IndexOf('"', currentEndIndex);
|
||||
if ((nextSingleQuoteIndex != -1 && nextSingleQuoteIndex < nextSpaceIndex)
|
||||
|| (nextDoubleQuoteIndex != -1 && nextDoubleQuoteIndex < nextSpaceIndex))
|
||||
{
|
||||
// There is a quote that we need to skip before looking for spaces.
|
||||
// Skip the quote content that happens first
|
||||
if (nextDoubleQuoteIndex == -1 || (nextSingleQuoteIndex != -1 && nextSingleQuoteIndex < nextDoubleQuoteIndex))
|
||||
{
|
||||
// single quote came first
|
||||
currentEndIndex = SetEndAtCharacter(content, nextSingleQuoteIndex + 1, '\'');
|
||||
}
|
||||
else
|
||||
{
|
||||
// double quote came first
|
||||
currentEndIndex = SetEndAtCharacter(content, nextDoubleQuoteIndex + 1, '"');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output.Add(content.Substring(currentStartIndex, nextSpaceIndex - currentStartIndex));
|
||||
currentStartIndex = nextSpaceIndex + 1;
|
||||
currentEndIndex = currentStartIndex;
|
||||
}
|
||||
|
||||
// check if we are done processing the string
|
||||
nextSpaceIndex = content.IndexOf(' ', currentEndIndex);
|
||||
hasMoreSpaces = nextSpaceIndex != -1;
|
||||
}
|
||||
|
||||
// put on the rest of the stirng
|
||||
if (currentStartIndex < content.Length)
|
||||
{
|
||||
output.Add(content.Substring(currentStartIndex, content.Length - currentStartIndex));
|
||||
}
|
||||
|
||||
return output.ToArray();
|
||||
}
|
||||
|
||||
private void ParseTypeContent(int openPosition, int closePosition, string htmlContent)
|
||||
{
|
||||
string text = htmlContent.Substring(openPosition, closePosition - openPosition);
|
||||
ElementState currentElementState = new ElementState(elementQueue.Peek());
|
||||
int afterTypeName = typeNameEndRegex.Match(htmlContent, openPosition).Index;
|
||||
if (afterTypeName < closePosition)
|
||||
{
|
||||
string content = htmlContent.Substring(afterTypeName, closePosition - afterTypeName).Trim();
|
||||
string[] splitOnSpace = SplitOnSpacesNotInQuotes(content);
|
||||
for (int i = 0; i < splitOnSpace.Length; i++)
|
||||
{
|
||||
string[] splitOnEquals = new Regex("=").Split(splitOnSpace[i]);
|
||||
string elementString = splitOnEquals[0];
|
||||
string elementValue = "";
|
||||
if (splitOnEquals.Length > 1)
|
||||
{
|
||||
elementValue = RemoveOuterQuotes(splitOnEquals[1]);
|
||||
}
|
||||
|
||||
switch (elementString)
|
||||
{
|
||||
case "title":
|
||||
case "alt":
|
||||
case "html":
|
||||
break;
|
||||
|
||||
case "style":
|
||||
currentElementState.ParseStyleContent(elementValue);
|
||||
break;
|
||||
|
||||
case "align":
|
||||
break;
|
||||
|
||||
case "class":
|
||||
{
|
||||
string[] classes = elementValue.Split(' ');
|
||||
foreach (string className in classes)
|
||||
{
|
||||
currentElementState.classes.Add(className);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "href":
|
||||
currentElementState.href = elementValue;
|
||||
break;
|
||||
|
||||
case "src":
|
||||
currentElementState.src = elementValue;
|
||||
break;
|
||||
|
||||
case "id":
|
||||
currentElementState.id = elementValue;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elementQueue.Push(currentElementState);
|
||||
}
|
||||
|
||||
private string RemoveOuterQuotes(string inputString)
|
||||
{
|
||||
int singleQuoteIndex = inputString.IndexOf('\'');
|
||||
int doubleQuoteIndex = inputString.IndexOf('"');
|
||||
|
||||
if (doubleQuoteIndex == -1 || (singleQuoteIndex != -1 && singleQuoteIndex < doubleQuoteIndex))
|
||||
{
|
||||
// single quote index is the least and exists
|
||||
int lastSingleQuoteIndex = inputString.LastIndexOf('\'');
|
||||
if (lastSingleQuoteIndex != -1 && lastSingleQuoteIndex != singleQuoteIndex)
|
||||
{
|
||||
return inputString.Substring(singleQuoteIndex+1, lastSingleQuoteIndex - singleQuoteIndex - 1);
|
||||
}
|
||||
return inputString.Substring(singleQuoteIndex+1);
|
||||
}
|
||||
else if (doubleQuoteIndex != -1)
|
||||
{
|
||||
int lastDoubleQuoteIndex = inputString.LastIndexOf('"');
|
||||
if (lastDoubleQuoteIndex != -1 && lastDoubleQuoteIndex != doubleQuoteIndex)
|
||||
{
|
||||
return inputString.Substring(doubleQuoteIndex+1, lastDoubleQuoteIndex - doubleQuoteIndex-1);
|
||||
}
|
||||
return inputString.Substring(doubleQuoteIndex+1);
|
||||
}
|
||||
else // there are no quotes return the input string
|
||||
{
|
||||
return inputString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,368 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014, Lars Brubaker
|
||||
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.Text.RegularExpressions;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.Font;
|
||||
using MatterHackers.Agg.Image;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.ContactForm;
|
||||
using MatterHackers.MatterControl.HtmlParsing;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.MatterControl
|
||||
{
|
||||
public class HtmlWidget : FlowLayoutWidget
|
||||
{
|
||||
private LinkButtonFactory linkButtonFactory = new LinkButtonFactory();
|
||||
|
||||
private Stack<GuiWidget> elementsUnderConstruction = new Stack<GuiWidget>();
|
||||
HtmlParser htmlParser = new HtmlParser();
|
||||
|
||||
public HtmlWidget(string htmlContent, Color aboutTextColor)
|
||||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
this.Name = "HtmlWidget";
|
||||
elementsUnderConstruction.Push(this);
|
||||
linkButtonFactory.fontSize = 12;
|
||||
linkButtonFactory.textColor = aboutTextColor;
|
||||
|
||||
VAnchor = VAnchor.Fit;
|
||||
HAnchor = HAnchor.Stretch;
|
||||
|
||||
htmlContent = htmlContent.Replace("\r", "");
|
||||
htmlContent = htmlContent.Replace("\n", "");
|
||||
htmlParser.ParseHtml(htmlContent, AddContent, CloseContent);
|
||||
}
|
||||
|
||||
public class WrappingTextWidget : GuiWidget
|
||||
{
|
||||
private String unwrappedMessage;
|
||||
private TextWidget messageContainer;
|
||||
|
||||
public WrappingTextWidget(string text, double pointSize = 12, Justification justification = Justification.Left, Color textColor = new Color(), bool ellipsisIfClipped = true, bool underline = false, Color backgroundColor = new Color())
|
||||
{
|
||||
unwrappedMessage = text;
|
||||
messageContainer = new TextWidget(text, 0, 0, pointSize, justification, textColor, ellipsisIfClipped, underline);
|
||||
this.BackgroundColor = backgroundColor;
|
||||
messageContainer.AutoExpandBoundsToText = true;
|
||||
messageContainer.HAnchor = HAnchor.Left;
|
||||
messageContainer.VAnchor = VAnchor.Bottom;
|
||||
this.HAnchor = HAnchor.Stretch;
|
||||
this.VAnchor = VAnchor.Fit;
|
||||
|
||||
AddChild(messageContainer);
|
||||
}
|
||||
|
||||
public override void OnBoundsChanged(EventArgs e)
|
||||
{
|
||||
AdjustTextWrap();
|
||||
base.OnBoundsChanged(e);
|
||||
}
|
||||
|
||||
private void AdjustTextWrap()
|
||||
{
|
||||
if (messageContainer != null)
|
||||
{
|
||||
double wrappingSize = this.Width - this.Padding.Width;
|
||||
if (wrappingSize > 0)
|
||||
{
|
||||
EnglishTextWrapping wrapper = new EnglishTextWrapping(messageContainer.Printer.TypeFaceStyle.EmSizeInPoints);
|
||||
string wrappedMessage = wrapper.InsertCRs(unwrappedMessage, wrappingSize);
|
||||
messageContainer.Text = wrappedMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChildAdded(EventArgs e)
|
||||
{
|
||||
foreach (var child in Children)
|
||||
{
|
||||
if (child.VAnchor == VAnchor.Stretch)
|
||||
{
|
||||
this.VAnchor = VAnchor.Stretch;
|
||||
}
|
||||
}
|
||||
base.OnChildAdded(e);
|
||||
}
|
||||
|
||||
|
||||
// Replace multiple white spaces with single whitespace
|
||||
private static readonly Regex replaceMultipleWhiteSpacesWithSingleWhitespaceRegex = new Regex(@"\s+", RegexOptions.Compiled);
|
||||
|
||||
private void AddContent(HtmlParser htmlParser, string htmlContent)
|
||||
{
|
||||
ElementState elementState = htmlParser.CurrentElementState;
|
||||
htmlContent = replaceMultipleWhiteSpacesWithSingleWhitespaceRegex.Replace(htmlContent, " ");
|
||||
string decodedHtml = HtmlParser.UrlDecode(htmlContent);
|
||||
switch (elementState.TypeName)
|
||||
{
|
||||
case "a":
|
||||
{
|
||||
elementsUnderConstruction.Push(new FlowLayoutWidget());
|
||||
elementsUnderConstruction.Peek().Name = "a";
|
||||
|
||||
if (decodedHtml != null && decodedHtml != "")
|
||||
{
|
||||
Button linkButton = linkButtonFactory.Generate(decodedHtml.Replace("\r\n", "\n"));
|
||||
StyledTypeFace styled = new StyledTypeFace(LiberationSansFont.Instance, elementState.PointSize);
|
||||
double descentInPixels = styled.DescentInPixels;
|
||||
linkButton.OriginRelativeParent = new Vector2((double)linkButton.OriginRelativeParent.X, (double)(linkButton.OriginRelativeParent.Y + descentInPixels));
|
||||
linkButton.Click += (sender, mouseEvent) =>
|
||||
{
|
||||
ApplicationController.Instance.LaunchBrowser(elementState.Href);
|
||||
};
|
||||
elementsUnderConstruction.Peek().AddChild(linkButton);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "h1":
|
||||
case "p":
|
||||
{
|
||||
elementsUnderConstruction.Push(new FlowLayoutWidget());
|
||||
elementsUnderConstruction.Peek().Name = "p";
|
||||
elementsUnderConstruction.Peek().HAnchor = HAnchor.Stretch;
|
||||
|
||||
if (decodedHtml != null && decodedHtml != "")
|
||||
{
|
||||
WrappingTextWidget content = new WrappingTextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
|
||||
elementsUnderConstruction.Peek().AddChild(content);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "div":
|
||||
{
|
||||
elementsUnderConstruction.Push(new FlowLayoutWidget());
|
||||
elementsUnderConstruction.Peek().Name = "div";
|
||||
|
||||
if (decodedHtml != null && decodedHtml != "")
|
||||
{
|
||||
TextWidget content = new TextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
|
||||
elementsUnderConstruction.Peek().AddChild(content);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "!DOCTYPE":
|
||||
break;
|
||||
|
||||
case "body":
|
||||
break;
|
||||
|
||||
case "html":
|
||||
break;
|
||||
|
||||
case "img":
|
||||
{
|
||||
// put the image into the widget when it is done downloading.
|
||||
var image = new ImageBuffer(Math.Max(elementState.SizeFixed.x, 1), Math.Max(elementState.SizeFixed.y, 1));
|
||||
var imageWidget = new ImageWidget(image);
|
||||
imageWidget.Load += (s, e) => ApplicationController.Instance.DownloadToImageAsync(image, elementState.src, elementState.SizeFixed.x != 0);
|
||||
|
||||
if (elementsUnderConstruction.Peek().Name == "a")
|
||||
{
|
||||
Button linkButton = new Button(0, 0, imageWidget);
|
||||
linkButton.Cursor = Cursors.Hand;
|
||||
linkButton.Click += (sender, mouseEvent) =>
|
||||
{
|
||||
ApplicationController.Instance.LaunchBrowser(elementState.Href);
|
||||
};
|
||||
elementsUnderConstruction.Peek().AddChild(linkButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
elementsUnderConstruction.Peek().AddChild(imageWidget);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "input":
|
||||
break;
|
||||
|
||||
case "table":
|
||||
break;
|
||||
|
||||
case "td":
|
||||
case "span":
|
||||
GuiWidget widgetToAdd;
|
||||
|
||||
if (elementState.Classes.Contains("translate"))
|
||||
{
|
||||
decodedHtml = decodedHtml.Localize();
|
||||
}
|
||||
if (elementState.Classes.Contains("toUpper"))
|
||||
{
|
||||
decodedHtml = decodedHtml.ToUpper();
|
||||
}
|
||||
if (elementState.Classes.Contains("versionNumber"))
|
||||
{
|
||||
decodedHtml = VersionInfo.Instance.ReleaseVersion;
|
||||
}
|
||||
if (elementState.Classes.Contains("buildNumber"))
|
||||
{
|
||||
decodedHtml = VersionInfo.Instance.BuildVersion;
|
||||
}
|
||||
|
||||
Button createdButton = null;
|
||||
if (elementState.Classes.Contains("centeredButton"))
|
||||
{
|
||||
createdButton = ApplicationController.Instance.Theme.ButtonFactory.Generate(decodedHtml);
|
||||
widgetToAdd = createdButton;
|
||||
}
|
||||
else if (elementState.Classes.Contains("linkButton"))
|
||||
{
|
||||
double oldFontSize = linkButtonFactory.fontSize;
|
||||
linkButtonFactory.fontSize = elementState.PointSize;
|
||||
createdButton = linkButtonFactory.Generate(decodedHtml);
|
||||
StyledTypeFace styled = new StyledTypeFace(LiberationSansFont.Instance, elementState.PointSize);
|
||||
double descentInPixels = styled.DescentInPixels;
|
||||
createdButton.OriginRelativeParent = new Vector2((double)createdButton.OriginRelativeParent.X, (double)(createdButton.OriginRelativeParent.Y + descentInPixels));
|
||||
widgetToAdd = createdButton;
|
||||
linkButtonFactory.fontSize = oldFontSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextWidget content = new TextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
|
||||
widgetToAdd = content;
|
||||
}
|
||||
|
||||
if (createdButton != null)
|
||||
{
|
||||
if (elementState.Id == "sendFeedback")
|
||||
{
|
||||
createdButton.Click += (s, e) => DialogWindow.Show<ContactFormPage>();
|
||||
}
|
||||
else if (elementState.Id == "clearCache")
|
||||
{
|
||||
createdButton.Click += (s, e) => CacheDirectory.DeleteCacheData(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (elementState.VerticalAlignment == ElementState.VerticalAlignType.top)
|
||||
{
|
||||
widgetToAdd.VAnchor = VAnchor.Top;
|
||||
}
|
||||
|
||||
elementsUnderConstruction.Peek().AddChild(widgetToAdd);
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
elementsUnderConstruction.Push(new FlowLayoutWidget());
|
||||
elementsUnderConstruction.Peek().Name = "tr";
|
||||
if (elementState.SizePercent.y == 100)
|
||||
{
|
||||
elementsUnderConstruction.Peek().VAnchor = VAnchor.Stretch;
|
||||
this.VAnchor = VAnchor.Stretch;
|
||||
}
|
||||
if (elementState.Alignment == ElementState.AlignType.center)
|
||||
{
|
||||
elementsUnderConstruction.Peek().HAnchor |= HAnchor.Center;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException("Don't know what to do with '{0}'".FormatWith(elementState.TypeName));
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseContent(HtmlParser htmlParser, string htmlContent)
|
||||
{
|
||||
ElementState elementState = htmlParser.CurrentElementState;
|
||||
switch (elementState.TypeName)
|
||||
{
|
||||
case "a":
|
||||
GuiWidget aWidget = elementsUnderConstruction.Pop();
|
||||
if (aWidget.Name != "a")
|
||||
{
|
||||
throw new Exception("Should have been 'a'.");
|
||||
}
|
||||
elementsUnderConstruction.Peek().AddChild(aWidget);
|
||||
break;
|
||||
|
||||
case "body":
|
||||
break;
|
||||
|
||||
case "html":
|
||||
break;
|
||||
|
||||
case "h1":
|
||||
case "p":
|
||||
GuiWidget pWidget = elementsUnderConstruction.Pop();
|
||||
if (pWidget.Name != "p")
|
||||
{
|
||||
throw new Exception("Should have been 'p'.");
|
||||
}
|
||||
elementsUnderConstruction.Peek().AddChild(pWidget);
|
||||
break;
|
||||
|
||||
case "div":
|
||||
GuiWidget divWidget = elementsUnderConstruction.Pop();
|
||||
if (divWidget.Name != "div")
|
||||
{
|
||||
throw new Exception("Should have been 'div'.");
|
||||
}
|
||||
elementsUnderConstruction.Peek().AddChild(divWidget);
|
||||
break;
|
||||
|
||||
case "input":
|
||||
break;
|
||||
|
||||
case "table":
|
||||
break;
|
||||
|
||||
case "span":
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
GuiWidget trWidget = elementsUnderConstruction.Pop();
|
||||
if (trWidget.Name != "tr")
|
||||
{
|
||||
throw new Exception("Should have been 'tr'.");
|
||||
}
|
||||
elementsUnderConstruction.Peek().AddChild(trWidget);
|
||||
break;
|
||||
|
||||
case "td":
|
||||
break;
|
||||
|
||||
case "img":
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ namespace MatterHackers.MatterControl
|
|||
break;
|
||||
|
||||
case "CLEAR_CACHE":
|
||||
CacheDirectory.DeleteCacheData(0);
|
||||
CacheDirectory.DeleteCacheData();
|
||||
break;
|
||||
|
||||
case "SHOW_MEMORY":
|
||||
|
|
|
|||
|
|
@ -130,11 +130,8 @@
|
|||
<Compile Include="ConfigurationPage\PrintLeveling\WizardPages\SelectMaterialPage.cs" />
|
||||
<Compile Include="ConfigurationPage\PrintLeveling\WizardPages\WaitForTempPage.cs" />
|
||||
<Compile Include="CustomWidgets\ConfigurePrinterWidget.cs" />
|
||||
<Compile Include="AboutPage\HTMLParser\HtmlWidget.cs" />
|
||||
<Compile Include="AboutPage\HTMLParser\ElementState.cs" />
|
||||
<Compile Include="AboutPage\UpdateControlData.cs" />
|
||||
<Compile Include="AboutPage\UpdateControlView.cs" />
|
||||
<Compile Include="AboutPage\HTMLParser\HtmlParser.cs" />
|
||||
<Compile Include="ActionBar\PrinterSelector.cs" />
|
||||
<Compile Include="ActionBar\TemperatureWidgetBed.cs" />
|
||||
<Compile Include="ApplicationView\OemProfileDictionary.cs" />
|
||||
|
|
@ -392,7 +389,6 @@
|
|||
<Compile Include="SetupWizard\LicenseAgreementPage.cs" />
|
||||
<Compile Include="SetupWizard\PrinterProfileHistoryPage.cs" />
|
||||
<Compile Include="ConfigurationPage\RunningMacroPage.cs" />
|
||||
<Compile Include="SetupWizard\PublishPartToMatterHackers.cs" />
|
||||
<Compile Include="SetupWizard\SyncingPrintersPage.cs" />
|
||||
<Compile Include="SetupWizard\DialogPage.cs" />
|
||||
<Compile Include="SetupWizard\SetupWizardTroubleshooting.cs" />
|
||||
|
|
|
|||
|
|
@ -576,15 +576,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
IsEnabled = () => sceneContext.EditableScene
|
||||
},
|
||||
new NamedAction()
|
||||
{
|
||||
Title = "Publish".Localize(),
|
||||
Action = () =>
|
||||
{
|
||||
UiThread.RunOnIdle(() => DialogWindow.Show<PublishPartToMatterHackers>());
|
||||
},
|
||||
IsEnabled = () => sceneContext.EditableScene
|
||||
},
|
||||
new NamedAction()
|
||||
{
|
||||
Title = "Arrange All Parts".Localize(),
|
||||
Action = () =>
|
||||
|
|
|
|||
|
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2016, Lars Brubaker
|
||||
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 MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.Agg;
|
||||
using System.Collections.Generic;
|
||||
using MatterHackers.MatterControl.SlicerConfiguration;
|
||||
|
||||
namespace MatterHackers.MatterControl
|
||||
{
|
||||
public class PublishPartToMatterHackers : DialogPage
|
||||
{
|
||||
string publishMessage = "Publish a copy of this part to MatterHackers.".Localize();
|
||||
string publicPublish = "\n\nThis copy will be made available under the terms of the 'Creative Commons Attribution 4.0 International Public License', click the link below for details.".Localize();
|
||||
|
||||
List<CheckBox> iAgreeCheckbox = new List<CheckBox>();
|
||||
|
||||
public PublishPartToMatterHackers()
|
||||
{
|
||||
this.WindowTitle = "Publish to the MatterHakers Part Community".Localize();
|
||||
this.HeaderText = "Publish your part for everyone!".Localize();
|
||||
|
||||
var scrollWindow = new ScrollableWidget()
|
||||
{
|
||||
AutoScroll = true,
|
||||
HAnchor = HAnchor.Stretch,
|
||||
VAnchor = VAnchor.Stretch,
|
||||
};
|
||||
scrollWindow.ScrollArea.HAnchor = HAnchor.Stretch;
|
||||
contentRow.AddChild(scrollWindow);
|
||||
|
||||
var container = new FlowLayoutWidget(FlowDirection.TopToBottom)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
};
|
||||
scrollWindow.AddChild(container);
|
||||
|
||||
var textColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
|
||||
container.AddChild(new WrappedTextWidget(publishMessage + publicPublish, textColor: textColor));
|
||||
|
||||
container.AddChild(new HorizontalLine()
|
||||
{
|
||||
Margin = new BorderDouble(0, 5)
|
||||
});
|
||||
|
||||
container.AddChild(new TextWidget("Author".Localize() + ":")
|
||||
{
|
||||
TextColor = textColor
|
||||
});
|
||||
|
||||
var userName = AuthenticationData.Instance.ActiveSessionUsername;
|
||||
container.AddChild(new MHTextEditWidget(userName == null ? "" : userName, messageWhenEmptyAndNotSelected: "Author Name")
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(5, 5, 0, 0)
|
||||
});
|
||||
|
||||
container.AddChild(new TextWidget("Part Name".Localize() + ":")
|
||||
{
|
||||
TextColor = textColor,
|
||||
Margin = new BorderDouble(0, 0, 0, 5)
|
||||
});
|
||||
|
||||
string partName = null;
|
||||
container.AddChild(new MHTextEditWidget(partName == null ? "" : partName, messageWhenEmptyAndNotSelected: "Part Name")
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(5, 5, 0, 0)
|
||||
});
|
||||
|
||||
container.AddChild(new TextWidget("Details".Localize() + ":")
|
||||
{
|
||||
TextColor = textColor,
|
||||
Margin = new BorderDouble(0, 0, 0, 5)
|
||||
});
|
||||
|
||||
container.AddChild(new MHTextEditWidget("", pixelHeight: 100, multiLine: true, messageWhenEmptyAndNotSelected: "A brief description of this part")
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Margin = new BorderDouble(5, 0, 0, 0)
|
||||
});
|
||||
|
||||
var publishButton = theme.CreateDialogButton("Publish".Localize());
|
||||
publishButton.Name = "PublishPartButton";
|
||||
publishButton.Click += (s, e) =>
|
||||
{
|
||||
// check that the author is set and 'I agree' box is checked
|
||||
// do the publish
|
||||
|
||||
// Close the window and update the PrintersImported flag
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
WizardWindow.Close();
|
||||
|
||||
ProfileManager.Instance.PrintersImported = true;
|
||||
ProfileManager.Instance.Save();
|
||||
});
|
||||
};
|
||||
|
||||
var haveRightsText = "I have the right to license these files.".Localize();
|
||||
contentRow.AddChild(CreateRequiredCheckBox(haveRightsText));
|
||||
|
||||
var agreeText = "I agree to license these files under ".Localize();
|
||||
var html = $"<div>{agreeText}<a href='https://creativecommons.org/licenses/by/4.0/'>'CC BY 4.0'.</a></div>";
|
||||
|
||||
contentRow.AddChild(CreateRequiredCheckBox("", new HtmlWidget(html, textColor)));
|
||||
|
||||
publishButton.Visible = true;
|
||||
|
||||
this.AddPageAction(publishButton);
|
||||
}
|
||||
|
||||
private static FlowLayoutWidget CreateRequiredCheckBox(string agreeText, GuiWidget extra = null)
|
||||
{
|
||||
var agreeRegion = new FlowLayoutWidget()
|
||||
{
|
||||
HAnchor = HAnchor.Stretch
|
||||
};
|
||||
var agreeCheckbox = new CheckBox(agreeText)
|
||||
{
|
||||
VAnchor = VAnchor.Center,
|
||||
TextColor = ActiveTheme.Instance.PrimaryTextColor
|
||||
};
|
||||
agreeRegion.AddChild(agreeCheckbox);
|
||||
if(extra != null)
|
||||
{
|
||||
agreeRegion.AddChild(extra);
|
||||
}
|
||||
return agreeRegion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +65,6 @@
|
|||
<Compile Include="MatterControl\GCodeProcessingTests.cs" />
|
||||
<Compile Include="MatterControl\MatterControlUiFeatures.cs" />
|
||||
<Compile Include="MatterControl\MatterControlUtilities.cs" />
|
||||
<Compile Include="MatterControl\HtmlParser.cs" />
|
||||
<Compile Include="MatterControl\OemProfileTests.cs" />
|
||||
<Compile Include="MatterControl\PrinterChooserUnitTests.cs" />
|
||||
<Compile Include="MatterControl\PrinterConfigurationTests.cs" />
|
||||
|
|
@ -77,7 +76,6 @@
|
|||
<Compile Include="MatterControl\TranslationsTests.cs" />
|
||||
<Compile Include="MatterControl\UIFieldTestWindow.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RemovedFromProduct.cs" />
|
||||
<Compile Include="SceneTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2014, Lars Brubaker
|
||||
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 NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MatterHackers.MatterControl.HtmlParsing
|
||||
{
|
||||
[TestFixture, Category("MatterControl.HtmlParsing")]
|
||||
public class HtmlParserTests
|
||||
{
|
||||
|
||||
private static string[] HtmlParserSplitOnSpacesNotInQuotes(string methodParameter)
|
||||
{
|
||||
MethodInfo method = typeof(HtmlParser).GetMethod("SplitOnSpacesNotInQuotes", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
return method.Invoke(null, parameters: new object[] { methodParameter }) as string[];
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestSplitOnSpacesNotInQuotes()
|
||||
{
|
||||
{
|
||||
string test1 = "one two three";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 3);
|
||||
Assert.IsTrue(results[0] == "one");
|
||||
Assert.IsTrue(results[1] == "two");
|
||||
Assert.IsTrue(results[2] == "three");
|
||||
}
|
||||
|
||||
{
|
||||
string test1 = "one 'two three' four";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 3);
|
||||
Assert.IsTrue(results[0] == "one");
|
||||
Assert.IsTrue(results[1] == "'two three'");
|
||||
Assert.IsTrue(results[2] == "four");
|
||||
}
|
||||
|
||||
{
|
||||
string test1 = "one 'two three''four' five";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 3);
|
||||
Assert.IsTrue(results[0] == "one");
|
||||
Assert.IsTrue(results[1] == "'two three''four'");
|
||||
Assert.IsTrue(results[2] == "five");
|
||||
}
|
||||
|
||||
{
|
||||
string test1 = "one \"two three\" four";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 3);
|
||||
Assert.IsTrue(results[0] == "one");
|
||||
Assert.IsTrue(results[1] == "\"two three\"");
|
||||
Assert.IsTrue(results[2] == "four");
|
||||
}
|
||||
|
||||
{
|
||||
string test1 = "one \"'two' three\" four";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 3);
|
||||
Assert.IsTrue(results[0] == "one");
|
||||
Assert.IsTrue(results[1] == "\"'two' three\"");
|
||||
Assert.IsTrue(results[2] == "four");
|
||||
}
|
||||
|
||||
{
|
||||
string test1 = "one '\"two\" three' four";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 3);
|
||||
Assert.IsTrue(results[0] == "one");
|
||||
Assert.IsTrue(results[1] == "'\"two\" three'");
|
||||
Assert.IsTrue(results[2] == "four");
|
||||
}
|
||||
|
||||
{
|
||||
string test1 = "<img src=\"https://lh6.ggpht.com/FMF8JYN2rGgceXpkG1GTUlmS4Z7qfron0Fm9NDi1Oqxg_TmDLMIThQuvnBXHhJD38_GK3RSnxFCX28Cp5ekxRhzx6g=s243\" alt=\"White PLA Filament - 1.75mm\" title=\"White PLA Filament - 1.75mm\" style=\"width:243px;height:183px;\">";
|
||||
string[] results = HtmlParserSplitOnSpacesNotInQuotes(test1);
|
||||
Assert.IsTrue(results.Length == 5);
|
||||
Assert.IsTrue(results[0] == "<img");
|
||||
Assert.IsTrue(results[1] == "src=\"https://lh6.ggpht.com/FMF8JYN2rGgceXpkG1GTUlmS4Z7qfron0Fm9NDi1Oqxg_TmDLMIThQuvnBXHhJD38_GK3RSnxFCX28Cp5ekxRhzx6g=s243\"");
|
||||
Assert.IsTrue(results[2] == "alt=\"White PLA Filament - 1.75mm\"");
|
||||
Assert.IsTrue(results[3] == "title=\"White PLA Filament - 1.75mm\"");
|
||||
Assert.IsTrue(results[4] == "style=\"width:243px;height:183px;\">");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.MatterControl;
|
||||
using MatterHackers.PolygonMesh;
|
||||
using MatterHackers.PolygonMesh.Csg;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterControl.Tests
|
||||
{
|
||||
class RemovedFromProduct
|
||||
{
|
||||
public static void WriteTestGCodeFile()
|
||||
{
|
||||
using (StreamWriter file = new StreamWriter("PerformanceTest.gcode"))
|
||||
{
|
||||
//int loops = 150000;
|
||||
int loops = 150;
|
||||
int steps = 200;
|
||||
double radius = 50;
|
||||
Vector2 center = new Vector2(150, 100);
|
||||
|
||||
file.WriteLine("G28 ; home all axes");
|
||||
file.WriteLine("G90 ; use absolute coordinates");
|
||||
file.WriteLine("G21 ; set units to millimeters");
|
||||
file.WriteLine("G92 E0");
|
||||
file.WriteLine("G1 F7800");
|
||||
file.WriteLine("G1 Z" + (5).ToString());
|
||||
WriteMove(file, center);
|
||||
|
||||
for (int loop = 0; loop < loops; loop++)
|
||||
{
|
||||
for (int step = 0; step < steps; step++)
|
||||
{
|
||||
Vector2 nextPosition = new Vector2(radius, 0);
|
||||
nextPosition.Rotate(MathHelper.Tau / steps * step);
|
||||
WriteMove(file, center + nextPosition);
|
||||
}
|
||||
}
|
||||
|
||||
file.WriteLine("M84 ; disable motors");
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteMove(StreamWriter file, Vector2 center)
|
||||
{
|
||||
file.WriteLine("G1 X" + center.X.ToString() + " Y" + center.Y.ToString());
|
||||
}
|
||||
|
||||
private static void HtmlWindowTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
SystemWindow htmlTestWindow = new SystemWindow(640, 480);
|
||||
string htmlContent = "";
|
||||
if (true)
|
||||
{
|
||||
string releaseNotesFile = Path.Combine("C:\\Users\\lbrubaker\\Downloads", "test1.html");
|
||||
htmlContent = File.ReadAllText(releaseNotesFile);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// WebClient webClient = new WebClient();
|
||||
// htmlContent = webClient.DownloadString("http://www.matterhackers.com/s/store?q=pla");
|
||||
//}
|
||||
|
||||
HtmlWidget content = new HtmlWidget(htmlContent, Color.Black);
|
||||
content.AddChild(new GuiWidget()
|
||||
{
|
||||
HAnchor = HAnchor.Absolute,
|
||||
VAnchor = VAnchor.Stretch
|
||||
});
|
||||
content.VAnchor |= VAnchor.Top;
|
||||
content.BackgroundColor = Color.White;
|
||||
htmlTestWindow.AddChild(content);
|
||||
htmlTestWindow.BackgroundColor = Color.Cyan;
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
htmlTestWindow.ShowAsSystemWindow();
|
||||
}, 1);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#region DoBooleanTest
|
||||
private bool DoBooleanTest = false;
|
||||
|
||||
Object3D booleanGroup;
|
||||
Vector3 offset = new Vector3();
|
||||
Vector3 direction = new Vector3(.11, .12, .13);
|
||||
Vector3 rotCurrent = new Vector3();
|
||||
Vector3 rotChange = new Vector3(.011, .012, .013);
|
||||
Vector3 scaleChange = new Vector3(.0011, .0012, .0013);
|
||||
Vector3 scaleCurrent = new Vector3(1, 1, 1);
|
||||
|
||||
// TODO: Write test for DoBooleanTest conditional test behavior
|
||||
//if (DoBooleanTest)
|
||||
//{
|
||||
// BeforeDraw += CreateBooleanTestGeometry;
|
||||
// AfterDraw += RemoveBooleanTestGeometry;
|
||||
//}
|
||||
|
||||
private void CreateBooleanTestGeometry(object sender, DrawEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
booleanGroup = new Object3D();
|
||||
|
||||
booleanGroup.Children.Add(new Object3D()
|
||||
{
|
||||
Mesh = ApplyBoolean(CsgOperations.Union, AxisAlignedBoundingBox.Union, new Vector3(100, 0, 20), "U")
|
||||
});
|
||||
|
||||
booleanGroup.Children.Add(new Object3D()
|
||||
{
|
||||
Mesh = ApplyBoolean(CsgOperations.Subtract, null, new Vector3(100, 100, 20), "S")
|
||||
});
|
||||
|
||||
booleanGroup.Children.Add(new Object3D()
|
||||
{
|
||||
Mesh = ApplyBoolean(CsgOperations.Intersect, AxisAlignedBoundingBox.Intersection, new Vector3(100, 200, 20), "I")
|
||||
});
|
||||
|
||||
offset += direction;
|
||||
rotCurrent += rotChange;
|
||||
scaleCurrent += scaleChange;
|
||||
|
||||
// Create dummy object to fix compilation issues
|
||||
IObject3D scene = null;
|
||||
|
||||
scene.Children.Modify(list =>
|
||||
{
|
||||
list.Add(booleanGroup);
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private Mesh ApplyBoolean(Func<Mesh, Mesh, Mesh> meshOperation, Func<AxisAlignedBoundingBox, AxisAlignedBoundingBox, AxisAlignedBoundingBox> aabbOperation, Vector3 centering, string opp)
|
||||
{
|
||||
Mesh boxA = PlatonicSolids.CreateCube(40, 40, 40);
|
||||
//boxA = PlatonicSolids.CreateIcosahedron(35);
|
||||
boxA.Translate(centering);
|
||||
Mesh boxB = PlatonicSolids.CreateCube(40, 40, 40);
|
||||
//boxB = PlatonicSolids.CreateIcosahedron(35);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (Math.Abs(direction[i] + offset[i]) > 10)
|
||||
{
|
||||
direction[i] = direction[i] * -1.00073112;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (Math.Abs(rotChange[i] + rotCurrent[i]) > 6)
|
||||
{
|
||||
rotChange[i] = rotChange[i] * -1.000073112;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (scaleChange[i] + scaleCurrent[i] > 1.1 || scaleChange[i] + scaleCurrent[i] < .9)
|
||||
{
|
||||
scaleChange[i] = scaleChange[i] * -1.000073112;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 offsetB = offset + centering;
|
||||
// switch to the failing offset
|
||||
//offsetB = new Vector3(105.240172225344, 92.9716306394062, 18.4619570261172);
|
||||
//rotCurrent = new Vector3(4.56890223673623, -2.67874102322035, 1.02768848238523);
|
||||
//scaleCurrent = new Vector3(1.07853517569753, 0.964980885267323, 1.09290934544604);
|
||||
Debug.WriteLine("t" + offsetB.ToString() + " r" + rotCurrent.ToString() + " s" + scaleCurrent.ToString() + " " + opp);
|
||||
Matrix4X4 transformB = Matrix4X4.CreateScale(scaleCurrent) * Matrix4X4.CreateRotation(rotCurrent) * Matrix4X4.CreateTranslation(offsetB);
|
||||
boxB.Transform(transformB);
|
||||
|
||||
Mesh meshToAdd = meshOperation(boxA, boxB);
|
||||
|
||||
if (aabbOperation != null)
|
||||
{
|
||||
AxisAlignedBoundingBox boundsA = boxA.GetAxisAlignedBoundingBox();
|
||||
AxisAlignedBoundingBox boundsB = boxB.GetAxisAlignedBoundingBox();
|
||||
AxisAlignedBoundingBox boundsAdd = meshToAdd.GetAxisAlignedBoundingBox();
|
||||
|
||||
AxisAlignedBoundingBox boundsResult = aabbOperation(boundsA, boundsB);
|
||||
}
|
||||
|
||||
return meshToAdd;
|
||||
}
|
||||
|
||||
private void RemoveBooleanTestGeometry(object sender, DrawEventArgs e)
|
||||
{
|
||||
// Create dummy object to fix compilation issues
|
||||
IObject3D scene = null;
|
||||
|
||||
if (scene.Children.Contains(booleanGroup))
|
||||
{
|
||||
scene.Children.Remove(booleanGroup);
|
||||
|
||||
// TODO: Figure out why this invalidate pump exists and restor
|
||||
//UiThread.RunOnIdle(() => Invalidate(), 1.0 / 30.0);
|
||||
}
|
||||
}
|
||||
#endregion DoBooleanTest
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue