2015-02-26 13:28:36 -08:00
/ *
2018-05-22 07:00:00 -07:00
Copyright ( c ) 2018 , Lars Brubaker , John Lewin
2015-02-26 13:28:36 -08: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 :
2015-02-26 13:28:36 -08: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 .
2015-02-26 13:28:36 -08: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 .
2015-02-26 13:28:36 -08: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 ,
2015-02-26 13:28:36 -08:00
either expressed or implied , of the FreeBSD Project .
* /
2017-10-18 18:18:10 -07:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
2018-06-08 08:41:15 -07:00
using System.Reflection ;
using JsonPath ;
2017-03-15 16:17:06 -07:00
using MatterHackers.Agg ;
2018-02-17 19:03:33 -08:00
using MatterHackers.Agg.Platform ;
2015-02-26 13:28:36 -08:00
using MatterHackers.Agg.UI ;
2017-10-18 14:56:10 -07:00
using MatterHackers.DataConverters3D ;
2017-03-15 16:17:06 -07:00
using MatterHackers.Localizations ;
2017-11-15 09:24:56 -08:00
using MatterHackers.MatterControl.CustomWidgets ;
2018-01-30 11:50:22 -08:00
using MatterHackers.MatterControl.DesignTools ;
2018-02-17 19:03:33 -08:00
using MatterHackers.MatterControl.Library ;
2018-02-05 17:22:19 -08:00
using MatterHackers.VectorMath ;
2018-06-08 08:41:15 -07:00
using static JsonPath . JsonPathContext . ReflectionValueSystem ;
2015-02-26 13:28:36 -08:00
2017-03-15 16:17:06 -07:00
namespace MatterHackers.MatterControl.PartPreviewWindow
2015-02-26 13:28:36 -08:00
{
2018-01-11 01:13:38 -08:00
public class SelectedObjectPanel : FlowLayoutWidget , IContentStore
2017-03-15 16:17:06 -07:00
{
2018-05-22 07:42:35 -07:00
private IObject3D item = new Object3D ( ) ;
2017-10-18 14:56:10 -07:00
2017-10-18 18:18:10 -07:00
private ThemeConfig theme ;
2018-05-31 20:07:49 -07:00
private BedConfig sceneContext ;
2017-10-18 18:18:10 -07:00
private View3DWidget view3DWidget ;
2018-06-09 11:21:31 -07:00
private SectionWidget editorSectionWidget ;
2018-01-08 23:34:40 -08:00
private TextButton editButton ;
2018-01-30 11:50:22 -08:00
2018-01-09 18:43:58 -08:00
private GuiWidget editorPanel ;
2018-01-17 23:17:49 -08:00
private InlineTitleEdit inlineTitleEdit ;
2018-06-09 11:21:31 -07:00
private BottomResizeContainer editorResizeContainer ;
2017-10-18 18:18:10 -07:00
2018-05-31 20:07:49 -07:00
public SelectedObjectPanel ( View3DWidget view3DWidget , BedConfig sceneContext , ThemeConfig theme )
2017-10-18 14:56:10 -07:00
: base ( FlowDirection . TopToBottom )
2015-04-08 15:20:10 -07:00
{
2018-01-08 14:23:26 -08:00
this . HAnchor = HAnchor . Stretch ;
2017-10-18 14:56:10 -07:00
this . VAnchor = VAnchor . Top | VAnchor . Fit ;
2018-05-22 12:51:04 -07:00
this . Padding = 0 ;
2017-10-18 18:18:10 -07:00
this . view3DWidget = view3DWidget ;
this . theme = theme ;
2018-05-31 20:07:49 -07:00
this . sceneContext = sceneContext ;
2017-10-18 14:56:10 -07:00
2018-04-11 11:29:21 -07:00
this . ContentPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom )
2017-10-18 14:56:10 -07:00
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit ,
2018-01-05 11:45:11 -08:00
} ;
var scrollable = new ScrollableWidget ( true )
{
Name = "editorPanel" ,
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
} ;
2018-04-11 11:29:21 -07:00
scrollable . AddChild ( this . ContentPanel ) ;
2018-01-05 11:45:11 -08:00
scrollable . ScrollArea . HAnchor = HAnchor . Stretch ;
this . AddChild ( scrollable ) ;
2017-10-18 18:18:10 -07:00
2018-06-09 11:21:31 -07:00
editorResizeContainer = new BottomResizeContainer ( theme )
2018-01-09 18:43:58 -08:00
{
HAnchor = HAnchor . Stretch ,
2018-05-22 13:40:13 -07:00
VAnchor = VAnchor . Absolute ,
2018-05-31 20:07:49 -07:00
Height = sceneContext . ViewState . SelectedObjectEditorHeight
2018-01-09 18:43:58 -08:00
} ;
2018-05-17 12:41:00 -07:00
var toolbar = new Toolbar ( theme )
2018-01-09 18:43:58 -08:00
{
Padding = theme . ToolbarPadding ,
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit
} ;
2018-06-09 11:21:31 -07:00
editorResizeContainer . AddChild ( toolbar ) ;
2018-06-07 18:16:16 -07:00
2018-06-09 11:21:31 -07:00
editorResizeContainer . Resized + = ( s , e ) = >
2018-06-07 18:16:16 -07:00
{
2018-06-09 11:21:31 -07:00
sceneContext . ViewState . SelectedObjectEditorHeight = editorResizeContainer . Height ;
2018-06-07 18:16:16 -07:00
} ;
2018-01-09 18:43:58 -08:00
2018-05-31 20:07:49 -07:00
var scene = sceneContext . Scene ;
2018-01-09 18:43:58 -08:00
editButton = new TextButton ( "Edit" . Localize ( ) , theme )
{
BackgroundColor = theme . MinimalShade ,
Margin = theme . ButtonSpacing
} ;
2018-02-23 18:05:13 -08:00
scene . SelectionChanged + = ( s , e ) = > editButton . Enabled = scene . SelectedItem ? . CanEdit = = true ;
2018-01-09 18:43:58 -08:00
editButton . Click + = async ( s , e ) = >
{
var bed = new BedConfig ( ) ;
var partPreviewContent = this . Parents < PartPreviewContent > ( ) . FirstOrDefault ( ) ;
partPreviewContent . CreatePartTab (
"New Part" ,
bed ,
theme ) ;
2018-05-22 07:42:35 -07:00
var clonedItem = this . item . Clone ( ) ;
2018-02-05 17:22:19 -08:00
// Edit in Identity transform
clonedItem . Matrix = Matrix4X4 . Identity ;
2018-01-09 18:43:58 -08:00
await bed . LoadContent (
new EditContext ( )
{
2018-02-09 21:21:49 -08:00
ContentStore = new DynamicContentStore ( ( libraryItem , object3D ) = >
2018-02-05 17:22:19 -08:00
{
2018-02-05 17:24:05 -08:00
var replacement = object3D . Clone ( ) ;
2018-05-22 07:42:35 -07:00
this . item . Parent . Children . Modify ( list = >
2018-02-05 17:22:19 -08:00
{
2018-05-22 07:42:35 -07:00
list . Remove ( item ) ;
2018-02-05 17:22:19 -08:00
// Restore matrix of item being replaced
2018-05-22 07:42:35 -07:00
replacement . Matrix = item . Matrix ;
2018-02-05 17:22:19 -08:00
list . Add ( replacement ) ;
2018-05-22 07:42:35 -07:00
item = replacement ;
2018-02-05 17:22:19 -08:00
} ) ;
2018-02-05 17:24:05 -08:00
scene . SelectedItem = replacement ;
2018-02-05 17:22:19 -08:00
} ) ,
2018-03-01 09:56:50 -08:00
SourceItem = new InMemoryLibraryItem ( clonedItem ) ,
2018-01-09 18:43:58 -08:00
} ) ;
} ;
toolbar . AddChild ( editButton ) ;
2018-04-09 11:57:45 -07:00
// put in a make permanent button
2018-05-02 14:34:44 -07:00
var icon = AggContext . StaticData . LoadIcon ( "fa-check_16.png" , 16 , 16 , theme . InvertIcons ) . SetPreMultiply ( ) ;
var applyButton = new IconButton ( icon , theme )
2018-01-30 11:50:22 -08:00
{
2018-02-12 15:28:26 -08:00
Margin = theme . ButtonSpacing ,
2018-05-02 14:34:44 -07:00
ToolTipText = "Apply operation and make permanent" . Localize ( )
2018-01-30 11:50:22 -08:00
} ;
2018-05-02 14:34:44 -07:00
applyButton . Click + = ( s , e ) = >
2018-01-30 11:50:22 -08:00
{
2018-02-12 15:28:26 -08:00
scene . SelectedItem = null ;
2018-05-22 07:42:35 -07:00
this . item . Apply ( view3DWidget . Scene . UndoBuffer ) ;
2018-01-30 11:50:22 -08:00
} ;
2018-05-02 14:34:44 -07:00
scene . SelectionChanged + = ( s , e ) = > applyButton . Enabled = scene . SelectedItem ? . CanApply = = true ;
toolbar . AddChild ( applyButton ) ;
2018-01-30 11:50:22 -08:00
2018-02-12 15:28:26 -08:00
// put in a remove button
2018-05-05 08:36:02 -07:00
var removeButton = new IconButton ( AggContext . StaticData . LoadIcon ( "close.png" , 16 , 16 , theme . InvertIcons ) , theme )
2018-02-12 15:28:26 -08:00
{
Margin = theme . ButtonSpacing ,
ToolTipText = "Remove operation from parts" . Localize ( )
} ;
removeButton . Click + = ( s , e ) = >
{
scene . SelectedItem = null ;
2018-05-22 07:42:35 -07:00
this . item . Remove ( view3DWidget . Scene . UndoBuffer ) ;
2018-02-12 15:28:26 -08:00
} ;
scene . SelectionChanged + = ( s , e ) = > removeButton . Enabled = scene . SelectedItem ? . CanRemove = = true ;
toolbar . AddChild ( removeButton ) ;
2018-01-30 11:50:22 -08:00
2018-01-09 18:43:58 -08:00
// Add container used to host the current specialized editor for the selection
2018-06-08 11:13:09 -07:00
var scrollableEditor = new ScrollableWidget ( true )
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch
} ;
scrollableEditor . AddChild ( editorPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom )
2018-01-09 18:43:58 -08:00
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit ,
2018-01-11 01:07:44 -08:00
Padding = new BorderDouble ( top : 10 )
2018-01-09 18:43:58 -08:00
} ) ;
2018-06-08 11:13:09 -07:00
scrollableEditor . ScrollArea . HAnchor = HAnchor . Stretch ;
2018-06-09 11:21:31 -07:00
editorResizeContainer . AddChild ( scrollableEditor ) ;
2018-01-09 18:43:58 -08:00
2018-06-09 11:21:31 -07:00
// A wrapping container to fix resize quirks - GuiWidget with H:Stretch V:Fit that can be hidden and shown and allow the ResizeContainer can keep it's size
var editorResizeWrapper = new GuiWidget ( )
2018-06-08 15:09:10 -07:00
{
HAnchor = HAnchor . Stretch ,
2018-06-09 11:21:31 -07:00
VAnchor = VAnchor . Fit ,
Name = "editorRootContainer"
2018-06-08 15:09:10 -07:00
} ;
2018-06-09 11:21:31 -07:00
editorResizeWrapper . AddChild ( editorResizeContainer ) ;
2018-06-08 15:09:10 -07:00
2018-05-22 13:28:42 -07:00
inlineTitleEdit = new InlineTitleEdit ( "" , theme , "Object Name" ) ;
inlineTitleEdit . TitleChanged + = ( s , e ) = >
{
if ( item ! = null )
{
item . Name = inlineTitleEdit . Text ;
}
} ;
2018-06-09 11:21:31 -07:00
editorSectionWidget = new SectionWidget ( "Editor" , editorResizeWrapper , theme , serializationKey : UserSettingsKey . EditorPanelExpanded , defaultExpansion : true )
2018-06-07 18:16:16 -07:00
{
VAnchor = VAnchor . Fit ,
} ;
2018-05-22 13:28:42 -07:00
// TODO: Replace hackery with practical solution
2018-06-09 11:21:31 -07:00
if ( editorSectionWidget . Children . FirstOrDefault ( ) is ExpandCheckboxButton checkbox )
2018-05-22 13:28:42 -07:00
{
checkbox . ReplaceChild ( checkbox . Children [ 1 ] , inlineTitleEdit ) ;
}
2018-06-09 11:21:31 -07:00
this . ContentPanel . AddChild ( editorSectionWidget ) ;
2018-01-08 23:34:40 -08:00
2018-04-06 06:07:32 -07:00
var colorSection = new SectionWidget (
2018-04-09 15:29:22 -07:00
"Color" . Localize ( ) ,
2018-04-06 06:07:32 -07:00
new ColorSwatchSelector ( scene , theme , buttonSize : 16 , buttonSpacing : new BorderDouble ( 1 , 1 , 0 , 0 ) )
{
Margin = new BorderDouble ( left : 10 )
2018-04-09 15:29:22 -07:00
} ,
2018-04-06 06:07:32 -07:00
theme ,
serializationKey : UserSettingsKey . ColorPanelExpanded )
2018-02-15 22:29:47 -08:00
{
Name = "Color Panel" ,
} ;
2018-04-11 11:29:21 -07:00
this . ContentPanel . AddChild ( colorSection ) ;
2018-02-15 22:29:47 -08:00
2018-04-06 06:07:32 -07:00
var mirrorSection = new SectionWidget ( "Mirror" . Localize ( ) , new MirrorControls ( scene , theme ) , theme , serializationKey : UserSettingsKey . MirrorPanelExpanded )
2018-01-08 23:34:40 -08:00
{
Name = "Mirror Panel" ,
} ;
2018-04-11 11:29:21 -07:00
this . ContentPanel . AddChild ( mirrorSection ) ;
2018-01-08 23:34:40 -08:00
2018-04-06 06:07:32 -07:00
var scaleSection = new SectionWidget ( "Scale" . Localize ( ) , new ScaleControls ( scene , theme ) , theme , serializationKey : UserSettingsKey . ScalePanelExpanded )
2018-01-08 23:34:40 -08:00
{
Name = "Scale Panel" ,
} ;
2018-04-11 11:29:21 -07:00
this . ContentPanel . AddChild ( scaleSection ) ;
2018-01-08 23:34:40 -08:00
2018-04-06 06:07:32 -07:00
var materialsSection = new SectionWidget ( "Materials" . Localize ( ) , new MaterialControls ( scene , theme ) , theme , serializationKey : UserSettingsKey . MaterialsPanelExpanded )
2018-01-08 23:34:40 -08:00
{
Name = "Materials Panel" ,
} ;
2018-04-11 11:29:21 -07:00
this . ContentPanel . AddChild ( materialsSection ) ;
2018-01-08 23:34:40 -08:00
2018-01-10 09:04:31 -08:00
// Enforce panel padding in sidebar
2018-04-11 11:29:21 -07:00
foreach ( var sectionWidget in this . ContentPanel . Children < SectionWidget > ( ) )
2018-01-10 09:04:31 -08:00
{
2018-06-09 11:40:59 -07:00
// Special case for editorResizeWrapper due to ResizeContainer
2018-06-09 11:21:31 -07:00
if ( sectionWidget . ContentPanel = = editorResizeWrapper )
{
2018-06-09 11:40:59 -07:00
// Apply padding to ResizeContainer not wrapper
2018-06-09 11:21:31 -07:00
editorResizeContainer . Padding = new BorderDouble ( 10 , 10 , 10 , 0 ) ;
}
else
{
sectionWidget . ContentPanel . Padding = new BorderDouble ( 10 , 10 , 10 , 0 ) ;
sectionWidget . ExpandableWhenDisabled = true ;
sectionWidget . Enabled = false ;
}
2018-01-10 09:04:31 -08:00
}
2017-10-18 14:56:10 -07:00
}
2018-04-11 11:29:21 -07:00
public GuiWidget ContentPanel { get ; set ; }
2018-06-08 08:41:15 -07:00
JsonPathContext xpathLikeResolver = new JsonPathContext ( ) ;
2017-10-18 18:18:10 -07:00
public void SetActiveItem ( IObject3D selectedItem )
2017-10-18 14:56:10 -07:00
{
2018-01-26 17:53:54 -08:00
var selectedItemType = selectedItem . GetType ( ) ;
2017-11-16 15:47:48 -08:00
editButton . Enabled = ( selectedItem . Children . Count > 0 ) ;
2018-01-26 17:53:54 -08:00
inlineTitleEdit . Text = selectedItem . Name ? ? selectedItemType . Name ;
2017-10-18 14:56:10 -07:00
2018-05-22 07:42:35 -07:00
this . item = selectedItem ;
2017-10-18 14:56:10 -07:00
2018-05-22 07:42:35 -07:00
HashSet < IObject3DEditor > mappedEditors = ApplicationController . Instance . GetEditorsForType ( selectedItemType ) ;
var activeEditors = new List < ( IObject3DEditor , IObject3D , string ) > ( ) ;
2018-06-08 08:41:15 -07:00
var editableItems = new List < IObject3D > { selectedItem } ;
var undoBuffer = sceneContext . Scene . UndoBuffer ;
editorPanel . CloseAllChildren ( ) ;
bool allowOperations = true ;
if ( selectedItem is ComponentObject3D componentObject )
{
allowOperations = false ;
foreach ( var selector in componentObject . SurfacedEditors )
{
// Get the named property via reflection
// Selector example: '$.Children<CylinderObject3D>'
var match = xpathLikeResolver . Select ( componentObject , selector ) . ToList ( ) ;
//// TODO: Create editor row for each property
//// - Use the type of the property to find a matching editor (ideally all datatype -> editor functionality would resolve consistently)
//// - Add editor row for each
foreach ( var instance in match )
{
if ( instance is IObject3D object3D )
{
editableItems . Add ( object3D ) ;
}
else if ( JsonPath . JsonPathContext . ReflectionValueSystem . LastMemberValue is ReflectionTarget reflectionTarget )
{
var context = new PPEContext ( )
{
item = item
} ;
var editableProperty = new EditableProperty ( reflectionTarget . PropertyInfo , reflectionTarget . Source ) ;
var editor = PublicPropertyEditor . CreatePropertyEditor ( editableProperty , undoBuffer , context , theme ) ;
if ( editor ! = null )
{
editorPanel . AddChild ( editor ) ;
}
}
}
}
}
foreach ( var child in editableItems )
2018-05-22 07:42:35 -07:00
{
if ( ApplicationController . Instance . GetEditorsForType ( child . GetType ( ) ) ? . FirstOrDefault ( ) is IObject3DEditor editor )
{
activeEditors . Add ( ( editor , child , child . Name ) ) ;
}
}
2018-06-08 08:41:15 -07:00
ShowObjectEditor ( activeEditors , selectedItem , allowOperations : allowOperations ) ;
2017-10-18 18:18:10 -07:00
}
2018-01-30 11:50:22 -08:00
private class OperationButton : TextButton
{
2018-03-22 15:00:07 -07:00
private NodeOperation graphOperation ;
2018-01-30 11:50:22 -08:00
private IObject3D sceneItem ;
2018-03-22 15:00:07 -07:00
public OperationButton ( NodeOperation graphOperation , IObject3D sceneItem , ThemeConfig theme )
2018-01-30 11:50:22 -08:00
: base ( graphOperation . Title , theme )
{
this . graphOperation = graphOperation ;
this . sceneItem = sceneItem ;
}
public void EnsureAvailablity ( )
{
this . Enabled = graphOperation . IsEnabled ( sceneItem ) ;
}
}
2018-06-08 08:41:15 -07:00
private void ShowObjectEditor ( IEnumerable < ( IObject3DEditor editor , IObject3D item , string displayName ) > scope , IObject3D rootSelection , bool allowOperations = true )
2017-10-18 18:18:10 -07:00
{
2018-05-22 07:42:35 -07:00
if ( scope = = null )
2017-10-18 18:18:10 -07:00
{
2018-05-22 07:42:35 -07:00
return ;
}
2018-05-15 17:45:14 -07:00
2018-05-22 07:42:35 -07:00
foreach ( var scopeItem in scope )
2018-01-31 14:36:08 -08:00
{
2018-05-22 07:42:35 -07:00
var selectedItem = scopeItem . item ;
var selectedItemType = selectedItem . GetType ( ) ;
2017-10-18 18:18:10 -07:00
2018-06-09 10:13:19 -07:00
var editorWidget = scopeItem . editor . Create ( selectedItem , theme ) ;
2018-05-22 07:26:22 -07:00
editorWidget . HAnchor = HAnchor . Stretch ;
editorWidget . VAnchor = VAnchor . Fit ;
2018-05-21 13:30:06 -07:00
2018-05-22 07:42:35 -07:00
if ( scopeItem . item ! = rootSelection
& & scopeItem . editor is PublicPropertyEditor )
{
editorWidget . Padding = new BorderDouble ( 10 , 10 , 10 , 0 ) ;
2018-03-27 14:15:28 -07:00
2018-05-22 07:42:35 -07:00
// EditOutline section
var sectionWidget = new SectionWidget (
scopeItem . displayName ? ? "Unknown" ,
editorWidget ,
theme ) ;
2018-04-14 20:52:35 -07:00
2018-05-22 07:42:35 -07:00
theme . ApplyBoxStyle ( sectionWidget , margin : 0 ) ;
2018-03-27 14:15:28 -07:00
2018-05-22 07:42:35 -07:00
editorWidget = sectionWidget ;
}
else
{
editorWidget . Padding = 0 ;
}
2018-01-30 11:50:22 -08:00
2018-05-22 07:42:35 -07:00
editorPanel . AddChild ( editorWidget ) ;
2018-01-30 11:50:22 -08:00
2018-05-22 07:26:22 -07:00
var buttons = new List < OperationButton > ( ) ;
2018-03-22 13:18:27 -07:00
2018-06-08 08:41:15 -07:00
if ( allowOperations )
2018-05-22 07:26:22 -07:00
{
2018-06-08 08:41:15 -07:00
foreach ( var nodeOperation in ApplicationController . Instance . Graph . Operations )
2018-01-30 11:50:22 -08:00
{
2018-06-08 08:41:15 -07:00
foreach ( var type in nodeOperation . MappedTypes )
2018-01-30 11:50:22 -08:00
{
2018-06-08 08:41:15 -07:00
if ( type . IsAssignableFrom ( selectedItemType )
& & ( nodeOperation . IsVisible = = null | | nodeOperation . IsVisible ( selectedItem ) ) )
2018-03-22 15:00:07 -07:00
{
2018-06-08 08:41:15 -07:00
var button = new OperationButton ( nodeOperation , selectedItem , theme )
{
BackgroundColor = theme . MinimalShade ,
Margin = theme . ButtonSpacing
} ;
button . EnsureAvailablity ( ) ;
button . Click + = ( s , e ) = >
{
nodeOperation . Operation ( selectedItem , sceneContext . Scene ) . ConfigureAwait ( false ) ;
} ;
buttons . Add ( button ) ;
}
2018-01-31 14:36:08 -08:00
}
2018-01-30 11:50:22 -08:00
}
2018-05-22 07:26:22 -07:00
}
2018-03-22 13:18:27 -07:00
2018-05-22 07:26:22 -07:00
if ( buttons . Any ( ) )
{
var toolbar = new Toolbar ( theme )
2018-03-22 15:00:07 -07:00
{
2018-05-22 07:26:22 -07:00
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit ,
Padding = theme . ToolbarPadding ,
Margin = new BorderDouble ( 0 , 8 )
} ;
2018-05-22 07:42:35 -07:00
editorPanel . AddChild ( toolbar ) ;
2018-05-22 07:26:22 -07:00
foreach ( var button in buttons )
2018-05-21 13:30:06 -07:00
{
2018-05-22 07:26:22 -07:00
toolbar . AddChild ( button ) ;
2018-05-21 13:30:06 -07:00
}
2018-05-22 07:26:22 -07:00
// TODO: Fix likely leak
2018-05-22 07:42:35 -07:00
selectedItem . Invalidated + = ( s , e ) = >
2018-05-22 07:26:22 -07:00
{
foreach ( var button in toolbar . ActionArea . Children . OfType < OperationButton > ( ) )
{
button . EnsureAvailablity ( ) ;
}
} ;
}
else
{
// If the button toolbar isn't added, ensure panel has bottom margin
editorWidget . Margin = editorWidget . Margin . Clone ( bottom : 15 ) ;
}
}
2015-04-08 15:20:10 -07:00
}
2017-11-15 09:24:56 -08:00
public void Save ( ILibraryItem item , IObject3D content )
{
2018-05-22 07:42:35 -07:00
this . item . Parent . Children . Modify ( children = >
2017-11-15 09:24:56 -08:00
{
2018-05-22 07:42:35 -07:00
children . Remove ( this . item ) ;
2017-11-15 09:24:56 -08:00
children . Add ( content ) ;
} ) ;
}
2015-04-08 15:20:10 -07:00
}
}