2015-08-15 16:38:07 -07:00
/ *
2022-02-02 17:31:44 -08:00
Copyright ( c ) 2022 , Lars Brubaker , John Lewin
2015-08-15 16:38:07 -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 .
* /
2015-04-08 15:20:10 -07:00
using System ;
2018-01-08 23:34:40 -08:00
using System.Collections.Generic ;
2015-04-08 15:20:10 -07:00
using System.IO ;
2017-05-24 19:11:51 -07:00
using System.Linq ;
2017-05-26 00:59:47 -07:00
using MatterHackers.Agg ;
2018-10-25 08:25:36 -07:00
using MatterHackers.Agg.Image ;
2017-08-20 02:34:39 -07:00
using MatterHackers.Agg.Platform ;
2017-05-26 00:59:47 -07:00
using MatterHackers.Agg.UI ;
2018-01-08 23:34:40 -08:00
using MatterHackers.DataConverters3D ;
2021-05-21 15:23:25 -07:00
using MatterHackers.ImageProcessing ;
2017-05-26 00:59:47 -07:00
using MatterHackers.Localizations ;
2017-08-14 12:34:44 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
2018-01-08 23:34:40 -08:00
using MatterHackers.MatterControl.DataStorage ;
using MatterHackers.MatterControl.Library ;
2022-03-15 17:51:28 -07:00
using MatterHackers.MatterControl.Library.Widgets ;
2019-03-29 10:10:39 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2017-08-14 12:34:44 -07:00
using MatterHackers.VectorMath ;
2014-05-25 11:11:11 -07:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2015-05-29 15:13:56 -07:00
public enum ViewControls3DButtons
{
Rotate ,
Scale ,
Translate ,
PartSelect
}
2017-10-19 09:01:07 -07:00
public enum PartViewMode
{
Layers2D ,
Layers3D ,
Model
}
public class ViewModeChangedEventArgs : EventArgs
{
public PartViewMode ViewMode { get ; set ; }
2019-06-13 08:16:50 -07:00
2018-11-08 08:13:08 -08:00
public PartViewMode PreviousMode { get ; set ; }
2017-10-19 09:01:07 -07:00
}
2017-05-25 17:58:20 -07:00
public class TransformStateChangedEventArgs : EventArgs
{
public ViewControls3DButtons TransformMode { get ; set ; }
}
2021-09-13 21:47:46 -07:00
public class ViewToolBarControls : FlowLeftRightWithWrapping
2015-04-08 15:20:10 -07:00
{
2017-05-26 00:59:47 -07:00
public event EventHandler ResetView ;
2017-10-19 09:01:07 -07:00
2017-05-26 00:59:47 -07:00
public event EventHandler < TransformStateChangedEventArgs > TransformStateChanged ;
2018-01-08 23:34:40 -08:00
private View3DWidget view3DWidget ;
2020-09-12 13:09:17 -07:00
private readonly ISceneContext sceneContext ;
private readonly PartWorkspace workspace ;
2018-02-02 17:43:54 -08:00
private ViewControls3DButtons activeTransformState = ViewControls3DButtons . PartSelect ;
2020-09-24 13:53:49 -07:00
private readonly Dictionary < GuiWidget , SceneOperation > operationButtons ;
2018-10-30 14:02:50 -07:00
private MainViewWidget mainViewWidget = null ;
2020-09-12 13:09:17 -07:00
private readonly PopupMenuButton bedMenuButton ;
private readonly UndoBuffer undoBuffer ;
2022-07-16 07:46:44 -07:00
private readonly ThemedIconButton undoButton ;
private readonly ThemedIconButton redoButton ;
2018-08-08 07:08:08 -07:00
2021-12-12 11:19:45 -08:00
public ViewToolBarControls ( PartWorkspace workspace , ThemeConfig theme , UndoBuffer undoBuffer , bool isPrinterType , bool showPrintButton )
2015-04-08 15:20:10 -07:00
{
2018-11-16 08:44:56 -08:00
this . undoBuffer = undoBuffer ;
2018-01-11 22:26:05 -08:00
this . IsPrinterMode = isPrinterType ;
2018-12-12 17:12:06 -08:00
this . sceneContext = workspace . SceneContext ;
this . workspace = workspace ;
2017-11-29 15:22:18 -08:00
2021-09-14 14:15:51 -07:00
this . RowPadding = 0 ;
2022-08-29 00:47:01 -07:00
this . RowBorder = new BorderDouble ( 0 , 0 , 0 , 1 ) ;
this . RowBorderColor = theme . GetBorderColor ( 50 ) ;
2021-09-14 14:15:51 -07:00
2021-09-16 14:55:26 -07:00
var openLibraryButton = CreateOpenLibraryButton ( sceneContext , theme ) ;
2015-04-08 15:20:10 -07:00
2021-09-16 14:55:26 -07:00
this . AddChild ( CreateOpenFileButton ( openLibraryButton , theme ) ) ;
2021-09-13 17:47:24 -07:00
this . AddChild ( CreateSaveButton ( theme ) ) ;
2018-01-11 22:25:36 -08:00
2020-10-19 18:08:15 -07:00
this . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
2018-01-12 23:19:44 -08:00
2021-09-13 17:47:24 -07:00
bedMenuButton = new PopupMenuButton ( "Bed" . Localize ( ) , StaticData . Instance . LoadIcon ( "bed.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) , theme )
2018-10-18 17:25:56 -07:00
{
Name = "Bed Options Menu" ,
Enabled = true ,
Margin = theme . ButtonSpacing ,
2018-10-19 18:17:27 -07:00
VAnchor = VAnchor . Center ,
DrawArrow = true
2018-10-18 17:25:56 -07:00
} ;
2018-10-23 09:38:03 -07:00
this . AddChild ( bedMenuButton ) ;
2018-10-18 17:25:56 -07:00
2020-10-19 18:08:15 -07:00
this . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
2018-10-18 17:25:56 -07:00
2022-07-16 07:46:44 -07:00
undoButton = new ThemedIconButton ( StaticData . Instance . LoadIcon ( "undo.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) , theme )
2017-11-09 12:44:47 -08:00
{
Name = "3D View Undo" ,
2019-01-31 12:35:12 -08:00
ToolTipText = "Undo" . Localize ( ) ,
2017-11-09 12:44:47 -08:00
Enabled = false ,
2018-06-25 08:39:57 -07:00
Margin = theme . ButtonSpacing ,
2017-11-09 12:44:47 -08:00
VAnchor = VAnchor . Center
} ;
2023-04-02 19:37:15 -07:00
undoButton . MouseEnterBounds + = ( s , e ) = > undoButton . SetActiveUiHint ( "Ctrl + z" . Localize ( ) ) ;
2017-08-14 12:34:44 -07:00
undoButton . Click + = ( sender , e ) = >
{
2018-12-16 08:35:16 -08:00
sceneContext . Scene . Undo ( ) ;
2020-09-11 19:59:14 -07:00
view3DWidget . Object3DControlLayer . Focus ( ) ;
2017-08-14 12:34:44 -07:00
} ;
this . AddChild ( undoButton ) ;
2017-11-09 12:44:47 -08:00
2022-07-16 07:46:44 -07:00
redoButton = new ThemedIconButton ( StaticData . Instance . LoadIcon ( "redo.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) , theme )
2017-11-09 12:44:47 -08:00
{
Name = "3D View Redo" ,
2018-06-25 08:39:57 -07:00
Margin = theme . ButtonSpacing ,
2019-01-31 12:35:12 -08:00
ToolTipText = "Redo" . Localize ( ) ,
2017-11-09 12:44:47 -08:00
Enabled = false ,
VAnchor = VAnchor . Center
} ;
2023-04-02 19:37:15 -07:00
redoButton . MouseEnterBounds + = ( s , e ) = > redoButton . SetActiveUiHint ( "Ctrl + Y, Ctrl + Shift + Z" . Localize ( ) ) ;
2017-08-14 12:34:44 -07:00
redoButton . Click + = ( sender , e ) = >
{
2018-12-16 08:35:16 -08:00
sceneContext . Scene . Redo ( ) ;
2020-09-11 19:59:14 -07:00
view3DWidget . Object3DControlLayer . Focus ( ) ;
2017-08-14 12:34:44 -07:00
} ;
this . AddChild ( redoButton ) ;
2018-10-15 15:13:40 -07:00
if ( showPrintButton )
{
2022-07-16 07:46:44 -07:00
var printButton = new ThemedTextButton ( "Print" , theme )
2018-10-17 14:42:01 -07:00
{
2018-10-17 17:38:20 -07:00
Name = "Print Button" ,
2018-10-17 14:42:01 -07:00
BackgroundColor = theme . AccentMimimalOverlay
} ;
2018-10-16 11:41:30 -07:00
printButton . Click + = ( s , e ) = >
{
2018-10-23 19:54:09 -07:00
view3DWidget . PushToPrinterAndPrint ( ) ;
2018-10-16 11:41:30 -07:00
} ;
2018-10-15 15:13:40 -07:00
this . AddChild ( printButton ) ;
}
2020-10-19 18:08:15 -07:00
this . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
2017-08-14 12:34:44 -07:00
2018-08-21 12:29:09 -07:00
undoButton . Enabled = undoBuffer . UndoCount > 0 ;
redoButton . Enabled = undoBuffer . RedoCount > 0 ;
2020-09-24 13:53:49 -07:00
operationButtons = new Dictionary < GuiWidget , SceneOperation > ( ) ;
2018-01-10 11:58:42 -08:00
2018-01-10 11:39:39 -08:00
// Add Selected IObject3D -> Operations to toolbar
2020-09-26 10:59:31 -07:00
foreach ( var namedAction in SceneOperations . All )
2018-01-10 11:39:39 -08:00
{
if ( namedAction is SceneSelectionSeparator )
{
2020-10-19 18:08:15 -07:00
this . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
2018-01-10 11:39:39 -08:00
continue ;
}
2019-06-13 08:28:09 -07:00
// add the create support before the align
if ( namedAction is OperationGroup group
2020-10-01 19:34:55 -07:00
& & group . Id = = "Transform" )
2019-06-13 08:28:09 -07:00
{
this . AddChild ( CreateSupportButton ( theme ) ) ;
2020-10-19 18:08:15 -07:00
this . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
2019-06-13 08:28:09 -07:00
}
2019-06-13 08:16:50 -07:00
if ( namedAction is OperationGroup operationGroup )
{
2021-09-14 14:15:51 -07:00
var expandoSet = new FlowLayoutWidget ( ) ;
2019-06-13 08:16:50 -07:00
2021-09-14 14:15:51 -07:00
var actionDropDown = CreateActionDropDown ( theme , operationGroup ) ;
var operationButtonGroup = CreateOperationButtonGroup ( theme , operationGroup ) ;
2019-06-20 13:29:58 -07:00
2021-09-14 14:15:51 -07:00
void UpdateVisability ( object s , EventArgs e )
2019-06-20 13:29:58 -07:00
{
2021-09-15 17:44:24 -07:00
if ( operationGroup . Visible )
2019-06-20 13:29:58 -07:00
{
2021-09-15 17:44:24 -07:00
if ( operationGroup . Collapse )
{
actionDropDown . Visible = true ;
operationButtonGroup . Visible = false ;
DoWrappingLayout ( ) ;
}
else
{
actionDropDown . Visible = false ;
operationButtonGroup . Visible = true ;
DoWrappingLayout ( ) ;
}
2019-06-20 13:29:58 -07:00
}
2021-09-14 14:15:51 -07:00
else
2019-06-20 13:29:58 -07:00
{
2021-09-14 14:15:51 -07:00
actionDropDown . Visible = false ;
2021-09-15 17:44:24 -07:00
operationButtonGroup . Visible = false ;
DoWrappingLayout ( ) ;
2019-06-20 13:29:58 -07:00
}
}
2021-09-14 14:15:51 -07:00
UserSettings . Instance . SettingChanged + = UpdateVisability ;
operationGroup . CollapseChanged + = UpdateVisability ;
2021-09-15 17:44:24 -07:00
operationGroup . VisibleChanged + = UpdateVisability ;
2021-09-14 14:15:51 -07:00
this . Closed + = ( s , e ) = >
2018-01-10 11:39:39 -08:00
{
2021-09-14 14:15:51 -07:00
UserSettings . Instance . SettingChanged - = UpdateVisability ;
2021-09-15 17:44:24 -07:00
operationGroup . CollapseChanged - = UpdateVisability ;
operationGroup . VisibleChanged - = UpdateVisability ;
2018-01-10 11:39:39 -08:00
} ;
2021-09-14 14:15:51 -07:00
UpdateVisability ( operationGroup , null ) ;
expandoSet . AddChild ( actionDropDown ) ;
expandoSet . AddChild ( operationButtonGroup ) ;
this . AddChild ( expandoSet ) ;
2018-01-10 11:39:39 -08:00
}
else
{
2021-09-14 15:45:14 -07:00
GuiWidget button ;
2019-06-20 13:29:58 -07:00
2021-09-14 14:15:51 -07:00
if ( namedAction . Icon ! = null )
2018-05-25 14:52:23 -07:00
{
2022-07-16 07:46:44 -07:00
button = new ThemedIconButton ( namedAction . Icon ( theme ) , theme )
2019-06-20 13:29:58 -07:00
{
2021-09-14 14:15:51 -07:00
Name = namedAction . Title + " Button" ,
ToolTipText = namedAction . Title ,
Margin = theme . ButtonSpacing ,
BackgroundColor = theme . ToolbarButtonBackground ,
HoverColor = theme . ToolbarButtonHover ,
MouseDownColor = theme . ToolbarButtonDown ,
} ;
2022-04-28 16:39:03 -07:00
if ( ! string . IsNullOrEmpty ( namedAction . UiHint ) )
{
2023-04-02 19:37:15 -07:00
button . MouseEnterBounds + = ( s1 , e1 ) = > button . SetActiveUiHint ( namedAction . UiHint ) ;
2022-04-28 16:39:03 -07:00
}
2021-09-14 14:15:51 -07:00
}
else
{
2022-07-16 07:46:44 -07:00
button = new ThemedTextButton ( namedAction . Title , theme )
2021-09-14 14:15:51 -07:00
{
Name = namedAction . Title + " Button" ,
Margin = theme . ButtonSpacing ,
BackgroundColor = theme . ToolbarButtonBackground ,
HoverColor = theme . ToolbarButtonHover ,
MouseDownColor = theme . ToolbarButtonDown ,
} ;
2019-06-20 13:29:58 -07:00
}
2019-06-13 08:16:50 -07:00
2021-09-14 15:45:14 -07:00
operationButtons . Add ( button , namedAction ) ;
2021-09-14 14:15:51 -07:00
2021-09-14 15:45:14 -07:00
button . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
namedAction . Action . Invoke ( sceneContext ) ;
2022-02-02 17:31:44 -08:00
var partTab = button . Parents < DesignTabPage > ( ) . FirstOrDefault ( ) ;
2021-09-14 15:45:14 -07:00
var view3D = partTab . Descendants < View3DWidget > ( ) . FirstOrDefault ( ) ;
view3D . Object3DControlLayer . Focus ( ) ;
} ) ;
2021-09-14 14:15:51 -07:00
2021-09-14 15:45:14 -07:00
this . AddChild ( button ) ;
2019-06-20 13:29:58 -07:00
}
2018-01-10 11:39:39 -08:00
}
2021-09-15 08:47:03 -07:00
// add the options menu
2021-09-15 17:44:24 -07:00
this . AddChild ( new HorizontalSpacer ( ) ) ;
2022-06-19 15:02:05 -07:00
optionsButton = new PopupMenuButton ( "Tools" . Localize ( ) , theme )
2021-09-15 17:44:24 -07:00
{
2022-06-19 15:02:05 -07:00
AlignToRightEdge = true ,
DrawArrow = true ,
2021-09-15 17:44:24 -07:00
} ;
2021-09-15 08:47:03 -07:00
this . AddChild ( optionsButton ) ;
2021-09-15 17:44:24 -07:00
optionsButton . Name = "ToolBar Overflow Menu" ;
optionsButton . ToolTipText = "Tool Bar Options" . Localize ( ) ;
optionsButton . DynamicPopupContent = ( ) = > GenerateToolBarOptionsMenu ( theme ) ;
2021-09-15 08:47:03 -07:00
2018-11-16 08:44:56 -08:00
// Register listeners
undoBuffer . Changed + = UndoBuffer_Changed ;
2019-09-13 08:41:56 -07:00
sceneContext . Scene . SelectionChanged + = UpdateToolbarButtons ;
sceneContext . Scene . ItemsModified + = UpdateToolbarButtons ;
2018-01-17 08:05:12 -08:00
// Run on load
2019-09-13 08:41:56 -07:00
UpdateToolbarButtons ( null , null ) ;
2021-12-12 11:19:45 -08:00
this . MouseDown + = ( s , mouseEvent ) = >
{
if ( mouseEvent . Button = = MouseButtons . Right )
{
UiThread . RunOnIdle ( ( ) = >
{
var popupMenu = GenerateToolBarOptionsMenu ( theme ) ;
popupMenu . ShowMenu ( this , mouseEvent ) ;
} ) ;
}
} ;
2018-01-10 11:58:42 -08:00
}
2021-12-12 11:19:45 -08:00
private string Collapsed ;
2021-09-16 14:55:26 -07:00
private string Expanded ;
private string Hidden ;
2022-03-23 18:06:35 -07:00
private string Default ;
private string Hide_All ;
private string Expand_All ;
2022-06-19 15:02:05 -07:00
private PopupMenuButton optionsButton ;
private IEnumerable < OperationGroup > GroupOperations
{
get
{
foreach ( var namedAction in SceneOperations . All )
{
if ( namedAction is OperationGroup operationGroup )
{
yield return operationGroup ;
}
}
}
}
2022-03-23 18:06:35 -07:00
2021-12-12 11:19:45 -08:00
private PopupMenu GenerateToolBarOptionsMenu ( ThemeConfig theme )
2021-09-15 08:47:03 -07:00
{
2021-09-15 17:44:24 -07:00
var popupMenu = new PopupMenu ( theme )
{
Padding = new BorderDouble ( 0 , 7 ) ,
} ;
2022-06-19 15:02:05 -07:00
#if true
void DefaultClicked ( object e , MouseEventArgs mouseEvent )
2022-03-23 18:06:35 -07:00
{
2022-06-19 15:02:05 -07:00
foreach ( var operationGroup in GroupOperations )
{
switch ( operationGroup . Id )
{
case "Path" :
case "Printing" :
case "Design Apps" :
operationGroup . Visible = false ;
break ;
default :
operationGroup . Collapse = true ;
operationGroup . Visible = true ;
break ;
}
}
optionsButton . InvokeClick ( ) ;
UiThread . RunOnIdle ( optionsButton . InvokeClick ) ;
}
2022-03-23 18:06:35 -07:00
2022-06-19 15:02:05 -07:00
void HideAll ( object e , MouseEventArgs mouseEvent )
2022-03-23 18:06:35 -07:00
{
2022-06-19 15:02:05 -07:00
foreach ( var operationGroup in GroupOperations )
2022-03-23 18:06:35 -07:00
{
2022-06-19 15:02:05 -07:00
operationGroup . Visible = false ;
2022-03-23 18:06:35 -07:00
}
2022-06-19 15:02:05 -07:00
optionsButton . InvokeClick ( ) ;
UiThread . RunOnIdle ( optionsButton . InvokeClick ) ;
}
void ExpandAll ( object e , MouseEventArgs mouseEvent )
{
foreach ( var operationGroup in GroupOperations )
{
operationGroup . Collapse = false ;
operationGroup . Visible = true ;
}
optionsButton . InvokeClick ( ) ;
UiThread . RunOnIdle ( optionsButton . InvokeClick ) ;
}
// buttons for the control of defaults
var topButtonData = new ( string , string , EventHandler < MouseEventArgs > ) [ ]
{
( nameof ( Default ) , nameof ( Default ) . Replace ( "_" , " " ) . Localize ( ) , DefaultClicked ) ,
( nameof ( Expand_All ) , nameof ( Expand_All ) . Replace ( "_" , " " ) . Localize ( ) , ExpandAll ) ,
( nameof ( Hide_All ) , nameof ( Hide_All ) . Replace ( "_" , " " ) . Localize ( ) , HideAll ) ,
} ;
popupMenu . CreateButtonMenuItem ( "Design Tools" . Localize ( ) , topButtonData , 40 * GuiWidget . DeviceScale , true ) ;
popupMenu . CreateSeparator ( 5 ) ;
2022-03-23 18:06:35 -07:00
#endif
// the buttons per setting
2021-09-15 17:44:24 -07:00
var buttonData = new ( string , string ) [ ]
{
2021-09-16 14:55:26 -07:00
( nameof ( Collapsed ) , "Collapse" . Localize ( ) ) ,
( nameof ( Expanded ) , "Expand" . Localize ( ) ) ,
( nameof ( Hidden ) , "Hide" . Localize ( ) ) ,
2021-09-15 17:44:24 -07:00
} ;
2022-06-19 15:02:05 -07:00
foreach ( var operationGroup in GroupOperations )
2021-09-15 08:47:03 -07:00
{
2022-06-19 15:02:05 -07:00
var startingValue = operationGroup . Collapse ? nameof ( Collapsed ) : nameof ( Expanded ) ;
if ( ! operationGroup . Visible )
2021-09-15 17:44:24 -07:00
{
2022-06-19 15:02:05 -07:00
startingValue = nameof ( Hidden ) ;
}
2021-09-15 17:44:24 -07:00
2022-06-19 15:02:05 -07:00
popupMenu . CreateButtonSelectMenuItem ( operationGroup . Title , buttonData , startingValue , ( value ) = >
{
switch ( value )
2021-09-15 17:44:24 -07:00
{
2022-06-19 15:02:05 -07:00
case nameof ( Expanded ) :
operationGroup . Collapse = false ;
operationGroup . Visible = true ;
break ;
case nameof ( Collapsed ) :
operationGroup . Collapse = true ;
operationGroup . Visible = true ;
break ;
case nameof ( Hidden ) :
operationGroup . Visible = false ;
break ;
}
} , 40 * GuiWidget . DeviceScale ) ;
2021-09-16 16:31:14 -07:00
2022-06-19 15:02:05 -07:00
popupMenu . CreateSeparator ( ) ;
2021-09-15 08:47:03 -07:00
} ;
2021-09-15 17:44:24 -07:00
return popupMenu ;
2021-09-15 08:47:03 -07:00
}
2021-09-14 14:15:51 -07:00
private FlowLayoutWidget CreateOperationButtonGroup ( ThemeConfig theme , OperationGroup operationGroup )
{
var buttonGroup = new FlowLayoutWidget ( ) ;
foreach ( var operation in operationGroup . Operations )
{
2022-03-24 09:55:35 -07:00
if ( operation = = null )
{
continue ;
}
2021-09-14 14:15:51 -07:00
var operationButton = new OperationIconButton ( operation , sceneContext , theme ) ;
2022-04-28 16:39:03 -07:00
if ( ! string . IsNullOrEmpty ( operation . UiHint ) )
{
2023-04-02 19:37:15 -07:00
operationButton . MouseEnterBounds + = ( s1 , e1 ) = > operationButton . SetActiveUiHint ( operation . UiHint ) ;
2022-04-28 16:39:03 -07:00
}
2021-09-14 14:15:51 -07:00
operationButtons . Add ( operationButton , operation ) ;
buttonGroup . AddChild ( operationButton ) ;
}
2022-07-16 07:46:44 -07:00
var collapseButton = buttonGroup . AddChild ( new ThemedIconButton ( StaticData . Instance . LoadIcon ( "collapse_single.png" , 8 , 16 ) . SetToColor ( theme . TextColor ) , theme ) ) ;
2021-09-14 14:15:51 -07:00
collapseButton . Width = 16 * DeviceScale ;
collapseButton . ToolTipText = "Collapse" . Localize ( ) ;
collapseButton . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
operationGroup . Collapse = true ;
DoWrappingLayout ( ) ;
} ) ;
buttonGroup . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
return buttonGroup ;
}
private GuiWidget CreateActionDropDown ( ThemeConfig theme , OperationGroup operationGroup )
{
var buttonGroup = new FlowLayoutWidget ( ) ;
var defaultOperation = operationGroup . GetDefaultOperation ( ) ;
PopupMenuButton actionAndDropDown = null ;
actionAndDropDown = theme . CreateSplitButton (
new SplitButtonParams ( )
{
Icon = defaultOperation . Icon ( theme ) ,
ButtonAction = ( menuButton ) = >
{
defaultOperation . Action . Invoke ( sceneContext ) ;
} ,
ButtonTooltip = defaultOperation . HelpText ? ? defaultOperation . Title ,
ButtonName = defaultOperation . Title ,
ExtendPopupMenu = ( PopupMenu popupMenu ) = >
{
foreach ( var operation in operationGroup . Operations )
{
var operationMenu = popupMenu . CreateMenuItem ( operation . Title , operation . Icon ? . Invoke ( theme ) ) ;
operationMenu . Enabled = operation . IsEnabled ( sceneContext ) ;
operationMenu . ToolTipText = operation . Title ;
if ( ! operationMenu . Enabled
& & ! string . IsNullOrEmpty ( operation . HelpText ) )
{
operationMenu . ToolTipText + = "\n\n" + operation . HelpText ;
}
operationMenu . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
if ( defaultOperation ! = operation )
{
// Update button
2022-07-16 07:46:44 -07:00
var iconButton = actionAndDropDown . Children . OfType < ThemedIconButton > ( ) . First ( ) ;
2021-09-14 14:15:51 -07:00
iconButton . SetIcon ( operation . Icon ( theme ) ) ;
iconButton . ToolTipText = operation . HelpText ? ? operation . Title ;
2022-04-28 16:39:03 -07:00
if ( ! string . IsNullOrEmpty ( operation . UiHint ) )
{
2023-04-02 19:37:15 -07:00
iconButton . MouseEnterBounds + = ( s1 , e1 ) = > iconButton . SetActiveUiHint ( operation . UiHint ) ;
2022-04-28 16:39:03 -07:00
}
2021-09-14 14:15:51 -07:00
UserSettings . Instance . set ( operationGroup . GroupRecordId , operationGroup . Operations . IndexOf ( operation ) . ToString ( ) ) ;
defaultOperation = operation ;
iconButton . Invalidate ( ) ;
}
operation . Action ? . Invoke ( sceneContext ) ;
} ) ;
}
var expandMenuItem = popupMenu . CreateMenuItem ( "Expand" . Localize ( ) , StaticData . Instance . LoadIcon ( "expand_single.png" , 8 , 16 ) . SetToColor ( theme . TextColor ) ) ;
expandMenuItem . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
operationGroup . Collapse = false ;
DoWrappingLayout ( ) ;
} ) ;
}
} ,
operationGroup ) ;
2021-09-14 15:45:14 -07:00
operationButtons . Add ( actionAndDropDown , operationGroup ) ;
2021-09-14 14:15:51 -07:00
buttonGroup . AddChild ( actionAndDropDown ) ;
buttonGroup . AddChild ( new ToolbarSeparator ( theme . GetBorderColor ( 50 ) , theme . SeparatorMargin ) ) ;
return buttonGroup ;
}
2021-05-25 17:25:44 -07:00
public void NotifyResetView ( )
2019-06-18 18:04:03 -07:00
{
this . ResetView . Invoke ( this , null ) ;
}
public bool IsPrinterMode { get ; }
public ViewControls3DButtons ActiveButton
{
get = > activeTransformState ;
set
{
this . activeTransformState = value ;
2021-05-17 07:25:37 -07:00
view3DWidget ? . UpdateControlButtons ( activeTransformState ) ;
2019-06-18 18:04:03 -07:00
TransformStateChanged ? . Invoke ( this , new TransformStateChangedEventArgs ( )
{
TransformMode = activeTransformState
} ) ;
}
}
internal void SetView3DWidget ( View3DWidget view3DWidget )
{
this . view3DWidget = view3DWidget ;
bedMenuButton . DynamicPopupContent = ( ) = >
{
var workspaceActions = ApplicationController . Instance . GetWorkspaceActions ( view3DWidget ) ;
var menuTheme = ApplicationController . Instance . MenuTheme ;
var popupMenu = new PopupMenu ( menuTheme ) ;
int thumbWidth = 45 ;
var gutterWidth = thumbWidth + 7 ;
popupMenu . CreateSubMenu ( "Open Recent" . Localize ( ) , menuTheme , ( subMenu ) = >
{
int maxItemWidth = 0 ;
var recentFiles = new DirectoryInfo ( ApplicationDataStorage . Instance . PlatingDirectory ) . GetFiles ( "*.mcx" ) . OrderByDescending ( f = > f . LastWriteTime ) ;
2023-09-28 18:11:34 -07:00
foreach ( var item in recentFiles . Where ( f = > f . Length > 215 ) . Select ( f = > new FileSystemFileItem ( f . FullName ) ) . Take ( 12 ) )
2019-06-18 18:04:03 -07:00
{
var imageBuffer = new ImageBuffer ( thumbWidth , thumbWidth ) ;
2022-01-24 14:49:29 -08:00
var title = new FileInfo ( item . FilePath ) . LastWriteTime . ToString ( "MMMM d h:mm tt" ) ;
2019-06-18 18:04:03 -07:00
var bedHistory = subMenu . CreateMenuItem ( title , imageBuffer ) ;
bedHistory . GutterWidth = gutterWidth ;
bedHistory . HAnchor = HAnchor . Fit ;
bedHistory . VAnchor = VAnchor . Absolute ;
bedHistory . Padding = new BorderDouble ( gutterWidth + 3 , 2 , 12 , 2 ) ;
bedHistory . Height = thumbWidth + 3 ;
bedHistory . Click + = ( s , e ) = >
{
UiThread . RunOnIdle ( async ( ) = >
{
await ApplicationController . Instance . Tasks . Execute ( "Saving changes" . Localize ( ) + "..." , sceneContext . Printer , sceneContext . SaveChanges ) ;
2022-02-20 07:59:28 -08:00
await sceneContext . LoadLibraryContent ( item , null ) ;
2019-06-18 18:04:03 -07:00
if ( sceneContext . Printer ! = null )
{
sceneContext . Printer . ViewState . ViewMode = PartViewMode . Model ;
}
} ) ;
} ;
maxItemWidth = ( int ) Math . Max ( maxItemWidth , bedHistory . Width ) ;
void UpdateImageBuffer ( ImageBuffer thumbnail )
{
// Copy updated thumbnail into original image
imageBuffer . CopyFrom ( thumbnail ) ;
bedHistory . Invalidate ( ) ;
}
ApplicationController . Instance . Library . LoadItemThumbnail (
UpdateImageBuffer ,
( contentProvider ) = >
{
if ( contentProvider is MeshContentProvider meshContentProvider )
{
ApplicationController . Instance . Thumbnails . QueueForGeneration ( async ( ) = >
{
// Ask the MeshContentProvider to RayTrace the image
var thumbnail = await meshContentProvider . GetThumbnail ( item , thumbWidth , thumbWidth ) ;
if ( thumbnail ! = null )
{
UpdateImageBuffer ( thumbnail ) ;
}
} ) ;
}
} ,
item ,
ApplicationController . Instance . Library . PlatingHistory ,
thumbWidth ,
thumbWidth ,
menuTheme ) . ConfigureAwait ( false ) ;
}
// Resize menu items to max item width
foreach ( var menuItem in subMenu . Children )
{
menuItem . HAnchor = HAnchor . Left | HAnchor . Absolute ;
menuItem . Width = maxItemWidth ;
}
} ) ;
2020-09-12 13:09:17 -07:00
var actions = new NamedAction [ ]
{
2019-06-18 18:04:03 -07:00
new ActionSeparator ( ) ,
2020-05-29 19:08:41 -07:00
workspaceActions [ "Edit" ] ,
2019-06-18 18:04:03 -07:00
new ActionSeparator ( ) ,
workspaceActions [ "Print" ] ,
new ActionSeparator ( ) ,
new NamedAction ( )
{
ID = "Export" ,
Title = "Export" . Localize ( ) ,
2021-05-21 15:23:25 -07:00
Icon = StaticData . Instance . LoadIcon ( "cube_export.png" , 16 , 16 ) . SetToColor ( menuTheme . TextColor ) ,
2019-06-18 18:04:03 -07:00
Action = ( ) = >
{
ApplicationController . Instance . ExportLibraryItems (
2020-09-12 13:09:17 -07:00
new [ ] { new InMemoryLibraryItem ( sceneContext . Scene ) } ,
2019-06-18 18:04:03 -07:00
centerOnBed : false ,
printer : view3DWidget . Printer ) ;
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
| | ( sceneContext . EditContext . SourceItem is ILibraryAsset libraryAsset
2020-09-12 13:09:17 -07:00
& & string . Equals ( Path . GetExtension ( libraryAsset . FileName ) , ".gcode" , StringComparison . OrdinalIgnoreCase ) )
2019-06-18 18:04:03 -07:00
} ,
new ActionSeparator ( ) ,
new NamedAction ( )
{
ID = "ClearBed" ,
Title = "Clear Bed" . Localize ( ) ,
Action = ( ) = >
{
UiThread . RunOnIdle ( ( ) = >
{
view3DWidget . ClearPlate ( ) ;
} ) ;
}
}
} ;
menuTheme . CreateMenuItems ( popupMenu , actions ) ;
return popupMenu ;
} ;
}
2018-11-16 08:44:56 -08:00
private void UndoBuffer_Changed ( object sender , EventArgs e )
{
undoButton . Enabled = undoBuffer . UndoCount > 0 ;
redoButton . Enabled = undoBuffer . RedoCount > 0 ;
}
2021-09-16 14:55:26 -07:00
private GuiWidget CreateOpenFileButton ( GuiWidget openLibraryButton , ThemeConfig theme )
2018-10-29 17:31:43 -07:00
{
2021-09-16 16:31:14 -07:00
var popupMenu = new PopupMenuButton ( openLibraryButton , theme )
2018-10-29 17:31:43 -07:00
{
2018-11-27 18:15:17 -08:00
Name = "Open File Button"
2018-10-29 17:31:43 -07:00
} ;
2021-09-16 16:31:14 -07:00
popupMenu . DistinctPopupButton = true ;
popupMenu . DrawArrow = true ;
openLibraryButton . Selectable = true ;
2021-09-13 17:47:24 -07:00
2022-07-16 07:46:44 -07:00
if ( popupMenu . Children < ThemedButton > ( ) . FirstOrDefault ( ) is ThemedButton simpleButton )
2021-09-13 17:47:24 -07:00
{
simpleButton . Padding = 0 ;
} ;
var openMenuItems = new PopupMenu ( ApplicationController . Instance . MenuTheme ) ;
popupMenu . PopupContent = openMenuItems ;
2022-02-23 08:09:56 -08:00
var openFileButton = openMenuItems . CreateMenuItem ( "Add System File to Bed" . Localize ( ) , StaticData . Instance . LoadIcon ( "fa-folder-open_16.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) ) ;
2021-09-13 17:47:24 -07:00
2021-09-16 16:31:14 -07:00
openFileButton . Click + = ( s , e ) = >
2022-02-12 18:47:59 -08:00
{
ApplicationController . OpenFileWithSystemDialog ( ( fileNames ) = >
{
sceneContext . AddToPlate ( fileNames ) ;
} ) ;
} ;
2021-09-16 14:55:26 -07:00
2021-09-13 17:47:24 -07:00
return popupMenu ;
2018-10-29 17:31:43 -07:00
}
2022-02-12 18:47:59 -08:00
private void UpdateToolbarButtons ( object sender , EventArgs e )
2018-01-10 11:58:42 -08:00
{
// Set enabled level based on operation rules
2019-06-18 18:29:10 -07:00
foreach ( var ( button , operation ) in operationButtons . Select ( kvp = > ( kvp . Key , kvp . Value ) ) )
2018-01-10 11:58:42 -08:00
{
2020-06-26 08:07:53 -07:00
button . Enabled = operation . IsEnabled ? . Invoke ( sceneContext ) ? ? false ;
2023-04-02 19:37:15 -07:00
button . MouseEnterBounds + = ( s , e ) = > button . SetActiveUiHint ( operation . Title ) ;
2020-06-26 08:07:53 -07:00
button . ToolTipText = operation . Title ;
if ( ! button . Enabled
& & ! string . IsNullOrEmpty ( operation . HelpText ) )
{
button . ToolTipText + = "\n\n" + operation . HelpText ;
}
2019-06-17 12:12:03 -07:00
2019-06-18 18:29:10 -07:00
if ( operation is OperationGroup operationGroup
& & button is PopupMenuButton splitButton
2022-07-16 07:46:44 -07:00
& & button . Descendants < ThemedIconButton > ( ) . FirstOrDefault ( ) is ThemedIconButton iconButton )
2019-06-17 12:12:03 -07:00
{
2020-06-26 08:07:53 -07:00
var defaultOperation = operationGroup . GetDefaultOperation ( ) ;
iconButton . Enabled = defaultOperation . IsEnabled ( sceneContext ) ;
iconButton . ToolTipText = defaultOperation . Title ;
if ( ! iconButton . Enabled
& & ! string . IsNullOrEmpty ( defaultOperation . HelpText ) )
{
iconButton . ToolTipText + = "\n\n" + defaultOperation . HelpText ;
}
2019-06-17 12:12:03 -07:00
}
2018-01-10 11:58:42 -08:00
}
2017-07-06 18:15:53 -07:00
}
2021-09-16 14:55:26 -07:00
private GuiWidget CreateOpenLibraryButton ( ISceneContext sceneContext , ThemeConfig theme )
2018-01-11 22:25:36 -08:00
{
2018-11-03 09:50:09 -07:00
var openColor = theme . ResolveColor ( theme . BackgroundColor , theme . SlightShade ) ;
2018-10-11 15:04:03 -07:00
2018-10-25 15:31:31 -07:00
PopupMenuButton libraryPopup = null ;
2022-02-12 18:19:03 -08:00
libraryPopup = new PopupMenuButton ( "Add to Bed" . Localize ( ) , StaticData . Instance . LoadIcon ( "fa-folder-open_16.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) , theme )
2018-01-11 22:25:36 -08:00
{
2018-10-16 16:23:25 -07:00
MakeScrollable = false ,
2018-10-10 13:33:16 -07:00
Name = "Add Content Menu" ,
2018-10-11 15:04:03 -07:00
AlwaysKeepOpen = true ,
2018-02-06 13:31:25 -08:00
DynamicPopupContent = ( ) = >
{
2018-10-30 14:02:50 -07:00
if ( mainViewWidget = = null )
2018-10-07 11:36:52 -07:00
{
2018-10-30 14:02:50 -07:00
mainViewWidget = this . Parents < MainViewWidget > ( ) . FirstOrDefault ( ) ;
2018-10-07 11:36:52 -07:00
}
2018-10-16 16:23:25 -07:00
var verticalResizeContainer = new VerticalResizeContainer ( theme , GrabBarSide . Right )
2018-10-07 11:36:52 -07:00
{
2018-10-25 15:31:31 -07:00
BackgroundColor = openColor ,
2018-10-16 16:23:25 -07:00
MinimumSize = new Vector2 ( 120 , 50 ) ,
Height = libraryPopup . TransformToScreenSpace ( libraryPopup . Position ) . Y ,
2018-10-25 15:31:31 -07:00
SplitterBarColor = theme . SlightShade ,
2018-10-07 11:36:52 -07:00
} ;
2018-10-16 16:23:25 -07:00
double . TryParse ( UserSettings . Instance . get ( UserSettingsKey . PopupLibraryWidth ) , out double controlWidth ) ;
if ( controlWidth = = 0 )
{
controlWidth = 400 ;
}
2020-08-08 07:12:56 -07:00
2018-10-16 16:23:25 -07:00
verticalResizeContainer . Width = controlWidth ;
verticalResizeContainer . BoundsChanged + = ( s2 , e2 ) = >
{
UserSettings . Instance . set ( UserSettingsKey . PopupLibraryWidth , verticalResizeContainer . Width . ToString ( ) ) ;
} ;
2018-10-11 17:25:01 -07:00
var systemWindow = this . Parents < SystemWindow > ( ) . FirstOrDefault ( ) ;
2018-02-06 13:31:25 -08:00
2019-04-18 16:41:45 -07:00
// Compute slight highlight of openColor for use as listView background color
var slightHighlight = theme . ResolveColor ( openColor , Color . White . WithAlpha ( theme . IsDarkTheme ? 10 : 50 ) ) ;
2023-03-11 11:26:16 -08:00
var popupLibraryWidget = new PopupLibraryWidget ( mainViewWidget , workspace , theme , slightHighlight , libraryPopup )
2018-10-07 11:36:52 -07:00
{
2018-10-16 16:23:25 -07:00
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Absolute ,
2018-10-11 17:25:01 -07:00
Height = libraryPopup . TransformToScreenSpace ( libraryPopup . Position ) . Y ,
2018-10-16 16:23:25 -07:00
Margin = new BorderDouble ( left : verticalResizeContainer . SplitterWidth )
2018-10-11 17:25:01 -07:00
} ;
systemWindow . SizeChanged + = ( s , e ) = >
{
2023-03-11 11:26:16 -08:00
popupLibraryWidget . Height = libraryPopup . TransformToScreenSpace ( libraryPopup . Position ) . Y ;
2018-10-11 15:04:03 -07:00
} ;
2018-10-07 11:36:52 -07:00
2023-03-11 11:26:16 -08:00
verticalResizeContainer . AddChild ( popupLibraryWidget ) ;
2018-10-11 15:04:03 -07:00
2020-09-12 13:09:17 -07:00
systemWindow . MouseDown + = SystemWindownMouseDown ;
2018-10-11 15:04:03 -07:00
2020-09-12 13:09:17 -07:00
void SystemWindownMouseDown ( object s2 , MouseEventArgs mouseEvent )
2018-10-11 15:04:03 -07:00
{
2018-10-23 14:22:32 -07:00
if ( verticalResizeContainer . Parent ! = null )
{
// MouseUp on our SystemWindow outside of our bounds should call close
var resizeContainerMousePosition = verticalResizeContainer . TransformFromScreenSpace ( mouseEvent . Position ) ;
bool mouseUpOnWidget = resizeContainerMousePosition . X > = 0 & & resizeContainerMousePosition . X < = verticalResizeContainer . Width
& & resizeContainerMousePosition . Y > = 0 & & resizeContainerMousePosition . Y < = verticalResizeContainer . Height ;
2018-10-07 11:36:52 -07:00
2018-10-23 14:22:32 -07:00
if ( ! mouseUpOnWidget )
{
libraryPopup . CloseMenu ( ) ;
2020-09-12 13:09:17 -07:00
systemWindow . MouseDown - = SystemWindownMouseDown ;
2018-10-23 14:22:32 -07:00
}
}
else
2018-10-11 15:04:03 -07:00
{
2020-09-12 13:09:17 -07:00
systemWindow . MouseDown - = SystemWindownMouseDown ;
2018-10-11 15:04:03 -07:00
}
2020-09-12 13:09:17 -07:00
}
2018-10-07 11:36:52 -07:00
2018-10-16 16:23:25 -07:00
return verticalResizeContainer ;
2018-02-06 13:31:25 -08:00
} ,
2018-01-16 19:01:09 -08:00
BackgroundColor = theme . ToolbarButtonBackground ,
HoverColor = theme . ToolbarButtonHover ,
MouseDownColor = theme . ToolbarButtonDown ,
2018-10-25 15:31:31 -07:00
OpenColor = openColor ,
2021-09-13 17:47:24 -07:00
// DrawArrow = true,
Margin = 0 ,
2019-02-24 10:02:53 -08:00
PopupBorderColor = Color . Transparent ,
PopupHAnchor = HAnchor . Fit ,
PopupVAnchor = VAnchor . Fit
2018-01-11 22:25:36 -08:00
} ;
2018-10-11 15:04:03 -07:00
return libraryPopup ;
2018-01-11 22:25:36 -08:00
}
2018-12-31 09:12:49 -08:00
private GuiWidget CreateSupportButton ( ThemeConfig theme )
{
PopupMenuButton toggleSupportButton = null ;
2019-03-29 10:10:39 -07:00
var minimumSupportHeight = . 05 ;
if ( sceneContext . Printer ! = null )
{
minimumSupportHeight = sceneContext . Printer . Settings . GetValue < double > ( SettingsKey . layer_height ) / 2 ;
}
2021-09-14 14:15:51 -07:00
toggleSupportButton = new PopupMenuButton ( StaticData . Instance . LoadIcon ( "edit_support.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) , theme )
2018-12-31 09:12:49 -08:00
{
Name = "Support SplitButton" ,
ToolTipText = "Generate Support" . Localize ( ) ,
2019-03-29 10:10:39 -07:00
DynamicPopupContent = ( ) = > new GenerateSupportPanel ( AppContext . MenuTheme , sceneContext . Scene , minimumSupportHeight ) ,
2018-12-31 12:12:05 -08:00
PopupHAnchor = HAnchor . Fit ,
PopupVAnchor = VAnchor . Fit ,
MakeScrollable = false ,
2018-12-31 09:12:49 -08:00
BackgroundColor = theme . ToolbarButtonBackground ,
HoverColor = theme . ToolbarButtonHover ,
MouseDownColor = theme . ToolbarButtonDown ,
DrawArrow = true ,
Margin = theme . ButtonSpacing ,
} ;
return toggleSupportButton ;
}
2018-10-07 11:36:52 -07:00
private GuiWidget CreateSaveButton ( ThemeConfig theme )
{
2019-06-13 08:16:50 -07:00
return theme . CreateSplitButton ( new SplitButtonParams ( )
2018-10-07 11:36:52 -07:00
{
2021-09-13 17:47:24 -07:00
ButtonText = "Save" . Localize ( ) ,
2022-02-04 14:51:41 -08:00
ButtonName = "Save" ,
2021-05-21 15:23:25 -07:00
Icon = StaticData . Instance . LoadIcon ( "save_grey_16x.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) ,
2021-02-25 23:06:42 -08:00
ButtonAction = ( menuButton ) = >
2018-10-31 09:23:58 -07:00
{
2019-06-13 08:16:50 -07:00
ApplicationController . Instance . Tasks . Execute ( "Saving" . Localize ( ) , sceneContext . Printer , async ( progress , cancellationToken ) = >
2018-10-31 09:23:58 -07:00
{
2019-06-13 08:16:50 -07:00
menuButton . Enabled = false ;
2018-10-07 11:36:52 -07:00
2022-02-03 15:02:19 -08:00
if ( sceneContext . EditContext . ContentStore = = null )
2019-06-13 08:16:50 -07:00
{
2022-02-03 15:02:19 -08:00
UiThread . RunOnIdle ( ( ) = >
{
// we need to ask for a destination
DialogWindow . Show (
new SaveAsPage (
( container , newName ) = >
{
sceneContext . SaveAs ( container , newName ) ;
} ) ) ;
} ) ;
2019-06-13 08:16:50 -07:00
}
2022-02-03 15:02:19 -08:00
else
2019-06-13 08:16:50 -07:00
{
2022-02-03 15:02:19 -08:00
try
{
await sceneContext . SaveChanges ( progress , cancellationToken ) ;
}
catch ( Exception ex )
{
ApplicationController . Instance . LogError ( "Error saving file" . Localize ( ) + ": " + ex . Message ) ;
}
2019-06-13 08:16:50 -07:00
}
2018-10-07 11:36:52 -07:00
2019-06-13 08:16:50 -07:00
menuButton . Enabled = true ;
} ) . ConfigureAwait ( false ) ;
} ,
ExtendPopupMenu = ( PopupMenu popupMenu ) = >
2018-10-07 11:36:52 -07:00
{
var saveAs = popupMenu . CreateMenuItem ( "Save As" . Localize ( ) ) ;
saveAs . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
2019-06-13 08:16:50 -07:00
DialogWindow . Show (
new SaveAsPage (
2022-02-02 22:47:05 -08:00
( container , newName ) = >
2019-06-13 08:16:50 -07:00
{
2022-02-02 22:47:05 -08:00
sceneContext . SaveAs ( container , newName ) ;
2019-06-13 08:16:50 -07:00
} ) ) ;
2018-10-07 11:36:52 -07:00
} ) ;
2021-05-21 15:23:25 -07:00
var export = popupMenu . CreateMenuItem ( "Export" . Localize ( ) , StaticData . Instance . LoadIcon ( "cube_export.png" , 16 , 16 ) . SetToColor ( theme . TextColor ) ) ;
2021-03-05 15:07:50 -08:00
export . Click + = ( s , e ) = > UiThread . RunOnIdle ( ( ) = >
{
ApplicationController . Instance . ExportLibraryItems (
new [ ] { new InMemoryLibraryItem ( sceneContext . Scene ) } ,
centerOnBed : false ,
printer : view3DWidget . Printer ) ;
} ) ;
2019-06-13 08:16:50 -07:00
}
} ) ;
2018-10-07 11:36:52 -07:00
}
2018-08-23 16:44:11 -07:00
public override void OnClosed ( EventArgs e )
2015-04-08 15:20:10 -07:00
{
2018-11-16 08:44:56 -08:00
// Unregister listeners
undoBuffer . Changed - = UndoBuffer_Changed ;
2019-09-13 08:41:56 -07:00
sceneContext . Scene . SelectionChanged - = UpdateToolbarButtons ;
sceneContext . Scene . Children . ItemsModified - = UpdateToolbarButtons ;
2018-11-16 08:44:56 -08:00
2015-04-08 15:20:10 -07:00
base . OnClosed ( e ) ;
}
}
}