2017-11-28 14:37:38 -08:00
/ *
Copyright ( c ) 2017 , Lars Brubaker , John Lewin
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.IO ;
using System.Net ;
using MatterHackers.Agg ;
using MatterHackers.Agg.Image ;
2018-02-21 16:41:31 -08:00
using MatterHackers.Agg.Platform ;
2017-11-28 14:37:38 -08:00
using MatterHackers.Agg.UI ;
2018-02-21 16:41:31 -08:00
using MatterHackers.Localizations ;
using MatterHackers.MatterControl.CustomWidgets ;
using MatterHackers.MatterControl.PrinterControls.PrinterConnections ;
2018-03-16 15:14:23 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2017-11-28 14:37:38 -08:00
using MatterHackers.VectorMath ;
using Newtonsoft.Json ;
namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
{
public class ExplorePanel : ScrollableWidget
{
2017-11-28 18:11:11 -08:00
private ThemeConfig theme ;
2018-02-21 15:08:42 -08:00
private FlowLayoutWidget topToBottom ;
2018-02-21 16:41:31 -08:00
private TextWidget headingA ;
private Toolbar toolBarA ;
2017-11-28 14:37:38 -08:00
2018-02-21 16:41:31 -08:00
public ExplorePanel ( PartPreviewContent partPreviewContent , SimpleTabs simpleTabs , ThemeConfig theme )
2017-11-28 18:11:11 -08:00
{
this . HAnchor = HAnchor . Stretch ;
this . VAnchor = VAnchor . Stretch ;
this . BackgroundColor = theme . TabBodyBackground ;
2017-11-28 14:37:38 -08:00
this . MinimumSize = new Vector2 ( 0 , 200 ) ;
this . AnchorAll ( ) ;
this . AutoScroll = true ;
this . ScrollArea . Padding = new BorderDouble ( 3 ) ;
this . ScrollArea . HAnchor = HAnchor . Stretch ;
2017-11-28 18:11:11 -08:00
this . theme = theme ;
2017-11-28 14:37:38 -08:00
2018-02-21 15:08:42 -08:00
topToBottom = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
HAnchor = HAnchor . Stretch
} ;
this . AddChild ( topToBottom ) ;
2018-02-21 16:41:31 -08:00
var columnA = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
Margin = new BorderDouble ( 20 , 10 ) ,
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit
} ;
topToBottom . AddChild ( columnA ) ;
columnA . AddChild ( headingA = new TextWidget ( "Create" . Localize ( ) , pointSize : theme . H1PointSize , textColor : ActiveTheme . Instance . PrimaryTextColor , bold : true )
{
HAnchor = HAnchor . Left ,
Margin = new BorderDouble ( 20 , 5 )
} ) ;
columnA . AddChild ( toolBarA = new Toolbar ( )
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit
} ) ;
var createPart = new TextButton ( "Create Part" . Localize ( ) , theme )
{
Margin = theme . ButtonSpacing
} ;
createPart . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
BedConfig bed ;
simpleTabs . RemoveTab ( simpleTabs . ActiveTab ) ;
partPreviewContent . CreatePartTab (
"New Part" ,
bed = new BedConfig ( ) ,
theme ) ;
bed . LoadContent (
new EditContext ( )
{
ContentStore = ApplicationController . Instance . Library . PlatingHistory ,
SourceItem = BedConfig . NewPlatingItem ( )
} ) . ConfigureAwait ( false ) ;
} ) ;
} ;
toolBarA . AddChild ( createPart ) ;
var createPrinter = new TextButton ( "Create Printer" . Localize ( ) , theme )
{
Name = "Create Printer" ,
Margin = theme . ButtonSpacing
} ;
createPrinter . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
simpleTabs . RemoveTab ( simpleTabs . ActiveTab ) ;
if ( ApplicationController . Instance . ActivePrinter . Connection . PrinterIsPrinting
| | ApplicationController . Instance . ActivePrinter . Connection . PrinterIsPaused )
{
StyledMessageBox . ShowMessageBox ( "Please wait until the print has finished and try again." . Localize ( ) , "Can't add printers while printing" . Localize ( ) ) ;
}
else
{
DialogWindow . Show ( PrinterSetup . GetBestStartPage ( PrinterSetup . StartPageOptions . ShowMakeModel ) ) ;
}
} ) ;
} ;
toolBarA . AddChild ( createPrinter ) ;
var importButton = new TextButton ( "Import Printer" . Localize ( ) , theme )
{
Margin = theme . ButtonSpacing
} ;
importButton . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
AggContext . FileDialogs . OpenFileDialog (
new OpenFileDialogParams (
"settings files|*.ini;*.printer;*.slice" ) ,
( result ) = >
{
if ( ! string . IsNullOrEmpty ( result . FileName )
& & File . Exists ( result . FileName ) )
{
simpleTabs . RemoveTab ( simpleTabs . ActiveTab ) ;
2018-03-16 15:14:23 -07:00
if ( ProfileManager . ImportFromExisting ( result . FileName ) )
{
string importPrinterSuccessMessage = "You have successfully imported a new printer profile. You can find '{0}' in your list of available printers." . Localize ( ) ;
DialogWindow . Show (
new ImportSucceeded ( importPrinterSuccessMessage . FormatWith ( Path . GetFileNameWithoutExtension ( result . FileName ) ) ) ) ;
}
else
{
StyledMessageBox . ShowMessageBox ( "Oops! Settings file '{0}' did not contain any settings we could import." . Localize ( ) . FormatWith ( Path . GetFileName ( result . FileName ) ) , "Unable to Import" . Localize ( ) ) ;
}
2018-02-21 16:41:31 -08:00
}
} ) ;
} ) ;
} ;
toolBarA . AddChild ( importButton ) ;
toolBarA . AddChild ( new VerticalLine ( 50 ) { Margin = new BorderDouble ( 12 , 0 ) } ) ;
2018-02-21 18:44:23 -08:00
toolBarA . AddChild ( new TextWidget ( "Open Existing" . Localize ( ) + ":" , textColor : theme . Colors . PrimaryTextColor , pointSize : theme . DefaultFontSize )
2018-02-21 16:41:31 -08:00
{
VAnchor = VAnchor . Center
} ) ;
var printerSelector = new PrinterSelector ( theme )
{
Margin = new BorderDouble ( left : 15 )
} ;
toolBarA . AddChild ( printerSelector ) ;
toolBarA . AddChild ( new VerticalLine ( 50 ) { Margin = new BorderDouble ( 12 , 0 ) } ) ;
var redeemDesignCode = new TextButton ( "Redeem Design Code" . Localize ( ) , theme )
{
Name = "Redeem Design Code Button" ,
Margin = theme . ButtonSpacing
} ;
redeemDesignCode . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
simpleTabs . RemoveTab ( simpleTabs . ActiveTab ) ;
// Implementation already does RunOnIdle
ApplicationController . Instance . RedeemDesignCode ? . Invoke ( ) ;
} ) ;
} ;
toolBarA . AddChild ( redeemDesignCode ) ;
var redeemShareCode = new TextButton ( "Enter Share Code" . Localize ( ) , theme )
{
Name = "Enter Share Code Button" ,
Margin = theme . ButtonSpacing
} ;
redeemShareCode . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
simpleTabs . RemoveTab ( simpleTabs . ActiveTab ) ;
// Implementation already does RunOnIdle
ApplicationController . Instance . EnterShareCode ? . Invoke ( ) ;
} ) ;
} ;
toolBarA . AddChild ( redeemShareCode ) ;
2017-11-28 14:37:38 -08:00
WebClient client = new WebClient ( ) ;
2018-02-21 15:04:16 -08:00
client . DownloadDataCompleted + = ( s , e ) = >
2017-11-28 14:37:38 -08:00
{
try // if we get a bad result we can get a target invocation exception. In that case just don't show anything
{
// scale the loaded image to the size of the target image
byte [ ] raw = e . Result ;
Stream stream = new MemoryStream ( raw ) ;
var jsonContent = new StreamReader ( stream ) . ReadToEnd ( ) ;
var content = JsonConvert . DeserializeObject < ExplorerFeed > ( jsonContent ) ;
// add a bunch of content
AddControlsForContent ( content ) ;
2017-11-28 15:32:09 -08:00
UiThread . RunOnIdle ( ( ) = >
{
// Force layout to change to get it working
var oldMargin = this . Margin ;
this . Margin = new BorderDouble ( 20 ) ;
this . Margin = oldMargin ;
} ) ;
2017-11-28 14:37:38 -08:00
}
catch
{
}
} ;
try
{
var url = "http://www.matterhackers.com/feeds/explore?sk=2lhddgi3q67xoqa53pchpeddl6w1uf" ;
client . DownloadDataAsync ( new Uri ( url ) ) ;
}
catch
{
}
}
2018-02-26 16:39:52 -08:00
public override void OnMouseWheel ( MouseEventArgs mouseEvent )
{
int direction = ( mouseEvent . WheelDelta > 0 ) ? - 1 : 1 ;
this . ScrollPosition + = new Vector2 ( 0 , ( ExploreItem . IconSize + ( ExploreItem . ItemSpacing * 2 ) ) * direction ) ;
}
2017-11-28 14:37:38 -08:00
private void AddControlsForContent ( ExplorerFeed contentList )
{
foreach ( var content in contentList . Content )
{
2018-03-14 17:45:51 -07:00
switch ( content . content_type )
2017-11-28 14:37:38 -08:00
{
2018-03-14 17:45:51 -07:00
case "banner_image" :
{
if ( ( content . theme_filter = = "dark" & & ActiveTheme . Instance . IsDarkTheme )
| | ( content . theme_filter = = "light" & & ! ActiveTheme . Instance . IsDarkTheme ) )
{
ImageBuffer image = new ImageBuffer ( 640 , 480 ) ;
ResponsiveImageWidget imageWidget = new ResponsiveImageWidget ( image )
{
Margin = new BorderDouble ( 5 ) ,
} ;
if ( content . link ! = null )
{
imageWidget . Cursor = Cursors . Hand ;
imageWidget . Click + = ( s , e ) = >
{
ApplicationController . Instance . LaunchBrowser ( content . link ) ;
} ;
}
imageWidget . Load + = ( s , e ) = > ApplicationController . Instance . DownloadToImageAsync ( image , content . image_url , false , new BlenderPreMultBGRA ( ) ) ;
topToBottom . AddChild ( imageWidget ) ;
}
}
break ;
2017-11-28 14:37:38 -08:00
case "article_group" :
case "product_group" :
2017-11-28 18:11:11 -08:00
topToBottom . AddChild ( new ExploreSection ( content , theme ) ) ;
2017-11-28 14:37:38 -08:00
break ;
}
}
}
}
2017-11-28 15:32:09 -08:00
#region json expand classes
public class ExploreFeedContent
{
public string content_type ;
public List < ExplorerFeedItem > group_items ;
public string group_link ;
public string group_subtitle ;
public string group_title ;
public string icon_url ;
public string image_url ;
public string link ;
public string theme_filter ;
}
2017-11-28 14:37:38 -08:00
public class ExplorerFeed
{
public List < ExploreFeedContent > Content ;
public string Status ;
}
public class ExplorerFeedItem
{
public string author ;
public string category ;
public string date_published ;
public string description ;
public string hero ;
public string icon ;
2017-12-08 17:41:42 -08:00
public string link ;
2017-11-28 14:37:38 -08:00
public string title ;
public string url ;
}
2017-11-28 15:32:09 -08:00
#endregion json expand classes
2017-11-28 14:37:38 -08:00
}