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 .
* /
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.IO ;
using System.Linq ;
using System.Threading.Tasks ;
using MatterHackers.Agg ;
using MatterHackers.Agg.UI ;
using MatterHackers.Localizations ;
using MatterHackers.MatterControl.DataStorage ;
using MatterHackers.MatterControl.PrinterCommunication ;
using MatterHackers.MatterControl.PrintQueue ;
using MatterHackers.MatterControl.SlicerConfiguration ;
2018-03-17 20:53:36 -07:00
using MatterHackers.MatterControl.DesignTools.Operations ;
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 ;
2017-12-11 14:15:50 -08:00
using System.Collections.ObjectModel ;
2018-09-06 11:31:09 -07:00
using System.Runtime.CompilerServices ;
[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-04-04 10:11:57 -07:00
using System.ComponentModel ;
2017-06-16 18:04:47 -07:00
using System.IO.Compression ;
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 System.Net ;
2018-09-29 15:48:41 -07:00
using System.Net.Http ;
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 System.Reflection ;
2017-08-17 18:18:41 -07:00
using System.Text ;
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 System.Threading ;
using Agg.Font ;
using Agg.Image ;
using CustomWidgets ;
2018-05-26 12:16:23 -07:00
using global : : MatterControl . Printing ;
2017-08-20 02:34:39 -07:00
using MatterHackers.Agg.Platform ;
2018-05-04 14:50:38 -07:00
using MatterHackers.Agg.VertexSource ;
2017-06-02 17:04:02 -07:00
using MatterHackers.DataConverters3D ;
2018-01-26 17:53:54 -08:00
using MatterHackers.DataConverters3D.UndoCommands ;
2017-06-16 18:04:47 -07:00
using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling ;
2018-01-23 09:52:05 -08:00
using MatterHackers.MatterControl.DesignTools ;
2018-01-29 13:50:55 -08:00
using MatterHackers.MatterControl.DesignTools.Operations ;
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.Library ;
2017-06-01 18:19:37 -07:00
using MatterHackers.MatterControl.PartPreviewWindow ;
2017-10-17 09:40:56 -07:00
using MatterHackers.MatterControl.PartPreviewWindow.View3D ;
2017-10-18 14:56:10 -07:00
using MatterHackers.MatterControl.PrinterControls.PrinterConnections ;
2018-04-18 14:38:09 -07:00
using MatterHackers.MatterControl.SetupWizard ;
2018-02-26 17:48:15 -08:00
using MatterHackers.PolygonMesh ;
2018-08-13 18:39:09 -07:00
using MatterHackers.PolygonMesh.Processors ;
2018-02-26 17:48:15 -08:00
using MatterHackers.RenderOpenGl ;
2017-06-16 18:04:47 -07:00
using MatterHackers.SerialPortCommunication ;
2018-02-21 15:23:54 -08:00
using MatterHackers.VectorMath ;
2018-04-23 14:33:27 -07:00
using MatterHackers.VectorMath.TrackBall ;
2018-05-15 13:56:05 -07:00
using Newtonsoft.Json.Converters ;
2018-10-13 17:58:54 -07:00
using Newtonsoft.Json.Serialization ;
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 SettingsManagement ;
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
public enum NamedTypeFace
{
Alfa_Slab ,
Audiowide ,
Bangers ,
Courgette ,
Damion ,
Fredoka ,
Great_Vibes ,
Liberation_Mono ,
Liberation_Sans ,
Liberation_Sans_Bold ,
Lobster ,
Pacifico ,
Poppins ,
Questrial ,
Righteous ,
Russo ,
Titan ,
Titillium ,
} ;
2018-11-11 21:25:50 -08:00
public class OpenPrintersChangedEventArgs : EventArgs
{
public OpenPrintersChangedEventArgs ( PrinterConfig printer , OperationType operation )
{
this . Printer = printer ;
this . Operation = operation ;
}
public PrinterConfig Printer { get ; }
public OperationType Operation { get ; }
public enum OperationType { Add , Remove }
}
2018-10-31 14:06:39 -07:00
public static class AppContext
2017-12-16 13:56:59 -08:00
{
/// <summary>
2018-03-26 16:54:36 -07:00
/// Native platform features
2017-12-16 13:56:59 -08:00
/// </summary>
public static INativePlatformFeatures Platform { get ; set ; }
2017-12-16 19:09:25 -08:00
2018-10-31 14:06:39 -07:00
public static MatterControlOptions Options { get ; set ; } = new MatterControlOptions ( ) ;
2017-12-18 17:22:50 -08:00
public static bool IsLoading { get ; internal set ; } = true ;
2017-12-16 19:09:25 -08:00
/// <summary>
/// The root SystemWindow
/// </summary>
public static SystemWindow RootSystemWindow { get ; internal set ; }
2018-10-13 17:58:54 -07:00
public static ThemeConfig Theme = > themeset . Theme ;
public static ThemeConfig MenuTheme = > themeset . MenuTheme ;
private static ThemeSet themeset ;
public static ThemeSet ThemeSet = > themeset ;
2018-10-20 23:07:16 -07:00
public static Dictionary < string , IColorTheme > ThemeProviders { get ; }
2018-10-13 17:58:54 -07:00
2018-10-30 12:21:48 -07:00
private static Dictionary < string , string > themes = new Dictionary < string , string > ( ) ;
2018-10-13 17:58:54 -07:00
static AppContext ( )
{
2018-10-20 23:07:16 -07:00
ThemeProviders = new Dictionary < string , IColorTheme > ( ) ;
2018-10-21 08:44:16 -07:00
string themesPath = Path . Combine ( "Themes" , "System" ) ;
2018-10-20 23:07:16 -07:00
2018-10-30 12:21:48 -07:00
var staticData = AggContext . StaticData ;
2018-10-21 08:44:16 -07:00
// Load available themes from StaticData
2018-10-30 12:21:48 -07:00
if ( staticData . DirectoryExists ( themesPath ) )
2018-10-21 08:44:16 -07:00
{
2018-10-30 12:21:48 -07:00
var themeFiles = staticData . GetDirectories ( themesPath ) . SelectMany ( d = > staticData . GetFiles ( d ) . Where ( p = > Path . GetExtension ( p ) = = ".json" ) ) ;
foreach ( var themeFile in themeFiles )
{
themes [ Path . GetFileNameWithoutExtension ( themeFile ) ] = themeFile ;
}
foreach ( var directoryTheme in AggContext . StaticData . GetDirectories ( themesPath ) . Where ( d = > Path . GetFileName ( d ) ! = "Menus" ) . Select ( d = > new DirectoryTheme ( d ) ) )
2018-10-21 08:47:57 -07:00
{
ThemeProviders . Add ( directoryTheme . Name , directoryTheme ) ;
}
2018-10-21 08:44:16 -07:00
}
2018-10-20 23:07:16 -07:00
2018-10-13 17:58:54 -07:00
// Load theme
try
{
if ( File . Exists ( ProfileManager . Instance . ProfileThemeSetPath ) )
{
themeset = JsonConvert . DeserializeObject < ThemeSet > ( File . ReadAllText ( ProfileManager . Instance . ProfileThemeSetPath ) ) ;
2018-10-23 12:37:50 -07:00
// If the serialized format is older than the current format, null and fall back to latest default below
if ( themeset . SchemeVersion ! = ThemeSet . LatestSchemeVersion )
{
themeset = null ;
}
2018-10-13 17:58:54 -07:00
}
}
catch { }
if ( themeset = = null )
{
2018-10-24 08:07:07 -07:00
var themeProvider = ThemeProviders [ "Modern" ] ;
themeset = themeProvider . GetTheme ( "Modern-Dark" ) ;
2018-10-13 17:58:54 -07:00
}
2018-11-03 09:13:07 -07:00
DefaultThumbView . ThumbColor = new Color ( themeset . Theme . TextColor , 30 ) ;
2018-10-13 17:58:54 -07:00
}
2018-10-30 12:21:48 -07:00
public static ThemeConfig LoadTheme ( string themeName )
{
try
{
if ( themes . TryGetValue ( themeName , out string themePath ) )
{
string json = AggContext . StaticData . ReadAllText ( themePath ) ;
return JsonConvert . DeserializeObject < ThemeConfig > ( json ) ;
}
}
catch
{
Console . WriteLine ( "Error loading theme: " + themeName ) ;
}
return new ThemeConfig ( ) ;
}
2018-10-20 23:07:16 -07:00
public static void SetThemeAccentColor ( Color accentColor )
{
2018-10-22 08:37:11 -07:00
themeset . SetAccentColor ( accentColor ) ;
2018-10-20 23:07:16 -07:00
AppContext . SetTheme ( themeset ) ;
}
2018-10-13 17:58:54 -07:00
public static void SetTheme ( ThemeSet themeSet )
{
themeset = themeSet ;
File . WriteAllText (
ProfileManager . Instance . ProfileThemeSetPath ,
JsonConvert . SerializeObject (
themeset ,
Formatting . Indented ,
new JsonSerializerSettings
{
2018-10-20 22:32:03 -07:00
ContractResolver = new ThemeContractResolver ( )
2018-10-13 17:58:54 -07:00
} ) ) ;
UiThread . RunOnIdle ( ( ) = >
{
2018-10-22 08:46:15 -07:00
UserSettings . Instance . set ( UserSettingsKey . ActiveThemeName , themeset . Name ) ;
2018-10-13 17:58:54 -07:00
// Explicitly fire ReloadAll in response to user interaction
ApplicationController . Instance . ReloadAll ( ) ;
} ) ;
}
2018-10-31 14:06:39 -07:00
public class MatterControlOptions
{
public bool McwsTestEnvironment { get ; set ; }
}
2018-10-13 17:58:54 -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-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 ;
2017-12-11 14:15:50 -08:00
public RunningTasksConfig Tasks { get ; set ; } = new RunningTasksConfig ( ) ;
2018-11-23 11:06:02 -08:00
public IReadOnlyList < PrinterConfig > ActivePrinters = > _activePrinters ;
2017-09-17 14:23:28 -07:00
// A list of printers which are open (i.e. displaying a tab) on this instance of MatterControl
2018-11-11 21:25:50 -08:00
private List < PrinterConfig > _activePrinters = new List < PrinterConfig > ( ) ;
2018-11-24 07:52:33 -08:00
2018-11-23 11:06:02 -08:00
private Dictionary < Type , HashSet < IObject3DEditor > > objectEditorsByType ;
2017-09-17 14:23:28 -07:00
2018-09-14 15:20:19 -07:00
public PopupMenu GetActionMenuForSceneItem ( IObject3D selectedItem , InteractiveScene scene , bool addInSubmenu )
2018-08-07 09:56:34 -07:00
{
var popupMenu = new PopupMenu ( ApplicationController . Instance . MenuTheme ) ;
2018-09-09 11:46:15 -07:00
var menuItem = popupMenu . CreateMenuItem ( "Rename" . Localize ( ) ) ;
2018-08-07 09:56:34 -07:00
menuItem . Click + = ( s , e ) = >
{
DialogWindow . Show (
new InputBoxPage (
"Rename Item" . Localize ( ) ,
"Name" . Localize ( ) ,
selectedItem . Name ,
"Enter New Name Here" . Localize ( ) ,
"Rename" . Localize ( ) ,
( newName ) = >
{
selectedItem . Name = newName ;
// TODO: Revise SelectedObjectPanel to sync name on model change
// editorSectionWidget.Text = newName;
} ) ) ;
} ;
2018-10-24 21:13:10 -07:00
popupMenu . CreateSeparator ( ) ;
2018-08-07 09:56:34 -07:00
2018-09-14 15:20:19 -07:00
var selectedItemType = selectedItem . GetType ( ) ;
2018-08-07 09:56:34 -07:00
2018-09-14 15:20:19 -07:00
var menuTheme = ApplicationController . Instance . MenuTheme ;
2018-08-07 09:56:34 -07:00
2018-09-14 15:20:19 -07:00
if ( addInSubmenu )
{
2018-09-11 10:57:53 -07:00
popupMenu . CreateSubMenu ( "Modify" . Localize ( ) , ApplicationController . Instance . MenuTheme , ( modifyMenu ) = >
2018-08-07 09:56:34 -07:00
{
2018-09-11 10:57:53 -07:00
foreach ( var nodeOperation in ApplicationController . Instance . Graph . Operations )
2018-08-07 09:56:34 -07:00
{
2018-09-11 10:57:53 -07:00
foreach ( var type in nodeOperation . MappedTypes )
2018-08-07 09:56:34 -07:00
{
2018-09-11 10:57:53 -07:00
if ( type . IsAssignableFrom ( selectedItemType )
& & ( nodeOperation . IsVisible ? . Invoke ( selectedItem ) ! = false )
& & nodeOperation . IsEnabled ? . Invoke ( selectedItem ) ! = false )
2018-08-07 09:56:34 -07:00
{
2018-09-11 10:57:53 -07:00
var subMenuItem = modifyMenu . CreateMenuItem ( nodeOperation . Title , nodeOperation . IconCollector ? . Invoke ( menuTheme ) ) ;
subMenuItem . Click + = ( s2 , e2 ) = >
{
nodeOperation . Operation ( selectedItem , scene ) . ConfigureAwait ( false ) ;
} ;
}
2018-08-07 09:56:34 -07:00
}
}
2018-09-11 10:57:53 -07:00
} ) ;
2018-09-14 15:20:19 -07:00
}
else
{
foreach ( var nodeOperation in ApplicationController . Instance . Graph . Operations )
{
foreach ( var type in nodeOperation . MappedTypes )
{
if ( type . IsAssignableFrom ( selectedItemType )
& & ( nodeOperation . IsVisible ? . Invoke ( selectedItem ) ! = false )
& & nodeOperation . IsEnabled ? . Invoke ( selectedItem ) ! = false )
{
menuItem = popupMenu . CreateMenuItem ( nodeOperation . Title , nodeOperation . IconCollector ? . Invoke ( menuTheme ) ) ;
menuItem . Click + = ( s2 , e2 ) = >
{
nodeOperation . Operation ( selectedItem , scene ) . ConfigureAwait ( false ) ;
} ;
}
}
}
}
2018-08-07 09:56:34 -07:00
return popupMenu ;
}
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-03-26 16:54:36 -07:00
// TODO: Any references to this property almost certainly need to be reconsidered. ActiveSliceSettings static references that assume a single printer
2017-09-20 18:05:15 -07:00
// selection are being redirected here. This allows us to break the dependency to the original statics and consolidates
// us down to a single point where code is making assumptions about the presence of a printer, printer counts, etc. If we previously checked for
2017-09-17 14:23:28 -07:00
// PrinterConnection.IsPrinterConnected, that could should be updated to iterate ActiverPrinters, checking each one and acting on each as it would
// have for the single case
2018-11-11 12:46:38 -08:00
[Obsolete("ActivePrinter references should be migrated to logic than supports multi-printer mode")]
2018-11-21 19:23:52 -08:00
public PrinterConfig ActivePrinter = > this . ActivePrinters . FirstOrDefault ( ) ? ? PrinterConfig . EmptyPrinter ;
2017-06-24 08:32:09 -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 Action RedeemDesignCode ;
public Action EnterShareCode ;
private static ApplicationController globalInstance ;
2018-10-05 09:34:43 -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 CloudSyncStatusChanged = new RootedObjectEventHandler ( ) ;
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
public event EventHandler < OpenPrintersChangedEventArgs > OpenPrintersChanged ;
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-11-11 21:25:50 -08:00
public void OnOpenPrintersChanged ( OpenPrintersChangedEventArgs e )
2018-10-05 09:44:28 -07:00
{
2018-11-11 21:25:50 -08:00
this . OpenPrintersChanged ? . Invoke ( this , e ) ;
2018-10-05 09:44:28 -07:00
}
2018-04-18 12:56:12 -07:00
public string GetFavIconUrl ( string oemName )
{
OemSettings . Instance . OemUrls . TryGetValue ( oemName , out string oemUrl ) ;
return "https://www.google.com/s2/favicons?domain=" + ( string . IsNullOrWhiteSpace ( oemUrl ) ? "www.matterhackers.com" : oemUrl ) ;
}
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-11-11 21:25:50 -08:00
_activePrinters . Remove ( printer ) ;
if ( allowChangedEvent )
{
this . OnOpenPrintersChanged ( new OpenPrintersChangedEventArgs ( printer , OpenPrintersChangedEventArgs . OperationType . Remove ) ) ;
}
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
2017-12-16 08:55:20 -08:00
public void LaunchBrowser ( string targetUri )
{
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" ) )
{
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}" ;
}
}
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
2018-04-05 13:55:23 -07:00
public static Func < string , IProgress < ProgressStatus > , Task > SyncPrinterProfiles ;
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
private EventHandler unregisterEvents ;
2018-10-24 21:10:39 -07:00
private 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-04-09 15:17:05 -07:00
private List < SceneSelectionOperation > registeredSceneOperations ;
2018-07-12 09:22:28 -07:00
public ThumbnailsConfig Thumbnails { get ; }
2018-06-21 09:02:31 -07:00
2018-04-12 08:42:10 -07:00
private void RebuildSceneOperations ( ThemeConfig theme )
2017-09-18 17:57:06 -07:00
{
2018-04-09 15:17:05 -07:00
registeredSceneOperations = new List < SceneSelectionOperation > ( )
2017-10-13 15:16:14 -07:00
{
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2018-03-28 17:20:47 -07:00
{
2018-06-21 21:02:37 -07:00
OperationType = typeof ( GroupObject3D ) ,
2018-05-26 08:34:24 -07:00
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Group" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-03-28 17:20:47 -07:00
{
2018-11-11 08:42:13 -08:00
var scene = sceneContext . Scene ;
2018-04-09 15:17:05 -07:00
var selectedItem = scene . SelectedItem ;
scene . SelectedItem = null ;
2018-03-28 17:20:47 -07:00
2018-06-21 21:02:37 -07:00
var newGroup = new GroupObject3D ( ) ;
2018-04-09 15:17:05 -07:00
// When grouping items, move them to be centered on their bounding box
newGroup . Children . Modify ( ( gChildren ) = >
{
selectedItem . Clone ( ) . Children . Modify ( ( sChildren ) = >
2018-03-28 17:20:47 -07:00
{
2018-04-09 15:17:05 -07:00
var center = selectedItem . GetAxisAlignedBoundingBox ( ) . Center ;
2018-03-28 17:20:47 -07:00
2018-04-09 15:17:05 -07:00
foreach ( var child in sChildren )
{
child . Translate ( - center . X , - center . Y , 0 ) ;
gChildren . Add ( child ) ;
}
newGroup . Translate ( center . X , center . Y , 0 ) ;
} ) ;
2018-03-28 17:20:47 -07:00
} ) ;
2018-04-09 15:17:05 -07:00
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( selectedItem . Children . ToList ( ) , new List < IObject3D > { newGroup } ) ) ;
2018-03-28 17:20:47 -07:00
2018-04-09 15:17:05 -07:00
newGroup . MakeNameNonColliding ( ) ;
2018-03-28 17:20:47 -07:00
2018-04-09 15:17:05 -07:00
scene . SelectedItem = newGroup ;
} ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null
2018-06-21 21:02:37 -07:00
& & scene . SelectedItem is SelectionGroupObject3D
2018-04-09 15:17:05 -07:00
& & scene . SelectedItem . Children . Count > 1 ,
Icon = AggContext . StaticData . LoadIcon ( "group.png" , 16 , 16 ) . SetPreMultiply ( ) ,
2018-03-28 17:20:47 -07:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
{
TitleResolver = ( ) = > "Ungroup" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = > sceneContext . Scene . UngroupSelection ( ) ,
2018-09-22 17:53:15 -07:00
IsEnabled = ( scene ) = >
{
var selectedItem = scene . SelectedItem ;
if ( selectedItem ! = null )
{
2018-10-09 14:38:08 -07:00
return selectedItem is GroupObject3D
| | selectedItem . GetType ( ) = = typeof ( Object3D ) ;
2018-09-22 17:53:15 -07:00
}
return false ;
} ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "ungroup.png" , 16 , 16 ) . SetPreMultiply ( ) ,
} ,
new SceneSelectionSeparator ( ) ,
new SceneSelectionOperation ( )
{
TitleResolver = ( ) = > "Duplicate" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = > sceneContext . DuplicateItem ( 5 ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "duplicate.png" ) . SetPreMultiply ( ) ,
} ,
new SceneSelectionOperation ( )
2018-02-13 13:42:57 -08:00
{
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Remove" . Localize ( ) ,
2018-11-11 08:51:16 -08:00
Action = ( sceneContext ) = > sceneContext . Scene . DeleteSelection ( ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "remove.png" ) . SetPreMultiply ( ) ,
} ,
new SceneSelectionSeparator ( ) ,
new SceneSelectionOperation ( )
{
2018-06-21 21:02:37 -07:00
OperationType = typeof ( AlignObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Align" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-02-13 13:42:57 -08:00
{
2018-11-11 08:42:13 -08:00
var scene = sceneContext . Scene ;
2018-06-20 17:16:38 -07:00
var selectedItem = scene . SelectedItem ;
2018-06-21 21:02:37 -07:00
var align = new AlignObject3D ( ) ;
2018-06-20 17:16:38 -07:00
align . AddSelectionAsChildren ( scene , selectedItem ) ;
align . Invalidate ( new InvalidateArgs ( align , InvalidateType . Properties , null ) ) ;
2018-04-09 15:17:05 -07:00
} ,
2018-04-12 08:42:10 -07:00
Icon = AggContext . StaticData . LoadIcon ( "align_left.png" , 16 , 16 , theme . InvertIcons ) . SetPreMultiply ( ) ,
2018-06-21 21:02:37 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem is SelectionGroupObject3D ,
2018-02-13 13:42:57 -08:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2017-10-17 09:40:56 -07:00
{
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Lay Flat" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2017-10-23 14:26:10 -07:00
{
2018-11-11 08:42:13 -08:00
var scene = sceneContext . Scene ;
2018-07-13 06:55:00 -07:00
var selectedItem = scene . SelectedItem ;
if ( selectedItem ! = null )
2018-04-09 15:17:05 -07:00
{
2018-07-13 06:55:00 -07:00
scene . MakeLowestFaceFlat ( selectedItem ) ;
2018-04-09 15:17:05 -07:00
}
} ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "lay_flat.png" , 16 , 16 ) . SetPreMultiply ( ) ,
2018-01-09 15:47:00 -08:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2018-01-18 07:33:12 -08:00
{
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Make Support" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-01-18 07:33:12 -08:00
{
2018-11-11 08:42:13 -08:00
var scene = sceneContext . Scene ;
2018-04-09 15:17:05 -07:00
if ( scene . SelectedItem ! = null
2018-05-29 17:46:59 -07:00
& & ! scene . SelectedItem . VisibleMeshes ( ) . All ( i = > i . OutputType = = PrintOutputTypes . Support ) )
2018-04-09 15:17:05 -07:00
{
scene . UndoBuffer . AddAndDo ( new MakeSupport ( scene . SelectedItem ) ) ;
}
} ,
Icon = AggContext . StaticData . LoadIcon ( "support.png" ) . SetPreMultiply ( ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null ,
2018-01-18 07:33:12 -08:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionSeparator ( ) ,
new SceneSelectionOperation ( )
{
2018-05-22 22:06:20 -07:00
OperationType = typeof ( CombineObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Combine" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = > new CombineObject3D ( ) . WrapSelectedItemAndSelect ( sceneContext . Scene ) ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "combine.png" ) . SetPreMultiply ( ) ,
2018-06-21 21:02:37 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem is SelectionGroupObject3D ,
2018-04-09 15:17:05 -07:00
} ,
new SceneSelectionOperation ( )
{
2018-05-22 22:06:20 -07:00
OperationType = typeof ( SubtractObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Subtract" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = > new SubtractObject3D ( ) . WrapSelectedItemAndSelect ( sceneContext . Scene ) ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "subtract.png" ) . SetPreMultiply ( ) ,
2018-06-21 21:02:37 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem is SelectionGroupObject3D ,
2018-04-09 15:17:05 -07:00
} ,
new SceneSelectionOperation ( )
{
2018-05-22 22:06:20 -07:00
OperationType = typeof ( IntersectionObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Intersect" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = > new IntersectionObject3D ( ) . WrapSelectedItemAndSelect ( sceneContext . Scene ) ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "intersect.png" ) ,
2018-06-21 21:02:37 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem is SelectionGroupObject3D ,
2018-04-09 15:17:05 -07:00
} ,
new SceneSelectionOperation ( )
{
2018-05-22 22:06:20 -07:00
OperationType = typeof ( SubtractAndReplaceObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Subtract & Replace" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = > new SubtractAndReplaceObject3D ( ) . WrapSelectedItemAndSelect ( sceneContext . Scene ) ,
2018-04-09 15:17:05 -07:00
Icon = AggContext . StaticData . LoadIcon ( "subtract_and_replace.png" ) . SetPreMultiply ( ) ,
2018-06-21 21:02:37 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem is SelectionGroupObject3D ,
2018-04-09 15:17:05 -07:00
} ,
new SceneSelectionSeparator ( ) ,
new SceneSelectionOperation ( )
2018-01-26 17:53:54 -08:00
{
2018-06-21 21:02:37 -07:00
OperationType = typeof ( ArrayLinearObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Linear Array" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-02-07 15:57:27 -08:00
{
2018-06-21 21:02:37 -07:00
var array = new ArrayLinearObject3D ( ) ;
2018-11-11 08:42:13 -08:00
array . AddSelectionAsChildren ( sceneContext . Scene , sceneContext . Scene . SelectedItem ) ;
2018-06-20 17:16:38 -07:00
array . Invalidate ( new InvalidateArgs ( array , InvalidateType . Properties , null ) ) ;
2018-04-09 15:17:05 -07:00
} ,
Icon = AggContext . StaticData . LoadIcon ( "array_linear.png" ) . SetPreMultiply ( ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null & & ! ( scene . SelectedItem is SelectionGroupObject3D ) ,
2018-01-26 17:53:54 -08:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2018-02-09 18:10:41 -08:00
{
2018-06-21 21:02:37 -07:00
OperationType = typeof ( ArrayRadialObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Radial Array" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-02-09 18:10:41 -08:00
{
2018-06-21 21:02:37 -07:00
var array = new ArrayRadialObject3D ( ) ;
2018-11-11 08:42:13 -08:00
array . AddSelectionAsChildren ( sceneContext . Scene , sceneContext . Scene . SelectedItem ) ;
2018-06-20 17:16:38 -07:00
array . Invalidate ( new InvalidateArgs ( array , InvalidateType . Properties , null ) ) ;
2018-04-09 15:17:05 -07:00
} ,
Icon = AggContext . StaticData . LoadIcon ( "array_radial.png" ) . SetPreMultiply ( ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null & & ! ( scene . SelectedItem is SelectionGroupObject3D ) ,
2018-02-09 18:10:41 -08:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2018-02-09 18:10:41 -08:00
{
2018-06-21 21:02:37 -07:00
OperationType = typeof ( ArrayAdvancedObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Advanced Array" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-02-09 18:10:41 -08:00
{
2018-06-21 21:02:37 -07:00
var array = new ArrayAdvancedObject3D ( ) ;
2018-11-11 08:42:13 -08:00
array . AddSelectionAsChildren ( sceneContext . Scene , sceneContext . Scene . SelectedItem ) ;
2018-06-20 17:16:38 -07:00
array . Invalidate ( new InvalidateArgs ( array , InvalidateType . Properties , null ) ) ;
2018-04-09 15:17:05 -07:00
} ,
Icon = AggContext . StaticData . LoadIcon ( "array_advanced.png" ) . SetPreMultiply ( ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null & & ! ( scene . SelectedItem is SelectionGroupObject3D ) ,
2018-02-09 18:10:41 -08:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionSeparator ( ) ,
new SceneSelectionOperation ( )
2018-04-01 16:06:31 -07:00
{
2018-05-22 22:06:20 -07:00
OperationType = typeof ( PinchObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Pinch" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-04-09 15:17:05 -07:00
{
var pinch = new PinchObject3D ( ) ;
2018-11-11 08:42:13 -08:00
pinch . WrapSelectedItemAndSelect ( sceneContext . Scene ) ;
2018-04-09 15:17:05 -07:00
} ,
2018-04-12 08:42:10 -07:00
Icon = AggContext . StaticData . LoadIcon ( "pinch.png" , 16 , 16 , theme . InvertIcons ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null ,
2018-04-01 16:06:31 -07:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2018-04-02 14:15:27 -07:00
{
2018-05-22 22:06:20 -07:00
OperationType = typeof ( CurveObject3D ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Curve" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-04-09 15:17:05 -07:00
{
var curve = new CurveObject3D ( ) ;
2018-11-11 08:42:13 -08:00
curve . WrapSelectedItemAndSelect ( sceneContext . Scene ) ;
2018-04-09 15:17:05 -07:00
} ,
2018-04-12 08:42:10 -07:00
Icon = AggContext . StaticData . LoadIcon ( "curve.png" , 16 , 16 , theme . InvertIcons ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null ,
2018-04-02 14:15:27 -07:00
} ,
2018-04-09 15:17:05 -07:00
new SceneSelectionOperation ( )
2018-03-17 20:53:36 -07:00
{
2018-07-03 08:32:02 -07:00
OperationType = typeof ( FitToBoundsObject3D_2 ) ,
2018-04-09 15:17:05 -07:00
TitleResolver = ( ) = > "Fit to Bounds" . Localize ( ) ,
2018-11-11 08:42:13 -08:00
Action = ( sceneContext ) = >
2018-04-09 15:17:05 -07:00
{
2018-11-11 08:42:13 -08:00
var scene = sceneContext . Scene ;
2018-04-09 15:17:05 -07:00
var selectedItem = scene . SelectedItem ;
scene . SelectedItem = null ;
2018-07-03 08:32:02 -07:00
var fit = FitToBoundsObject3D_2 . Create ( selectedItem . Clone ( ) ) ;
2018-04-09 15:17:05 -07:00
fit . MakeNameNonColliding ( ) ;
2018-03-17 20:53:36 -07:00
2018-04-09 15:17:05 -07:00
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( new List < IObject3D > { selectedItem } , new List < IObject3D > { fit } ) ) ;
scene . SelectedItem = fit ;
} ,
2018-05-17 16:01:26 -07:00
Icon = AggContext . StaticData . LoadIcon ( "fit.png" , 16 , 16 , theme . InvertIcons ) ,
2018-07-13 06:55:00 -07:00
IsEnabled = ( scene ) = > scene . SelectedItem ! = null & & ! ( scene . SelectedItem is SelectionGroupObject3D ) ,
2018-03-17 20:53:36 -07:00
} ,
2018-04-09 15:17:05 -07:00
} ;
2018-10-26 09:29:22 -07:00
var operationIconsByType = new Dictionary < Type , Func < ImageBuffer > > ( ) ;
2018-05-22 22:06:20 -07:00
2018-06-21 09:56:52 -07:00
foreach ( var operation in registeredSceneOperations )
2018-05-22 22:06:20 -07:00
{
if ( operation . OperationType ! = null )
{
2018-10-26 09:29:22 -07:00
operationIconsByType . Add ( operation . OperationType , ( ) = > operation . Icon ) ;
2018-05-22 22:06:20 -07:00
}
}
2018-06-21 09:56:52 -07:00
// TODO: Use custom selection group icon if reusing group icon seems incorrect
//
// Explicitly register SelectionGroup icon
2018-10-26 09:29:22 -07:00
if ( operationIconsByType . TryGetValue ( typeof ( GroupObject3D ) , out Func < ImageBuffer > groupIconSource ) )
2018-06-21 09:56:52 -07:00
{
2018-10-26 09:29:22 -07:00
operationIconsByType . Add ( typeof ( SelectionGroupObject3D ) , groupIconSource ) ;
2018-06-21 09:56:52 -07:00
}
this . Thumbnails . OperationIcons = operationIconsByType ;
2018-07-10 15:34:08 -07:00
2018-10-26 09:29:22 -07:00
operationIconsByType . Add ( typeof ( ImageObject3D ) , ( ) = > AggContext . StaticData . LoadIcon ( "140.png" , 16 , 16 , theme . InvertIcons ) ) ;
2018-04-09 15:17:05 -07:00
}
2017-09-18 17:57:06 -07:00
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 ( )
{
UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show ( new HelpPage ( "AllGuides" ) ) ;
} ) ;
}
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 ) ;
double radius = size / 8.0 ;
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 ( ) ;
graphics . Render ( new Stroke ( new Arc ( frame . Width / 2 , frame . Height / 2 ,
size / 4 - strokeWidth / 2 , size / 4 - strokeWidth / 2 ,
MathHelper . Tau / frameCount * i ,
MathHelper . Tau / 4 + MathHelper . Tau / frameCount * i ) , strokeWidth ) , color ) ;
workingAnimation . AddImage ( frame ) ;
}
return workingAnimation ;
}
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
static int applicationInstanceCount = 0 ;
public static int ApplicationInstanceCount
{
get
{
if ( applicationInstanceCount = = 0 )
{
Assembly mcAssembly = Assembly . GetEntryAssembly ( ) ;
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-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 ( ) ,
2018-10-07 11:36:52 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "download_20x20.png" ) ) ,
2018-10-06 13:55:48 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "download_folder.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 )
{
UseIncrementedNameDuringTypeChange = true
} ) ) ;
}
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 ( ) ,
2018-10-07 11:36:52 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "library_20x20.png" ) ) ,
2018-10-06 13:55:48 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "library_folder.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 ) )
{
2017-12-15 14:55:10 -08: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 ( ) ,
2018-10-07 11:36:52 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "history_20x20.png" ) ) ,
2018-10-06 13:55:48 -07:00
AggContext . StaticData . LoadIcon ( Path . Combine ( "Library" , "history_folder.png" ) ) ,
2018-04-29 11:08:09 -07:00
( ) = > new RootHistoryContainer ( ) ) ) ;
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 ( ( ) = >
{
if ( printer ! = null | | this . ActivePrinters . Count = = 1 )
{
// 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
{
// Resolve printer context before showing export page
DialogWindow dialogWindow = null ;
dialogWindow = DialogWindow . Show (
2018-11-13 08:13:41 -08:00
new SelectPrinterProfilePage (
2018-11-12 09:32:08 -08:00
"Next" . Localize ( ) ,
( selectedPrinter ) = >
{
2018-11-13 08:13:41 -08:00
var historyContainer = ApplicationController . Instance . Library . PlatingHistory ;
selectedPrinter . Bed . LoadEmptyContent (
new EditContext ( )
{
ContentStore = historyContainer ,
SourceItem = historyContainer . NewPlatingItem ( )
} ) ;
2018-11-12 09:32:08 -08:00
dialogWindow . ChangeToPage (
new ExportPrintItemPage ( libraryItems , centerOnBed , selectedPrinter ) ) ;
} ) ) ;
}
} ) ;
}
2018-09-22 18:59:42 -07:00
public static IObject3D SelectionAsSingleClone ( IObject3D selection )
{
IEnumerable < IObject3D > items = new [ ] { selection } ;
// If SelectionGroup, operate on Children instead
if ( selection is SelectionGroupObject3D )
{
items = selection . Children ;
var group = new GroupObject3D ( ) ;
group . Children . Modify ( children = >
{
children . AddRange ( items . Select ( o = > o . Clone ( ) ) ) ;
} ) ;
return group ;
}
return selection . Clone ( ) ;
}
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 ) = >
{
_activePrinters = new List < PrinterConfig > ( ) ;
} ;
2018-10-13 17:58:54 -07:00
this . RebuildSceneOperations ( this . Theme ) ;
2018-04-07 12:17:23 -07:00
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
2017-10-31 11:43:25 -07:00
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 ( ) ) ;
this . Graph . RegisterOperation (
typeof ( ImageObject3D ) ,
2018-07-10 15:34:08 -07:00
typeof ( ImageToPathObject3D ) ,
2018-06-06 15:46:30 -07:00
"Image to Path" . Localize ( ) ,
( sceneItem , scene ) = >
{
if ( sceneItem is IObject3D imageObject )
{
2018-06-21 21:02:37 -07:00
var path = new ImageToPathObject3D ( ) ;
2018-06-06 15:46:30 -07:00
sceneItem . WrapWith ( path , scene ) ;
2018-06-20 17:16:38 -07:00
path . Invalidate ( new InvalidateArgs ( path , InvalidateType . Properties , null ) ) ;
2018-06-06 15:46:30 -07:00
}
return Task . CompletedTask ;
} ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "noun_479927.png" , theme . InvertIcons ) ) ;
2018-06-06 15:46:30 -07:00
2018-07-06 07:10:39 -07:00
this . Graph . RegisterOperation (
typeof ( IObject3D ) ,
2018-07-10 15:34:08 -07:00
typeof ( TranslateObject3D ) ,
2018-07-06 07:10:39 -07:00
"Translate" . Localize ( ) ,
( sceneItem , scene ) = >
{
var selectedItem = scene . SelectedItem ;
2018-09-22 18:59:42 -07:00
var replaceItems = ( selectedItem is SelectionGroupObject3D ) ? selectedItem . Children . ToList ( ) : new List < IObject3D > { selectedItem } ;
2018-07-06 07:10:39 -07:00
scene . SelectedItem = null ;
2018-09-22 18:59:42 -07:00
var selectedClone = SelectionAsSingleClone ( selectedItem ) ;
var tranlate = TranslateObject3D . Create ( selectedClone ) ;
tranlate . MakeNameNonColliding ( ) ;
2018-07-06 07:10:39 -07:00
2018-09-22 18:59:42 -07:00
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( replaceItems , new List < IObject3D > { tranlate } ) ) ;
scene . SelectedItem = tranlate ;
2018-07-06 07:10:39 -07:00
return Task . CompletedTask ;
} ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( Path . Combine ( "ViewTransformControls" , "translate.png" ) , 16 , 16 , theme . InvertIcons ) ) ;
2018-07-06 07:10:39 -07:00
2018-06-26 15:54:05 -07:00
this . Graph . RegisterOperation (
typeof ( IObject3D ) ,
2018-07-10 15:34:08 -07:00
typeof ( RotateObject3D_2 ) ,
2018-06-26 15:54:05 -07:00
"Rotate" . Localize ( ) ,
( sceneItem , scene ) = >
{
2018-07-01 20:53:42 -07:00
var selectedItem = scene . SelectedItem ;
2018-09-22 18:59:42 -07:00
var replaceItems = ( selectedItem is SelectionGroupObject3D ) ? selectedItem . Children . ToList ( ) : new List < IObject3D > { selectedItem } ;
2018-07-01 20:53:42 -07:00
scene . SelectedItem = null ;
2018-09-22 18:59:42 -07:00
var selectedClone = SelectionAsSingleClone ( selectedItem ) ;
var rotate = new RotateObject3D_2 ( selectedClone ) ;
2018-07-01 20:53:42 -07:00
rotate . MakeNameNonColliding ( ) ;
2018-09-22 18:59:42 -07:00
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( replaceItems , new List < IObject3D > { rotate } ) ) ;
2018-07-01 20:53:42 -07:00
scene . SelectedItem = rotate ;
2018-06-26 15:54:05 -07:00
return Task . CompletedTask ;
} ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( Path . Combine ( "ViewTransformControls" , "rotate.png" ) , 16 , 16 , theme . InvertIcons ) ) ;
2018-06-26 15:54:05 -07:00
2018-08-01 18:05:04 -07:00
this . Graph . RegisterOperation (
typeof ( IObject3D ) ,
2018-08-02 15:13:45 -07:00
typeof ( ComponentObject3D ) ,
2018-08-01 18:05:04 -07:00
"Make Component" . Localize ( ) ,
( sceneItem , scene ) = >
{
2018-08-02 15:45:31 -07:00
IEnumerable < IObject3D > items = new [ ] { sceneItem } ;
// If SelectionGroup, operate on Children instead
if ( sceneItem is SelectionGroupObject3D )
{
items = sceneItem . Children ;
}
// Dump selection forcing collapse of selection group
2018-08-01 18:05:04 -07:00
scene . SelectedItem = null ;
2018-08-02 15:45:31 -07:00
var component = new ComponentObject3D
{
Name = "New Component" ,
Finalized = false
} ;
// Copy an selected item into the component as a clone
component . Children . Modify ( children = >
{
children . AddRange ( items . Select ( o = > o . Clone ( ) ) ) ;
} ) ;
2018-08-01 18:05:04 -07:00
component . MakeNameNonColliding ( ) ;
2018-08-02 15:45:31 -07:00
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( items , new [ ] { component } ) ) ;
2018-08-01 18:05:04 -07:00
scene . SelectedItem = component ;
return Task . CompletedTask ;
} ,
isVisible : ( sceneItem ) = >
{
2018-08-06 12:21:44 -07:00
return sceneItem . Parent ! = null
& & sceneItem . Parent . Parent = = null
2018-08-02 15:13:45 -07:00
& & sceneItem . DescendantsAndSelf ( ) . All ( d = > ! ( d is ComponentObject3D ) ) ;
} ,
2018-08-01 18:05:04 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "scale_32x32.png" , 16 , 16 , theme . InvertIcons ) ) ;
2018-08-03 12:20:56 -07:00
this . Graph . RegisterOperation (
typeof ( IObject3D ) ,
typeof ( ComponentObject3D ) ,
"Edit Component" . Localize ( ) ,
( sceneItem , scene ) = >
{
if ( sceneItem is ComponentObject3D componentObject )
{
// Enable editing mode
componentObject . Finalized = false ;
// Force editor rebuild
scene . SelectedItem = null ;
scene . SelectedItem = componentObject ;
}
return Task . CompletedTask ;
} ,
isVisible : ( sceneItem ) = >
{
2018-08-06 12:21:44 -07:00
return sceneItem . Parent ! = null
& & sceneItem . Parent . Parent = = null
2018-08-03 12:20:56 -07:00
& & sceneItem is ComponentObject3D componentObject
& & componentObject . Finalized ;
} ,
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "scale_32x32.png" , 16 , 16 , theme . InvertIcons ) ) ;
2018-07-06 17:11:33 -07:00
this . Graph . RegisterOperation (
typeof ( IObject3D ) ,
2018-07-10 15:34:08 -07:00
typeof ( ScaleObject3D ) ,
2018-07-06 17:11:33 -07:00
"Scale" . Localize ( ) ,
( sceneItem , scene ) = >
{
var selectedItem = scene . SelectedItem ;
2018-09-22 18:59:42 -07:00
var replaceItems = ( selectedItem is SelectionGroupObject3D ) ? selectedItem . Children . ToList ( ) : new List < IObject3D > { selectedItem } ;
2018-07-06 17:11:33 -07:00
scene . SelectedItem = null ;
2018-09-22 18:59:42 -07:00
var selectedClone = SelectionAsSingleClone ( selectedItem ) ;
var scale = new ScaleObject3D ( selectedClone ) ;
2018-07-06 17:11:33 -07:00
scale . MakeNameNonColliding ( ) ;
2018-09-22 18:59:42 -07:00
scene . UndoBuffer . AddAndDo ( new ReplaceCommand ( replaceItems , new List < IObject3D > { scale } ) ) ;
2018-07-06 17:11:33 -07:00
scene . SelectedItem = scale ;
return Task . CompletedTask ;
} ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "scale_32x32.png" , 16 , 16 , theme . InvertIcons ) ) ;
2018-07-06 17:11:33 -07:00
this . Graph . RegisterOperation (
typeof ( IObject3D ) ,
2018-07-10 15:34:08 -07:00
typeof ( MirrorObject3D ) ,
2018-07-06 17:11:33 -07:00
"Mirror" . Localize ( ) ,
( sceneItem , scene ) = >
{
var mirror = new MirrorObject3D ( ) ;
mirror . WrapSelectedItemAndSelect ( scene ) ;
return Task . CompletedTask ;
} ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "mirror_32x32.png" , 16 , 16 , theme . InvertIcons ) ) ;
2018-07-06 17:11:33 -07:00
2018-06-06 15:46:30 -07:00
this . Graph . RegisterOperation (
typeof ( IPathObject ) ,
2018-07-10 15:34:08 -07:00
typeof ( LinearExtrudeObject3D ) ,
2018-06-06 15:46:30 -07:00
"Linear Extrude" . Localize ( ) ,
( sceneItem , scene ) = >
{
if ( sceneItem is IPathObject imageObject )
{
2018-06-21 21:02:37 -07:00
var extrude = new LinearExtrudeObject3D ( ) ;
2018-06-20 17:16:38 -07:00
sceneItem . WrapWith ( extrude , scene ) ;
extrude . Invalidate ( new InvalidateArgs ( extrude , InvalidateType . Properties , null ) ) ;
2018-06-06 15:46:30 -07:00
}
return Task . CompletedTask ;
} ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "noun_84751.png" , theme . InvertIcons ) ) ;
2018-06-06 15:46:30 -07:00
this . Graph . RegisterOperation (
typeof ( IPathObject ) ,
2018-07-10 15:34:08 -07:00
typeof ( SmoothPathObject3D ) ,
2018-06-06 15:46:30 -07:00
"Smooth Path" . Localize ( ) ,
( sceneItem , scene ) = >
{
if ( sceneItem is IPathObject imageObject )
{
2018-06-21 21:02:37 -07:00
var smoothPath = new SmoothPathObject3D ( ) ;
2018-06-06 15:46:30 -07:00
sceneItem . WrapWith ( smoothPath , scene ) ;
2018-06-20 17:16:38 -07:00
smoothPath . Invalidate ( new InvalidateArgs ( smoothPath , InvalidateType . Properties , null ) ) ;
2018-06-06 15:46:30 -07:00
}
return Task . CompletedTask ;
} ,
2018-08-08 07:49:39 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "noun_simplify_340976_000000.png" , 16 , 16 , theme . InvertIcons ) ) ;
this . Graph . RegisterOperation (
typeof ( IPathObject ) ,
typeof ( InflatePathObject3D ) ,
"Inflate Path" . Localize ( ) ,
( sceneItem , scene ) = >
{
if ( sceneItem is IPathObject imageObject )
{
var inflatePath = new InflatePathObject3D ( ) ;
sceneItem . WrapWith ( inflatePath , scene ) ;
inflatePath . Invalidate ( new InvalidateArgs ( inflatePath , InvalidateType . Properties , null ) ) ;
}
return Task . CompletedTask ;
} ,
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "noun_expand_1823853_000000.png" , 16 , 16 , theme . InvertIcons ) ) ;
2017-06-21 07:41:12 -07:00
2018-06-06 18:18:33 -07:00
this . Graph . RegisterOperation (
2018-06-07 14:20:39 -07:00
typeof ( IObject3D ) ,
2018-07-10 15:34:08 -07:00
typeof ( BaseObject3D ) ,
2018-06-06 18:18:33 -07:00
"Add Base" . Localize ( ) ,
2018-06-07 14:20:39 -07:00
( item , scene ) = >
2018-06-06 18:18:33 -07:00
{
2018-06-15 14:37:07 -07:00
bool wasSelected = scene . SelectedItem = = item ;
2018-06-07 14:20:39 -07:00
2018-06-15 14:37:07 -07:00
var newChild = item . Clone ( ) ;
var baseMesh = new BaseObject3D ( )
{
Matrix = newChild . Matrix
} ;
newChild . Matrix = Matrix4X4 . Identity ;
baseMesh . Children . Add ( newChild ) ;
2018-06-20 17:16:38 -07:00
baseMesh . Invalidate ( new InvalidateArgs ( baseMesh , InvalidateType . Properties , null ) ) ;
2018-06-15 14:37:07 -07: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
}
return Task . CompletedTask ;
} ,
2018-06-23 14:18:04 -07:00
isVisible : ( sceneItem ) = > sceneItem . Children . Any ( ( i ) = > i is IPathObject ) ,
2018-07-10 15:34:08 -07:00
iconCollector : ( theme ) = > AggContext . StaticData . LoadIcon ( "noun_55060.png" , theme . InvertIcons ) ) ;
2018-06-23 14:18:04 -07:00
2018-11-08 17:16:35 -08:00
this . InitializeLibrary ( ) ;
HashSet < IObject3DEditor > mappedEditors ;
objectEditorsByType = new Dictionary < Type , HashSet < IObject3DEditor > > ( ) ;
// Initialize plugins, passing the MatterControl assembly as the only non-dll instance
//PluginFinder.Initialize(Assembly.GetExecutingAssembly());
foreach ( IObject3DEditor editor in PluginFinder . CreateInstancesOf < IObject3DEditor > ( ) )
{
foreach ( Type type in editor . SupportedTypes ( ) )
{
if ( ! objectEditorsByType . TryGetValue ( type , out mappedEditors ) )
{
mappedEditors = new HashSet < IObject3DEditor > ( ) ;
objectEditorsByType . Add ( type , mappedEditors ) ;
}
2018-01-30 14:48:53 -08:00
2018-11-08 17:16:35 -08:00
mappedEditors . Add ( editor ) ;
}
}
}
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 ) = >
{
if ( clickedOk & & printerConnection . PrinterIsPaused )
{
printerConnection . Resume ( ) ;
}
} ,
message ,
"Printer Hardware Error" . Localize ( ) ,
StyledMessageBox . MessageType . YES_NO ,
"Resume" . Localize ( ) ,
"OK" . Localize ( ) )
) ;
}
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 ;
Tasks . Execute ( "" , ( 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
2018-07-17 10:04:08 -07:00
& & printerConnection . ContinuHoldingTemperature )
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 ( ) ,
( int ) ( printerConnection . SecondsToHoldTemperature ) / 60 ,
( int ) ( printerConnection . SecondsToHoldTemperature ) % 60 ) ;
}
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
}
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 ( ) ,
2018-07-17 10:04:08 -07:00
StopAction = ( ) = > UiThread . RunOnIdle ( ( ) = >
{
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-04-18 14:38:09 -07:00
public bool RunAnyRequiredPrinterSetup ( PrinterConfig printer , ThemeConfig theme )
2018-04-06 14:58:25 -07:00
{
2018-10-19 15:46:36 -07:00
// run probe calibration first if we need to
if ( ProbeCalibrationWizard . NeedsToBeRun ( printer ) )
2018-04-06 14:58:25 -07:00
{
2018-10-19 15:46:36 -07:00
UiThread . RunOnIdle ( ( ) = >
2018-04-06 14:58:25 -07:00
{
2018-11-02 16:14:37 -07:00
ProbeCalibrationWizard . Start ( printer , theme ) ;
2018-10-19 15:46:36 -07:00
} ) ;
return true ;
}
// run the leveling wizard if we need to
2018-11-24 15:01:06 -08:00
if ( LevelingValidation . NeedsToBeRun ( printer ) )
2018-10-19 15:46:36 -07:00
{
UiThread . RunOnIdle ( ( ) = >
2018-04-06 14:58:25 -07:00
{
2018-11-02 16:14:37 -07:00
PrintLevelingWizard . Start ( printer , theme ) ;
} ) ;
return true ;
}
// run load filament if we need to
if ( LoadFilamentWizard . NeedsToBeRun ( printer ) )
{
UiThread . RunOnIdle ( ( ) = >
{
LoadFilamentWizard . Start ( printer , theme , false ) ;
2018-10-19 15:46:36 -07:00
} ) ;
2018-04-06 14:58:25 -07:00
return true ;
}
return false ;
}
2018-03-26 16:54:36 -07:00
public HashSet < IObject3DEditor > GetEditorsForType ( Type selectedItemType )
{
HashSet < IObject3DEditor > mappedEditors ;
objectEditorsByType . TryGetValue ( selectedItemType , out mappedEditors ) ;
if ( mappedEditors = = null )
{
foreach ( var kvp in objectEditorsByType )
{
var editorType = kvp . Key ;
2018-06-20 17:16:38 -07:00
if ( editorType . IsAssignableFrom ( selectedItemType )
& & selectedItemType ! = typeof ( Object3D ) )
2018-03-26 16:54:36 -07:00
{
mappedEditors = kvp . Value ;
break ;
}
}
}
return mappedEditors ;
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-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
}
2018-05-15 13:56:05 -07:00
static Dictionary < NamedTypeFace , TypeFace > TypeFaceCache { get ; set ; } = 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" ) ) )
} ;
public static TypeFace GetTypeFace ( NamedTypeFace Name )
{
if ( ! TypeFaceCache . ContainsKey ( Name ) )
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
TypeFace typeFace = new TypeFace ( ) ;
var file = Path . Combine ( "Fonts" , $"{Name}.ttf" ) ;
var exists = AggContext . StaticData . FileExists ( file ) ;
var stream = exists ? AggContext . StaticData . OpenStream ( file ) : null ;
2018-05-22 22:06:20 -07:00
if ( stream ! = null
2018-05-15 13:56:05 -07:00
& & typeFace . LoadTTF ( stream ) )
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
TypeFaceCache . Add ( Name , typeFace ) ;
}
else
{
// try the svg
file = Path . Combine ( "Fonts" , $"{Name}.svg" ) ;
exists = AggContext . StaticData . FileExists ( file ) ;
typeFace = exists ? TypeFace . LoadFrom ( AggContext . StaticData . ReadAllText ( file ) ) : null ;
if ( typeFace ! = null )
{
TypeFaceCache . Add ( Name , typeFace ) ;
}
else
{
// assign it to the default
TypeFaceCache . Add ( Name , TypeFaceCache [ NamedTypeFace . Liberation_Sans ] ) ;
}
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
return TypeFaceCache [ Name ] ;
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
2018-01-28 07:53:23 -08:00
private static TypeFace titilliumTypeFace = null ;
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
return Task . FromResult (
JsonConvert . DeserializeObject < T > ( cachedFile ) ) ;
}
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 ) ) ;
}
/// <summary>
/// Requests fresh content from online services, falling back to cached content if offline
/// </summary>
/// <param name="collector">The custom collector function to load the content</param>
/// <returns></returns>
public async static Task < T > LoadCacheableAsync < T > ( string cacheKey , string cacheScope , Func < Task < T > > collector , string staticDataFallbackPath = null ) where T : class
{
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
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 ReloadAll ( )
{
2018-04-24 13:32:20 -07:00
UiThread . RunOnIdle ( ( ) = >
2017-11-08 23:39:35 -08:00
{
2018-04-24 13:32:20 -07:00
var reloadingOverlay = new GuiWidget
{
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
2018-04-24 13:32:20 -07:00
this . IsReloading = true ;
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-04-24 13:32:20 -07:00
UiThread . RunOnIdle ( ( ) = >
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-24 08:54:44 -07:00
GuiWidget . LayoutCount = 0 ;
2018-11-07 13:26:44 -08:00
2018-04-24 13:32:20 -07: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-10-30 14:02:50 -07:00
MainView = new MainViewWidget ( ApplicationController . Instance . Theme ) ;
2018-04-24 13:32:20 -07:00
this . DoneReloadingAll ? . CallEvents ( null , null ) ;
using ( new QuickTimer ( "Time to AddMainview: " ) )
{
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-11-07 13:26:44 -08:00
2018-06-24 08:54:44 -07: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
2018-04-24 13:32:20 -07:00
this . IsReloading = false ;
} ) ;
2017-11-07 13:54:09 -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
}
static int reloadCount = 0 ;
2018-02-13 17:00:23 -08:00
public async 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 ( ) ;
2017-11-03 10:32:11 -07:00
public string ShortProductName = > "MatterControl" ;
2017-10-07 15:17:39 -07:00
public string ProductName = > "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-09-26 14:09:35 -07:00
// Show the End User License Agreement if it has not been shown (on windows it is shown in the installer)
2018-10-24 13:51:30 -07:00
if ( AggContext . OperatingSystem ! = OSType . Windows )
2017-12-18 17:22:50 -08:00
{
2018-11-01 09:36:58 -07:00
// *********************************************************************************
// TODO: This should happen much earlier in the process and we should conditionally
// show License page or RootSystemWindow
// *********************************************************************************
//
2018-09-26 14:09:35 -07:00
// Make sure this window is show modal (if available)
2017-12-18 17:22:50 -08:00
// show this last so it is on top
2018-10-24 13:51:30 -07:00
if ( UserSettings . Instance . get ( UserSettingsKey . SoftwareLicenseAccepted ) ! = "true" )
2017-12-18 17:22:50 -08:00
{
UiThread . RunOnIdle ( ( ) = > DialogWindow . Show < LicenseAgreementPage > ( ) ) ;
}
}
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-11-11 21:25:50 -08:00
public async Task < PrinterConfig > OpenPrinter ( string printerID , bool loadPlateFromHistory = true )
{
2018-11-12 09:41:44 -08:00
if ( ! _activePrinters . Any ( p = > p . Settings . ID = = printerID ) )
{
2018-11-21 09:48:43 -08:00
ProfileManager . Instance . OpenPrinter ( printerID ) ;
2018-11-11 21:25:50 -08:00
2018-11-15 15:34:13 -08:00
var printer = new PrinterConfig ( await ProfileManager . LoadSettingsAsync ( printerID ) ) ;
2018-11-11 21:25:50 -08:00
2018-11-12 09:41:44 -08:00
_activePrinters . Add ( printer ) ;
if ( loadPlateFromHistory )
{
await printer . Bed . LoadPlateFromHistory ( ) ;
}
2018-11-11 21:25:50 -08:00
2018-11-12 09:41:44 -08:00
this . OnOpenPrintersChanged ( new OpenPrintersChangedEventArgs ( printer , OpenPrintersChangedEventArgs . OperationType . Add ) ) ;
2018-11-16 16:00:22 -08:00
if ( printer . Settings . PrinterSelected
& & printer . Settings . GetValue < bool > ( SettingsKey . auto_connect ) )
{
printer . Connection . Connect ( ) ;
}
2018-11-12 09:41:44 -08:00
return printer ;
}
2018-11-11 21:25:50 -08:00
2018-11-12 09:41:44 -08:00
return PrinterConfig . EmptyPrinter ;
2018-11-11 21:25:50 -08:00
}
2018-11-11 21:26:08 -08:00
public async Task OpenAllPrinters ( )
2018-11-11 21:25:50 -08:00
{
2018-11-11 21:26:08 -08:00
// TODO: broadcast message to UI to close all printer tabs
foreach ( var printerID in ProfileManager . Instance . OpenPrinterIDs )
{
await this . OpenPrinter ( printerID ) ;
}
2018-11-11 21:25:50 -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 ) ;
string SHA1 = BitConverter . ToString ( hash ) . Replace ( "-" , string . Empty ) ;
// Console.WriteLine("{0} {1} {2}", SHA1, timer.ElapsedMilliseconds, filePath);
return SHA1 ;
}
}
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>
/// Download an image from the web into the specified ImageBuffer
/// </summary>
/// <param name="uri"></param>
public void DownloadToImageAsync ( ImageBuffer imageToLoadInto , string uriToLoad , bool scaleToImageX , IRecieveBlenderByte scalingBlender = null )
{
WebClient client = new WebClient ( ) ;
2018-09-29 15:48:41 -07:00
client . DownloadDataCompleted + = ( sender , e ) = >
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 we get a bad result we can get a target invocation exception. In that case just don't show anything
{
2018-09-29 15:48:41 -07:00
Stream stream = new MemoryStream ( e . Result ) ;
2017-09-16 01:11:44 -07:00
2018-09-29 15:48:41 -07:00
this . LoadImageInto ( imageToLoadInto , scaleToImageX , scalingBlender , stream ) ;
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
{
}
} ;
try
{
client . DownloadDataAsync ( new Uri ( uriToLoad ) ) ;
}
catch
{
}
}
2018-09-29 15:48:41 -07:00
private HttpClient httpClient = new HttpClient ( ) ;
public async Task LoadRemoteImage ( ImageBuffer imageToLoadInto , string uriToLoad , bool scaleToImageX , IRecieveBlenderByte scalingBlender = null )
{
try
{
using ( var stream = await httpClient . GetStreamAsync ( uriToLoad ) )
{
this . LoadImageInto ( imageToLoadInto , scaleToImageX , scalingBlender , stream ) ;
} ;
}
catch ( Exception ex )
{
Trace . WriteLine ( "Error loading image: " + uriToLoad ) ;
Trace . WriteLine ( ex . Message ) ;
}
}
private void LoadImageInto ( ImageBuffer imageToLoadInto , bool scaleToImageX , IRecieveBlenderByte scalingBlender , Stream stream )
{
if ( scalingBlender = = null )
{
scalingBlender = new BlenderBGRA ( ) ;
}
ImageBuffer unScaledImage = new ImageBuffer ( 10 , 10 ) ;
if ( scaleToImageX )
{
// scale the loaded image to the size of the target image
AggContext . StaticData . LoadImageData ( stream , unScaledImage ) ;
// If the source image (the one we downloaded) is more than twice as big as our dest image.
while ( unScaledImage . Width > imageToLoadInto . Width * 2 )
{
// The image sampler we use is a 2x2 filter so we need to scale by a max of 1/2 if we want to get good results.
// So we scale as many times as we need to get the Image to be the right size.
// If this were going to be a non-uniform scale we could do the x and y separately to get better results.
ImageBuffer halfImage = new ImageBuffer ( unScaledImage . Width / 2 , unScaledImage . Height / 2 , 32 , scalingBlender ) ;
halfImage . NewGraphics2D ( ) . Render ( unScaledImage , 0 , 0 , 0 , halfImage . Width / ( double ) unScaledImage . Width , halfImage . Height / ( double ) unScaledImage . Height ) ;
unScaledImage = halfImage ;
}
double finalScale = imageToLoadInto . Width / ( double ) unScaledImage . Width ;
imageToLoadInto . Allocate ( imageToLoadInto . Width , ( int ) ( unScaledImage . Height * finalScale ) , imageToLoadInto . Width * ( imageToLoadInto . BitDepth / 8 ) , imageToLoadInto . BitDepth ) ;
imageToLoadInto . NewGraphics2D ( ) . Render ( unScaledImage , 0 , 0 , 0 , finalScale , finalScale ) ;
}
else
{
AggContext . StaticData . LoadImageData ( stream , imageToLoadInto ) ;
}
imageToLoadInto . MarkImageChanged ( ) ;
}
2018-04-25 11:35:33 -07:00
/// <summary>
/// Download an image from the web into the specified ImageSequence
/// </summary>
/// <param name="uri"></param>
public void DownloadToImageSequenceAsync ( ImageSequence imageSequenceToLoadInto , string uriToLoad )
{
WebClient client = new WebClient ( ) ;
client . DownloadDataCompleted + = ( object sender , DownloadDataCompletedEventArgs e ) = >
{
try // if we get a bad result we can get a target invocation exception. In that case just don't show anything
{
2018-05-04 14:50:38 -07:00
Task . Run ( ( ) = >
{
// scale the loaded image to the size of the target image
byte [ ] raw = e . Result ;
Stream stream = new MemoryStream ( raw ) ;
var asyncImageSequence = new ImageSequence ( ) ;
2018-04-25 11:35:33 -07:00
2018-05-04 14:50:38 -07:00
AggContext . StaticData . LoadImageSequenceData ( stream , asyncImageSequence ) ;
UiThread . RunOnIdle ( ( ) = >
{
imageSequenceToLoadInto . Copy ( asyncImageSequence ) ;
imageSequenceToLoadInto . Invalidate ( ) ;
} ) ;
} ) ;
2018-04-25 11:35:33 -07:00
}
catch
{
}
} ;
try
{
client . DownloadDataAsync ( new Uri ( uriToLoad ) ) ;
}
catch
{
}
}
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
{
2018-10-24 21:10:39 -07:00
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
if ( ! registeredLibraryActions . TryGetValue ( section , out items ) )
{
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>
/// <returns></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
{
2018-10-24 21:10:39 -07:00
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
if ( registeredLibraryActions . TryGetValue ( section , out items ) )
{
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-01-09 15:47:00 -08:00
public IEnumerable < SceneSelectionOperation > RegisteredSceneOperations = > registeredSceneOperations ;
2017-09-18 17:57:06 -07:00
2018-02-06 13:31:25 -08:00
public static IObject3D ClipboardItem { get ; internal set ; }
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 ( ) ;
2018-07-09 23:29:34 -07:00
public Uri HelpArticleSource { get ; set ; }
2018-08-28 18:45:58 -07:00
public Dictionary < string , HelpArticle > HelpArticlesByID { get ; set ; }
2018-10-19 17:43:43 -07:00
2018-10-10 17:43:53 -07:00
public string MainTabKey { get ; internal set ; }
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 > ( ) ;
2018-11-06 16:08:13 -08:00
public static Type ServicesStatusType { get ; set ; }
2018-11-01 09:36:58 -07:00
2018-11-07 14:31:51 -08:00
public bool PrinterTabSelected { get ; set ; } = false ;
2018-11-11 13:16:32 -08:00
/// <summary>
/// Indicates if any ActivePrinter is running a print task, either in paused or printing states
/// </summary>
public bool AnyPrintTaskRunning = > this . ActivePrinters . Any ( p = > p . Connection . PrinterIsPrinting | | p . Connection . PrinterIsPaused ) ;
2017-08-07 14:19:28 -07:00
public event EventHandler < WidgetSourceEventArgs > AddPrintersTabRightElement ;
public void NotifyPrintersTabRightElement ( GuiWidget sourceExentionArea )
{
AddPrintersTabRightElement ? . Invoke ( this , new WidgetSourceEventArgs ( sourceExentionArea ) ) ;
}
2017-06-16 18:04:47 -07:00
private string doNotAskAgainMessage = "Don't remind me again" . Localize ( ) ;
2018-02-09 18:11:55 -08:00
public async Task PrintPart ( EditContext editContext , PrinterConfig printer , IProgress < ProgressStatus > reporter , CancellationToken cancellationToken , bool overrideAllowGCode = false )
2017-06-16 18:04:47 -07:00
{
2018-02-09 18:11:55 -08:00
var partFilePath = editContext . SourceFilePath ;
2018-11-14 14:28:29 -08:00
var gcodeFilePath = 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
{
// If leveling is required or is currently on
2018-07-10 15:34:08 -07:00
if ( this . RunAnyRequiredPrinterSetup ( printer , this . Theme ) )
2017-06-16 18:04:47 -07:00
{
2018-04-06 14:58:25 -07:00
// We need to calibrate. So, don't print this part.
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
2018-11-24 15:27:18 -08:00
if ( SettingsValidation . SettingsValid ( printer ) )
2017-06-16 18:04:47 -07:00
{
2018-10-19 15:46:36 -07:00
// check that current bed temp is is within 10 degrees of leveling temp
var enabled = printer . Settings . GetValue < bool > ( SettingsKey . print_leveling_enabled ) ;
var required = printer . Settings . GetValue < bool > ( SettingsKey . print_leveling_required_to_print ) ;
if ( enabled | | required )
{
double requiredLevelingTemp = printer . Settings . GetValue < bool > ( SettingsKey . has_heated_bed ) ?
printer . Settings . GetValue < double > ( SettingsKey . bed_temperature )
: 0 ;
PrintLevelingData levelingData = printer . Settings . Helpers . GetPrintLevelingData ( ) ;
2018-10-21 08:52:22 -07:00
if ( ! levelingData . IssuedLevelingTempWarning
2018-10-19 15:46:36 -07:00
& & Math . Abs ( requiredLevelingTemp - levelingData . BedTemperature ) > 10 )
{
// Show a warning that leveling may be a good idea if better adhesion needed
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox (
@ "Leveling data created with bed temperature of: {0}°C
Current bed temperature : { 1 } ° C
If you experience adhesion problems , please re - run leveling . "
. FormatWith ( levelingData . BedTemperature , requiredLevelingTemp ) ,
"Leveling data warning" ) ;
levelingData . IssuedLevelingTempWarning = true ;
printer . Settings . Helpers . SetPrintLevelingData ( levelingData , true ) ;
} ) ;
}
}
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
2018-05-23 06:23:13 -07:00
if ( Path . GetExtension ( partFilePath ) . ToUpper ( ) = = ".GCODE"
& & hideGCodeWarning = = null
& & ! overrideAllowGCode )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
var hideGCodeWarningCheckBox = new CheckBox ( doNotAskAgainMessage )
2017-06-16 18:04:47 -07:00
{
2018-11-03 09:13:07 -07:00
TextColor = this . Theme . TextColor ,
2018-05-23 06:23:13 -07:00
Margin = new BorderDouble ( top : 6 , left : 6 ) ,
HAnchor = Agg . UI . HAnchor . Left
} ;
hideGCodeWarningCheckBox . Click + = ( sender , e ) = >
{
if ( hideGCodeWarningCheckBox . Checked )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
ApplicationSettings . Instance . set ( ApplicationSettingsKey . HideGCodeWarning , "true" ) ;
}
else
{
ApplicationSettings . Instance . set ( ApplicationSettingsKey . HideGCodeWarning , null ) ;
}
} ;
UiThread . RunOnIdle ( ( ) = >
{
StyledMessageBox . ShowMessageBox (
( messageBoxResponse ) = >
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
if ( messageBoxResponse )
2017-06-16 18:04:47 -07:00
{
2018-11-11 12:36:15 -08:00
printer . Connection . CommunicationState = CommunicationStates . PreparingToPrint ;
2018-05-23 07:14:21 -07:00
this . ArchiveAndStartPrint ( partFilePath , gcodeFilePath , printer ) ;
2017-06-16 18:04:47 -07:00
}
2018-05-23 06:23:13 -07:00
} ,
"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 [ ]
2017-09-15 18:45:21 -07:00
{
2018-05-23 06:23:13 -07:00
new VerticalSpacer ( ) ,
hideGCodeWarningCheckBox
} ,
StyledMessageBox . MessageType . YES_NO ) ;
} ) ;
}
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 )
{
}
}
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 ( ) ;
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-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 ;
while ( ! printer . Connection . PrinterIsPrinting
& & ! cancellationTokenB . IsCancellationRequested )
{
// Wait for printing
Thread . Sleep ( 200 ) ;
}
while ( ( printer . Connection . PrinterIsPrinting | | printer . Connection . PrinterIsPaused )
& & ! 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 = ( ) = >
{
return printer . Connection . PrinterIsPaused ;
} ,
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 ( ) ,
2018-05-06 08:29:24 -07:00
StopAction = ( ) = > UiThread . RunOnIdle ( ( ) = >
2018-03-19 11:45:28 -07:00
{
2018-11-12 07:57:13 -08:00
printer . CancelPrint ( ) ;
2018-07-20 14:40:41 -07:00
} ) ,
StopToolTip = "Cancel Print" . Localize ( ) ,
2018-03-19 11:45:28 -07:00
} ) ;
}
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
// TODO: We should zip mcx and settings when starting a print
string platingDirectory = Path . Combine ( ApplicationDataStorage . Instance . ApplicationLibraryDataPath , "PrintHistory" ) ;
Directory . CreateDirectory ( platingDirectory ) ;
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" ) ;
string archivePath = Path . Combine ( platingDirectory , now + ".zip" ) ;
2017-06-16 18:04:47 -07:00
2018-05-23 06:23:13 -07:00
using ( var file = File . OpenWrite ( archivePath ) )
using ( var zip = new ZipArchive ( file , ZipArchiveMode . Create ) )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
zip . CreateEntryFromFile ( sourcePath , "PrinterPlate.mcx" ) ;
2018-10-05 09:24:57 -07:00
zip . CreateEntryFromFile ( printer . Settings . DocumentPath , printer . Settings . GetValue ( SettingsKey . printer_name ) + ".printer" ) ;
2018-05-23 06:23:13 -07:00
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
{
// read the last few k of the file and see if it says "filament used". We use this marker to tell if the file finished writing
int bufferSize = 32000 ;
using ( Stream fileStream = new FileStream ( gcodeFilePath , FileMode . Open , FileAccess . Read , FileShare . ReadWrite ) )
2017-06-16 18:04:47 -07:00
{
2018-05-23 06:23:13 -07:00
byte [ ] buffer = new byte [ bufferSize ] ;
fileStream . Seek ( Math . Max ( 0 , fileStream . Length - bufferSize ) , SeekOrigin . Begin ) ;
int numBytesRead = fileStream . Read ( buffer , 0 , bufferSize ) ;
fileStream . Close ( ) ;
2017-06-16 18:04:47 -07:00
2018-05-23 06:23:13 -07:00
string fileEnd = System . Text . Encoding . UTF8 . GetString ( buffer ) ;
if ( fileEnd . Contains ( "filament used" ) )
{
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 ;
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 ;
2018-07-10 15:34:08 -07:00
await this . Tasks . Execute ( "Slicing" . Localize ( ) , 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
// 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-07-10 15:34:08 -07:00
await this . Tasks . Execute ( "Loading GCode" . Localize ( ) , ( 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 ) ;
printer . Bed . LoadGCode ( gcodeFilePath , token , ( progress0to1 , statusText ) = >
{
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
}
2018-09-10 12:02:20 -07:00
internal void GetViewOptionButtons ( GuiWidget parent , BedConfig sceneContext , PrinterConfig printer , ThemeConfig theme )
2018-04-02 16:21:34 -07:00
{
2018-04-12 08:42:10 -07:00
var bedButton = new RadioIconButton ( AggContext . StaticData . LoadIcon ( "bed.png" , 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
2018-04-18 18:10:06 -07:00
Func < bool > buildHeightValid = ( ) = > sceneContext . BuildHeight > 0 ;
2018-04-04 10:11:57 -07:00
2018-04-18 18:10:06 -07:00
var printAreaButton = new RadioIconButton ( AggContext . StaticData . LoadIcon ( "print_area.png" , theme . InvertIcons ) , theme )
2018-04-02 16:21:34 -07:00
{
2018-04-18 18:10:06 -07:00
Name = "Bed Button" ,
ToolTipText = ( buildHeightValid ( ) ) ? "Show Print Area" . Localize ( ) : "Define printer build height to enable" ,
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 ,
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
EventHandler < ViewModeChangedEventArgs > viewModeChanged = ( s , e ) = >
{
2018-04-18 17:55:32 -07:00
// Button is conditionally created based on BuildHeight, only set enabled if created
2018-04-18 18:10:06 -07:00
printAreaButton . Enabled = buildHeightValid ( ) & & printer . ViewState . ViewMode ! = PartViewMode . Layers2D ;
2018-04-09 17:43:31 -07:00
} ;
printer . ViewState . ViewModeChanged + = viewModeChanged ;
2018-09-10 12:02:20 -07:00
parent . Closed + = ( s , e ) = >
2018-04-09 17:43:31 -07:00
{
printer . ViewState . ViewModeChanged - = viewModeChanged ;
} ;
}
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 )
{
PropertyChangedEventHandler syncProperties = ( s , e ) = >
{
switch ( e . PropertyName )
{
case nameof ( renderOptions . RenderBed ) :
bedButton . Checked = renderOptions . RenderBed ;
break ;
case nameof ( renderOptions . RenderBuildVolume ) when printAreaButton ! = null :
printAreaButton . Checked = renderOptions . RenderBuildVolume ;
break ;
}
} ;
renderOptions . PropertyChanged + = syncProperties ;
container . Closed + = ( s , e ) = >
{
renderOptions . PropertyChanged - = syncProperties ;
} ;
}
2018-11-27 12:22:38 -08:00
public void ShellOpenFile ( string file )
{
UiThread . RunOnIdle ( ( ) = > this . ShellFileOpened ? . Invoke ( this , file ) ) ;
}
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 ; }
public int Priority { get ; set ; }
public Func < IProgress < ProgressStatus > , CancellationToken , Task > Action { get ; set ; }
}
public class StartupAction
{
public string Title { get ; set ; }
public int Priority { get ; set ; }
public Action Action { get ; set ; }
}
2017-08-07 14:19:28 -07:00
}
public class WidgetSourceEventArgs : EventArgs
{
public GuiWidget Source { get ; }
2017-06-16 18:04:47 -07:00
2017-08-07 14:19:28 -07:00
public WidgetSourceEventArgs ( GuiWidget source )
{
this . Source = source ;
}
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-09-16 01:11:44 -07:00
public class DragDropData
{
public View3DWidget View3DWidget { get ; set ; }
2017-10-05 22:32:23 -07:00
public BedConfig SceneContext { get ; set ; }
2017-09-16 01:11:44 -07:00
}
2017-12-11 14:15:50 -08:00
public class RunningTaskDetails : IProgress < ProgressStatus >
{
public event EventHandler < ProgressStatus > ProgressChanged ;
2017-12-12 17:53:32 -08:00
public Func < GuiWidget > DetailsItemAction { get ; set ; }
2017-12-11 22:22:56 -08:00
2018-05-07 13:12:32 -07:00
private CancellationTokenSource tokenSource ;
private bool? _isExpanded = null ;
2017-12-11 14:15:50 -08:00
public RunningTaskDetails ( CancellationTokenSource tokenSource )
{
this . tokenSource = tokenSource ;
}
public string Title { get ; set ; }
2018-04-09 16:59:17 -07:00
2018-05-06 08:29:24 -07:00
public RunningTaskOptions Options { get ; internal set ; }
2017-12-11 14:15:50 -08:00
2018-05-07 13:12:32 -07:00
public bool IsExpanded
{
get
{
if ( _isExpanded = = null )
{
if ( this . Options is RunningTaskOptions options
& & ! string . IsNullOrWhiteSpace ( options . ExpansionSerializationKey ) )
{
string dbValue = UserSettings . Instance . get ( options . ExpansionSerializationKey ) ;
_isExpanded = dbValue ! = "0" ;
}
else
{
_isExpanded = false ;
}
}
return _isExpanded ? ? false ;
}
set
{
_isExpanded = value ;
if ( this . Options ? . ExpansionSerializationKey is string expansionKey
& & ! string . IsNullOrWhiteSpace ( expansionKey ) )
{
UserSettings . Instance . set ( expansionKey , ( _isExpanded ? ? false ) ? "1" : "0" ) ;
}
}
}
2017-12-11 14:15:50 -08:00
public void Report ( ProgressStatus progressStatus )
{
this . ProgressChanged ? . Invoke ( this , progressStatus ) ;
}
public void CancelTask ( )
{
this . tokenSource . Cancel ( ) ;
}
}
2018-05-06 08:29:24 -07:00
public class RunningTaskOptions
2017-12-12 17:53:32 -08:00
{
2018-05-07 13:12:32 -07:00
/// <summary>
/// The Rich progress widget to be shown when expanded
/// </summary>
2017-12-12 17:53:32 -08:00
public Func < GuiWidget > RichProgressWidget { get ; set ; }
2018-05-07 13:12:32 -07:00
/// <summary>
/// The database key used to round trip expansion state
/// </summary>
public string ExpansionSerializationKey { get ; set ; }
2018-09-17 14:31:26 -07:00
/// <summary>
/// Set this if you would like to update the stated of the pause resume button
/// </summary>
public Func < bool > IsPaused { get ; set ; }
2018-05-06 08:29:24 -07:00
public Action PauseAction { get ; set ; }
public Action ResumeAction { get ; set ; }
public Action StopAction { get ; set ; }
2018-04-09 16:59:17 -07:00
2018-07-20 14:40:41 -07:00
public string StopToolTip { get ; set ; } = "Cancel" . Localize ( ) ;
public string ResumeToolTip { get ; set ; } = "Resume" . Localize ( ) ;
public string PauseToolTip { get ; set ; } = "Pause" . Localize ( ) ;
2018-04-09 16:59:17 -07:00
/// <summary>
/// Indicates if the task should suppress pause/resume/stop operations
/// </summary>
public bool ReadOnlyReporting { get ; set ; } = false ;
2017-12-12 17:53:32 -08:00
}
2017-12-11 14:15:50 -08:00
public class RunningTasksConfig
{
public event EventHandler TasksChanged ;
private ObservableCollection < RunningTaskDetails > executingTasks = new ObservableCollection < RunningTaskDetails > ( ) ;
public IEnumerable < RunningTaskDetails > RunningTasks = > executingTasks . ToList ( ) ;
public RunningTasksConfig ( )
{
executingTasks . CollectionChanged + = ( s , e ) = >
{
2018-05-29 17:46:59 -07:00
UiThread . RunOnIdle ( ( ) = > this . TasksChanged ? . Invoke ( this , null ) ) ;
2017-12-11 14:15:50 -08:00
} ;
}
2018-05-06 08:29:24 -07:00
public Task Execute ( string taskTitle , Func < IProgress < ProgressStatus > , CancellationToken , Task > func , RunningTaskOptions taskActions = null )
2017-12-11 14:15:50 -08:00
{
var tokenSource = new CancellationTokenSource ( ) ;
2017-12-11 22:22:56 -08:00
var taskDetails = new RunningTaskDetails ( tokenSource )
{
2018-05-06 08:29:24 -07:00
Options = taskActions ,
2018-02-20 18:27:52 -08:00
Title = taskTitle
2017-12-11 22:22:56 -08:00
} ;
2017-12-11 14:15:50 -08:00
executingTasks . Add ( taskDetails ) ;
return Task . Run ( async ( ) = >
{
2017-12-12 18:18:39 -08:00
try
{
await func ? . Invoke ( taskDetails , tokenSource . Token ) ;
}
catch
{
}
2017-12-11 14:15:50 -08:00
2018-07-12 12:26:37 -07:00
UiThread . RunOnIdle ( ( ) = >
{
executingTasks . Remove ( taskDetails ) ;
} ) ;
2017-12-11 14:15:50 -08:00
} ) ;
}
}
2017-12-16 13:56:59 -08:00
2017-12-18 17:22:50 -08:00
public enum ReportSeverity2 { Warning , Error }
public static class Application
2017-12-16 13:56:59 -08:00
{
2017-12-18 17:22:50 -08:00
private static ProgressBar progressBar ;
private static TextWidget statusText ;
private static FlowLayoutWidget progressPanel ;
private static string lastSection = "" ;
private static Stopwatch timer ;
2017-12-16 13:56:59 -08:00
2017-12-18 17:22:50 -08:00
public static SystemWindow LoadRootWindow ( int width , int height )
2017-12-16 13:56:59 -08:00
{
2017-12-18 17:22:50 -08:00
timer = Stopwatch . StartNew ( ) ;
2017-12-16 13:56:59 -08:00
2018-02-21 15:23:54 -08:00
var systemWindow = new RootSystemWindow ( width , height ) ;
2017-12-18 17:22:50 -08:00
2018-02-26 17:48:15 -08:00
var overlay = new GuiWidget ( )
{
2018-11-03 09:50:09 -07:00
BackgroundColor = AppContext . Theme . BackgroundColor ,
2018-02-26 17:48:15 -08:00
} ;
2017-12-18 17:22:50 -08:00
overlay . AnchorAll ( ) ;
systemWindow . AddChild ( overlay ) ;
2018-10-13 17:58:54 -07:00
var mutedAccentColor = AppContext . Theme . SplashAccentColor ;
2018-05-14 11:43:06 -07:00
var spinner = new LogoSpinner ( overlay , rotateX : - 0.05 )
{
MeshColor = mutedAccentColor
} ;
2018-02-21 15:23:54 -08:00
2017-12-18 17:22:50 -08:00
progressPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom )
2017-12-16 13:56:59 -08:00
{
2018-04-23 14:33:27 -07:00
Position = new Vector2 ( 0 , height * . 25 ) ,
2018-02-21 15:23:54 -08:00
HAnchor = HAnchor . Center | HAnchor . Fit ,
VAnchor = VAnchor . Fit ,
2018-03-08 17:23:03 -08:00
MinimumSize = new Vector2 ( 400 , 100 ) ,
2018-02-21 15:23:54 -08:00
Margin = new BorderDouble ( 0 , 0 , 0 , 200 )
2017-12-18 17:22:50 -08:00
} ;
overlay . AddChild ( progressPanel ) ;
2017-12-16 13:56:59 -08:00
2018-11-03 09:13:07 -07:00
progressPanel . AddChild ( statusText = new TextWidget ( "" , textColor : AppContext . Theme . TextColor )
2017-12-18 17:22:50 -08:00
{
2018-02-27 08:46:54 -08:00
MinimumSize = new Vector2 ( 200 , 30 ) ,
2018-02-21 15:23:54 -08:00
HAnchor = HAnchor . Center ,
AutoExpandBoundsToText = true
2017-12-18 17:22:50 -08:00
} ) ;
progressPanel . AddChild ( progressBar = new ProgressBar ( )
{
2018-05-14 11:43:06 -07:00
FillColor = mutedAccentColor ,
2018-10-16 21:21:42 -07:00
BorderColor = Color . Gray , // theme.BorderColor75,
2017-12-18 17:22:50 -08:00
Height = 11 ,
2018-02-27 08:46:54 -08:00
Width = 230 ,
2018-02-21 15:23:54 -08:00
HAnchor = HAnchor . Center ,
2017-12-18 17:22:50 -08:00
VAnchor = VAnchor . Absolute
} ) ;
AppContext . RootSystemWindow = systemWindow ;
2018-04-23 14:33:27 -07:00
// hook up a keyboard watcher to rout keys when not handled by children
2018-05-03 14:14:17 -07:00
systemWindow . KeyPressed + = ( s , keyEvent ) = >
2018-04-23 14:33:27 -07:00
{
2018-04-23 18:48:17 -07:00
var view3D = systemWindow . Descendants < View3DWidget > ( ) . Where ( ( v ) = > v . ActuallyVisibleOnScreen ( ) ) . FirstOrDefault ( ) ;
var printerTabPage = systemWindow . Descendants < PrinterTabPage > ( ) . Where ( ( v ) = > v . ActuallyVisibleOnScreen ( ) ) . FirstOrDefault ( ) ;
2018-04-23 14:33:27 -07:00
var offsetDist = 50 ;
2018-04-29 11:08:09 -07:00
if ( ! keyEvent . Handled
2018-04-23 14:33:27 -07:00
& & view3D ! = null )
{
2018-05-03 14:14:17 -07:00
switch ( keyEvent . KeyChar )
2018-04-23 14:33:27 -07:00
{
2018-05-06 14:20:16 -07:00
case 'w' :
case 'W' :
view3D . ResetView ( ) ;
keyEvent . Handled = true ;
break ;
case ' ' :
view3D . Scene . ClearSelection ( ) ;
keyEvent . Handled = true ;
break ;
}
}
} ;
systemWindow . KeyDown + = ( s , keyEvent ) = >
{
var view3D = systemWindow . Descendants < View3DWidget > ( ) . Where ( ( v ) = > v . ActuallyVisibleOnScreen ( ) ) . FirstOrDefault ( ) ;
var printerTabPage = systemWindow . Descendants < PrinterTabPage > ( ) . Where ( ( v ) = > v . ActuallyVisibleOnScreen ( ) ) . FirstOrDefault ( ) ;
var offsetDist = 50 ;
var arrowKeyOpperation = keyEvent . Shift ? TrackBallTransformType . Translation : TrackBallTransformType . Rotation ;
2018-06-04 15:04:15 -07:00
var gcode2D = systemWindow . Descendants < GCode2DWidget > ( ) . Where ( ( v ) = > v . ActuallyVisibleOnScreen ( ) ) . FirstOrDefault ( ) ;
2018-06-05 09:13:21 -07:00
if ( keyEvent . KeyCode = = Keys . F1 )
{
UiThread . RunOnIdle ( ( ) = >
{
2018-06-30 23:26:57 -07:00
DialogWindow . Show ( new HelpPage ( "AllGuides" ) ) ;
2018-06-05 09:13:21 -07:00
} ) ;
}
if ( ! keyEvent . Handled
2018-06-04 15:04:15 -07:00
& & gcode2D ! = null )
{
switch ( keyEvent . KeyCode )
{
case Keys . Oemplus :
case Keys . Add :
if ( keyEvent . Control )
{
// Zoom out
gcode2D . Zoom ( 1.2 ) ;
keyEvent . Handled = true ;
}
break ;
case Keys . OemMinus :
case Keys . Subtract :
if ( keyEvent . Control )
{
// Zoom in
gcode2D . Zoom ( . 8 ) ;
keyEvent . Handled = true ;
}
break ;
}
}
2018-05-06 14:20:16 -07:00
if ( ! keyEvent . Handled
& & view3D ! = null )
{
switch ( keyEvent . KeyCode )
{
case Keys . C :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
view3D . Scene . Copy ( ) ;
keyEvent . Handled = true ;
}
break ;
2018-10-23 19:54:09 -07:00
case Keys . P :
if ( keyEvent . Control )
{
view3D . PushToPrinterAndPrint ( ) ;
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . X :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
2018-05-06 14:20:16 -07:00
view3D . Scene . Cut ( ) ;
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . Y :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
2018-05-06 14:20:16 -07:00
view3D . Scene . UndoBuffer . Redo ( ) ;
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . A :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
2018-05-06 14:20:16 -07:00
view3D . SelectAll ( ) ;
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . S :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
2018-05-06 14:20:16 -07:00
view3D . Save ( ) ;
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . V :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
2018-11-11 08:51:16 -08:00
view3D . sceneContext . Paste ( ) ;
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
}
break ;
2018-06-04 15:04:15 -07:00
case Keys . Oemplus :
case Keys . Add :
if ( keyEvent . Control )
{
// Zoom out
Offset3DView ( view3D , new Vector2 ( 0 , offsetDist ) , TrackBallTransformType . Scale ) ;
keyEvent . Handled = true ;
}
break ;
case Keys . OemMinus :
case Keys . Subtract :
if ( keyEvent . Control )
{
// Zoom in
Offset3DView ( view3D , new Vector2 ( 0 , - offsetDist ) , TrackBallTransformType . Scale ) ;
keyEvent . Handled = true ;
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . Z :
if ( keyEvent . Control )
2018-04-23 14:33:27 -07:00
{
2018-05-06 14:20:16 -07:00
if ( keyEvent . Shift )
{
view3D . Scene . UndoBuffer . Redo ( ) ;
}
else
{
// undo last operation
view3D . Scene . UndoBuffer . Undo ( ) ;
}
keyEvent . Handled = true ;
2018-04-23 14:33:27 -07:00
}
break ;
2018-05-06 14:20:16 -07:00
case Keys . Insert :
if ( keyEvent . Shift )
{
2018-11-11 08:51:16 -08:00
view3D . sceneContext . Paste ( ) ;
2018-05-06 14:20:16 -07:00
keyEvent . Handled = true ;
}
2018-05-03 14:14:17 -07:00
break ;
2018-04-23 14:33:27 -07:00
case Keys . Delete :
case Keys . Back :
view3D . Scene . DeleteSelection ( ) ;
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
break ;
case Keys . Escape :
if ( view3D . CurrentSelectInfo . DownOnPart )
{
view3D . CurrentSelectInfo . DownOnPart = false ;
view3D . Scene . SelectedItem . Matrix = view3D . TransformOnMouseDown ;
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
}
2018-06-12 10:03:37 -07:00
foreach ( var interactionVolume in view3D . InteractionLayer . InteractionVolumes )
{
interactionVolume . CancelOpperation ( ) ;
}
2018-04-23 14:33:27 -07:00
break ;
case Keys . Left :
2018-04-29 11:08:09 -07:00
// move or rotate view left
2018-04-23 14:33:27 -07:00
Offset3DView ( view3D , new Vector2 ( - offsetDist , 0 ) , arrowKeyOpperation ) ;
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
break ;
case Keys . Right :
Offset3DView ( view3D , new Vector2 ( offsetDist , 0 ) , arrowKeyOpperation ) ;
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
break ;
case Keys . Up :
2018-04-23 18:48:17 -07:00
if ( view3D . Printer ! = null
& & printerTabPage ! = null
& & view3D . Printer . ViewState . ViewMode ! = PartViewMode . Model )
{
printerTabPage . LayerScrollbar . Value + = 1 ;
}
else
{
Offset3DView ( view3D , new Vector2 ( 0 , offsetDist ) , arrowKeyOpperation ) ;
}
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
break ;
case Keys . Down :
2018-04-23 18:48:17 -07:00
if ( view3D . Printer ! = null
& & printerTabPage ! = null
& & view3D . Printer . ViewState . ViewMode ! = PartViewMode . Model )
{
printerTabPage . LayerScrollbar . Value - = 1 ;
}
else
{
Offset3DView ( view3D , new Vector2 ( 0 , - offsetDist ) , arrowKeyOpperation ) ;
}
2018-04-23 14:33:27 -07:00
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
break ;
}
}
} ;
2017-12-18 17:22:50 -08:00
// Hook SystemWindow load and spin up MatterControl once we've hit first draw
systemWindow . Load + = ( s , e ) = >
2017-12-16 13:56:59 -08:00
{
2017-12-18 17:22:50 -08:00
ReportStartupProgress ( 0.02 , "First draw->RunOnIdle" ) ;
//UiThread.RunOnIdle(() =>
2017-12-20 18:25:12 -08:00
Task . Run ( async ( ) = >
2017-12-16 13:56:59 -08:00
{
2018-03-28 18:05:06 -07:00
try
2017-12-18 17:22:50 -08:00
{
2018-03-28 18:05:06 -07:00
ReportStartupProgress ( 0.15 , "MatterControlApplication.Initialize" ) ;
var mainView = await Initialize ( systemWindow , ( progress0To1 , status ) = >
{
ReportStartupProgress ( 0.2 + progress0To1 * 0.7 , status ) ;
} ) ;
2018-07-30 11:50:22 -07:00
ApplicationController . LoadTranslationMap ( ) ;
2018-03-28 18:05:06 -07:00
ReportStartupProgress ( 0.9 , "AddChild->MainView" ) ;
systemWindow . AddChild ( mainView , 0 ) ;
ReportStartupProgress ( 1 , "" ) ;
systemWindow . BackgroundColor = Color . Transparent ;
overlay . Close ( ) ;
}
catch ( Exception ex )
{
UiThread . RunOnIdle ( ( ) = >
{
statusText . Visible = false ;
2017-12-18 17:22:50 -08:00
2018-03-28 18:05:06 -07:00
var errorTextColor = Color . White ;
2018-03-21 17:17:36 -07:00
2018-03-28 18:05:06 -07:00
progressPanel . Margin = 0 ;
progressPanel . VAnchor = VAnchor . Center | VAnchor . Fit ;
progressPanel . BackgroundColor = Color . DarkGray ;
progressPanel . Padding = 20 ;
progressPanel . Border = 1 ;
progressPanel . BorderColor = Color . Red ;
2017-12-18 17:22:50 -08:00
2018-05-16 12:03:21 -07:00
var theme = new ThemeConfig ( ) ;
2018-03-28 18:05:06 -07:00
progressPanel . AddChild (
new TextWidget ( "Startup Failure" . Localize ( ) + ":" , pointSize : theme . DefaultFontSize , textColor : errorTextColor ) ) ;
progressPanel . AddChild (
new TextWidget ( ex . Message , pointSize : theme . FontSize9 , textColor : errorTextColor ) ) ;
2018-04-12 08:42:10 -07:00
var closeButton = new TextButton ( "Close" , theme )
2018-03-28 18:05:06 -07:00
{
BackgroundColor = theme . SlightShade ,
HAnchor = HAnchor . Right ,
VAnchor = VAnchor . Absolute
} ;
closeButton . Click + = ( s1 , e1 ) = >
{
systemWindow . Close ( ) ;
} ;
spinner . SpinLogo = false ;
progressBar . Visible = false ;
progressPanel . AddChild ( closeButton ) ;
} ) ;
}
2017-12-18 17:22:50 -08:00
2017-12-27 05:42:28 -08:00
AppContext . IsLoading = false ;
2017-12-18 17:22:50 -08:00
} ) ;
} ;
ReportStartupProgress ( 0 , "ShowAsSystemWindow" ) ;
return systemWindow ;
2017-12-16 13:56:59 -08:00
}
2018-04-23 14:33:27 -07:00
private static void Offset3DView ( View3DWidget view3D , Vector2 offset , TrackBallTransformType opperation )
{
var center = view3D . TrackballTumbleWidget . LocalBounds . Center ;
2018-04-29 11:08:09 -07:00
2018-04-23 14:33:27 -07:00
view3D . TrackballTumbleWidget . TrackBallController . OnMouseDown ( center , Matrix4X4 . Identity , opperation ) ;
view3D . TrackballTumbleWidget . TrackBallController . OnMouseMove ( center + offset ) ;
view3D . TrackballTumbleWidget . TrackBallController . OnMouseUp ( ) ;
view3D . TrackballTumbleWidget . Invalidate ( ) ;
}
2017-12-20 18:25:12 -08:00
public static async Task < GuiWidget > Initialize ( SystemWindow systemWindow , Action < double , string > reporter )
2017-12-16 13:56:59 -08:00
{
2018-10-24 13:45:41 -07:00
var loading = "Loading..." ;
#if DEBUG
loading = null ;
#endif
reporter ? . Invoke ( 0.01 , ( loading ! = null ) ? loading : "PlatformInit" ) ;
2017-12-18 17:22:50 -08:00
AppContext . Platform . PlatformInit ( ( status ) = >
{
2018-10-24 13:45:41 -07:00
reporter ? . Invoke ( 0.01 , ( loading ! = null ) ? loading : status ) ;
2017-12-18 17:22:50 -08:00
} ) ;
// TODO: Appears to be unused and should be removed
// set this at startup so that we can tell next time if it got set to true in close
UserSettings . Instance . Fields . StartCount = UserSettings . Instance . Fields . StartCount + 1 ;
2018-10-24 13:45:41 -07:00
reporter ? . Invoke ( 0.05 , ( loading ! = null ) ? loading : "ApplicationController" ) ;
2018-07-12 09:22:28 -07:00
var applicationController = ApplicationController . Instance ;
2017-12-18 17:22:50 -08:00
// Accessing any property on ProfileManager will run the static constructor and spin up the ProfileManager instance
2018-10-24 13:45:41 -07:00
reporter ? . Invoke ( 0.2 , ( loading ! = null ) ? loading : "ProfileManager" ) ;
2017-12-18 17:22:50 -08:00
bool na2 = ProfileManager . Instance . IsGuestProfile ;
2017-12-20 18:25:12 -08:00
await ProfileManager . Instance . Initialize ( ) ;
2018-10-24 13:45:41 -07:00
reporter ? . Invoke ( 0.25 , ( loading ! = null ) ? loading : "Initialize printer" ) ;
2018-11-11 21:25:50 -08:00
var printer = PrinterConfig . EmptyPrinter ;
2018-10-10 14:58:03 -07:00
// Restore bed
if ( printer . Settings . PrinterSelected )
{
printer . ViewState . ViewMode = PartViewMode . Model ;
2018-11-01 09:36:58 -07:00
ApplicationController . StartupTasks . Add ( new ApplicationController . StartupTask ( )
2018-10-10 14:58:03 -07:00
{
2018-11-01 09:36:58 -07:00
Title = "Loading Bed" . Localize ( ) ,
Priority = 100 ,
Action = ( progress , cancellationToken ) = >
{
return printer . Bed . LoadPlateFromHistory ( ) ;
}
} ) ;
2018-10-10 14:58:03 -07:00
}
2018-10-30 16:14:55 -07:00
reporter ? . Invoke ( 0.3 , ( loading ! = null ) ? loading : "Plugins" ) ;
2017-12-18 17:22:50 -08:00
AppContext . Platform . FindAndInstantiatePlugins ( systemWindow ) ;
2018-10-30 16:14:55 -07:00
reporter ? . Invoke ( 0.4 , ( loading ! = null ) ? loading : "MainView" ) ;
applicationController . MainView = new MainViewWidget ( applicationController . Theme ) ;
2018-10-24 13:45:41 -07:00
reporter ? . Invoke ( 0.91 , ( loading ! = null ) ? loading : "OnLoadActions" ) ;
2018-07-12 09:22:28 -07:00
applicationController . OnLoadActions ( ) ;
2017-12-18 17:22:50 -08:00
2018-11-01 09:36:58 -07:00
// Wired up to MainView.Load with the intent to fire startup actions and tasks in order with reporting
async void initialWindowLoad ( object s , EventArgs e )
{
try
{
// Batch startup actions
await applicationController . Tasks . Execute (
"Finishing Startup" . Localize ( ) ,
( progress , cancellationToken ) = >
{
var status = new ProgressStatus ( ) ;
int itemCount = ApplicationController . StartupActions . Count ;
double i = 1 ;
foreach ( var action in ApplicationController . StartupActions . OrderByDescending ( t = > t . Priority ) )
{
status . Status = action . Title ;
progress . Report ( status ) ;
action . Action ? . Invoke ( ) ;
status . Progress0To1 = i + + / itemCount ;
progress . Report ( status ) ;
}
return Task . CompletedTask ;
} ) ;
2018-11-11 21:26:08 -08:00
await applicationController . Tasks . Execute (
"Restoring Printers" . Localize ( ) ,
async ( progress , cancellationToken ) = >
{
await applicationController . OpenAllPrinters ( ) ;
} ) ;
2018-11-01 09:36:58 -07:00
// Batch startup tasks
foreach ( var task in ApplicationController . StartupTasks . OrderByDescending ( t = > t . Priority ) )
{
await applicationController . Tasks . Execute ( task . Title , task . Action ) ;
}
}
catch
{
}
// Unhook after execution
applicationController . MainView . Load - = initialWindowLoad ;
}
// Hook after first draw
applicationController . MainView . Load + = initialWindowLoad ;
2018-07-12 09:22:28 -07:00
return applicationController . MainView ;
2017-12-16 13:56:59 -08:00
}
2017-12-18 17:22:50 -08:00
private static void ReportStartupProgress ( double progress0To1 , string section )
2017-12-16 13:56:59 -08:00
{
2017-12-18 18:36:41 -08:00
UiThread . RunOnIdle ( ( ) = >
{
statusText . Text = section ;
progressBar . RatioComplete = progress0To1 ;
progressPanel . Invalidate ( ) ;
2017-12-18 17:22:50 -08:00
2017-12-18 18:36:41 -08:00
Console . WriteLine ( $"Time to '{lastSection}': {timer.ElapsedMilliseconds}" ) ;
timer . Restart ( ) ;
2017-12-18 17:22:50 -08:00
2017-12-18 18:36:41 -08:00
lastSection = section ;
} ) ;
2017-12-16 13:56:59 -08:00
}
}
2018-10-15 20:08:15 -07:00
public class PartWorkspace
{
public string Name { get ; set ; }
public BedConfig SceneContext { 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
}