Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
/ *
2018-10-20 22:32:03 -07:00
Copyright ( c ) 2018 , Lars Brubaker , John Lewin
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -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 .
* /
2020-07-03 12:05:28 -07:00
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Diagnostics ;
using System.IO ;
using System.IO.Compression ;
using System.Linq ;
using System.Net ;
using System.Net.Http ;
using System.Reflection ;
using System.Runtime.CompilerServices ;
using System.Text ;
using System.Text.RegularExpressions ;
using System.Threading ;
using System.Threading.Tasks ;
2019-10-22 18:00:55 -07:00
using global : : MatterControl . Printing ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.Agg ;
2019-10-22 18:00:55 -07:00
using MatterHackers.Agg.Font ;
using MatterHackers.Agg.Image ;
using MatterHackers.Agg.Platform ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.Agg.UI ;
2019-10-22 18:00:55 -07:00
using MatterHackers.Agg.VertexSource ;
using MatterHackers.DataConverters3D ;
using MatterHackers.DataConverters3D.UndoCommands ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.Localizations ;
2019-10-22 18:00:55 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.MatterControl.DataStorage ;
2019-10-22 18:00:55 -07:00
using MatterHackers.MatterControl.DesignTools ;
using MatterHackers.MatterControl.DesignTools.Operations ;
using MatterHackers.MatterControl.Extensibility ;
using MatterHackers.MatterControl.Library ;
using MatterHackers.MatterControl.PartPreviewWindow ;
using MatterHackers.MatterControl.PartPreviewWindow.View3D ;
using MatterHackers.MatterControl.Plugins ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2019-10-22 18:00:55 -07:00
using MatterHackers.MatterControl.PrinterControls.PrinterConnections ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.MatterControl.PrintQueue ;
2019-10-22 18:00:55 -07:00
using MatterHackers.MatterControl.SettingsManagement ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2019-10-22 18:00:55 -07:00
using MatterHackers.MatterControl.Tour ;
using MatterHackers.PolygonMesh ;
using MatterHackers.PolygonMesh.Processors ;
using MatterHackers.VectorMath ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using Newtonsoft.Json ;
2019-10-22 18:00:55 -07:00
using Newtonsoft.Json.Converters ;
using Newtonsoft.Json.Linq ;
2018-09-06 11:31:09 -07:00
[assembly: InternalsVisibleTo("MatterControl.Tests")]
[assembly: InternalsVisibleTo("MatterControl.AutomationTests")]
[assembly: InternalsVisibleTo("CloudServices.Tests")]
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
namespace MatterHackers.MatterControl
{
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
public enum NamedTypeFace
{
Alfa_Slab ,
Audiowide ,
Bangers ,
Courgette ,
Damion ,
2020-05-22 17:33:54 -07:00
Firefly_Sung ,
2018-05-15 13:56:05 -07:00
Fredoka ,
Great_Vibes ,
Liberation_Mono ,
Liberation_Sans ,
Liberation_Sans_Bold ,
Lobster ,
2020-05-21 08:38:26 -07:00
Nunito_Regular ,
Nunito_Bold ,
Nunito_Bold_Italic ,
Nunito_Italic ,
2018-05-15 13:56:05 -07:00
Pacifico ,
Poppins ,
Questrial ,
Righteous ,
Russo ,
Titan ,
Titillium ,
2019-12-06 10:18:38 -08:00
}
2018-05-15 13:56:05 -07:00
2017-06-24 10:30:11 -07:00
public class ApplicationController
{
2018-11-23 11:04:22 -08:00
public event EventHandler < string > ApplicationError ;
2018-05-16 12:06:32 -07:00
2018-11-30 12:35:56 -08:00
public event EventHandler < string > ApplicationEvent ;
2018-11-23 11:06:02 -08:00
public HelpArticle HelpArticles { get ; set ; }
2018-03-26 16:54:36 -07:00
2018-10-13 17:58:54 -07:00
public ThemeConfig Theme = > AppContext . Theme ;
2017-06-24 10:30:11 -07:00
2018-10-13 17:58:54 -07:00
public ThemeConfig MenuTheme = > AppContext . MenuTheme ;
2018-04-12 08:42:10 -07:00
2018-11-27 12:22:38 -08:00
public event EventHandler < string > ShellFileOpened ;
2020-07-03 12:05:28 -07:00
public event EventHandler AnyPrintStarted ;
2020-09-22 17:52:57 -07:00
2020-07-03 12:05:28 -07:00
public event EventHandler AnyPrintCanceled ;
2020-09-22 17:52:57 -07:00
2020-07-03 12:05:28 -07:00
public event EventHandler AnyPrintComplete ;
2020-05-13 09:07:22 -07:00
public bool IsMatterControlPro ( )
{
2020-05-15 20:58:41 -07:00
var result = ApplicationController . Instance . UserHasPermissionToId ? . Invoke ( "ag1zfm1oLWRmcy1wcm9kchgLEgtEaWdpdGFsSXRlbRiAgIDzyMGxCgw" ) ;
if ( result ! = null )
{
return result . Value ;
}
return false ;
2020-05-13 09:07:22 -07:00
}
2017-12-11 14:15:50 -08:00
public RunningTasksConfig Tasks { get ; set ; } = new RunningTasksConfig ( ) ;
2018-12-07 18:41:32 -08:00
public IEnumerable < PrinterConfig > ActivePrinters = > this . Workspaces . Where ( w = > w . Printer ! = null ) . Select ( w = > w . Printer ) ;
2018-11-23 11:06:02 -08:00
2019-02-04 08:41:08 -08:00
public ExtensionsConfig Extensions { get ; }
2017-09-17 14:23:28 -07:00
2020-09-22 17:52:57 -07:00
public PopupMenu GetActionMenuForSceneItem ( IObject3D selectedItem , InteractiveScene scene , bool addInSubmenu , View3DWidget view3DWidget )
2018-08-07 09:56:34 -07:00
{
2018-12-19 09:24:11 -08:00
var popupMenu = new PopupMenu ( this . MenuTheme ) ;
2018-09-14 15:20:19 -07:00
var selectedItemType = selectedItem . GetType ( ) ;
2018-12-19 09:24:11 -08:00
var menuTheme = this . MenuTheme ;
2018-08-07 09:56:34 -07:00
2019-01-07 10:11:12 -08:00
if ( ! selectedItemType . IsDefined ( typeof ( ImmutableAttribute ) , false ) )
2018-09-14 15:20:19 -07:00
{
2020-09-22 17:52:57 -07:00
AddActionMenuItems ( selectedItem , scene , addInSubmenu , this . Graph . Operations . Values , menuTheme , popupMenu , selectedItemType ) ;
2018-09-14 15:20:19 -07:00
}
2018-08-07 09:56:34 -07:00
2019-06-12 11:48:45 -07:00
var workspaceActions = GetWorkspaceActions ( view3DWidget ) ;
var sceneContext = view3DWidget . sceneContext ;
var printer = view3DWidget . Printer ;
var actions = new [ ]
{
new ActionSeparator ( ) ,
2020-05-29 19:08:41 -07:00
workspaceActions [ "Edit" ] ,
2019-06-12 11:48:45 -07:00
new ActionSeparator ( ) ,
new NamedAction ( )
{
Title = "Save As" . Localize ( ) ,
Action = ( ) = > UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show (
new SaveAsPage (
async ( newName , destinationContainer ) = >
{
// Save to the destination provider
if ( destinationContainer is ILibraryWritableContainer writableContainer )
{
// Wrap stream with ReadOnlyStream library item and add to container
writableContainer . Add ( new [ ]
{
new InMemoryLibraryItem ( selectedItem )
{
Name = newName
}
} ) ;
destinationContainer . Dispose ( ) ;
}
} ) ) ;
} ) ,
IsEnabled = ( ) = > sceneContext . EditableScene
} ,
new NamedAction ( )
{
ID = "Export" ,
Title = "Export" . Localize ( ) ,
2019-06-20 14:51:27 -07:00
Icon = AggContext . StaticData . LoadIcon ( "cube_export.png" , 16 , 16 , menuTheme . InvertIcons ) ,
2019-06-12 11:48:45 -07:00
Action = ( ) = >
{
ApplicationController . Instance . ExportLibraryItems (
new [ ] { new InMemoryLibraryItem ( selectedItem ) } ,
centerOnBed : false ,
printer : printer ) ;
}
} ,
new ActionSeparator ( ) ,
workspaceActions [ "Delete" ]
} ;
2019-06-12 11:56:38 -07:00
menuTheme . CreateMenuItems ( popupMenu , actions ) ;
2019-06-12 11:48:45 -07:00
2019-06-12 11:08:14 -07:00
if ( selectedItem is ComponentObject3D componentObject )
{
popupMenu . CreateSeparator ( ) ;
string componentID = componentObject . ComponentID ;
var helpItem = popupMenu . CreateMenuItem ( "Help" . Localize ( ) ) ;
2019-06-18 17:28:35 -07:00
helpItem . Enabled = ! string . IsNullOrEmpty ( componentID ) & & this . HelpArticlesByID . ContainsKey ( componentID ) ;
2019-06-12 11:08:14 -07:00
helpItem . Click + = ( s , e ) = >
{
2019-06-18 17:28:35 -07:00
var helpTab = ApplicationController . Instance . ActivateHelpTab ( ) ;
if ( helpTab . TabContent is HelpTreePanel helpTreePanel )
{
if ( this . HelpArticlesByID . TryGetValue ( componentID , out HelpArticle helpArticle ) )
{
helpTreePanel . ActiveNodePath = componentID ;
}
}
2019-06-12 11:08:14 -07:00
} ;
}
2018-08-07 09:56:34 -07:00
return popupMenu ;
}
2019-06-20 14:51:27 -07:00
public PopupMenu GetModifyMenu ( IObject3D selectedItem , InteractiveScene scene , IEnumerable < NodeOperation > nodeOperations = null )
{
var popupMenu = new PopupMenu ( this . MenuTheme ) ;
2020-09-22 17:52:57 -07:00
AddActionMenuItems (
2019-06-20 14:51:27 -07:00
selectedItem ,
scene ,
false ,
nodeOperations ,
this . MenuTheme ,
popupMenu ,
selectedItem . GetType ( ) ) ;
return popupMenu ;
}
2020-09-22 17:52:57 -07:00
private static void AddActionMenuItems ( IObject3D selectedItem , InteractiveScene scene , bool useSubMenu , IEnumerable < NodeOperation > nodeOperations , ThemeConfig menuTheme , PopupMenu popupMenu , Type selectedItemType )
2019-06-20 14:51:27 -07:00
{
void AddItems ( PopupMenu menu )
{
foreach ( var nodeOperation in nodeOperations )
{
foreach ( var type in nodeOperation . MappedTypes )
{
if ( type . IsAssignableFrom ( selectedItemType )
& & ( nodeOperation . IsVisible ? . Invoke ( selectedItem ) ! = false )
& & nodeOperation . IsEnabled ? . Invoke ( selectedItem ) ! = false )
{
var menuItem = menu . CreateMenuItem ( nodeOperation . Title , nodeOperation . IconCollector ? . Invoke ( menuTheme . InvertIcons ) ) ;
menuItem . Click + = ( s , e ) = >
{
nodeOperation . Operation ( selectedItem , scene ) . ConfigureAwait ( false ) ;
} ;
}
}
}
}
var renameMenuItem = popupMenu . CreateMenuItem ( "Rename" . Localize ( ) ) ;
renameMenuItem . Click + = ( s , e ) = >
{
DialogWindow . Show (
new InputBoxPage (
"Rename Item" . Localize ( ) ,
"Name" . Localize ( ) ,
selectedItem . Name ,
"Enter New Name Here" . Localize ( ) ,
"Rename" . Localize ( ) ,
( newName ) = >
{
// TODO: add undo data to this operation
selectedItem . Name = newName ;
} ) ) ;
} ;
popupMenu . CreateSeparator ( ) ;
if ( useSubMenu )
{
2020-05-15 16:58:12 -07:00
// Create items in a 'Modify' sub-menu
2020-09-22 17:52:57 -07:00
popupMenu . CreateSubMenu ( "Actions" . Localize ( ) , menuTheme , ( modifyMenu ) = > AddItems ( modifyMenu ) ) ;
2019-06-20 14:51:27 -07:00
}
else
{
// Create items directly in the referenced menu
AddItems ( popupMenu ) ;
}
}
2018-12-26 15:51:00 -08:00
public async Task PersistUserTabs ( )
2018-12-10 17:45:33 -08:00
{
2018-12-26 15:51:00 -08:00
// Persist all pending changes in all workspaces to disk
2020-01-09 07:59:38 -08:00
foreach ( var workspace in this . Workspaces . ToArray ( ) )
2018-12-26 15:51:00 -08:00
{
2019-04-24 11:40:25 -07:00
await this . Tasks . Execute ( "Saving " . Localize ( ) + $" \" { workspace . Name } \ " ..." , workspace , workspace . SceneContext . SaveChanges ) ;
2018-12-26 15:51:00 -08:00
}
// Project workspace definitions to serializable structure
2018-12-19 09:24:11 -08:00
var workspaces = this . Workspaces . Select ( w = >
2018-12-10 17:45:33 -08:00
{
if ( w . Printer = = null )
{
return new PartWorkspace ( w . SceneContext )
{
ContentPath = w . SceneContext . EditContext ? . SourceFilePath ,
} ;
}
else
{
return new PartWorkspace ( w . Printer )
{
ContentPath = w . SceneContext . EditContext ? . SourceFilePath ,
} ;
}
} ) ;
2018-12-26 15:51:00 -08:00
// Persist workspace definitions to disk
2018-12-10 17:45:33 -08:00
File . WriteAllText (
ProfileManager . Instance . OpenTabsPath ,
JsonConvert . SerializeObject (
workspaces ,
Formatting . Indented ,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling . Ignore
} ) ) ;
}
2018-11-24 16:15:54 -08:00
internal void ExportAsMatterControlConfig ( PrinterConfig printer )
{
AggContext . FileDialogs . SaveFileDialog (
new SaveFileDialogParams ( "MatterControl Printer Export|*.printer" , title : "Export Printer Settings" )
{
FileName = printer . Settings . GetValue ( SettingsKey . printer_name )
} ,
( saveParams ) = >
{
try
{
if ( ! string . IsNullOrWhiteSpace ( saveParams . FileName ) )
{
File . WriteAllText ( saveParams . FileName , JsonConvert . SerializeObject ( printer . Settings , Formatting . Indented ) ) ;
}
}
catch ( Exception e )
{
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox ( e . Message , "Couldn't save file" . Localize ( ) ) ;
} ) ;
}
} ) ;
}
2018-11-23 11:04:22 -08:00
public void LogError ( string errorMessage )
{
this . ApplicationError ? . Invoke ( this , errorMessage ) ;
}
2018-11-30 12:35:56 -08:00
public void LogInfo ( string message )
{
this . ApplicationEvent ? . Invoke ( this , message ) ;
}
2020-05-15 16:58:12 -07:00
public Action RedeemDesignCode { get ; set ; }
2019-05-23 08:05:51 -07:00
2020-05-15 16:58:12 -07:00
public Action EnterShareCode { get ; set ; }
2019-05-23 08:05:51 -07:00
2020-06-26 14:17:08 -07:00
// check permission to an IObject3D instance
2020-06-26 14:11:30 -07:00
public Func < IObject3D , bool > UserHasPermission { get ; set ; } = ( item ) = > false ;
2019-05-23 08:05:51 -07:00
2020-05-13 09:07:22 -07:00
// check permission to a purchase
public Func < string , bool > UserHasPermissionToId { get ; set ; }
2020-05-21 15:11:03 -07:00
public Func < IObject3D , ThemeConfig , ( string url , GuiWidget markdownWidget ) > GetUnlockData { get ; set ; }
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
private static ApplicationController globalInstance ;
2018-10-05 09:34:43 -07:00
2020-05-15 16:58:12 -07:00
public RootedObjectEventHandler CloudSyncStatusChanged { get ; private set ; } = new RootedObjectEventHandler ( ) ;
2020-09-22 17:52:57 -07:00
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public RootedObjectEventHandler DoneReloadingAll = new RootedObjectEventHandler ( ) ;
2018-10-05 09:34:43 -07:00
public RootedObjectEventHandler ActiveProfileModified = new RootedObjectEventHandler ( ) ;
2018-11-11 21:25:50 -08:00
2018-12-07 18:41:32 -08:00
public event EventHandler < WorkspacesChangedEventArgs > WorkspacesChanged ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public static Action WebRequestFailed ;
public static Action WebRequestSucceeded ;
2018-10-14 11:03:58 -07:00
public static Action < DialogWindow > ChangeToPrintNotification = null ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
#if DEBUG
public const string EnvironmentName = "TestEnv_" ;
#else
public const string EnvironmentName = "" ;
#endif
2017-12-16 19:09:25 -08:00
public bool ApplicationExiting { get ; internal set ; } = false ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public static Func < string , Task < Dictionary < string , string > > > GetProfileHistory ;
2018-12-07 18:41:32 -08:00
public void OnWorkspacesChanged ( WorkspacesChangedEventArgs e )
2018-10-05 09:44:28 -07:00
{
2018-12-07 18:41:32 -08:00
this . WorkspacesChanged ? . Invoke ( this , e ) ;
2019-04-24 13:23:52 -07:00
if ( e . Operation ! = WorkspacesChangedEventArgs . OperationType . Restore )
{
2020-05-29 19:08:41 -07:00
UiThread . RunOnIdle ( async ( ) = >
2019-04-24 13:23:52 -07:00
{
await ApplicationController . Instance . PersistUserTabs ( ) ;
} ) ;
}
2018-10-05 09:44:28 -07:00
}
2018-04-18 12:56:12 -07:00
public string GetFavIconUrl ( string oemName )
{
2019-05-11 14:46:28 -07:00
if ( OemSettings . Instance . OemUrls . TryGetValue ( oemName , out string oemUrl )
& & ! string . IsNullOrWhiteSpace ( oemUrl ) )
{
return "https://www.google.com/s2/favicons?domain=" + oemUrl ;
}
return null ;
2018-04-18 12:56:12 -07:00
}
2018-11-11 21:25:50 -08:00
public void ClosePrinter ( PrinterConfig printer , bool allowChangedEvent = true )
2017-09-23 14:44:43 -07:00
{
2018-10-16 17:10:36 -07:00
// Actually clear printer
2018-11-21 09:48:43 -08:00
ProfileManager . Instance . ClosePrinter ( printer . Settings . ID ) ;
2018-10-16 17:10:36 -07:00
2018-12-26 16:42:48 -08:00
// Shutdown the printer connection
printer . Connection . Disable ( ) ;
2018-11-11 21:25:50 -08:00
if ( allowChangedEvent )
{
2018-12-19 09:22:03 -08:00
if ( this . Workspaces . FirstOrDefault ( w = > w . Printer ? . Settings . ID = = printer . Settings . ID ) is PartWorkspace workspace )
2018-12-07 18:41:32 -08:00
{
2018-12-19 09:22:03 -08:00
this . Workspaces . Remove ( workspace ) ;
2018-12-07 18:41:32 -08:00
this . OnWorkspacesChanged (
new WorkspacesChangedEventArgs (
workspace ,
WorkspacesChangedEventArgs . OperationType . Remove ) ) ;
}
2018-11-11 21:25:50 -08:00
}
2018-11-13 16:51:48 -08:00
printer . Dispose ( ) ;
2017-09-23 14:44:43 -07:00
}
2018-04-18 12:56:12 -07:00
2020-09-22 17:52:57 -07:00
public static void LaunchBrowser ( string targetUri )
2017-12-16 08:55:20 -08:00
{
UiThread . RunOnIdle ( ( ) = >
{
2018-04-05 13:55:23 -07:00
if ( ! string . IsNullOrEmpty ( OemSettings . Instance . AffiliateCode )
2018-03-16 15:43:32 -07:00
& & targetUri . Contains ( "matterhackers.com" ) )
{
2019-04-12 15:02:34 -07:00
string internalLink = "" ;
// if we have a trailing internal link
if ( targetUri . Contains ( "#" ) )
{
internalLink = targetUri . Substring ( targetUri . IndexOf ( "#" ) ) ;
targetUri = targetUri . Substring ( 0 , targetUri . Length - internalLink . Length ) ;
}
2018-04-05 13:55:23 -07:00
if ( targetUri . Contains ( "?" ) )
2018-03-16 15:43:32 -07:00
{
targetUri + = $"&aff={OemSettings.Instance.AffiliateCode}" ;
}
else
{
targetUri + = $"?aff={OemSettings.Instance.AffiliateCode}" ;
}
2019-12-06 10:18:38 -08:00
2019-04-12 15:02:34 -07:00
targetUri + = internalLink ;
2018-03-16 15:43:32 -07:00
}
2019-04-12 15:02:34 -07:00
2017-12-16 08:55:20 -08:00
Process . Start ( targetUri ) ;
} ) ;
}
2017-09-23 14:44:43 -07:00
2018-09-29 15:47:23 -07:00
internal void MakeGrayscale ( ImageBuffer sourceImage )
{
var buffer = sourceImage . GetBuffer ( ) ;
int destIndex = 0 ;
for ( int y = 0 ; y < sourceImage . Height ; y + + )
{
for ( int x = 0 ; x < sourceImage . Width ; x + + )
{
int b = buffer [ destIndex + 0 ] ;
int g = buffer [ destIndex + 1 ] ;
int r = buffer [ destIndex + 2 ] ;
int c = ( r * 77 ) + ( g * 151 ) + ( b * 28 ) ;
byte gray = ( byte ) ( c > > 8 ) ;
buffer [ destIndex + 0 ] = gray ;
buffer [ destIndex + 1 ] = gray ;
buffer [ destIndex + 2 ] = gray ;
destIndex + = 4 ;
}
}
}
2018-10-07 11:36:52 -07:00
// Plugin Registration Points
// Returns the user printer profile from the webservices plugin
2018-04-05 13:55:23 -07:00
public static Func < PrinterInfo , string , Task < PrinterSettings > > GetPrinterProfileAsync ;
2018-10-07 11:36:52 -07:00
// Executes the user printer profile sync logic in the webservices plugin
2019-04-17 07:33:14 -07:00
public static Func < string , IProgress < ProgressStatus > , Task > SyncCloudProfiles ;
public static Action < string > QueueCloudProfileSync ;
2018-10-07 11:36:52 -07:00
// Returns all public printer profiles from the webservices plugin
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public static Func < Task < OemProfileDictionary > > GetPublicProfileList ;
2018-10-07 11:36:52 -07:00
// Returns the public printer profile from the webservices plugin
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public static Func < string , Task < PrinterSettings > > DownloadPublicProfileAsync ;
2018-10-07 11:36:52 -07:00
// Indicates if guest, rather than an authenticated user, is active
public static Func < bool > GuestUserActive { get ; set ; }
// Returns the authentication dialog from the authentication plugin
2018-10-16 16:00:06 -07:00
public static Func < AuthenticationContext , DialogPage > GetAuthPage ;
2018-10-07 11:36:52 -07:00
2018-06-17 12:22:33 -07:00
public SlicePresetsPage EditMaterialPresetsPage { get ; set ; }
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-06-17 12:22:33 -07:00
public SlicePresetsPage EditQualityPresetsWindow { get ; set ; }
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-10-30 14:02:50 -07:00
public MainViewWidget MainView ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2019-05-10 20:44:33 -07:00
private readonly Dictionary < string , List < LibraryAction > > registeredLibraryActions = new Dictionary < string , List < LibraryAction > > ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-07-12 09:22:28 -07:00
public ThumbnailsConfig Thumbnails { get ; }
2018-06-21 09:02:31 -07:00
2019-06-12 11:48:45 -07:00
public Dictionary < string , NamedAction > GetWorkspaceActions ( View3DWidget view3DWidget )
{
var sceneContext = view3DWidget . sceneContext ;
var printer = sceneContext . Printer ;
bool invertIcons = ApplicationController . Instance . MenuTheme . InvertIcons ;
// Build workspace actions, each having a unique ID
var actions = new [ ]
{
new NamedAction ( )
{
ID = "Print" ,
Title = "Print" . Localize ( ) ,
Shortcut = "Ctrl+P" ,
Action = view3DWidget . PushToPrinterAndPrint ,
IsEnabled = ( ) = > sceneContext . EditableScene
| | ( sceneContext . EditContext . SourceItem is ILibraryAsset libraryAsset
& & string . Equals ( Path . GetExtension ( libraryAsset . FileName ) , ".gcode" , StringComparison . OrdinalIgnoreCase ) )
} ,
2020-05-29 19:08:41 -07:00
new NamedActionGroup ( )
2019-06-12 11:48:45 -07:00
{
2020-05-29 19:08:41 -07:00
ID = "Edit" ,
Title = "Edit" ,
Group = new NamedAction [ ]
2019-06-12 11:48:45 -07:00
{
2020-05-29 19:08:41 -07:00
new NamedAction ( )
{
ID = "Cut" ,
Title = "Cut" . Localize ( ) ,
Action = ( ) = > sceneContext . Scene . Cut ( ) ,
IsEnabled = ( ) = > sceneContext . Scene . SelectedItem ! = null
} ,
new NamedAction ( )
{
ID = "Copy" ,
Title = "Copy" . Localize ( ) ,
Action = ( ) = > sceneContext . Scene . Copy ( ) ,
IsEnabled = ( ) = > sceneContext . Scene . SelectedItem ! = null
} ,
new NamedAction ( )
{
ID = "Paste" ,
Title = "Paste" . Localize ( ) ,
Action = ( ) = > sceneContext . Paste ( ) ,
IsEnabled = ( ) = > Clipboard . Instance . ContainsImage | | Clipboard . Instance . GetText ( ) = = "!--IObjectSelection--!"
}
2019-06-12 11:48:45 -07:00
} ,
2020-05-29 19:08:41 -07:00
IsEnabled = ( ) = > true ,
2019-06-12 11:48:45 -07:00
} ,
new NamedAction ( )
{
ID = "Delete" ,
2020-08-04 08:15:20 -07:00
Icon = AggContext . StaticData . LoadIcon ( "remove.png" , 16 , 16 ) . SetPreMultiply ( ) ,
2019-06-12 11:48:45 -07:00
Title = "Remove" . Localize ( ) ,
Action = sceneContext . Scene . DeleteSelection ,
IsEnabled = ( ) = > sceneContext . Scene . SelectedItem ! = null
} ,
new NamedAction ( )
{
ID = "Export" ,
Title = "Export" . Localize ( ) ,
Icon = AggContext . StaticData . LoadIcon ( "cube_export.png" , 16 , 16 , invertIcons ) ,
Action = ( ) = >
{
ApplicationController . Instance . ExportLibraryItems (
new [ ] { new InMemoryLibraryItem ( sceneContext . Scene ) } ,
centerOnBed : false ,
printer : printer ) ;
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
| | ( sceneContext . EditContext . SourceItem is ILibraryAsset libraryAsset
& & string . Equals ( Path . GetExtension ( libraryAsset . FileName ) , ".gcode" , StringComparison . OrdinalIgnoreCase ) )
} ,
new NamedAction ( )
{
ID = "Save" ,
Title = "Save" . Localize ( ) ,
Shortcut = "Ctrl+S" ,
Action = ( ) = >
{
ApplicationController . Instance . Tasks . Execute ( "Saving" . Localize ( ) , printer , sceneContext . SaveChanges ) . ConfigureAwait ( false ) ;
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
} ,
new NamedAction ( )
{
ID = "SaveAs" ,
Title = "Save As" . Localize ( ) ,
Action = ( ) = > UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show (
new SaveAsPage (
async ( newName , destinationContainer ) = >
{
// Save to the destination provider
if ( destinationContainer is ILibraryWritableContainer writableContainer )
{
// Wrap stream with ReadOnlyStream library item and add to container
writableContainer . Add ( new [ ]
{
new InMemoryLibraryItem ( sceneContext . Scene )
{
Name = newName
}
} ) ;
destinationContainer . Dispose ( ) ;
}
} ) ) ;
} ) ,
IsEnabled = ( ) = > sceneContext . EditableScene
} ,
new NamedAction ( )
{
ID = "ArrangeAll" ,
Title = "Arrange All Parts" . Localize ( ) ,
Action = async ( ) = >
{
await sceneContext . Scene . AutoArrangeChildren ( view3DWidget . BedCenter ) . ConfigureAwait ( false ) ;
} ,
2020-09-23 07:40:11 -07:00
IsEnabled = ( ) = > sceneContext . EditableScene ,
Icon = AggContext . StaticData . LoadIcon ( "arrange_all.png" , 16 , 16 , invertIcons ) ,
2019-06-12 11:48:45 -07:00
} ,
new NamedAction ( )
{
ID = "ClearBed" ,
Title = "Clear Bed" . Localize ( ) ,
Action = ( ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
view3DWidget . ClearPlate ( ) ;
} ) ;
}
}
} ;
// Construct dictionary from workspace actions by ID
return actions . ToDictionary ( a = > a . ID ) ;
}
2018-11-01 17:00:27 -07:00
public void OpenIntoNewTab ( IEnumerable < ILibraryItem > selectedLibraryItems )
{
this . MainView . CreatePartTab ( ) . ContinueWith ( task = >
{
var workspace = this . Workspaces . Last ( ) ;
workspace . SceneContext . AddToPlate ( selectedLibraryItems ) ;
} ) ;
}
2018-10-22 14:15:29 -07:00
internal void BlinkTab ( ITab tab )
{
var theme = this . Theme ;
if ( tab is GuiWidget guiWidget )
{
2018-11-03 09:13:07 -07:00
guiWidget . Descendants < TextWidget > ( ) . FirstOrDefault ( ) . FlashBackground ( theme . PrimaryAccentColor . WithContrast ( theme . TextColor , 6 ) . ToColor ( ) ) ;
2018-10-22 14:15:29 -07:00
}
}
2018-09-27 16:59:42 -07:00
public void ShowApplicationHelp ( )
{
2019-06-18 17:28:35 -07:00
this . ActivateHelpTab ( ) ;
2018-09-27 16:59:42 -07:00
}
public void ShowAboutPage ( )
{
UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show < AboutPage > ( ) ;
} ) ;
}
2018-05-04 14:50:38 -07:00
public ImageSequence GetProcessingSequence ( Color color )
{
int size = ( int ) Math . Round ( 80 * GuiWidget . DeviceScale ) ;
var workingAnimation = new ImageSequence ( ) ;
var frameCount = 30.0 ;
var strokeWidth = 4 * GuiWidget . DeviceScale ;
2018-07-13 16:13:53 -07:00
2018-05-15 13:56:05 -07:00
for ( int i = 0 ; i < frameCount ; i + + )
2018-05-04 14:50:38 -07:00
{
var frame = new ImageBuffer ( size , size ) ;
var graphics = frame . NewGraphics2D ( ) ;
2020-06-28 11:39:41 -07:00
graphics . Render ( new Stroke ( new Arc ( frame . Width / 2 ,
frame . Height / 2 ,
size / 4 - strokeWidth / 2 ,
size / 4 - strokeWidth / 2 ,
2018-05-04 14:50:38 -07:00
MathHelper . Tau / frameCount * i ,
2020-06-28 11:39:41 -07:00
MathHelper . Tau / 4 + MathHelper . Tau / frameCount * i ) ,
strokeWidth ) ,
color ) ;
2018-05-04 14:50:38 -07:00
workingAnimation . AddImage ( frame ) ;
}
return workingAnimation ;
}
2020-05-15 16:58:12 -07:00
private static int applicationInstanceCount = 0 ;
2019-06-13 08:16:50 -07:00
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public static int ApplicationInstanceCount
{
get
{
if ( applicationInstanceCount = = 0 )
{
2020-09-22 17:52:57 -07:00
var mcAssembly = Assembly . GetEntryAssembly ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
if ( mcAssembly ! = null )
{
string applicationName = Path . GetFileNameWithoutExtension ( mcAssembly . Location ) . ToUpper ( ) ;
Process [ ] p1 = Process . GetProcesses ( ) ;
foreach ( System . Diagnostics . Process pro in p1 )
{
try
{
if ( pro ? . ProcessName ! = null
& & pro . ProcessName . ToUpper ( ) . Contains ( applicationName ) )
{
applicationInstanceCount + + ;
}
}
catch
{
}
}
}
}
return applicationInstanceCount ;
}
}
public LibraryConfig Library { get ; }
2018-12-12 18:13:22 -08:00
public ILibraryContext LibraryTabContext { get ; private set ; }
2018-01-30 11:50:22 -08:00
public GraphConfig Graph { get ; }
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
private void InitializeLibrary ( )
{
if ( Directory . Exists ( ApplicationDataStorage . Instance . DownloadsDirectory ) )
{
2018-01-15 12:38:43 -08:00
this . Library . RegisterContainer (
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
new DynamicContainerLink (
2017-12-04 14:08:54 -08:00
( ) = > "Downloads" . Localize ( ) ,
2020-08-30 09:43:22 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "folder.png" ) ) ,
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "download_icon.png" ) ) ,
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
( ) = > new FileSystemContainer ( ApplicationDataStorage . Instance . DownloadsDirectory )
{
2019-06-19 12:02:46 -07:00
UseIncrementedNameDuringTypeChange = true ,
DefaultSort = new SortBehavior ( )
{
SortKey = SortKey . ModifiedDate ,
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
} ) ) ;
}
2018-05-03 23:32:17 -07:00
this . Library . LibraryCollectionContainer = new LibraryCollectionContainer ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-01-15 12:38:43 -08:00
this . Library . RegisterContainer (
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
new DynamicContainerLink (
2018-05-03 23:32:17 -07:00
( ) = > "Library" . Localize ( ) ,
2020-08-30 09:43:22 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "folder.png" ) ) ,
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "library_icon.png" ) ) ,
2018-05-03 23:32:17 -07:00
( ) = > this . Library . LibraryCollectionContainer ) ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
if ( File . Exists ( ApplicationDataStorage . Instance . CustomLibraryFoldersPath ) )
{
// Add each path defined in the CustomLibraryFolders file as a new FileSystemContainerItem
foreach ( string directory in File . ReadLines ( ApplicationDataStorage . Instance . CustomLibraryFoldersPath ) )
{
2020-05-15 16:58:12 -07:00
// if (Directory.Exists(directory))
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-01-15 12:38:43 -08:00
this . Library . RegisterContainer (
2017-06-03 15:11:12 -07:00
new FileSystemContainer . DirectoryContainerLink ( directory )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
UseIncrementedNameDuringTypeChange = true
} ) ;
}
}
}
2017-11-14 14:15:34 -08:00
this . Library . PlatingHistory = new PlatingHistoryContainer ( ) ;
2018-01-15 12:38:43 -08:00
this . Library . RegisterContainer (
2017-11-14 14:15:34 -08:00
new DynamicContainerLink (
2018-04-29 11:08:09 -07:00
( ) = > "History" . Localize ( ) ,
2020-08-30 09:43:22 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "folder.png" ) ) ,
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "history_icon.png" ) ) ,
2018-04-29 11:08:09 -07:00
( ) = > new RootHistoryContainer ( ) ) ) ;
2018-12-12 18:13:22 -08:00
// Create a new library context for the SaveAs view
this . LibraryTabContext = new LibraryConfig ( )
{
ActiveContainer = new WrappedLibraryContainer ( this . Library . RootLibaryContainer )
{
ExtraContainers = new List < ILibraryContainerLink > ( )
{
new DynamicContainerLink (
( ) = > "Printers" . Localize ( ) ,
2020-08-30 09:43:22 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "folder.png" ) ) ,
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "printer_icon.png" ) ) ,
2018-12-12 18:13:22 -08:00
( ) = > new OpenPrintersContainer ( ) )
}
}
} ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2018-11-12 09:32:08 -08:00
public void ExportLibraryItems ( IEnumerable < ILibraryItem > libraryItems , bool centerOnBed = true , PrinterConfig printer = null )
{
UiThread . RunOnIdle ( ( ) = >
{
2018-12-07 18:41:32 -08:00
if ( printer ! = null | | this . ActivePrinters . Count ( ) = = 1 )
2018-11-12 09:32:08 -08:00
{
// If unspecified but count is one, select the one active printer
if ( printer = = null )
{
printer = this . ActivePrinters . First ( ) ;
}
DialogWindow . Show (
new ExportPrintItemPage ( libraryItems , centerOnBed , printer ) ) ;
}
else
{
2018-12-05 17:48:32 -08:00
// If there are no printers setup show the export dialog but have the gcode option disabled
2020-08-02 15:19:16 -07:00
if ( ProfileManager . Instance . ActiveProfiles . Count ( ) = = 0
| | ProfileManager . Instance . ActiveProfiles . Count ( ) > 1 )
2018-12-05 17:48:32 -08:00
{
DialogWindow . Show ( new ExportPrintItemPage ( libraryItems , centerOnBed , null ) ) ;
}
2020-08-02 15:19:16 -07:00
else // If there is only one printer constructed, use it.
2018-12-05 17:48:32 -08:00
{
2018-12-19 09:24:11 -08:00
var historyContainer = this . Library . PlatingHistory ;
2018-12-05 17:48:32 -08:00
var printerInfo = ProfileManager . Instance . ActiveProfiles . First ( ) ;
ProfileManager . LoadSettingsAsync ( printerInfo . ID ) . ContinueWith ( task = >
{
var settings = task . Result ;
var onlyPrinter = new PrinterConfig ( settings ) ;
onlyPrinter . Bed . LoadEmptyContent (
new EditContext ( )
{
ContentStore = historyContainer ,
SourceItem = historyContainer . NewPlatingItem ( )
} ) ;
2018-11-12 09:32:08 -08:00
2018-12-05 17:48:32 -08:00
UiThread . RunOnIdle ( ( ) = >
2018-11-12 09:32:08 -08:00
{
2018-12-05 17:48:32 -08:00
DialogWindow . Show ( new ExportPrintItemPage ( libraryItems , centerOnBed , onlyPrinter ) ) ;
} ) ;
} ) ;
}
2018-11-12 09:32:08 -08:00
}
} ) ;
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public ApplicationController ( )
{
2018-10-26 09:29:22 -07:00
this . Thumbnails = new ThumbnailsConfig ( ) ;
2018-10-13 17:58:54 -07:00
2018-11-21 10:58:52 -08:00
ProfileManager . UserChanged + = ( s , e ) = >
{
2020-05-15 16:58:12 -07:00
// _activePrinters = new List<PrinterConfig>();
2018-11-21 10:58:52 -08:00
} ;
2019-02-04 08:41:08 -08:00
this . Extensions = new ExtensionsConfig ( this . Library ) ;
this . Extensions . Register ( new ImageEditor ( ) ) ;
this . Extensions . Register ( new PublicPropertyEditor ( ) ) ;
2018-06-30 23:26:57 -07:00
HelpArticle helpArticle = null ;
2018-06-22 17:01:20 -07:00
2018-06-30 23:26:57 -07:00
string helpPath = Path . Combine ( "OEMSettings" , "toc.json" ) ;
if ( AggContext . StaticData . FileExists ( helpPath ) )
2018-06-22 17:01:20 -07:00
{
try
{
2018-06-30 23:26:57 -07:00
helpArticle = JsonConvert . DeserializeObject < HelpArticle > ( AggContext . StaticData . ReadAllText ( helpPath ) ) ;
2018-06-22 17:01:20 -07:00
}
catch { }
}
2018-06-30 23:26:57 -07:00
this . HelpArticles = helpArticle ? ? new HelpArticle ( ) ;
2018-06-22 17:01:20 -07:00
2018-02-06 22:27:46 -08:00
Object3D . AssetsPath = Path . Combine ( ApplicationDataStorage . Instance . ApplicationLibraryDataPath , "Assets" ) ;
2018-08-13 18:39:09 -07:00
using ( var meshSteam = AggContext . StaticData . OpenStream ( Path . Combine ( "Stls" , "missing.stl" ) ) )
{
Object3D . FileMissingMesh = StlProcessing . Load ( meshSteam , CancellationToken . None ) ;
}
2017-11-10 23:03:48 -08:00
ScrollBar . DefaultMargin = new BorderDouble ( right : 1 ) ;
ScrollBar . ScrollBarWidth = 8 * GuiWidget . DeviceScale ;
ScrollBar . GrowThumbBy = 2 ;
2017-12-16 13:56:59 -08:00
// Initialize statics
2020-08-17 07:12:49 -07:00
ScrollBar . DefaultThumbBackground . DefaultBackgroundColor = Color . Transparent ;
2017-07-12 14:47:01 -07:00
Object3D . AssetsPath = ApplicationDataStorage . Instance . LibraryAssetsPath ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
this . Library = new LibraryConfig ( ) ;
2018-07-10 15:34:08 -07:00
this . Graph = new GraphConfig ( this ) ;
2017-11-03 13:43:31 -07:00
this . Library . ContentProviders . Add ( new [ ] { "stl" , "obj" , "amf" , "mcx" } , new MeshContentProvider ( ) ) ;
2017-06-21 07:41:12 -07:00
this . Library . ContentProviders . Add ( "gcode" , new GCodeContentProvider ( ) ) ;
2018-06-06 15:46:30 -07:00
this . Library . ContentProviders . Add ( new [ ] { "png" , "gif" , "jpg" , "jpeg" } , new ImageContentProvider ( ) ) ;
2019-01-22 19:52:19 -08:00
this . Library . ContentProviders . Add ( new [ ] { "scad" } , new OpenScadContentProvider ( ) ) ;
2018-06-06 15:46:30 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-06-06 15:46:30 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "ImageToPath" ,
2019-01-14 17:23:45 -08:00
Title = "Image to Path" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( ImageObject3D ) } ,
ResultType = typeof ( ImageToPathObject3D ) ,
Operation = ( sceneItem , scene ) = >
2018-06-06 15:46:30 -07:00
{
2019-01-14 17:20:12 -08:00
if ( sceneItem is IObject3D imageObject )
{
2019-01-24 18:47:50 -08:00
// TODO: make it look like this (and get rid of all the other stuff)
2020-05-15 16:58:12 -07:00
// scene.Replace(sceneItem, new ImageToPathObject3D(sceneItem.Clone()));
2019-01-24 18:47:50 -08:00
2019-01-14 17:20:12 -08:00
var path = new ImageToPathObject3D ( ) ;
2019-01-24 10:32:22 -08:00
var itemClone = sceneItem . Clone ( ) ;
path . Children . Add ( itemClone ) ;
path . Matrix = itemClone . Matrix ;
itemClone . Matrix = Matrix4X4 . Identity ;
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new [ ] { sceneItem } , new [ ] { path } ) ) ;
2019-01-24 18:03:43 -08:00
scene . SelectedItem = null ;
scene . SelectedItem = path ;
2019-01-28 17:44:00 -08:00
path . Invalidate ( InvalidateType . Properties ) ;
2019-01-14 17:20:12 -08:00
}
2018-06-06 15:46:30 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2020-08-04 08:15:20 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "noun_479927.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2018-06-06 15:46:30 -07:00
2018-07-06 07:10:39 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-07-06 07:10:39 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "Translate" ,
2019-01-14 17:23:45 -08:00
Title = "Translate" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IObject3D ) } ,
ResultType = typeof ( TranslateObject3D ) ,
Operation = ( sceneItem , scene ) = >
{
2019-01-31 15:41:49 -08:00
var items = scene . GetSelectedItems ( ) ;
2019-01-28 07:40:52 -08:00
using ( new SelectionMaintainer ( scene ) )
{
2019-01-31 15:41:49 -08:00
var translate = new TranslateObject3D ( ) ;
translate . WrapItems ( items , scene . UndoBuffer ) ;
2019-01-28 07:40:52 -08:00
}
2018-07-06 07:10:39 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( Path . Combine ( "ViewTransformControls" , "translate.png" ) , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2018-07-06 07:10:39 -07:00
2018-06-26 15:54:05 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-06-26 15:54:05 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "Rotate" ,
2019-01-14 17:23:45 -08:00
Title = "Rotate" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IObject3D ) } ,
ResultType = typeof ( RotateObject3D_2 ) ,
Operation = ( sceneItem , scene ) = >
{
2019-01-31 15:41:49 -08:00
var items = scene . GetSelectedItems ( ) ;
2019-01-28 07:40:52 -08:00
using ( new SelectionMaintainer ( scene ) )
{
var rotate = new RotateObject3D_2 ( ) ;
2019-01-31 15:41:49 -08:00
rotate . WrapItems ( items , scene . UndoBuffer ) ;
2019-01-28 07:40:52 -08:00
}
2018-06-26 15:54:05 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( Path . Combine ( "ViewTransformControls" , "rotate.png" ) , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2019-01-01 16:00:50 -08:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2019-01-01 16:00:50 -08:00
{
2019-01-16 15:06:30 -08:00
OperationID = "Scale" ,
2019-01-14 17:23:45 -08:00
Title = "Scale" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IObject3D ) } ,
ResultType = typeof ( ScaleObject3D ) ,
Operation = ( sceneItem , scene ) = >
{
2019-01-31 15:41:49 -08:00
var items = scene . GetSelectedItems ( ) ;
using ( new SelectionMaintainer ( scene ) )
{
var scale = new ScaleObject3D ( ) ;
scale . WrapItems ( items , scene . UndoBuffer ) ;
}
2019-12-06 10:18:38 -08:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "scale_32x32.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2019-01-01 16:00:50 -08:00
2019-01-14 18:23:34 -08:00
this . Graph . RegisterOperation (
new NodeOperation ( )
{
2019-01-16 15:06:30 -08:00
OperationID = "ImageConverter" ,
2019-01-14 18:23:34 -08:00
Title = "Image Converter" . Localize ( ) ,
MappedTypes = new List < Type > { typeof ( ImageObject3D ) } ,
ResultType = typeof ( ComponentObject3D ) ,
Operation = ( sceneItem , scene ) = >
{
2019-01-24 18:03:43 -08:00
var imageObject = sceneItem . Clone ( ) as ImageObject3D ;
2019-01-14 18:23:34 -08:00
var path = new ImageToPathObject3D ( ) ;
path . Children . Add ( imageObject ) ;
var smooth = new SmoothPathObject3D ( ) ;
smooth . Children . Add ( path ) ;
var extrude = new LinearExtrudeObject3D ( ) ;
extrude . Children . Add ( smooth ) ;
var baseObject = new BaseObject3D ( )
{
BaseType = BaseTypes . None
} ;
baseObject . Children . Add ( extrude ) ;
var component = new ComponentObject3D ( new [ ] { baseObject } )
{
Name = "Image Converter" . Localize ( ) ,
ComponentID = "4D9BD8DB-C544-4294-9C08-4195A409217A" ,
SurfacedEditors = new List < string >
{
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D>.Children<ImageObject3D>" ,
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Height" ,
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.SmoothDistance" ,
"$.Children<BaseObject3D>.Children<LinearExtrudeObject3D>.Children<SmoothPathObject3D>.Children<ImageToPathObject3D>" ,
"$.Children<BaseObject3D>" ,
}
} ;
2019-01-24 10:32:22 -08:00
component . Matrix = imageObject . Matrix ;
imageObject . Matrix = Matrix4X4 . Identity ;
2019-01-15 15:30:16 -08:00
2019-01-31 15:41:49 -08:00
using ( new SelectionMaintainer ( scene ) )
{
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new [ ] { sceneItem } , new [ ] { component } ) ) ;
2020-09-22 17:52:57 -07:00
}
2019-12-06 10:18:38 -08:00
2020-09-22 17:52:57 -07:00
// Invalidate image to kick off rebuild of ImageConverter stack
2019-01-28 17:44:00 -08:00
imageObject . Invalidate ( InvalidateType . Image ) ;
2019-01-14 18:23:34 -08:00
return Task . CompletedTask ;
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "140.png" , 16 , 16 , invertIcon )
2019-01-14 18:23:34 -08:00
} ) ;
2019-01-01 16:00:50 -08:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2019-01-01 16:00:50 -08:00
{
2019-01-16 15:06:30 -08:00
OperationID = "Mirror" ,
2019-01-14 17:23:45 -08:00
Title = "Mirror" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IObject3D ) } ,
2019-01-28 07:40:52 -08:00
ResultType = typeof ( MirrorObject3D_2 ) ,
2019-01-14 17:20:12 -08:00
Operation = ( sceneItem , scene ) = >
{
2019-01-28 07:40:52 -08:00
var mirror = new MirrorObject3D_2 ( ) ;
2019-01-14 17:20:12 -08:00
mirror . WrapSelectedItemAndSelect ( scene ) ;
2019-01-01 16:00:50 -08:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "mirror_32x32.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2019-01-01 16:00:50 -08:00
2018-08-03 12:20:56 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-08-03 12:20:56 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "EditComponent" ,
2019-01-14 17:23:45 -08:00
Title = "Edit Component" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IObject3D ) } ,
ResultType = typeof ( ComponentObject3D ) ,
Operation = ( sceneItem , scene ) = >
2018-08-03 12:20:56 -07:00
{
2019-01-14 17:20:12 -08:00
if ( sceneItem is ComponentObject3D componentObject )
{
// Enable editing mode
componentObject . Finalized = false ;
2018-08-03 12:20:56 -07:00
2019-01-14 17:20:12 -08:00
// Force editor rebuild
scene . SelectedItem = null ;
scene . SelectedItem = componentObject ;
}
2018-08-03 12:20:56 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
IsVisible = ( sceneItem ) = >
{
return sceneItem . Parent ! = null
& & sceneItem . Parent . Parent = = null
& & sceneItem is ComponentObject3D componentObject
2019-05-20 21:23:45 -07:00
& & componentObject . Finalized
2020-05-24 22:52:43 -07:00
& & ! componentObject . ProOnly ;
2019-01-14 17:20:12 -08:00
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "scale_32x32.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2018-08-03 12:20:56 -07:00
2018-06-06 15:46:30 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-06-06 15:46:30 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "LinearExtrude" ,
2019-01-14 17:23:45 -08:00
Title = "Linear Extrude" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IPathObject ) } ,
ResultType = typeof ( LinearExtrudeObject3D ) ,
Operation = ( sceneItem , scene ) = >
2018-06-06 15:46:30 -07:00
{
2019-01-14 17:20:12 -08:00
if ( sceneItem is IPathObject imageObject )
{
var extrude = new LinearExtrudeObject3D ( ) ;
2019-01-24 10:32:22 -08:00
var itemClone = sceneItem . Clone ( ) ;
extrude . Children . Add ( itemClone ) ;
extrude . Matrix = itemClone . Matrix ;
itemClone . Matrix = Matrix4X4 . Identity ;
2019-01-31 15:41:49 -08:00
using ( new SelectionMaintainer ( scene ) )
{
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new [ ] { sceneItem } , new [ ] { extrude } ) ) ;
}
2019-12-06 10:18:38 -08:00
2019-01-28 17:44:00 -08:00
extrude . Invalidate ( InvalidateType . Properties ) ;
2019-01-14 17:20:12 -08:00
}
2018-06-06 15:46:30 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2020-08-04 08:15:20 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "noun_84751.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2018-06-06 15:46:30 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-06-06 15:46:30 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "SmoothPath" ,
2019-01-14 17:23:45 -08:00
Title = "Smooth Path" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IPathObject ) } ,
ResultType = typeof ( SmoothPathObject3D ) ,
Operation = ( sceneItem , scene ) = >
2018-06-06 15:46:30 -07:00
{
2019-01-14 17:20:12 -08:00
if ( sceneItem is IPathObject imageObject )
{
var smoothPath = new SmoothPathObject3D ( ) ;
2019-01-24 10:32:22 -08:00
var itemClone = sceneItem . Clone ( ) ;
smoothPath . Children . Add ( itemClone ) ;
smoothPath . Matrix = itemClone . Matrix ;
itemClone . Matrix = Matrix4X4 . Identity ;
2019-01-31 15:41:49 -08:00
using ( new SelectionMaintainer ( scene ) )
{
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new [ ] { sceneItem } , new [ ] { smoothPath } ) ) ;
}
2019-12-06 10:18:38 -08:00
2019-01-28 17:44:00 -08:00
smoothPath . Invalidate ( InvalidateType . Properties ) ;
2019-01-14 17:20:12 -08:00
}
2018-06-06 15:46:30 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2019-05-10 20:44:33 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "noun_simplify_340976_000000.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2018-08-08 07:49:39 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-08-08 07:49:39 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "InflatePath" ,
2019-01-14 17:23:45 -08:00
Title = "Inflate Path" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IPathObject ) } ,
ResultType = typeof ( InflatePathObject3D ) ,
Operation = ( sceneItem , scene ) = >
2018-08-08 07:49:39 -07:00
{
2019-01-14 17:20:12 -08:00
if ( sceneItem is IPathObject imageObject )
{
var inflatePath = new InflatePathObject3D ( ) ;
2019-01-24 10:32:22 -08:00
var itemClone = sceneItem . Clone ( ) ;
inflatePath . Children . Add ( itemClone ) ;
inflatePath . Matrix = itemClone . Matrix ;
itemClone . Matrix = Matrix4X4 . Identity ;
2019-01-31 15:41:49 -08:00
using ( new SelectionMaintainer ( scene ) )
{
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new [ ] { sceneItem } , new [ ] { inflatePath } ) ) ;
}
2019-12-06 10:18:38 -08:00
2019-01-28 17:44:00 -08:00
inflatePath . Invalidate ( InvalidateType . Properties ) ;
2019-01-14 17:20:12 -08:00
}
2018-08-08 07:49:39 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
2020-05-24 12:06:05 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "inflate.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2017-06-21 07:41:12 -07:00
2020-05-23 22:54:41 -07:00
this . Graph . RegisterOperation (
new NodeOperation ( )
{
OperationID = "OutlinePath" ,
Title = "Outline Path" . Localize ( ) ,
MappedTypes = new List < Type > { typeof ( IPathObject ) } ,
ResultType = typeof ( OutlinePathObject3D ) ,
Operation = ( sceneItem , scene ) = >
{
if ( sceneItem is IPathObject imageObject )
{
var outlinePath = new OutlinePathObject3D ( ) ;
var itemClone = sceneItem . Clone ( ) ;
outlinePath . Children . Add ( itemClone ) ;
outlinePath . Matrix = itemClone . Matrix ;
itemClone . Matrix = Matrix4X4 . Identity ;
using ( new SelectionMaintainer ( scene ) )
{
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new [ ] { sceneItem } , new [ ] { outlinePath } ) ) ;
}
outlinePath . Invalidate ( InvalidateType . Properties ) ;
}
return Task . CompletedTask ;
} ,
2020-05-24 12:06:05 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "outline.png" , 16 , 16 , invertIcon )
2020-05-23 22:54:41 -07:00
} ) ;
2018-06-06 18:18:33 -07:00
this . Graph . RegisterOperation (
2019-01-14 17:20:12 -08:00
new NodeOperation ( )
2018-06-06 18:18:33 -07:00
{
2019-01-16 15:06:30 -08:00
OperationID = "AddBase" ,
2019-01-14 17:23:45 -08:00
Title = "Add Base" . Localize ( ) ,
2019-01-14 17:20:12 -08:00
MappedTypes = new List < Type > { typeof ( IObject3D ) } ,
ResultType = typeof ( BaseObject3D ) ,
Operation = ( item , scene ) = >
2018-06-15 14:37:07 -07:00
{
2019-01-14 17:20:12 -08:00
bool wasSelected = scene . SelectedItem = = item ;
2018-06-15 14:37:07 -07:00
2019-01-14 17:20:12 -08:00
var newChild = item . Clone ( ) ;
var baseMesh = new BaseObject3D ( )
{
Matrix = newChild . Matrix
} ;
newChild . Matrix = Matrix4X4 . Identity ;
baseMesh . Children . Add ( newChild ) ;
2019-01-28 17:44:00 -08:00
baseMesh . Invalidate ( InvalidateType . Properties ) ;
2019-01-14 17:20:12 -08:00
scene . UndoBuffer . AddAndDo (
new ReplaceCommand (
new List < IObject3D > { item } ,
new List < IObject3D > { baseMesh } ) ) ;
if ( wasSelected )
{
scene . SelectedItem = baseMesh ;
}
2018-06-06 18:18:33 -07:00
2019-01-14 17:20:12 -08:00
return Task . CompletedTask ;
} ,
IsVisible = ( sceneItem ) = > sceneItem . Children . Any ( ( i ) = > i is IPathObject ) ,
2020-08-04 08:15:20 -07:00
IconCollector = ( invertIcon ) = > AggContext . StaticData . LoadIcon ( "noun_55060.png" , 16 , 16 , invertIcon )
2019-01-14 17:20:12 -08:00
} ) ;
2018-06-23 14:18:04 -07:00
2018-11-08 17:16:35 -08:00
this . InitializeLibrary ( ) ;
2019-01-24 18:03:43 -08:00
this . Graph . PrimaryOperations . Add ( typeof ( ImageObject3D ) , new List < NodeOperation > { this . Graph . Operations [ "ImageConverter" ] , this . Graph . Operations [ "ImageToPath" ] , } ) ;
this . Graph . PrimaryOperations . Add ( typeof ( ImageToPathObject3D ) , new List < NodeOperation > { this . Graph . Operations [ "LinearExtrude" ] , this . Graph . Operations [ "SmoothPath" ] , this . Graph . Operations [ "InflatePath" ] } ) ;
this . Graph . PrimaryOperations . Add ( typeof ( SmoothPathObject3D ) , new List < NodeOperation > { this . Graph . Operations [ "LinearExtrude" ] , this . Graph . Operations [ "InflatePath" ] } ) ;
this . Graph . PrimaryOperations . Add ( typeof ( InflatePathObject3D ) , new List < NodeOperation > { this . Graph . Operations [ "LinearExtrude" ] } ) ;
2020-05-24 12:06:05 -07:00
this . Graph . PrimaryOperations . Add ( typeof ( OutlinePathObject3D ) , new List < NodeOperation > { this . Graph . Operations [ "LinearExtrude" ] } ) ;
2019-01-24 18:03:43 -08:00
this . Graph . PrimaryOperations . Add ( typeof ( Object3D ) , new List < NodeOperation > { this . Graph . Operations [ "Scale" ] } ) ;
2018-11-08 17:16:35 -08:00
}
2018-11-09 12:04:56 -08:00
public void Connection_ErrorReported ( object sender , string line )
2018-11-08 17:16:35 -08:00
{
2018-11-09 12:04:56 -08:00
if ( line ! = null )
2018-11-08 17:16:35 -08:00
{
string message = "Your printer is reporting a HARDWARE ERROR and has been paused. Check the error and cancel the print if required." . Localize ( )
+ "\n"
+ "\n"
+ "Error Reported" . Localize ( ) + ":"
2018-11-09 12:04:56 -08:00
+ $" \" { line } \ "." ;
2018-11-11 12:36:15 -08:00
if ( sender is PrinterConnection printerConnection )
{
UiThread . RunOnIdle ( ( ) = >
StyledMessageBox . ShowMessageBox (
( clickedOk ) = >
{
2019-02-06 10:34:19 -08:00
if ( clickedOk & & printerConnection . Paused )
2018-11-11 12:36:15 -08:00
{
printerConnection . Resume ( ) ;
}
} ,
message ,
"Printer Hardware Error" . Localize ( ) ,
StyledMessageBox . MessageType . YES_NO ,
"Resume" . Localize ( ) ,
2020-06-25 08:27:05 -07:00
"OK" . Localize ( ) ) ) ;
2018-11-11 12:36:15 -08:00
}
2018-11-08 17:16:35 -08:00
}
}
public void Connection_TemporarilyHoldingTemp ( object sender , EventArgs e )
{
if ( sender is PrinterConnection printerConnection )
{
2018-04-05 12:44:51 -07:00
if ( printerConnection . AnyHeatIsOn )
2018-01-30 14:48:53 -08:00
{
2018-07-18 11:57:54 -07:00
var paused = false ;
2018-12-05 13:48:25 -08:00
Tasks . Execute ( "" , printerConnection . Printer , ( reporter , cancellationToken ) = >
2018-01-30 14:48:53 -08:00
{
var progressStatus = new ProgressStatus ( ) ;
2018-07-17 10:04:08 -07:00
while ( printerConnection . SecondsToHoldTemperature > 0
2018-01-30 14:48:53 -08:00
& & ! cancellationToken . IsCancellationRequested
2019-03-19 13:13:14 -07:00
& & printerConnection . ContinueHoldingTemperature )
2018-01-30 14:48:53 -08:00
{
2018-07-18 11:57:54 -07:00
if ( paused )
{
progressStatus . Status = "Holding Temperature" . Localize ( ) ;
}
else
{
2018-10-19 15:46:36 -07:00
if ( printerConnection . SecondsToHoldTemperature > 60 )
{
progressStatus . Status = string . Format (
"{0} {1:0}m {2:0}s" ,
"Automatic Heater Shutdown in" . Localize ( ) ,
2020-06-25 08:27:05 -07:00
( int ) printerConnection . SecondsToHoldTemperature / 60 ,
( int ) printerConnection . SecondsToHoldTemperature % 60 ) ;
2018-10-19 15:46:36 -07:00
}
else
2018-10-21 08:52:22 -07:00
{
2018-10-19 15:46:36 -07:00
progressStatus . Status = string . Format (
"{0} {1:0}s" ,
"Automatic Heater Shutdown in" . Localize ( ) ,
printerConnection . SecondsToHoldTemperature ) ;
}
2018-07-18 11:57:54 -07:00
}
2019-12-06 10:18:38 -08:00
2018-07-18 11:57:54 -07:00
progressStatus . Progress0To1 = printerConnection . SecondsToHoldTemperature / printerConnection . TimeToHoldTemperature ;
2018-01-30 14:48:53 -08:00
reporter . Report ( progressStatus ) ;
2018-07-18 11:57:54 -07:00
Thread . Sleep ( 20 ) ;
2018-01-30 14:48:53 -08:00
}
2018-07-17 10:04:08 -07:00
return Task . CompletedTask ;
} ,
taskActions : new RunningTaskOptions ( )
{
PauseAction = ( ) = > UiThread . RunOnIdle ( ( ) = >
2018-01-30 14:48:53 -08:00
{
2018-07-18 11:57:54 -07:00
paused = true ;
2018-07-17 10:04:08 -07:00
printerConnection . TimeHaveBeenHoldingTemperature . Stop ( ) ;
} ) ,
2018-07-20 14:40:41 -07:00
PauseToolTip = "Pause automatic heater shutdown" . Localize ( ) ,
2018-07-17 10:04:08 -07:00
ResumeAction = ( ) = > UiThread . RunOnIdle ( ( ) = >
2018-02-09 13:37:21 -08:00
{
2018-07-18 11:57:54 -07:00
paused = false ;
2018-07-17 10:04:08 -07:00
printerConnection . TimeHaveBeenHoldingTemperature . Start ( ) ;
} ) ,
2018-07-20 14:40:41 -07:00
ResumeToolTip = "Resume automatic heater shutdown" . Localize ( ) ,
2019-03-19 15:11:34 -07:00
StopAction = ( abortCancel ) = > UiThread . RunOnIdle ( ( ) = >
2018-07-17 10:04:08 -07:00
{
printerConnection . TurnOffBedAndExtruders ( TurnOff . Now ) ;
2018-07-20 14:40:41 -07:00
} ) ,
StopToolTip = "Immediately turn off heaters" . Localize ( )
2018-01-30 14:48:53 -08:00
} ) ;
}
2018-03-26 16:54:36 -07:00
}
}
2018-11-07 14:41:11 -08:00
public void Shutdown ( )
2017-10-09 07:58:32 -07:00
{
// Ensure all threads shutdown gracefully on close
// Release any waiting generator threads
2018-06-21 10:50:40 -07:00
this . Thumbnails . Shutdown ( ) ;
2018-02-01 17:25:42 -08:00
2018-07-12 22:49:39 -07:00
// Kill all long running tasks (this will release the slicing thread if running)
2018-05-15 13:56:05 -07:00
foreach ( var task in Tasks . RunningTasks )
2018-02-01 17:25:42 -08:00
{
task . CancelTask ( ) ;
}
2017-10-09 07:58:32 -07:00
}
2019-05-01 13:23:02 -07:00
private static readonly Dictionary < NamedTypeFace , TypeFace > TypeFaceCache = new Dictionary < NamedTypeFace , TypeFace > ( )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-05-15 13:56:05 -07:00
[NamedTypeFace.Liberation_Sans] = LiberationSansFont . Instance ,
[NamedTypeFace.Liberation_Sans_Bold] = LiberationSansBoldFont . Instance ,
[NamedTypeFace.Liberation_Mono] = TypeFace . LoadFrom ( AggContext . StaticData . ReadAllText ( Path . Combine ( "Fonts" , "LiberationMono.svg" ) ) )
} ;
2020-06-28 11:39:41 -07:00
private static object locker = new object ( ) ;
2020-06-19 11:06:03 -07:00
2019-05-01 13:27:31 -07:00
public static TypeFace GetTypeFace ( NamedTypeFace namedTypeFace )
2018-05-15 13:56:05 -07:00
{
2020-06-19 11:06:03 -07:00
lock ( locker )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2020-06-19 11:06:03 -07:00
if ( ! TypeFaceCache . ContainsKey ( namedTypeFace ) )
2018-05-15 13:56:05 -07:00
{
2020-09-22 17:52:57 -07:00
var typeFace = new TypeFace ( ) ;
2020-06-19 11:06:03 -07:00
var path = Path . Combine ( "Fonts" , $"{namedTypeFace}.ttf" ) ;
var exists = AggContext . StaticData . FileExists ( path ) ;
var stream = exists ? AggContext . StaticData . OpenStream ( path ) : null ;
if ( stream ! = null
& & typeFace . LoadTTF ( stream ) )
2018-05-15 13:56:05 -07:00
{
2019-05-01 13:27:31 -07:00
TypeFaceCache . Add ( namedTypeFace , typeFace ) ;
2018-05-15 13:56:05 -07:00
}
else
{
2020-06-19 11:06:03 -07:00
// try the svg
path = Path . Combine ( "Fonts" , $"{namedTypeFace}.svg" ) ;
exists = AggContext . StaticData . FileExists ( path ) ;
typeFace = exists ? TypeFace . LoadFrom ( AggContext . StaticData . ReadAllText ( path ) ) : null ;
if ( typeFace ! = null )
{
TypeFaceCache . Add ( namedTypeFace , typeFace ) ;
}
else
{
// assign it to the default
TypeFaceCache . Add ( namedTypeFace , TypeFaceCache [ NamedTypeFace . Liberation_Sans ] ) ;
}
2018-05-15 13:56:05 -07:00
}
2020-06-19 11:06:03 -07:00
stream ? . Dispose ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2019-05-01 13:28:03 -07:00
2020-06-19 11:06:03 -07:00
return TypeFaceCache [ namedTypeFace ] ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
}
2018-01-28 07:53:23 -08:00
private static TypeFace titilliumTypeFace = null ;
2019-12-06 10:18:38 -08:00
2018-01-28 07:53:23 -08:00
public static TypeFace TitilliumTypeFace
{
get
{
if ( titilliumTypeFace = = null )
{
titilliumTypeFace = TypeFace . LoadFrom ( AggContext . StaticData . ReadAllText ( Path . Combine ( "Fonts" , "TitilliumWeb-Black.svg" ) ) ) ;
}
return titilliumTypeFace ;
}
}
2018-05-30 13:40:23 -07:00
public static string LoadCachedFile ( string cacheKey , string cacheScope )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
string cachePath = CacheablePath ( cacheScope , cacheKey ) ;
2018-05-29 13:11:38 -07:00
if ( File . Exists ( cachePath ) )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-05-29 13:11:38 -07:00
// Load from cache and deserialize
return File . ReadAllText ( cachePath ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2018-05-29 13:11:38 -07:00
return null ;
}
public static Task < T > LoadCacheableAsync < T > ( string cacheKey , string cacheScope , string staticDataFallbackPath = null ) where T : class
{
2018-05-30 13:40:23 -07:00
if ( LoadCachedFile ( cacheKey , cacheScope ) is string cachedFile )
{
// Load from cache and deserialize
2019-04-24 11:40:25 -07:00
return Task . FromResult (
JsonConvert . DeserializeObject < T > ( cachedFile ) ) ;
2018-05-30 13:40:23 -07:00
}
2018-05-29 13:11:38 -07:00
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
try
{
if ( staticDataFallbackPath ! = null
2017-08-20 02:34:39 -07:00
& & AggContext . StaticData . FileExists ( staticDataFallbackPath ) )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
return Task . FromResult (
2017-08-20 02:34:39 -07:00
JsonConvert . DeserializeObject < T > ( AggContext . StaticData . ReadAllText ( staticDataFallbackPath ) ) ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
}
catch
{
}
return Task . FromResult ( default ( T ) ) ;
}
2020-09-22 17:52:57 -07:00
// Requests fresh content from online services, falling back to cached content if offline
2020-06-25 08:27:05 -07:00
public static async Task < T > LoadCacheableAsync < T > ( string cacheKey , string cacheScope , Func < Task < T > > collector , string staticDataFallbackPath = null ) where T : class
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
string cachePath = CacheablePath ( cacheScope , cacheKey ) ;
try
{
// Try to update the document
T item = await collector ( ) ;
if ( item ! = null )
{
// update cache on success
File . WriteAllText ( cachePath , JsonConvert . SerializeObject ( item , Formatting . Indented ) ) ;
return item ;
}
}
catch
{
// Fall back to preexisting cache if failed
}
return await LoadCacheableAsync < T > ( cacheKey , cacheScope , staticDataFallbackPath ) ;
}
public static string CacheablePath ( string cacheScope , string cacheKey )
{
2018-07-31 12:21:44 -07:00
string scopeDirectory = Path . Combine ( ApplicationDataStorage . Instance . CacheDirectory , cacheScope ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
// Ensure directory exists
Directory . CreateDirectory ( scopeDirectory ) ;
2017-12-28 16:45:34 -08:00
return Path . Combine ( scopeDirectory , cacheKey ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
// Indicates if given file can be opened on the design surface
public bool IsLoadableFile ( string filePath )
{
string extension = Path . GetExtension ( filePath ) . ToLower ( ) ;
string extensionWithoutPeriod = extension . Trim ( '.' ) ;
return ! string . IsNullOrEmpty ( extension )
2018-03-26 16:54:36 -07:00
& & ( ApplicationSettings . OpenDesignFileParams . Contains ( extension )
2017-11-07 12:06:43 -08:00
| | this . Library . ContentProviders . Keys . Contains ( extensionWithoutPeriod ) ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2017-11-07 11:31:30 -08:00
public bool IsReloading { get ; private set ; } = false ;
2017-11-07 13:54:09 -08:00
2019-05-21 19:33:06 -07:00
private GuiWidget reloadingOverlay ;
2019-03-06 17:25:24 -08:00
public async Task ReloadAll ( )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-12-10 17:45:33 -08:00
try
2017-11-08 23:39:35 -08:00
{
2019-03-01 14:45:51 -08:00
#if DEBUG
AggContext . StaticData . PurgeCache ( ) ;
#endif
2018-12-10 17:45:33 -08:00
this . IsReloading = true ;
2019-05-21 19:33:06 -07:00
reloadingOverlay = new GuiWidget
2018-04-24 13:32:20 -07:00
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
BackgroundColor = this . Theme . DarkShade
} ;
2017-11-07 12:06:43 -08:00
2018-04-24 13:32:20 -07:00
reloadingOverlay . AddChild ( new TextWidget ( "Reloading" . Localize ( ) + "..." , textColor : Color . White , pointSize : this . Theme . DefaultFontSize * 1.5 )
{
HAnchor = HAnchor . Center ,
VAnchor = VAnchor . Center
} ) ;
2017-11-07 12:06:43 -08:00
2018-04-24 13:32:20 -07:00
AppContext . RootSystemWindow . AddChild ( reloadingOverlay ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2019-03-06 17:25:24 -08:00
await Task . Delay ( 50 ) ;
2018-12-10 17:45:33 -08:00
GuiWidget . LayoutCount = 0 ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-12-10 17:45:33 -08:00
using ( new QuickTimer ( $"ReloadAll_{reloadCount++}:" ) )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-12-19 09:24:11 -08:00
MainView = new MainViewWidget ( this . Theme ) ;
2018-12-10 17:45:33 -08:00
this . DoneReloadingAll ? . CallEvents ( null , null ) ;
2018-11-07 13:26:44 -08:00
2018-12-10 17:45:33 -08:00
using ( new QuickTimer ( "Time to AddMainview: " ) )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-12-10 17:45:33 -08:00
AppContext . RootSystemWindow . CloseAllChildren ( ) ;
AppContext . RootSystemWindow . AddChild ( MainView ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2018-12-10 17:45:33 -08:00
}
}
2019-05-21 19:33:06 -07:00
catch ( Exception ex )
2018-12-10 17:45:33 -08:00
{
2019-07-06 13:24:57 -07:00
reloadingOverlay ? . CloseOnIdle ( ) ;
2019-05-21 19:33:06 -07:00
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox ( "An unexpected error occurred during reload" . Localize ( ) + ": \n\n" + ex . Message , "Reload Failed" . Localize ( ) ) ;
} ) ;
2018-12-10 17:45:33 -08:00
}
finally
{
this . IsReloading = false ;
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-12-10 17:45:33 -08:00
Debug . WriteLine ( $"LayoutCount: {GuiWidget.LayoutCount:0.0}" ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2019-05-01 13:27:31 -07:00
private static int reloadCount = 0 ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-12-10 17:45:33 -08:00
public void OnApplicationClosed ( )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-06-21 10:50:40 -07:00
this . Thumbnails . Shutdown ( ) ;
2017-11-30 08:52:01 -08:00
ApplicationSettings . Instance . ReleaseClientToken ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
public static ApplicationController Instance
{
get
{
if ( globalInstance = = null )
{
2017-12-16 20:06:03 -08:00
globalInstance = new ApplicationController ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2018-05-08 13:27:13 -07:00
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
return globalInstance ;
}
}
2017-09-16 01:11:44 -07:00
public DragDropData DragDropData { get ; set ; } = new DragDropData ( ) ;
2020-05-21 10:54:57 -07:00
public string ShortProductName
{
get
{
if ( this . IsMatterControlPro ( ) )
{
return "MatterControl Pro" ;
}
return "MatterControl" ;
}
}
2019-04-24 11:40:25 -07:00
2020-05-21 10:54:57 -07:00
public string ProductName
{
get
{
if ( this . IsMatterControlPro ( ) )
{
return "MatterControl Pro Edition" ;
}
return "MatterHackers: MatterControl" ;
}
}
2017-09-20 15:28:58 -07:00
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public void SwitchToPurchasedLibrary ( )
{
var purchasedContainer = Library . RootLibaryContainer . ChildContainers . Where ( c = > c . ID = = "LibraryProviderPurchasedKey" ) . FirstOrDefault ( ) ;
if ( purchasedContainer ! = null )
{
// TODO: Navigate to purchased container
throw new NotImplementedException ( "SwitchToPurchasedLibrary" ) ;
}
}
2017-12-18 17:22:50 -08:00
public void OnLoadActions ( )
{
2018-03-08 10:36:00 -08:00
if ( AssetObject3D . AssetManager = = null )
{
2018-03-26 16:54:36 -07:00
AssetObject3D . AssetManager = new AssetManager ( ) ;
2018-03-08 10:36:00 -08:00
}
2017-12-18 17:22:50 -08:00
}
private static void RunSetupIfRequired ( )
{
if ( ! ProfileManager . Instance . ActiveProfiles . Any ( ) )
{
// Start the setup wizard if no profiles exist
UiThread . RunOnIdle ( ( ) = > DialogWindow . Show ( PrinterSetup . GetBestStartPage ( ) ) ) ;
}
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
public void SwitchToSharedLibrary ( )
{
// Switch to the shared library
var libraryContainer = Library . RootLibaryContainer . ChildContainers . Where ( c = > c . ID = = "LibraryProviderSharedKey" ) . FirstOrDefault ( ) ;
if ( libraryContainer ! = null )
{
// TODO: Navigate to purchased container
throw new NotImplementedException ( "SwitchToSharedLibrary" ) ;
}
}
public void ChangeCloudSyncStatus ( bool userAuthenticated , string reason = "" )
{
UserSettings . Instance . set ( UserSettingsKey . CredentialsInvalid , userAuthenticated ? "false" : "true" ) ;
UserSettings . Instance . set ( UserSettingsKey . CredentialsInvalidReason , userAuthenticated ? "" : reason ) ;
CloudSyncStatusChanged . CallEvents ( this , new CloudSyncEventArgs ( ) { IsAuthenticated = userAuthenticated } ) ;
if ( ! string . IsNullOrEmpty ( AuthenticationData . Instance . ActiveSessionUsername )
& & AuthenticationData . Instance . ActiveSessionUsername ! = AuthenticationData . Instance . LastSessionUsername )
{
AuthenticationData . Instance . LastSessionUsername = AuthenticationData . Instance . ActiveSessionUsername ;
}
2018-11-21 09:28:23 -08:00
// TODO: Unclear why we'd reload on status change - it seems like this state should be managed entirely from ProfileManager and removed from this location
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
ProfileManager . ReloadActiveUser ( ) ;
}
2017-08-17 18:18:41 -07:00
public Stream LoadHttpAsset ( string url )
{
string fingerPrint = ToSHA1 ( url ) ;
string cachePath = ApplicationController . CacheablePath ( "HttpAssets" , fingerPrint ) ;
if ( File . Exists ( cachePath ) )
{
return File . Open ( cachePath , FileMode . Open ) ;
}
else
{
var client = new WebClient ( ) ;
var bytes = client . DownloadData ( url ) ;
File . WriteAllBytes ( cachePath , bytes ) ;
return new MemoryStream ( bytes ) ;
}
}
2018-12-10 14:14:56 -08:00
public async Task < PrinterConfig > LoadPrinter ( string printerID )
2018-11-11 21:25:50 -08:00
{
2018-12-07 18:41:32 -08:00
var printer = this . ActivePrinters . FirstOrDefault ( p = > p . Settings . ID = = printerID ) ;
if ( printer = = null )
2018-11-12 09:41:44 -08:00
{
2018-12-07 18:41:32 -08:00
if ( ! string . IsNullOrEmpty ( printerID )
& & ProfileManager . Instance [ printerID ] ! = null )
{
printer = new PrinterConfig ( await ProfileManager . LoadSettingsAsync ( printerID ) ) ;
}
}
2018-11-11 21:25:50 -08:00
2018-12-07 18:41:32 -08:00
if ( printer ! = null
& & printer . Settings . PrinterSelected
& & printer . Settings . GetValue < bool > ( SettingsKey . auto_connect ) )
{
printer . Connection . Connect ( ) ;
}
2018-11-12 09:41:44 -08:00
2018-12-07 18:41:32 -08:00
return printer ;
}
2018-11-16 16:00:22 -08:00
2018-12-10 14:14:56 -08:00
public async Task < PrinterConfig > OpenEmptyPrinter ( string printerID )
{
if ( ! string . IsNullOrEmpty ( printerID )
& & ProfileManager . Instance [ printerID ] ! = null )
{
2018-12-19 09:24:11 -08:00
var printer = await this . LoadPrinter ( printerID ) ;
2018-12-10 14:14:56 -08:00
// Add workspace for printer
2020-09-22 17:52:57 -07:00
var workspace = new PartWorkspace ( printer ) ;
2018-12-19 09:24:11 -08:00
var history = this . Library . PlatingHistory ;
2018-12-10 14:14:56 -08:00
await workspace . SceneContext . LoadContent ( new EditContext ( )
{
ContentStore = history ,
SourceItem = history . NewPlatingItem ( )
} ) ;
if ( workspace . Printer ! = null )
{
workspace . Name = workspace . Printer . Settings . GetValue ( SettingsKey . printer_name ) ;
}
2018-12-19 09:24:11 -08:00
this . OpenWorkspace ( workspace ) ;
2018-12-10 14:14:56 -08:00
return printer ;
}
return null ;
}
2019-03-01 08:06:50 -08:00
public void OpenPrinter ( PrinterInfo printerInfo )
{
if ( this . ActivePrinters . FirstOrDefault ( p = > p . Settings . ID = = printerInfo . ID ) is PrinterConfig printer
& & this . MainView . TabControl . AllTabs . FirstOrDefault ( t = > t . TabContent is PrinterTabPage printerTabPage & & printerTabPage . printer = = printer ) is ITab tab )
{
// Switch to existing printer tab
this . MainView . TabControl . ActiveTab = tab ;
}
else
{
// Open new printer tab
this . OpenEmptyPrinter ( printerInfo . ID ) . ConfigureAwait ( false ) ;
}
}
2018-12-07 18:41:32 -08:00
public void OpenWorkspace ( PartWorkspace workspace )
2019-04-24 13:23:52 -07:00
{
this . OpenWorkspace ( workspace , WorkspacesChangedEventArgs . OperationType . Add ) ;
}
private void OpenWorkspace ( PartWorkspace workspace , WorkspacesChangedEventArgs . OperationType operationType )
2018-12-07 18:41:32 -08:00
{
this . OnWorkspacesChanged (
new WorkspacesChangedEventArgs (
workspace ,
2019-04-24 13:23:52 -07:00
operationType ) ) ;
2019-06-14 14:15:25 -07:00
this . Workspaces . Add ( workspace ) ;
2018-11-11 21:25:50 -08:00
}
2019-04-24 13:23:52 -07:00
public void RestoreWorkspace ( PartWorkspace workspace )
{
this . OpenWorkspace ( workspace , WorkspacesChangedEventArgs . OperationType . Restore ) ;
}
2018-12-19 15:05:25 -08:00
private string loadedUserTabs = null ;
2018-12-10 17:45:33 -08:00
public async Task RestoreUserTabs ( )
{
2018-12-19 15:05:25 -08:00
// Prevent reload of loaded user
if ( loadedUserTabs = = ProfileManager . Instance . UserName )
{
return ;
}
loadedUserTabs = ProfileManager . Instance . UserName ;
2018-12-10 17:45:33 -08:00
var history = this . Library . PlatingHistory ;
this . Workspaces . Clear ( ) ;
if ( File . Exists ( ProfileManager . Instance . OpenTabsPath ) )
{
try
{
string openTabsText = File . ReadAllText ( ProfileManager . Instance . OpenTabsPath ) ;
var persistedWorkspaces = JsonConvert . DeserializeObject < List < PartWorkspace > > (
openTabsText ,
new ContentStoreConverter ( ) ,
new LibraryItemConverter ( ) ) ;
2018-12-26 17:13:58 -08:00
var loadedPrinters = new HashSet < string > ( ) ;
2018-12-10 17:45:33 -08:00
foreach ( var persistedWorkspace in persistedWorkspaces )
{
2019-05-24 14:21:25 -07:00
try
2018-12-10 17:45:33 -08:00
{
2019-05-24 14:21:25 -07:00
// Load the actual workspace if content file exists
if ( File . Exists ( persistedWorkspace . ContentPath ) )
{
string printerID = persistedWorkspace . PrinterID ;
2018-12-10 17:45:33 -08:00
2019-05-24 14:21:25 -07:00
PartWorkspace workspace = null ;
2018-12-10 17:45:33 -08:00
2019-05-24 14:21:25 -07:00
if ( ! string . IsNullOrEmpty ( printerID )
& & ProfileManager . Instance [ printerID ] ! = null )
2018-12-26 17:13:58 -08:00
{
2019-05-24 14:21:25 -07:00
// Only create one workspace per printer
if ( ! loadedPrinters . Contains ( printerID ) )
{
// Add workspace for printer
workspace = new PartWorkspace ( await this . LoadPrinter ( persistedWorkspace . PrinterID ) ) ;
2018-12-26 17:13:58 -08:00
2019-05-24 14:21:25 -07:00
loadedPrinters . Add ( printerID ) ;
}
else
{
// Ignore additional workspaces for the same printer once one is loaded
continue ;
}
2018-12-26 17:13:58 -08:00
}
else
{
2019-05-24 14:21:25 -07:00
// Add workspace for part
workspace = new PartWorkspace ( new BedConfig ( history ) ) ;
2018-12-26 17:13:58 -08:00
}
2018-12-10 17:45:33 -08:00
2019-05-24 14:21:25 -07:00
// Load the previous content
await workspace . SceneContext . LoadContent ( new EditContext ( )
{
ContentStore = history ,
SourceItem = new FileSystemFileItem ( persistedWorkspace . ContentPath )
} ) ;
2018-12-10 17:45:33 -08:00
2019-05-24 14:21:25 -07:00
if ( workspace . Printer ! = null )
{
workspace . Name = workspace . Printer . Settings . GetValue ( SettingsKey . printer_name ) ;
}
else
{
workspace . Name = workspace ? . SceneContext . EditContext ? . SourceItem ? . Name ? ? "Unknown" ;
}
2018-12-10 17:45:33 -08:00
2019-05-24 14:21:25 -07:00
this . RestoreWorkspace ( workspace ) ;
}
}
catch
{
// Suppress workspace load exceptions and continue to the next workspace
2018-12-10 17:45:33 -08:00
}
}
}
catch
{
2019-05-24 14:21:25 -07:00
// Suppress deserialization issues with opentabs.json and continue with an empty Workspaces lists
2018-12-10 17:45:33 -08:00
}
}
if ( this . Workspaces . Count = = 0 )
{
var workspace = new PartWorkspace ( new BedConfig ( history ) )
{
Name = "New Design" . Localize ( )
} ;
// Load it up
workspace . SceneContext . LoadEmptyContent (
new EditContext ( )
{
ContentStore = history ,
SourceItem = history . NewPlatingItem ( )
} ) ;
2019-06-24 17:00:32 -07:00
ApplicationController . Instance . MainTabKey = workspace . Name ;
2019-06-20 22:54:05 -07:00
// Open but no need to save
this . OpenWorkspace ( workspace , WorkspacesChangedEventArgs . OperationType . Restore ) ;
2018-12-10 17:45:33 -08:00
}
}
2017-08-17 18:18:41 -07:00
/// <summary>
/// Compute hash for string encoded as UTF8
/// </summary>
/// <param name="s">String to be hashed</param>
public static string ToSHA1 ( string s )
{
byte [ ] bytes = Encoding . UTF8 . GetBytes ( s ) ;
// var timer = Stopwatch.StartNew();
using ( var sha1 = System . Security . Cryptography . SHA1 . Create ( ) )
{
byte [ ] hash = sha1 . ComputeHash ( bytes ) ;
2020-09-22 17:52:57 -07:00
string sHA1 = BitConverter . ToString ( hash ) . Replace ( "-" , string . Empty ) ;
2017-08-17 18:18:41 -07:00
// Console.WriteLine("{0} {1} {2}", SHA1, timer.ElapsedMilliseconds, filePath);
2020-09-22 17:52:57 -07:00
return sHA1 ;
2017-08-17 18:18:41 -07:00
}
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
/// <summary>
/// Register the given PrintItemAction into the named section
/// </summary>
/// <param name="section">The section to register in</param>
/// <param name="printItemAction">The action to register</param>
2018-10-24 21:10:39 -07:00
public void RegisterLibraryAction ( string section , LibraryAction printItemAction )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2019-05-10 20:44:33 -07:00
if ( ! registeredLibraryActions . TryGetValue ( section , out List < LibraryAction > items ) )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2018-10-24 21:10:39 -07:00
items = new List < LibraryAction > ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
registeredLibraryActions . Add ( section , items ) ;
}
items . Add ( printItemAction ) ;
}
/// <summary>
/// Enumerate the given section, returning all registered actions
/// </summary>
/// <param name="section">The section to enumerate</param>
2020-09-22 17:52:57 -07:00
/// <returns>The registered Actions</returns>
2018-10-24 21:10:39 -07:00
public IEnumerable < LibraryAction > RegisteredLibraryActions ( string section )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2019-05-10 20:44:33 -07:00
if ( registeredLibraryActions . TryGetValue ( section , out List < LibraryAction > items ) )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
return items ;
}
2018-10-24 21:10:39 -07:00
return Enumerable . Empty < LibraryAction > ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
}
2017-06-16 18:04:47 -07:00
2018-02-06 13:31:25 -08:00
public static IObject3D ClipboardItem { get ; internal set ; }
2019-04-24 11:40:25 -07:00
2018-05-03 14:37:30 -07:00
public Action < ILibraryItem > ShareLibraryItem { get ; set ; }
2018-02-06 13:31:25 -08:00
2018-10-15 20:08:15 -07:00
public List < PartWorkspace > Workspaces { get ; } = new List < PartWorkspace > ( ) ;
2018-05-03 23:00:02 -07:00
2018-05-09 07:52:05 -07:00
public AppViewState ViewState { get ; } = new AppViewState ( ) ;
2019-04-24 11:40:25 -07:00
2018-07-09 23:29:34 -07:00
public Uri HelpArticleSource { get ; set ; }
2019-04-24 11:40:25 -07:00
2018-08-28 18:45:58 -07:00
public Dictionary < string , HelpArticle > HelpArticlesByID { get ; set ; }
2018-10-19 17:43:43 -07:00
2019-04-24 15:08:11 -07:00
public string MainTabKey
{
get = > UserSettings . Instance . get ( UserSettingsKey . MainTabKey ) ;
set = > UserSettings . Instance . set ( UserSettingsKey . MainTabKey , value ) ;
}
2018-05-09 07:52:05 -07:00
2018-11-01 09:36:58 -07:00
public static List < StartupAction > StartupActions { get ; } = new List < StartupAction > ( ) ;
public static List < StartupTask > StartupTasks { get ; } = new List < StartupTask > ( ) ;
2019-04-24 11:40:25 -07:00
2018-11-06 16:08:13 -08:00
public static Type ServicesStatusType { get ; set ; }
2018-11-01 09:36:58 -07:00
2018-11-11 13:16:32 -08:00
/// <summary>
2019-04-24 11:40:25 -07:00
/// Gets a value indicating whether any ActivePrinter is running a print task, either in paused or printing states
2018-11-11 13:16:32 -08:00
/// </summary>
2019-02-06 10:34:19 -08:00
public bool AnyPrintTaskRunning = > this . ActivePrinters . Any ( p = > p . Connection . Printing | | p . Connection . Paused | | p . Connection . CommunicationState = = CommunicationStates . PreparingToPrint ) ;
2018-11-11 13:16:32 -08:00
2018-12-28 16:00:21 -08:00
private List < TourLocation > _productTour ;
2018-12-13 08:31:32 -08:00
2018-12-28 16:00:21 -08:00
public async Task < List < TourLocation > > LoadProductTour ( )
2018-12-13 08:31:32 -08:00
{
2018-12-13 09:24:45 -08:00
if ( _productTour = = null )
2018-12-13 08:31:32 -08:00
{
2018-12-28 16:00:21 -08:00
_productTour = await ApplicationController . LoadCacheableAsync < List < TourLocation > > (
2018-12-13 09:24:45 -08:00
"ProductTour.json" ,
"MatterHackers" ,
async ( ) = >
{
var httpClient = new HttpClient ( ) ;
2018-12-13 11:18:04 -08:00
string json = await httpClient . GetStringAsync ( "https://matterhackers.github.io/MatterControl-Help/docs/product-tour.json" ) ;
2020-06-03 12:37:16 -07:00
// string json = await httpClient.GetStringAsync("https://matterhackers.github.io/MatterControl-Docs/Help/product-tour.json");
2018-12-13 08:31:32 -08:00
2018-12-28 16:00:21 -08:00
return JsonConvert . DeserializeObject < List < TourLocation > > ( json ) ;
2018-12-13 09:24:45 -08:00
} ,
Path . Combine ( "OemSettings" , "ProductTour.json" ) ) ;
2018-12-13 08:31:32 -08:00
}
2018-12-13 09:24:45 -08:00
return _productTour ;
2018-12-13 08:31:32 -08:00
}
2020-06-28 11:39:41 -07:00
public event EventHandler < ApplicationTopBarCreatedEventArgs > ApplicationTopBarCreated ;
2017-08-07 14:19:28 -07:00
public void NotifyPrintersTabRightElement ( GuiWidget sourceExentionArea )
{
2020-06-28 11:39:41 -07:00
ApplicationTopBarCreated ? . Invoke ( this , new ApplicationTopBarCreatedEventArgs ( sourceExentionArea ) ) ;
2020-05-30 16:50:36 -07:00
// after adding content to the right side make sure we hold the space in the tab bar
var leftChild = sourceExentionArea . Parent . Children . First ( ) ;
var padding = leftChild . Padding ;
leftChild . Padding = new BorderDouble ( padding . Left , padding . Bottom , sourceExentionArea . Width , padding . Height ) ;
2017-08-07 14:19:28 -07:00
}
2019-01-31 11:23:09 -08:00
public async Task PrintPart ( EditContext editContext , PrinterConfig printer , IProgress < ProgressStatus > reporter , CancellationToken cancellationToken )
2017-06-16 18:04:47 -07:00
{
2018-02-09 18:11:55 -08:00
var partFilePath = editContext . SourceFilePath ;
2020-07-29 14:29:59 -07:00
var gcodeFilePath = await editContext . GCodeFilePath ( printer ) ;
2018-02-09 18:11:55 -08:00
var printItemName = editContext . SourceItem . Name ;
2017-10-16 17:28:18 -07:00
// Exit if called in a non-applicable state
2018-11-11 12:36:15 -08:00
if ( printer . Connection . CommunicationState ! = CommunicationStates . Connected
& & printer . Connection . CommunicationState ! = CommunicationStates . FinishedPrint )
2017-10-16 17:28:18 -07:00
{
return ;
}
2017-06-16 18:04:47 -07:00
try
{
2019-05-16 15:34:34 -07:00
if ( PrinterCalibrationWizard . SetupRequired ( printer , requiresLoadedFilament : true ) )
2017-06-16 18:04:47 -07:00
{
2019-04-04 17:26:16 -07:00
UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show (
new PrinterCalibrationWizard ( printer , AppContext . Theme ) ,
advanceToIncompleteStage : true ) ;
} ) ;
2018-04-06 14:58:25 -07:00
return ;
2017-06-16 18:04:47 -07:00
}
2018-11-14 16:54:23 -08:00
printer . Connection . PrintingItemName = printItemName ;
2018-05-23 06:23:13 -07:00
2019-06-14 14:13:23 -07:00
var errors = printer . ValidateSettings ( validatePrintBed : ! printer . Bed . EditContext . IsGGCodeSource ) ;
2019-04-24 11:40:25 -07:00
if ( errors . Any ( e = > e . ErrorLevel = = ValidationErrorLevel . Error ) )
2019-01-03 16:58:05 -08:00
{
2019-06-14 14:13:23 -07:00
this . ShowValidationErrors ( "Validation Error" . Localize ( ) , errors ) ;
2019-01-03 16:58:05 -08:00
}
2019-01-04 17:49:58 -08:00
else // there are no errors continue printing
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
// clear the output cache prior to starting a print
2018-11-11 12:36:15 -08:00
printer . Connection . TerminalLog . Clear ( ) ;
2018-05-23 06:23:13 -07:00
string hideGCodeWarning = ApplicationSettings . Instance . get ( ApplicationSettingsKey . HideGCodeWarning ) ;
2017-09-23 09:19:32 -07:00
2019-01-31 11:23:09 -08:00
if ( Path . GetExtension ( partFilePath ) . ToUpper ( ) = = ".GCODE" )
2017-06-16 18:04:47 -07:00
{
2019-01-31 11:23:09 -08:00
if ( hideGCodeWarning ! = "true" )
2017-06-16 18:04:47 -07:00
{
2019-01-31 11:23:09 -08:00
var hideGCodeWarningCheckBox = new CheckBox ( "Don't remind me again" . Localize ( ) )
2017-06-16 18:04:47 -07:00
{
2019-01-31 11:23:09 -08:00
TextColor = this . Theme . TextColor ,
Margin = new BorderDouble ( top : 6 , left : 6 ) ,
HAnchor = Agg . UI . HAnchor . Left
} ;
hideGCodeWarningCheckBox . Click + = ( sender , e ) = >
2018-05-23 06:23:13 -07:00
{
2019-01-31 11:23:09 -08:00
if ( hideGCodeWarningCheckBox . Checked )
2017-06-16 18:04:47 -07:00
{
2019-01-31 11:23:09 -08:00
ApplicationSettings . Instance . set ( ApplicationSettingsKey . HideGCodeWarning , "true" ) ;
}
else
2017-09-15 18:45:21 -07:00
{
2019-01-31 11:23:09 -08:00
ApplicationSettings . Instance . set ( ApplicationSettingsKey . HideGCodeWarning , null ) ;
}
} ;
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox (
( messageBoxResponse ) = >
{
if ( messageBoxResponse )
{
printer . Connection . CommunicationState = CommunicationStates . PreparingToPrint ;
this . ArchiveAndStartPrint ( partFilePath , gcodeFilePath , printer ) ;
}
} ,
"The file you are attempting to print is a GCode file.\n\nIt is recommended that you only print Gcode files known to match your printer's configuration.\n\nAre you sure you want to print this GCode file?" . Localize ( ) ,
"Warning - GCode file" . Localize ( ) ,
new GuiWidget [ ]
{
2019-01-18 09:49:38 -08:00
hideGCodeWarningCheckBox
2019-01-31 11:23:09 -08:00
} ,
StyledMessageBox . MessageType . YES_NO ) ;
} ) ;
}
else
{
printer . Connection . CommunicationState = CommunicationStates . PreparingToPrint ;
this . ArchiveAndStartPrint ( partFilePath , gcodeFilePath , printer ) ;
}
2018-05-23 06:23:13 -07:00
}
else
{
2018-11-11 12:36:15 -08:00
printer . Connection . CommunicationState = CommunicationStates . PreparingToPrint ;
2017-10-16 17:09:00 -07:00
2018-07-10 15:34:08 -07:00
( bool slicingSucceeded , string finalPath ) = await this . SliceItemLoadOutput (
2018-05-23 06:23:13 -07:00
printer ,
printer . Bed . Scene ,
gcodeFilePath ) ;
2017-12-11 22:22:56 -08:00
2018-05-23 06:49:58 -07:00
// Only start print if slicing completed
if ( slicingSucceeded )
{
2018-05-26 12:16:23 -07:00
this . ArchiveAndStartPrint ( partFilePath , finalPath , printer ) ;
2018-05-23 06:49:58 -07:00
}
2018-05-23 07:18:22 -07:00
else
{
// TODO: Need to reset printing state? This seems like I shouldn't own this indicator
2018-11-11 12:36:15 -08:00
printer . Connection . CommunicationState = CommunicationStates . Connected ;
2018-05-23 07:18:22 -07:00
}
2017-06-16 18:04:47 -07:00
}
}
}
catch ( Exception )
{
}
}
2019-01-04 18:05:10 -08:00
public void ShowValidationErrors ( string windowTitle , List < ValidationError > errors )
{
UiThread . RunOnIdle ( ( ) = >
{
2019-01-23 08:43:41 -08:00
var dialogPage = new DialogPage ( "Close" . Localize ( ) )
2019-01-04 18:05:10 -08:00
{
2019-01-23 08:43:41 -08:00
HAnchor = HAnchor . Stretch ,
WindowTitle = windowTitle ,
HeaderText = "Action Required" . Localize ( )
} ;
2019-01-04 21:58:16 -08:00
2019-01-23 08:43:41 -08:00
dialogPage . ContentRow . AddChild ( new ValidationErrorsPanel ( errors , AppContext . Theme )
{
HAnchor = HAnchor . Stretch
} ) ;
2019-01-04 18:05:10 -08:00
2019-01-23 08:43:41 -08:00
DialogWindow . Show ( dialogPage ) ;
2019-01-04 18:05:10 -08:00
} ) ;
}
2018-03-21 17:17:36 -07:00
public void ResetTranslationMap ( )
{
2018-07-30 11:50:22 -07:00
LoadTranslationMap ( ) ;
}
public static void LoadTranslationMap ( )
{
// Select either the user supplied language name or the current thread language name
string twoLetterIsoLanguageName = string . IsNullOrEmpty ( UserSettings . Instance . Language ) ?
Thread . CurrentThread . CurrentUICulture . TwoLetterISOLanguageName . ToLower ( ) :
UserSettings . Instance . Language . ToLower ( ) ;
2020-05-22 17:33:54 -07:00
if ( twoLetterIsoLanguageName = = "ja"
| | twoLetterIsoLanguageName = = "zh" )
{
AggContext . DefaultFont = ApplicationController . GetTypeFace ( NamedTypeFace . Firefly_Sung ) ;
AggContext . DefaultFontBold = ApplicationController . GetTypeFace ( NamedTypeFace . Firefly_Sung ) ;
AggContext . DefaultFontItalic = ApplicationController . GetTypeFace ( NamedTypeFace . Firefly_Sung ) ;
AggContext . DefaultFontBoldItalic = ApplicationController . GetTypeFace ( NamedTypeFace . Firefly_Sung ) ;
}
else
{
AggContext . DefaultFont = LiberationSansFont . Instance ;
AggContext . DefaultFontBold = LiberationSansBoldFont . Instance ;
AggContext . DefaultFontItalic = LiberationSansFont . Instance ;
AggContext . DefaultFontBoldItalic = LiberationSansBoldFont . Instance ;
}
2018-07-30 11:50:22 -07:00
string translationFilePath = Path . Combine ( "Translations" , twoLetterIsoLanguageName , "Translation.txt" ) ;
if ( twoLetterIsoLanguageName = = "en" )
{
TranslationMap . ActiveTranslationMap = new TranslationMap ( ) ;
}
else
{
using ( var stream = AggContext . StaticData . OpenStream ( translationFilePath ) )
using ( var streamReader = new StreamReader ( stream ) )
{
TranslationMap . ActiveTranslationMap = new TranslationMap ( streamReader , UserSettings . Instance . Language ) ;
}
}
2018-03-21 17:17:36 -07:00
}
2018-05-23 07:17:47 -07:00
public void MonitorPrintTask ( PrinterConfig printer )
2018-03-19 11:45:28 -07:00
{
2018-04-13 16:16:51 -07:00
string layerDetails = ( printer . Bed . LoadedGCode ? . LayerCount > 0 ) ? $" of {printer.Bed.LoadedGCode.LayerCount}" : "" ;
2018-04-09 18:05:46 -07:00
2018-07-10 15:34:08 -07:00
this . Tasks . Execute (
2018-04-09 18:05:46 -07:00
"Printing" . Localize ( ) ,
2018-12-05 13:48:25 -08:00
printer ,
2018-03-19 11:45:28 -07:00
( reporterB , cancellationTokenB ) = >
{
var progressStatus = new ProgressStatus ( ) ;
reporterB . Report ( progressStatus ) ;
return Task . Run ( ( ) = >
{
string printing = "Printing" . Localize ( ) ;
int totalLayers = printer . Connection . TotalLayersInPrint ;
2019-02-06 10:34:19 -08:00
while ( ! printer . Connection . Printing
2018-03-19 11:45:28 -07:00
& & ! cancellationTokenB . IsCancellationRequested )
{
// Wait for printing
Thread . Sleep ( 200 ) ;
}
2019-02-06 10:34:19 -08:00
while ( ( printer . Connection . Printing | | printer . Connection . Paused )
2018-03-19 11:45:28 -07:00
& & ! cancellationTokenB . IsCancellationRequested )
{
2018-04-09 18:05:46 -07:00
progressStatus . Status = $"{printing} ({printer.Connection.CurrentlyPrintingLayer + 1}{layerDetails}) - {printer.Connection.PercentComplete:0}%" ;
2018-03-19 11:45:28 -07:00
progressStatus . Progress0To1 = printer . Connection . PercentComplete / 100 ;
reporterB . Report ( progressStatus ) ;
Thread . Sleep ( 200 ) ;
}
} ) ;
} ,
2018-05-06 08:29:24 -07:00
taskActions : new RunningTaskOptions ( )
2018-03-19 11:45:28 -07:00
{
2018-05-07 13:12:32 -07:00
ExpansionSerializationKey = $"{nameof(MonitorPrintTask)}_expanded" ,
2018-07-10 15:34:08 -07:00
RichProgressWidget = ( ) = > PrinterTabPage . PrintProgressWidget ( printer , this . Theme ) ,
2018-05-06 08:29:24 -07:00
PauseAction = ( ) = > UiThread . RunOnIdle ( ( ) = >
2018-03-19 11:45:28 -07:00
{
printer . Connection . RequestPause ( ) ;
} ) ,
2018-09-17 14:31:26 -07:00
IsPaused = ( ) = >
{
2019-02-06 10:34:19 -08:00
return printer . Connection . Paused ;
2018-09-17 14:31:26 -07:00
} ,
2018-07-20 14:40:41 -07:00
PauseToolTip = "Pause Print" . Localize ( ) ,
2018-05-06 08:29:24 -07:00
ResumeAction = ( ) = > UiThread . RunOnIdle ( ( ) = >
2018-03-19 11:45:28 -07:00
{
printer . Connection . Resume ( ) ;
} ) ,
2018-07-20 14:40:41 -07:00
ResumeToolTip = "Resume Print" . Localize ( ) ,
2019-03-19 15:11:34 -07:00
StopAction = ( abortCancel ) = > UiThread . RunOnIdle ( ( ) = >
2018-03-19 11:45:28 -07:00
{
2019-03-19 15:11:34 -07:00
printer . CancelPrint ( abortCancel ) ;
2018-07-20 14:40:41 -07:00
} ) ,
StopToolTip = "Cancel Print" . Localize ( ) ,
2018-03-19 11:45:28 -07:00
} ) ;
}
2019-02-04 08:41:08 -08:00
private static PluginManager pluginManager = null ;
public static PluginManager Plugins
{
get
{
// PluginManager initialization must occur late, after the config is loaded and after localization libraries
// have occurred, which currently is driven by MatterControlApplication init
if ( pluginManager = = null )
{
pluginManager = new PluginManager ( ) ;
}
return pluginManager ;
}
}
2020-05-16 09:31:54 -07:00
public bool Allow32BitReSlice { get ; set ; }
2018-02-09 18:11:55 -08:00
/// <summary>
/// Archives MCX and validates GCode results before starting a print operation
/// </summary>
/// <param name="sourcePath">The source file which originally caused the slice->print operation</param>
/// <param name="gcodeFilePath">The resulting GCode to print</param>
2018-05-23 07:14:21 -07:00
private async void ArchiveAndStartPrint ( string sourcePath , string gcodeFilePath , PrinterConfig printer )
2017-06-16 18:04:47 -07:00
{
2018-02-09 18:11:55 -08:00
if ( File . Exists ( sourcePath )
& & File . Exists ( gcodeFilePath ) )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
bool originalIsGCode = Path . GetExtension ( sourcePath ) . ToUpper ( ) = = ".GCODE" ;
if ( File . Exists ( gcodeFilePath ) )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
// Create archive point for printing attempt
if ( Path . GetExtension ( sourcePath ) . ToUpper ( ) = = ".MCX" )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
string now = "Workspace " + DateTime . Now . ToString ( "yyyy-MM-dd HH_mm_ss" ) ;
2019-05-23 08:39:27 -07:00
string archivePath = Path . Combine ( ApplicationDataStorage . Instance . PrintHistoryPath , now + ".zip" ) ;
2017-06-16 18:04:47 -07:00
2018-11-25 07:39:09 -08:00
string settingsFilePath = ProfileManager . Instance . ProfilePath ( printer . Settings . ID ) ;
2020-07-16 07:59:57 -07:00
// if the printer was deleted while printing the path can be null
if ( settingsFilePath ! = null )
2017-06-16 18:04:47 -07:00
{
2020-07-16 07:59:57 -07:00
using ( var file = File . OpenWrite ( archivePath ) )
using ( var zip = new ZipArchive ( file , ZipArchiveMode . Create ) )
{
zip . CreateEntryFromFile ( sourcePath , "PrinterPlate.mcx" ) ;
zip . CreateEntryFromFile ( settingsFilePath , printer . Settings . GetValue ( SettingsKey . printer_name ) + ".printer" ) ;
zip . CreateEntryFromFile ( gcodeFilePath , "sliced.gcode" ) ;
}
2017-06-16 18:04:47 -07:00
}
2018-05-23 06:23:13 -07:00
}
if ( originalIsGCode )
{
2018-11-11 12:36:15 -08:00
await printer . Connection . StartPrint ( gcodeFilePath ) ;
2018-05-23 07:14:21 -07:00
MonitorPrintTask ( printer ) ;
2018-05-23 06:23:13 -07:00
return ;
}
else
{
2019-06-26 18:36:58 -07:00
// Ask for slicer specific gcode validation
2019-07-01 16:58:17 -07:00
if ( printer . Settings . Slicer . ValidateFile ( gcodeFilePath ) )
2017-06-16 18:04:47 -07:00
{
2019-06-26 18:36:58 -07:00
await printer . Connection . StartPrint ( gcodeFilePath ) ;
MonitorPrintTask ( printer ) ;
2019-07-01 16:08:10 -07:00
return ;
2017-06-16 18:04:47 -07:00
}
}
}
2018-05-23 06:23:13 -07:00
2018-11-11 12:36:15 -08:00
printer . Connection . CommunicationState = CommunicationStates . Connected ;
2017-06-16 18:04:47 -07:00
}
}
2018-05-23 06:49:58 -07:00
/// <summary>
/// Slice the given IObject3D to the target GCode file using the referenced printer settings
/// </summary>
/// <param name="printer">The printer/settings to use</param>
/// <param name="object3D">The IObject3D to slice</param>
/// <param name="gcodeFilePath">The path to write the file to</param>
/// <returns>A boolean indicating if the slicing operation completed without aborting</returns>
2018-05-26 12:16:23 -07:00
public async Task < ( bool , string ) > SliceItemLoadOutput ( PrinterConfig printer , IObject3D object3D , string gcodeFilePath )
2017-10-16 17:09:00 -07:00
{
// Slice
2018-02-01 21:42:09 -08:00
bool slicingSucceeded = false ;
2019-05-06 16:03:13 -07:00
printer . ViewState . SlicingItem = true ;
2018-12-05 13:48:25 -08:00
await this . Tasks . Execute ( "Slicing" . Localize ( ) , printer , async ( reporter , cancellationToken ) = >
2017-12-11 14:15:50 -08:00
{
2018-02-09 18:11:55 -08:00
slicingSucceeded = await Slicer . SliceItem (
2018-03-26 16:54:36 -07:00
object3D ,
gcodeFilePath ,
2017-12-11 14:15:50 -08:00
printer ,
2018-08-17 17:49:41 -07:00
reporter ,
2018-01-17 08:32:40 -08:00
cancellationToken ) ;
2017-12-11 14:15:50 -08:00
} ) ;
2018-02-01 21:42:09 -08:00
2019-05-06 16:03:13 -07:00
printer . ViewState . SlicingItem = false ;
2018-02-01 21:42:09 -08:00
// Skip loading GCode output if slicing failed
if ( ! slicingSucceeded )
{
2018-05-26 12:16:23 -07:00
return ( false , gcodeFilePath ) ;
}
var postProcessors = printer . Bed . Scene . Children . OfType < IGCodePostProcessor > ( ) ;
if ( postProcessors . Any ( ) )
{
using ( var resultStream = File . OpenRead ( gcodeFilePath ) )
{
Stream contextStream = resultStream ;
// Execute each post processor
foreach ( var processor in postProcessors )
{
// Invoke the processor and store the resulting output to the context stream reference
contextStream = processor . ProcessOutput ( contextStream ) ;
// Reset to the beginning
contextStream . Position = 0 ;
}
// Modify final file name
gcodeFilePath = Path . ChangeExtension ( gcodeFilePath , GCodeFile . PostProcessedExtension ) ;
// Copy the final stream to the revised gcodeFilePath
using ( var finalStream = File . OpenWrite ( gcodeFilePath ) )
{
contextStream . CopyTo ( finalStream ) ;
}
}
2018-02-01 21:42:09 -08:00
}
2018-12-05 13:48:25 -08:00
await this . Tasks . Execute ( "Loading GCode" . Localize ( ) , printer , ( innerProgress , token ) = >
2017-12-11 14:15:50 -08:00
{
2018-02-20 18:27:52 -08:00
var status = new ProgressStatus ( ) ;
2017-12-11 14:15:50 -08:00
innerProgress . Report ( status ) ;
2019-03-22 11:50:05 -07:00
printer . Bed . LoadActiveSceneGCode ( gcodeFilePath , token , ( progress0to1 , statusText ) = >
2017-12-11 14:15:50 -08:00
{
UiThread . RunOnIdle ( ( ) = >
{
status . Progress0To1 = progress0to1 ;
status . Status = statusText ;
innerProgress . Report ( status ) ;
} ) ;
} ) ;
2018-10-29 16:38:31 -07:00
if ( printer . Bed . LoadedGCode is GCodeMemoryFile gcodeMemoryFile )
{
// try to validate the gcode file and warn if it seems invalid.
// for now the definition of invalid is that it has a print time of < 30 seconds
var estimatedPrintSeconds = gcodeMemoryFile . EstimatedPrintSeconds ( ) ;
if ( estimatedPrintSeconds < 30 )
{
var message = "The time to print this G-Code is estimated to be {0} seconds.\n\nPlease check your part for errors if this is unexpected."
. Localize ( )
. FormatWith ( ( int ) estimatedPrintSeconds ) ;
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox ( message , "Warning, very short print" . Localize ( ) ) ;
} ) ;
}
}
2018-11-08 05:40:01 -08:00
// Switch to the 3D layer view if on Model view and slicing succeeded
if ( printer . ViewState . ViewMode = = PartViewMode . Model )
{
printer . ViewState . ViewMode = PartViewMode . Layers3D ;
}
2017-12-11 14:15:50 -08:00
return Task . CompletedTask ;
} ) ;
2018-05-23 06:49:58 -07:00
2018-05-26 12:16:23 -07:00
return ( slicingSucceeded , gcodeFilePath ) ;
2017-10-16 17:09:00 -07:00
}
2019-02-01 16:12:12 -08:00
internal void GetViewOptionButtons ( GuiWidget parent , ISceneContext sceneContext , PrinterConfig printer , ThemeConfig theme )
2018-04-02 16:21:34 -07:00
{
2020-08-04 14:56:27 -07:00
var bedButton = new RadioIconButton ( AggContext . StaticData . LoadIcon ( "bed.png" , 16 , 16 , theme . InvertIcons ) , theme )
2018-04-02 16:21:34 -07:00
{
Name = "Bed Button" ,
ToolTipText = "Show Print Bed" . Localize ( ) ,
2018-04-05 18:46:31 -07:00
Checked = sceneContext . RendererOptions . RenderBed ,
2018-04-02 16:21:34 -07:00
Margin = theme . ButtonSpacing ,
2018-09-10 12:02:20 -07:00
VAnchor = VAnchor . Absolute ,
2018-04-02 16:21:34 -07:00
ToggleButton = true ,
2018-09-10 12:02:20 -07:00
Height = theme . ButtonHeight ,
Width = theme . ButtonHeight ,
2018-09-07 17:01:48 -07:00
SiblingRadioButtonList = new List < GuiWidget > ( )
2018-04-02 16:21:34 -07:00
} ;
bedButton . CheckedStateChanged + = ( s , e ) = >
{
2018-04-05 18:46:31 -07:00
sceneContext . RendererOptions . RenderBed = bedButton . Checked ;
2018-04-02 16:21:34 -07:00
} ;
2018-09-10 12:02:20 -07:00
parent . AddChild ( bedButton ) ;
2018-04-02 16:21:34 -07:00
2020-09-22 17:52:57 -07:00
bool BuildHeightValid ( ) = > sceneContext . BuildHeight > 0 ;
2018-04-04 10:11:57 -07:00
2020-08-04 14:56:27 -07:00
var printAreaButton = new RadioIconButton ( AggContext . StaticData . LoadIcon ( "print_area.png" , 16 , 16 , theme . InvertIcons ) , theme )
2018-04-02 16:21:34 -07:00
{
2018-04-18 18:10:06 -07:00
Name = "Bed Button" ,
2020-09-22 17:52:57 -07:00
ToolTipText = BuildHeightValid ( ) ? "Show Print Area" . Localize ( ) : "Define printer build height to enable" ,
2018-04-18 18:10:06 -07:00
Checked = sceneContext . RendererOptions . RenderBuildVolume ,
Margin = theme . ButtonSpacing ,
2018-09-10 12:02:20 -07:00
VAnchor = VAnchor . Absolute ,
2018-04-18 18:10:06 -07:00
ToggleButton = true ,
2020-09-22 17:52:57 -07:00
Enabled = BuildHeightValid ( ) & & printer ? . ViewState . ViewMode ! = PartViewMode . Layers2D ,
2018-09-10 12:02:20 -07:00
Height = theme . ButtonHeight ,
Width = theme . ButtonHeight ,
2018-09-07 17:01:48 -07:00
SiblingRadioButtonList = new List < GuiWidget > ( )
2018-04-18 18:10:06 -07:00
} ;
printAreaButton . CheckedStateChanged + = ( s , e ) = >
{
sceneContext . RendererOptions . RenderBuildVolume = printAreaButton . Checked ;
} ;
2018-09-10 12:02:20 -07:00
parent . AddChild ( printAreaButton ) ;
2018-04-02 16:21:34 -07:00
2018-09-10 12:02:20 -07:00
this . BindBedOptions ( parent , bedButton , printAreaButton , sceneContext . RendererOptions ) ;
2018-04-04 10:11:57 -07:00
2018-04-09 17:43:31 -07:00
if ( printer ! = null )
{
// Disable print area button in GCode2D view
2020-09-22 17:52:57 -07:00
void ViewModeChanged ( object s , ViewModeChangedEventArgs e )
2018-04-09 17:43:31 -07:00
{
2018-04-18 17:55:32 -07:00
// Button is conditionally created based on BuildHeight, only set enabled if created
2020-09-22 17:52:57 -07:00
printAreaButton . Enabled = BuildHeightValid ( ) & & printer . ViewState . ViewMode ! = PartViewMode . Layers2D ;
}
2018-04-09 17:43:31 -07:00
2020-09-22 17:52:57 -07:00
printer . ViewState . ViewModeChanged + = ViewModeChanged ;
2018-04-09 17:43:31 -07:00
2018-09-10 12:02:20 -07:00
parent . Closed + = ( s , e ) = >
2018-04-09 17:43:31 -07:00
{
2020-09-22 17:52:57 -07:00
printer . ViewState . ViewModeChanged - = ViewModeChanged ;
2018-04-09 17:43:31 -07:00
} ;
}
2018-04-02 16:21:34 -07:00
}
2018-04-04 10:11:57 -07:00
public void BindBedOptions ( GuiWidget container , ICheckbox bedButton , ICheckbox printAreaButton , View3DConfig renderOptions )
{
2020-09-22 17:52:57 -07:00
void SyncProperties ( object s , PropertyChangedEventArgs e )
2018-04-04 10:11:57 -07:00
{
switch ( e . PropertyName )
{
case nameof ( renderOptions . RenderBed ) :
bedButton . Checked = renderOptions . RenderBed ;
break ;
case nameof ( renderOptions . RenderBuildVolume ) when printAreaButton ! = null :
printAreaButton . Checked = renderOptions . RenderBuildVolume ;
break ;
}
2020-09-22 17:52:57 -07:00
}
2018-04-04 10:11:57 -07:00
2020-09-22 17:52:57 -07:00
renderOptions . PropertyChanged + = SyncProperties ;
2018-04-04 10:11:57 -07:00
container . Closed + = ( s , e ) = >
{
2020-09-22 17:52:57 -07:00
renderOptions . PropertyChanged - = SyncProperties ;
2018-04-04 10:11:57 -07:00
} ;
}
2018-11-27 12:22:38 -08:00
public void ShellOpenFile ( string file )
{
UiThread . RunOnIdle ( ( ) = > this . ShellFileOpened ? . Invoke ( this , file ) ) ;
}
2020-07-03 12:05:28 -07:00
public void Connection_PrintStarted ( object sender , EventArgs e )
{
AnyPrintStarted ? . Invoke ( sender , e ) ;
}
2019-04-01 16:19:23 -07:00
public void Connection_PrintFinished ( object sender , string e )
{
2019-04-20 21:56:11 -07:00
if ( sender is PrinterConnection printerConnection
& & ! printerConnection . CalibrationPrint )
2019-04-12 15:02:34 -07:00
{
// show a long running task asking about print feedback and up-selling more materials
// Ask about the print, offer help if needed.
// Let us know how your print came out.
2019-04-21 07:51:04 -07:00
string markdownText = @ "**Find more at MatterHackers**
Supplies and accessories :
2020-06-28 11:39:41 -07:00
- [ Filament ] ( https : //www.matterhackers.com/store/c/3d-printer-filament)
- [ Bed Adhesives ] ( https : //www.matterhackers.com/store/c/3d-printer-adhesive)
2019-04-12 15:02:34 -07:00
- [ Digital Designs ] ( https : //www.matterhackers.com/store/c/digital-designs)
Support and tutorials :
- [ MatterControl Docs ] ( https : //www.matterhackers.com/mattercontrol/support)
- [ Tutorials ] ( https : //www.matterhackers.com/store/l/mattercontrol/sk/MKZGTDW6#tutorials)
- [ Trick , Tips & Support Articles ] ( https : //www.matterhackers.com/support#mattercontrol)
- [ User Forum ] ( https : //forums.matterhackers.com/recent)";
var time = Stopwatch . StartNew ( ) ;
2019-04-21 07:51:04 -07:00
ShowNotification ( "Congratulations Print Complete" . Localize ( ) , markdownText , UserSettingsKey . ShownPrintCompleteMessage ) ;
2019-04-12 15:02:34 -07:00
}
2020-07-03 12:05:28 -07:00
AnyPrintComplete ? . Invoke ( sender , null ) ;
2019-04-01 16:19:23 -07:00
}
public void Connection_PrintCanceled ( object sender , EventArgs e )
{
2019-04-20 21:56:11 -07:00
if ( sender is PrinterConnection printerConnection
& & ! printerConnection . CalibrationPrint )
2019-04-12 07:54:27 -07:00
{
2019-04-12 15:02:34 -07:00
// show a long running task showing support options
2019-04-12 07:54:27 -07:00
// add links to forum, articles and documentation
// support: "https://www.matterhackers.com/support#mattercontrol"
// documentation: "https://www.matterhackers.com/mattercontrol/support"
// forum: "https://forums.matterhackers.com/recent"
2019-04-12 15:02:34 -07:00
string markdownText = @ "Looks like you canceled this print. If you need help, here are some links that might be useful.
- [ MatterControl Docs ] ( https : //www.matterhackers.com/mattercontrol/support)
- [ Tutorials ] ( https : //www.matterhackers.com/store/l/mattercontrol/sk/MKZGTDW6#tutorials)
- [ Trick , Tips & Support Articles ] ( https : //www.matterhackers.com/support#mattercontrol)
- [ User Forum ] ( https : //forums.matterhackers.com/recent)";
2019-04-12 07:54:27 -07:00
2019-04-12 15:02:34 -07:00
var time = Stopwatch . StartNew ( ) ;
2019-04-20 21:56:11 -07:00
ShowNotification ( "Print Canceled" . Localize ( ) , markdownText , UserSettingsKey . ShownPrintCanceledMessage ) ;
2019-04-12 07:54:27 -07:00
}
2020-07-03 12:05:28 -07:00
AnyPrintCanceled ? . Invoke ( sender , e ) ;
2020-07-09 13:20:09 -07:00
}
2020-07-03 12:05:28 -07:00
2020-07-09 13:20:09 -07:00
private void ShowNotification ( string title , string markdownText , string userKey )
2019-04-12 07:54:27 -07:00
{
2019-04-20 21:56:11 -07:00
var hideAfterPrintMessage = new CheckBox ( "Don't show this again" . Localize ( ) )
2019-04-12 07:54:27 -07:00
{
2019-04-20 21:56:11 -07:00
TextColor = AppContext . Theme . TextColor ,
Margin = new BorderDouble ( top : 6 , left : 6 ) ,
HAnchor = Agg . UI . HAnchor . Left ,
2020-05-17 15:29:35 -07:00
Checked = UserSettings . Instance . get ( userKey ) = = "false" ,
2019-04-20 21:56:11 -07:00
} ;
hideAfterPrintMessage . Click + = ( s , e1 ) = >
{
if ( hideAfterPrintMessage . Checked )
{
2020-05-17 13:28:35 -07:00
UserSettings . Instance . set ( userKey , "false" ) ;
2019-04-20 21:56:11 -07:00
}
else
{
2020-05-17 13:28:35 -07:00
UserSettings . Instance . set ( userKey , "true" ) ;
2019-04-20 21:56:11 -07:00
}
} ;
2019-04-12 15:02:34 -07:00
2019-04-20 21:56:11 -07:00
if ( ! hideAfterPrintMessage . Checked
& & ! string . IsNullOrEmpty ( markdownText ) )
{
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox ( null ,
2019-04-21 07:51:04 -07:00
markdownText ,
title ,
new [ ] { hideAfterPrintMessage } ,
StyledMessageBox . MessageType . OK ,
useMarkdown : true ) ;
2019-04-20 21:56:11 -07:00
} ) ;
2019-04-12 07:54:27 -07:00
}
2019-04-01 16:19:23 -07:00
}
2019-04-05 12:04:28 -07:00
public void ConnectToPrinter ( PrinterConfig printer )
{
if ( ! printer . Settings . PrinterSelected )
{
return ;
}
bool listenForConnectFailed = true ;
long connectStartMs = UiThread . CurrentTimerMs ;
void Connection_Failed ( object s , EventArgs e )
{
#if ! __ANDROID__
// TODO: Someday this functionality should be revised to an awaitable Connect() call in the Connect button that
// shows troubleshooting on failed attempts, rather than hooking the failed event and trying to determine if the
// Connect button started the task
if ( listenForConnectFailed
& & UiThread . CurrentTimerMs - connectStartMs < 25000 )
{
UiThread . RunOnIdle ( ( ) = >
{
// User initiated connect attempt failed, show port selection dialog
DialogWindow . Show ( new SetupStepComPortOne ( printer ) ) ;
} ) ;
}
#endif
ClearEvents ( ) ;
}
void Connection_Succeeded ( object s , EventArgs e )
{
ClearEvents ( ) ;
}
void ClearEvents ( )
{
listenForConnectFailed = false ;
printer . Connection . ConnectionFailed - = Connection_Failed ;
printer . Connection . ConnectionSucceeded - = Connection_Succeeded ;
}
printer . Connection . ConnectionFailed + = Connection_Failed ;
printer . Connection . ConnectionSucceeded + = Connection_Succeeded ;
if ( AppContext . Platform . HasPermissionToDevice ( printer ) )
{
printer . Connection . HaltConnectionThread ( ) ;
printer . Connection . Connect ( ) ;
}
}
2019-05-28 15:22:55 -07:00
/// <summary>
/// Replace invalid filename characters with the given replacement value to ensure working paths for the current filesystem
/// </summary>
/// <param name="name">The filename name to consider</param>
/// <param name="replacementCharacter">The replacement character to use</param>
/// <returns>A sanitized file name that is safe to use on the current system</returns>
public string SanitizeFileName ( string name , string replacementCharacter = "_" )
2019-05-28 14:43:05 -07:00
{
if ( string . IsNullOrEmpty ( name ) )
{
return name ;
}
string invalidChars = Regex . Escape ( new string ( Path . GetInvalidFileNameChars ( ) ) ) ;
string invalidRegStr = string . Format ( @"([{0}]*\.+$)|([{0}]+)" , invalidChars ) ;
return Regex . Replace ( name , invalidRegStr , replacementCharacter ) ;
}
2019-06-18 17:28:35 -07:00
public ChromeTab ActivateHelpTab ( )
{
var tabControl = this . MainView . TabControl ;
var theme = AppContext . Theme ;
var helpDocsTab = tabControl . AllTabs . FirstOrDefault ( t = > t . Key = = "HelpDocs" ) as ChromeTab ;
if ( helpDocsTab = = null )
{
var helpTreePanel = new HelpTreePanel ( theme )
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch
} ;
2019-06-20 11:03:45 -07:00
var icon = AggContext . StaticData . LoadIcon ( "help_page.png" , 16 , 16 , theme . InvertIcons ) ;
helpDocsTab = new ChromeTab ( "HelpDocs" , "Help" . Localize ( ) , tabControl , helpTreePanel , theme , icon )
2019-06-18 17:28:35 -07:00
{
MinimumSize = new Vector2 ( 0 , theme . TabButtonHeight ) ,
2019-06-20 11:03:45 -07:00
Name = "Help Tab" ,
2019-06-18 17:28:35 -07:00
} ;
tabControl . AddTab ( helpDocsTab ) ;
}
tabControl . ActiveTab = helpDocsTab ;
return helpDocsTab ;
}
2017-09-16 01:11:44 -07:00
public class CloudSyncEventArgs : EventArgs
{
public bool IsAuthenticated { get ; set ; }
}
2018-11-01 09:36:58 -07:00
public class StartupTask
{
public string Title { get ; set ; }
2019-04-12 15:02:34 -07:00
2018-11-01 09:36:58 -07:00
public int Priority { get ; set ; }
2019-12-06 10:18:38 -08:00
2018-11-01 09:36:58 -07:00
public Func < IProgress < ProgressStatus > , CancellationToken , Task > Action { get ; set ; }
}
public class StartupAction
{
public string Title { get ; set ; }
2019-12-06 10:18:38 -08:00
2018-11-01 09:36:58 -07:00
public int Priority { get ; set ; }
2019-12-06 10:18:38 -08:00
2018-11-01 09:36:58 -07:00
public Action Action { get ; set ; }
}
2017-08-07 14:19:28 -07:00
}
2020-06-28 11:39:41 -07:00
}