2014-10-30 14:42:00 -07:00
/ *
2018-05-03 23:00:02 -07:00
Copyright ( c ) 2018 , Lars Brubaker , John Lewin
2014-10-30 14:42:00 -07:00
All rights reserved .
Redistribution and use in source and binary forms , with or without
2015-04-08 15:20:10 -07:00
modification , are permitted provided that the following conditions are met :
2014-10-30 14:42:00 -07:00
1. Redistributions of source code must retain the above copyright notice , this
2015-04-08 15:20:10 -07:00
list of conditions and the following disclaimer .
2014-10-30 14:42:00 -07:00
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
2015-04-08 15:20:10 -07:00
and / or other materials provided with the distribution .
2014-10-30 14:42:00 -07:00
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
2015-04-08 15:20:10 -07:00
of the authors and should not be interpreted as representing official policies ,
2014-10-30 14:42:00 -07:00
either expressed or implied , of the FreeBSD Project .
* /
2017-07-06 12:22:56 -07:00
using System ;
2017-08-15 12:32:09 -07:00
using System.Linq ;
2014-10-30 14:42:00 -07:00
using MatterHackers.Agg ;
2018-01-03 17:14:30 -08:00
using MatterHackers.Agg.Platform ;
2014-10-30 14:42:00 -07:00
using MatterHackers.Agg.UI ;
using MatterHackers.Localizations ;
2017-11-28 14:37:38 -08:00
using MatterHackers.MatterControl.PartPreviewWindow.PlusTab ;
2018-10-07 11:36:52 -07:00
using MatterHackers.MatterControl.PrintLibrary ;
2014-10-30 14:42:00 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2017-11-11 17:28:03 -08:00
using MatterHackers.VectorMath ;
2018-06-05 12:22:26 -07:00
using Newtonsoft.Json ;
2014-10-30 14:42:00 -07:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2017-05-24 19:11:51 -07:00
public class PartPreviewContent : FlowLayoutWidget
2015-04-08 15:20:10 -07:00
{
2017-07-27 14:25:21 -07:00
private EventHandler unregisterEvents ;
2018-01-08 13:13:32 -08:00
private ChromeTab printerTab = null ;
2017-11-11 17:28:03 -08:00
private ChromeTabs tabControl ;
2017-09-29 21:30:51 -07:00
2018-07-12 09:22:28 -07:00
public PartPreviewContent ( ThemeConfig theme )
2017-11-11 17:28:03 -08:00
: base ( FlowDirection . TopToBottom )
2015-04-08 15:20:10 -07:00
{
this . AnchorAll ( ) ;
2017-03-15 16:17:06 -07:00
2018-05-16 18:38:46 -07:00
var extensionArea = new LeftClipFlowLayoutWidget ( )
{
BackgroundColor = theme . TabBarBackground ,
2018-05-17 12:41:00 -07:00
VAnchor = VAnchor . Stretch ,
Padding = new BorderDouble ( left : 8 )
2018-05-16 18:38:46 -07:00
} ;
2017-08-15 12:32:09 -07:00
2017-11-11 17:28:03 -08:00
tabControl = new ChromeTabs ( extensionArea , theme )
2017-11-07 14:58:43 -08:00
{
2017-11-11 17:28:03 -08:00
VAnchor = VAnchor . Stretch ,
HAnchor = HAnchor . Stretch ,
BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ,
2018-01-08 14:28:52 -08:00
BorderColor = theme . MinimalShade ,
Border = new BorderDouble ( left : 1 ) ,
2017-11-11 17:28:03 -08:00
} ;
tabControl . ActiveTabChanged + = ( s , e ) = >
{
if ( this . tabControl . ActiveTab ? . TabContent is PartTabPage tabPage )
2017-11-07 14:58:43 -08:00
{
var dragDropData = ApplicationController . Instance . DragDropData ;
// Set reference on tab change
dragDropData . View3DWidget = tabPage . view3DWidget ;
dragDropData . SceneContext = tabPage . sceneContext ;
}
} ;
2018-05-17 12:41:00 -07:00
// Force the ActionArea to be as high as ButtonHeight
tabControl . TabBar . ActionArea . MinimumSize = new Vector2 ( 0 , theme . ButtonHeight ) ;
tabControl . TabBar . BackgroundColor = theme . TabBarBackground ;
2017-11-21 11:11:07 -08:00
tabControl . TabBar . BorderColor = theme . ActiveTabColor ;
2018-05-17 12:41:00 -07:00
// Force common padding into top region
2018-06-27 22:25:55 -07:00
tabControl . TabBar . Padding = theme . TabbarPadding . Clone ( top : theme . TabbarPadding . Top * 2 , bottom : 0 ) ;
2015-04-08 15:20:10 -07:00
2018-04-25 11:35:33 -07:00
// add in a what's new button
2018-07-11 09:26:54 -07:00
var seeWhatsNewButton = new LinkLabel ( "What's New..." . Localize ( ) , theme )
{
Name = "What's New Link" ,
ToolTipText = "See what's new in this version of MatterControl" . Localize ( ) ,
VAnchor = VAnchor . Center ,
Margin = new BorderDouble ( 10 , 0 ) ,
TextColor = theme . Colors . PrimaryTextColor
} ;
2018-04-25 11:35:33 -07:00
seeWhatsNewButton . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
2018-06-05 12:22:26 -07:00
UserSettings . Instance . set ( UserSettingsKey . LastReadWhatsNew , JsonConvert . SerializeObject ( DateTime . Now ) ) ;
2018-06-30 23:26:57 -07:00
DialogWindow . Show ( new HelpPage ( "What's New" ) ) ;
2018-04-25 11:35:33 -07:00
} ) ;
tabControl . TabBar . ActionArea . AddChild ( seeWhatsNewButton ) ;
2017-09-05 15:44:22 -07:00
// add in the update available button
2018-07-11 09:26:54 -07:00
var updateAvailableButton = new LinkLabel ( "Update Available" . Localize ( ) , theme )
{
Visible = false ,
} ;
2018-04-25 11:35:33 -07:00
// make the function inline so we don't have to create members for the buttons
2018-09-07 14:27:57 -07:00
EventHandler < StringEventArgs > SetLinkButtonsVisibility = ( s , e ) = >
2018-04-25 11:35:33 -07:00
{
2018-05-16 14:36:01 -07:00
if ( UserSettings . Instance . HasLookedAtWhatsNew ( ) )
2018-04-25 11:35:33 -07:00
{
// hide it
seeWhatsNewButton . Visible = false ;
}
if ( UpdateControlData . Instance . UpdateStatus = = UpdateControlData . UpdateStatusStates . UpdateAvailable )
{
updateAvailableButton . Visible = true ;
// if we are going to show the update link hide the whats new link no matter what
seeWhatsNewButton . Visible = false ;
}
else
{
updateAvailableButton . Visible = false ;
}
} ;
2018-09-07 14:27:57 -07:00
UserSettings . Instance . SettingChanged + = SetLinkButtonsVisibility ;
this . Closed + = ( s , e ) = > UserSettings . Instance . SettingChanged - = SetLinkButtonsVisibility ;
2018-04-26 16:41:51 -07:00
2018-05-16 14:36:01 -07:00
RunningInterval showUpdateInterval = null ;
updateAvailableButton . VisibleChanged + = ( s , e ) = >
{
if ( ! updateAvailableButton . Visible )
{
if ( showUpdateInterval ! = null )
{
showUpdateInterval . Continue = false ;
showUpdateInterval = null ;
}
return ;
}
showUpdateInterval = UiThread . SetInterval ( ( ) = >
{
double displayTime = 1 ;
double pulseTime = 1 ;
double totalSeconds = 0 ;
var textWidgets = updateAvailableButton . Descendants < TextWidget > ( ) . Where ( ( w ) = > w . Visible = = true ) . ToArray ( ) ;
Color startColor = theme . Colors . PrimaryTextColor ;
2018-07-12 22:49:39 -07:00
// Show a highlight on the button as the user did not click it
2018-05-16 14:36:01 -07:00
Animation flashBackground = null ;
flashBackground = new Animation ( )
{
DrawTarget = updateAvailableButton ,
FramesPerSecond = 10 ,
Update = ( s1 , updateEvent ) = >
{
totalSeconds + = updateEvent . SecondsPassed ;
if ( totalSeconds < displayTime )
{
double blend = AttentionGetter . GetFadeInOutPulseRatio ( totalSeconds , pulseTime ) ;
var color = new Color ( startColor , ( int ) ( ( 1 - blend ) * 255 ) ) ;
foreach ( var textWidget in textWidgets )
{
textWidget . TextColor = color ;
}
}
else
{
foreach ( var textWidget in textWidgets )
{
textWidget . TextColor = startColor ;
}
flashBackground . Stop ( ) ;
}
}
} ;
flashBackground . Start ( ) ;
} , 120 ) ;
} ;
2017-09-05 15:44:22 -07:00
updateAvailableButton . Name = "Update Available Link" ;
2018-07-11 09:26:54 -07:00
SetLinkButtonsVisibility ( this , null ) ;
2017-09-05 15:44:22 -07:00
updateAvailableButton . ToolTipText = "There is a new update available for download" . Localize ( ) ;
updateAvailableButton . VAnchor = VAnchor . Center ;
2018-07-11 09:26:54 -07:00
updateAvailableButton . Margin = new BorderDouble ( 10 , 0 ) ;
2017-09-05 15:44:22 -07:00
updateAvailableButton . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
2018-10-10 08:19:09 -07:00
UpdateControlData . Instance . CheckForUpdate ( ) ;
DialogWindow . Show < CheckForUpdatesPage > ( ) ;
2017-09-05 15:44:22 -07:00
} ) ;
2017-11-11 17:28:03 -08:00
2017-12-26 08:15:28 -08:00
tabControl . TabBar . ActionArea . AddChild ( updateAvailableButton ) ;
2017-09-05 15:44:22 -07:00
2018-09-07 14:27:57 -07:00
UpdateControlData . Instance . UpdateStatusChanged . RegisterEvent ( ( s , e ) = >
{
SetLinkButtonsVisibility ( s , new StringEventArgs ( "Unknown" ) ) ;
} , ref unregisterEvents ) ;
2017-09-05 15:44:22 -07:00
2017-08-07 14:19:28 -07:00
this . AddChild ( tabControl ) ;
2017-09-15 09:23:53 -07:00
2018-10-05 09:55:46 -07:00
PrinterSettings . SettingChanged . RegisterEvent ( ( s , e ) = >
2017-07-27 14:25:21 -07:00
{
2018-10-05 09:24:57 -07:00
var activePrinter = ApplicationController . Instance . ActivePrinter ;
2017-09-15 09:23:53 -07:00
if ( e is StringEventArgs stringEvent
& & stringEvent . Data = = SettingsKey . printer_name
& & printerTab ! = null )
2017-07-27 14:25:21 -07:00
{
2018-10-05 09:24:57 -07:00
printerTab . Text = activePrinter . Settings . GetValue ( SettingsKey . printer_name ) ;
2017-07-27 14:25:21 -07:00
}
2017-09-15 09:23:53 -07:00
2017-07-27 14:25:21 -07:00
} , ref unregisterEvents ) ;
2018-10-05 09:44:28 -07:00
ApplicationController . Instance . ActivePrinterChanged . RegisterEvent ( ( s , e ) = >
2018-05-16 14:35:15 -07:00
{
var activePrinter = ApplicationController . Instance . ActivePrinter ;
// If ActivePrinter has been nulled and a printer tab is open, close it
var tab1 = tabControl . AllTabs . Skip ( 1 ) . FirstOrDefault ( ) ;
if ( ( activePrinter = = null | | ! activePrinter . Settings . PrinterSelected )
& & tab1 ? . TabContent is PrinterTabPage )
{
tabControl . RemoveTab ( tab1 ) ;
}
else
{
2018-07-11 12:40:04 -07:00
this . CreatePrinterTab ( activePrinter , theme ) ;
2018-05-16 14:35:15 -07:00
}
} , ref unregisterEvents ) ;
2017-08-07 14:19:28 -07:00
ApplicationController . Instance . NotifyPrintersTabRightElement ( extensionArea ) ;
2018-10-07 11:36:52 -07:00
// Add a tab for the current printer
if ( ApplicationController . Instance . ActivePrinter . Settings . PrinterSelected )
{
this . CreatePrinterTab ( ApplicationController . Instance . ActivePrinter , theme ) ;
}
// Library tab
var libraryWidget = new LibraryWidget ( this , theme )
{
BackgroundColor = theme . ActiveTabColor
} ;
2018-05-03 23:00:02 -07:00
tabControl . AddTab (
2018-10-07 11:36:52 -07:00
new ChromeTab ( "Library" , "Library" . Localize ( ) , tabControl , libraryWidget , theme , hasClose : false )
2018-05-03 23:00:02 -07:00
{
MinimumSize = new Vector2 ( 0 , theme . TabButtonHeight ) ,
2018-10-07 11:36:52 -07:00
Name = "Library Tab" ,
2018-05-03 23:00:02 -07:00
Padding = new BorderDouble ( 15 , 0 )
} ) ;
2018-04-19 15:53:59 -07:00
2018-10-07 11:36:52 -07:00
tabControl . AddTab (
new ChromeTab ( "Inventory" , "Hardware" . Localize ( ) , tabControl , new InventoryTabPage ( theme ) , theme , hasClose : false )
{
MinimumSize = new Vector2 ( 0 , theme . TabButtonHeight ) ,
Name = "Library Tab" ,
Padding = new BorderDouble ( 15 , 0 )
} ) ;
// Store tab
tabControl . AddTab (
new ChromeTab ( "Store" , "Store" . Localize ( ) , tabControl , new StoreTabPage ( this , theme ) , theme , hasClose : false )
{
MinimumSize = new Vector2 ( 0 , theme . TabButtonHeight ) ,
Name = "Store Tab" ,
Padding = new BorderDouble ( 15 , 0 )
} ) ;
var brandMenu = new BrandMenuButton ( theme )
2018-04-19 15:53:59 -07:00
{
2018-10-07 11:36:52 -07:00
HAnchor = HAnchor . Fit ,
VAnchor = VAnchor . Fit ,
BackgroundColor = theme . TabBarBackground ,
Border = new BorderDouble ( right : 1 ) ,
BorderColor = theme . MinimalShade ,
Padding = theme . TabbarPadding . Clone ( right : 0 )
} ;
tabControl . TabBar . ActionArea . AddChild ( brandMenu , 0 ) ;
2018-05-03 23:00:02 -07:00
// Restore active tabs
foreach ( var bed in ApplicationController . Instance . Workspaces )
2018-04-19 15:53:59 -07:00
{
2018-05-03 23:00:02 -07:00
this . CreatePartTab ( "New Part" , bed , theme ) ;
2018-04-19 15:53:59 -07:00
}
2018-10-07 11:36:52 -07:00
// TODO: Initial hack to prototype desired behavior. Ideally loading the printer would occur during the loading screen and be initialized before widget load
UiThread . RunOnIdle ( ( ) = >
{
ProfileManager . Instance . LoadPrinter ( ) . ContinueWith ( task = >
{
var printer = task . Result ;
if ( printer . Settings . PrinterSelected )
{
printer . ViewState . ViewMode = PartViewMode . Model ;
printer . Bed . LoadPlateFromHistory ( ) . ConfigureAwait ( false ) ;
}
} ) ;
} ) ;
2017-08-07 14:19:28 -07:00
}
2018-05-24 23:09:38 -07:00
public ChromeTabs TabControl = > tabControl ;
2018-07-11 12:40:04 -07:00
private ChromeTab CreatePrinterTab ( PrinterConfig printer , ThemeConfig theme )
2017-09-15 09:23:53 -07:00
{
2018-05-08 15:47:00 -07:00
// Printer page is in fixed position
2018-10-07 11:36:52 -07:00
var tab1 = tabControl . AllTabs . Skip ( 0 ) . FirstOrDefault ( ) ;
2018-05-08 15:47:00 -07:00
2018-05-16 14:35:15 -07:00
var printerTabPage = tab1 ? . TabContent as PrinterTabPage ;
2018-05-08 15:47:00 -07:00
if ( printerTabPage = = null
| | printerTabPage . printer ! = printer )
2018-05-08 08:53:37 -07:00
{
// TODO - call save before remove
// printerTabPage.sceneContext.SaveChanges();
2018-05-08 15:47:00 -07:00
if ( printerTabPage ! = null )
{
tabControl . RemoveTab ( tab1 ) ;
}
2018-05-08 08:53:37 -07:00
2018-05-08 15:47:00 -07:00
printerTab = new ChromeTab (
2018-09-07 14:49:26 -07:00
printer . Settings . GetValue ( SettingsKey . printer_name ) ,
2018-08-06 13:17:29 -07:00
printer . Settings . GetValue ( SettingsKey . printer_name ) ,
2018-05-08 15:47:00 -07:00
tabControl ,
2018-08-06 13:17:29 -07:00
new PrinterTabPage ( printer , theme , "unused_tab_title" ) ,
2018-05-08 15:47:00 -07:00
theme ,
2018-07-11 09:26:54 -07:00
tabImageUrl : ApplicationController . Instance . GetFavIconUrl ( oemName : printer . Settings . GetValue ( SettingsKey . make ) ) ,
2018-06-05 13:38:25 -07:00
hasClose : false )
2018-05-08 15:47:00 -07:00
{
Name = "3D View Tab" ,
MinimumSize = new Vector2 ( 120 , theme . TabButtonHeight )
} ;
2018-04-17 17:13:18 -07:00
2018-10-05 09:55:46 -07:00
PrinterSettings . SettingChanged . RegisterEvent ( ( s , e ) = >
2018-08-06 13:17:29 -07:00
{
string settingsName = ( e as StringEventArgs ) ? . Data ;
if ( settingsName ! = null & & settingsName = = SettingsKey . printer_name )
{
printerTab . Title = printer . Settings . GetValue ( SettingsKey . printer_name ) ;
}
} , ref unregisterEvents ) ;
2018-05-08 15:47:00 -07:00
// Add printer into fixed position
2018-10-07 11:36:52 -07:00
if ( tabControl . AllTabs . Any ( ) )
{
tabControl . AddTab ( printerTab , 0 ) ;
}
else
{
tabControl . AddTab ( printerTab ) ;
}
2018-05-08 15:47:00 -07:00
return printerTab ;
}
else if ( printerTab ! = null )
{
tabControl . ActiveTab = tab1 ;
return tab1 as ChromeTab ;
}
2018-04-17 17:13:18 -07:00
2018-05-08 15:47:00 -07:00
return null ;
2017-09-15 09:23:53 -07:00
}
2018-01-08 13:13:32 -08:00
public ChromeTab CreatePartTab ( string tabTitle , BedConfig sceneContext , ThemeConfig theme )
2017-09-29 21:30:51 -07:00
{
2018-01-08 13:13:32 -08:00
var partTab = new ChromeTab (
2018-09-07 14:49:26 -07:00
tabTitle ,
2017-09-29 21:30:51 -07:00
tabTitle ,
2017-11-11 17:28:03 -08:00
tabControl ,
2018-06-24 00:07:58 -07:00
new PartTabPage ( null , sceneContext , theme , "" ) ,
2017-11-21 11:11:07 -08:00
theme ,
2018-06-25 08:12:49 -07:00
AggContext . StaticData . LoadIcon ( "cube.png" , 16 , 16 , theme . InvertIcons ) )
2017-11-11 17:28:03 -08:00
{
Name = "newPart" + tabControl . AllTabs . Count ( ) ,
2018-04-14 13:06:28 -07:00
MinimumSize = new Vector2 ( 120 , theme . TabButtonHeight )
2017-11-11 17:28:03 -08:00
} ;
2017-09-29 21:30:51 -07:00
2017-11-11 17:28:03 -08:00
tabControl . AddTab ( partTab ) ;
2017-09-29 21:30:51 -07:00
return partTab ;
}
2018-08-23 16:44:11 -07:00
public override void OnClosed ( EventArgs e )
2017-08-07 14:19:28 -07:00
{
unregisterEvents ? . Invoke ( this , null ) ;
base . OnClosed ( e ) ;
2017-05-24 19:11:51 -07:00
}
2015-04-08 15:20:10 -07:00
}
}