2014-01-29 19:09:30 -08:00
/ *
2014-02-15 18:06:03 -08:00
Copyright ( c ) 2014 , Lars Brubaker
2014-01-29 19:09:30 -08: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.Diagnostics ;
using System.Globalization ;
2014-03-16 10:23:56 -07:00
using System.IO ;
using System.Text ;
using System.Threading ;
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg ;
using MatterHackers.Agg.UI ;
using MatterHackers.MatterControl.DataStorage ;
2014-02-04 22:28:30 -08:00
using MatterHackers.MatterControl.PartPreviewWindow ;
2014-03-16 10:23:56 -07:00
using MatterHackers.MatterControl.PluginSystem ;
using MatterHackers.MatterControl.PrintQueue ;
2014-02-15 18:06:03 -08:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2014-05-06 18:25:16 -07:00
using MatterHackers.MatterControl.SettingsManagement ;
2014-03-16 10:23:56 -07:00
using MatterHackers.VectorMath ;
2014-01-29 19:09:30 -08:00
namespace MatterHackers.MatterControl
{
2014-04-27 16:16:47 -07:00
public static class MainScreenUiState
{
2014-04-30 11:21:06 -07:00
public static readonly int EmpytValue = - 2 ;
2014-04-27 16:16:47 -07:00
public static int lastMainScreenTabIndex = 0 ;
2014-04-30 11:21:06 -07:00
public static int lastSelectedIndex = EmpytValue ;
public static int lastAdvancedControlsTab = EmpytValue ;
2014-04-27 16:16:47 -07:00
}
2014-01-29 19:09:30 -08:00
public class MatterControlApplication : SystemWindow
{
2014-02-04 22:28:30 -08:00
string [ ] commandLineArgs = null ;
2014-01-29 19:09:30 -08:00
bool firstDraw = true ;
2014-02-27 14:56:20 -08:00
bool ShowMemoryUsed = false ;
bool DoCGCollectEveryDraw = false ;
2014-03-30 17:52:33 -07:00
public bool RestartOnClose = false ;
2014-01-29 19:09:30 -08:00
2014-02-10 14:11:51 -08:00
public MatterControlApplication ( double width , double height )
2014-01-29 19:09:30 -08:00
: base ( width , height )
{
2014-02-26 11:05:58 -08:00
this . commandLineArgs = Environment . GetCommandLineArgs ( ) ;
2014-01-29 19:09:30 -08:00
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
2014-03-25 07:46:14 -07:00
foreach ( string command in commandLineArgs )
2014-02-26 11:05:58 -08:00
{
2014-03-25 07:46:14 -07:00
string commandUpper = command . ToUpper ( ) ;
switch ( commandUpper )
2014-02-26 11:05:58 -08:00
{
2014-02-27 14:56:20 -08:00
case "TEST" :
Testing . TestingDispatch testDispatch = new Testing . TestingDispatch ( ) ;
string [ ] testCommands = new string [ commandLineArgs . Length - 2 ] ;
if ( commandLineArgs . Length > 2 )
{
commandLineArgs . CopyTo ( testCommands , 2 ) ;
}
testDispatch . RunTests ( testCommands ) ;
return ;
2014-03-25 07:46:14 -07:00
case "CLEAR_CACHE" :
AboutPage . DeleteCacheData ( ) ;
break ;
2014-02-27 14:56:20 -08:00
case "SHOW_MEMORY" :
ShowMemoryUsed = true ;
break ;
case "DO_GC_COLLECT_EVERY_DRAW" :
ShowMemoryUsed = true ;
DoCGCollectEveryDraw = true ;
break ;
2014-02-26 11:05:58 -08:00
}
}
2014-02-04 10:47:57 -08:00
//WriteTestGCodeFile();
2014-03-02 15:28:47 -08:00
#if ! DEBUG
2014-01-29 19:09:30 -08:00
if ( File . Exists ( "RunUnitTests.txt" ) )
2014-03-02 15:28:47 -08:00
#endif
2014-01-29 19:09:30 -08:00
{
2014-04-12 12:20:04 -07:00
Clipboard . SetSystemClipboardFunctions ( System . Windows . Forms . Clipboard . GetText , System . Windows . Forms . Clipboard . SetText , System . Windows . Forms . Clipboard . ContainsText ) ;
2014-01-29 19:09:30 -08:00
2014-04-07 18:28:47 -07:00
MatterHackers . PolygonMesh . UnitTests . UnitTests . Run ( ) ;
2014-03-31 13:42:18 -07:00
MatterHackers . RayTracer . UnitTests . Run ( ) ;
2014-01-29 19:09:30 -08:00
MatterHackers . Agg . Tests . UnitTests . Run ( ) ;
MatterHackers . VectorMath . Tests . UnitTests . Run ( ) ;
MatterHackers . Agg . UI . Tests . UnitTests . Run ( ) ;
// you can turn this on to debug some bounds issues
//GuiWidget.DebugBoundsUnderMouse = true;
}
GuiWidget . DefaultEnforceIntegerBounds = true ;
2014-03-17 14:41:36 -07:00
this . AddChild ( ApplicationWidget . Instance ) ;
2014-01-29 19:09:30 -08:00
this . Padding = new BorderDouble ( 0 ) ; //To be re-enabled once native borders are turned off
#if false // this is to test freeing gcodefile memory
Button test = new Button ( "test" ) ;
test . Click + = ( sender , e ) = >
{
//MatterHackers.GCodeVisualizer.GCodeFile gcode = new GCodeVisualizer.GCodeFile();
//gcode.Load(@"C:\Users\lbrubaker\Downloads\drive assy.gcode");
SystemWindow window = new SystemWindow ( 100 , 100 ) ;
window . ShowAsSystemWindow ( ) ;
} ;
allControls . AddChild ( test ) ;
#endif
this . AnchorAll ( ) ;
UseOpenGL = true ;
2014-05-06 18:25:16 -07:00
string version = "1.1" ;
2014-05-22 16:55:28 -07:00
Title = "MatterControl {0}" . FormatWith ( version ) ;
if ( OemSettings . Instance . WindowTitleExtra ! = null & & OemSettings . Instance . WindowTitleExtra . Trim ( ) . Length > 0 )
{
Title = Title + " - {1}" . FormatWith ( version , OemSettings . Instance . WindowTitleExtra ) ;
}
2014-01-29 19:09:30 -08:00
2014-02-14 12:06:44 -08:00
ActivePrinterProfile . CheckForAndDoAutoConnect ( ) ;
2014-01-29 19:09:30 -08:00
UiThread . RunOnIdle ( CheckOnPrinter ) ;
2014-05-12 09:59:56 -07:00
MinimumSize = new Vector2 ( 590 , 630 ) ;
2014-04-07 16:15:22 -07:00
2014-04-12 11:54:05 -07:00
string desktopPosition = ApplicationSettings . Instance . get ( "DesktopPosition" ) ;
if ( desktopPosition ! = null & & desktopPosition ! = "" )
{
string [ ] sizes = desktopPosition . Split ( ',' ) ;
2014-04-28 15:19:41 -07:00
//If the desktop position is less than -10,-10, override
int xpos = Math . Max ( int . Parse ( sizes [ 0 ] ) , - 10 ) ;
int ypos = Math . Max ( int . Parse ( sizes [ 1 ] ) , - 10 ) ;
DesktopPosition = new Point2D ( xpos , ypos ) ;
}
2014-01-29 19:09:30 -08:00
ShowAsSystemWindow ( ) ;
}
2014-02-04 10:47:57 -08:00
private static void WriteMove ( StringBuilder gcodeStringBuilder , Vector2 center )
{
gcodeStringBuilder . AppendLine ( "G1 X" + center . x . ToString ( ) + " Y" + center . y . ToString ( ) ) ;
}
2014-02-27 14:56:20 -08:00
2014-02-04 10:47:57 -08:00
public static void WriteTestGCodeFile ( )
{
StringBuilder gcodeStringBuilder = new StringBuilder ( ) ;
2014-03-17 14:41:36 -07:00
int loops = 15 ;
int steps = 20 ;
double radius = 90 ;
Vector2 center = new Vector2 ( 0 , 0 ) ;
2014-02-04 10:47:57 -08:00
gcodeStringBuilder . AppendLine ( "G28 ; home all axes" ) ;
gcodeStringBuilder . AppendLine ( "G90 ; use absolute coordinates" ) ;
gcodeStringBuilder . AppendLine ( "G21 ; set units to millimeters" ) ;
gcodeStringBuilder . AppendLine ( "G92 E0" ) ;
gcodeStringBuilder . AppendLine ( "G1 F7800.000" ) ;
2014-03-17 14:41:36 -07:00
//gcodeStringBuilder.AppendLine("G1 Z" + (30).ToString());
2014-02-04 10:47:57 -08:00
WriteMove ( gcodeStringBuilder , 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 ( gcodeStringBuilder , center + nextPosition ) ;
}
}
gcodeStringBuilder . AppendLine ( "M84 ; disable motors" ) ;
System . IO . File . WriteAllText ( "PerformanceTest.gcode" , gcodeStringBuilder . ToString ( ) ) ;
}
2014-02-27 14:56:20 -08:00
2014-01-29 19:09:30 -08:00
void CheckOnPrinter ( object state )
{
PrinterCommunication . Instance . OnIdle ( ) ;
UiThread . RunOnIdle ( CheckOnPrinter ) ;
}
public override void OnParentChanged ( EventArgs e )
{
if ( File . Exists ( "RunUnitTests.txt" ) )
{
//DiagnosticWidget diagnosticView = new DiagnosticWidget(this);
}
base . OnParentChanged ( e ) ;
// now that we are all set up lets load our plugins and allow them their chance to set things up
FindAndInstantiatePlugins ( ) ;
}
private void FindAndInstantiatePlugins ( )
{
#if false
string pluginDirectory = Path . Combine ( ".." , ".." , ".." , "MatterControlPlugins" , "bin" ) ;
#if DEBUG
pluginDirectory = Path . Combine ( pluginDirectory , "Debug" ) ;
#else
pluginDirectory = Path . Combine ( pluginDirectory , "Release" ) ;
#endif
if ( ! Directory . Exists ( pluginDirectory ) )
{
string dataPath = DataStorage . ApplicationDataStorage . Instance . ApplicationUserDataPath ;
pluginDirectory = Path . Combine ( dataPath , "Plugins" ) ;
}
// TODO: this should look in a plugin folder rather than just the application directory (we probably want it in the user folder).
PluginFinder < MatterControlPlugin > pulginFinder = new PluginFinder < MatterControlPlugin > ( pluginDirectory ) ;
#else
PluginFinder < MatterControlPlugin > pulginFinder = new PluginFinder < MatterControlPlugin > ( ) ;
#endif
string oemName = ApplicationSettings . Instance . GetOEMName ( ) ;
foreach ( MatterControlPlugin plugin in pulginFinder . Plugins )
{
string pluginInfo = plugin . GetPluginInfoJSon ( ) ;
Dictionary < string , string > nameValuePairs = Newtonsoft . Json . JsonConvert . DeserializeObject < Dictionary < string , string > > ( pluginInfo ) ;
if ( nameValuePairs ! = null & & nameValuePairs . ContainsKey ( "OEM" ) )
{
if ( nameValuePairs [ "OEM" ] = = oemName )
{
plugin . Initialize ( this ) ;
}
}
else
{
plugin . Initialize ( this ) ;
}
}
}
Stopwatch totalDrawTime = new Stopwatch ( ) ;
int drawCount = 0 ;
public override void OnDraw ( Graphics2D graphics2D )
{
2014-03-02 15:28:47 -08:00
totalDrawTime . Restart ( ) ;
2014-01-29 19:09:30 -08:00
base . OnDraw ( graphics2D ) ;
2014-03-02 15:28:47 -08:00
totalDrawTime . Stop ( ) ;
2014-01-29 19:09:30 -08:00
2014-02-27 14:56:20 -08:00
if ( ShowMemoryUsed )
2014-01-29 19:09:30 -08:00
{
2014-02-27 14:56:20 -08:00
long memory = GC . GetTotalMemory ( false ) ;
this . Title = string . Format ( "Allocated = {0:n0} : {1}ms, d{2} Size = {3}x{4}" , memory , totalDrawTime . ElapsedMilliseconds , drawCount + + , this . Width , this . Height ) ;
if ( DoCGCollectEveryDraw )
{
GC . Collect ( ) ;
}
2014-01-29 19:09:30 -08:00
}
2014-02-27 14:56:20 -08:00
2014-01-29 19:09:30 -08:00
if ( firstDraw )
{
firstDraw = false ;
2014-02-04 22:28:30 -08:00
foreach ( string arg in commandLineArgs )
{
if ( Path . GetExtension ( arg ) . ToUpper ( ) = = ".STL" )
{
2014-06-05 11:45:40 -07:00
new PartPreviewMainWindow ( new PrintItemWrapper ( new DataStorage . PrintItem ( Path . GetFileName ( arg ) , Path . GetFullPath ( arg ) ) ) , View3DTransformPart . AutoRotate . Enabled ) ;
2014-02-04 22:28:30 -08:00
}
}
2014-01-29 19:09:30 -08:00
}
}
public override void OnMouseMove ( MouseEventArgs mouseEvent )
{
if ( GuiWidget . DebugBoundsUnderMouse )
{
Invalidate ( ) ;
}
base . OnMouseMove ( mouseEvent ) ;
}
[STAThread]
2014-02-10 14:11:51 -08:00
public static void Main ( )
2014-01-29 19:09:30 -08:00
{
Datastore . Instance . Initialize ( ) ;
// try and open our window matching the last size that we had for it.
string windowSize = ApplicationSettings . Instance . get ( "WindowSize" ) ;
int width = 600 ;
2014-05-12 09:59:56 -07:00
int height = 660 ;
2014-02-27 14:56:20 -08:00
if ( windowSize ! = null & & windowSize ! = "" )
2014-01-29 19:09:30 -08:00
{
string [ ] sizes = windowSize . Split ( ',' ) ;
2014-04-28 15:19:41 -07:00
width = Math . Max ( int . Parse ( sizes [ 0 ] ) , 600 ) ;
height = Math . Max ( int . Parse ( sizes [ 1 ] ) , 600 ) ;
2014-01-29 19:09:30 -08:00
}
2014-04-12 11:54:05 -07:00
2014-02-10 14:11:51 -08:00
new MatterControlApplication ( width , height ) ;
2014-01-29 19:09:30 -08:00
}
public override void OnClosed ( EventArgs e )
{
// save the last size of the window so we can restore it next time.
ApplicationSettings . Instance . set ( "WindowSize" , string . Format ( "{0},{1}" , Width , Height ) ) ;
2014-04-10 15:56:15 -07:00
ApplicationSettings . Instance . set ( "DesktopPosition" , string . Format ( "{0},{1}" , DesktopPosition . x , DesktopPosition . y ) ) ;
2014-01-29 19:09:30 -08:00
PrinterCommunication . Instance . Disable ( ) ;
//Close connection to the local datastore
Datastore . Instance . Exit ( ) ;
PrinterCommunication . Instance . HaltConnectionThread ( ) ;
SlicingQueue . Instance . ShutDownSlicingThread ( ) ;
2014-04-10 10:36:59 -07:00
if ( RestartOnClose )
{
string appPathAndFile = System . Reflection . Assembly . GetExecutingAssembly ( ) . Location ;
string pathToAppFolder = Path . GetDirectoryName ( appPathAndFile ) ;
ProcessStartInfo runAppLauncherStartInfo = new ProcessStartInfo ( ) ;
runAppLauncherStartInfo . Arguments = "\"{0}\" \"{1}\"" . FormatWith ( appPathAndFile , 1000 ) ;
runAppLauncherStartInfo . FileName = Path . Combine ( pathToAppFolder , "Launcher.exe" ) ;
runAppLauncherStartInfo . WindowStyle = ProcessWindowStyle . Hidden ;
runAppLauncherStartInfo . CreateNoWindow = true ;
Process . Start ( runAppLauncherStartInfo ) ;
}
2014-01-29 19:09:30 -08:00
base . OnClosed ( e ) ;
}
public override void OnClosing ( out bool CancelClose )
{
//Save a snapshot of the prints in queue
2014-04-15 18:13:27 -07:00
QueueData . Instance . SaveDefaultQueue ( ) ;
2014-01-29 19:09:30 -08:00
if ( PrinterCommunication . Instance . PrinterIsPrinting )
{
2014-05-16 16:52:01 -07:00
StyledMessageBox . ShowMessageBox ( "Oops! You cannot exit while a print is active." , "Unable to Exit" ) ;
2014-01-29 19:09:30 -08:00
CancelClose = true ;
}
2014-02-27 14:56:20 -08:00
else if ( PartsSheet . IsSaving ( ) )
2014-01-29 19:09:30 -08:00
{
if ( ! StyledMessageBox . ShowMessageBox ( "You are currently saving a parts sheet, are you sure you want to exit?" , "Confirm Exit" , StyledMessageBox . MessageType . YES_NO ) )
{
CancelClose = true ;
}
else
{
base . OnClosing ( out CancelClose ) ;
}
}
else
{
base . OnClosing ( out CancelClose ) ;
}
}
}
}