Merge pull request #5357 from larsbrubaker/main

All buttons switch to agg themed buttons
This commit is contained in:
Lars Brubaker 2022-08-16 17:23:26 -07:00 committed by GitHub
commit 58506ee005
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
114 changed files with 663 additions and 1515 deletions

View file

@ -381,7 +381,7 @@ namespace MatterHackers.MatterControl.ActionBar
// material can be changed even when the printer is not connected
alwaysEnabled.Add(materialSettingsRow);
// add in a shop button
var shopButton = new TextIconButton("Shop".Localize(), StaticData.Instance.LoadIcon("cart.png", 16, 16).SetToColor(menuTheme.TextColor), theme)
var shopButton = new ThemedTextIconButton("Shop".Localize(), StaticData.Instance.LoadIcon("cart.png", 16, 16).SetToColor(menuTheme.TextColor), theme)
{
BackgroundColor = theme.SlightShade,
HoverColor = theme.SlightShade.WithAlpha(75),

View file

@ -164,8 +164,8 @@ namespace MatterHackers.MatterControl
var themeConfig = JsonConvert.DeserializeObject<ThemeConfig>(json);
themeConfig.EnsureDefaults();
ThemeConfigExtensions.RebuildTheme(ThemeSet.Theme);
ThemeConfigExtensions.RebuildTheme(themeConfig);
return themeConfig;
}
}

View file

@ -505,7 +505,7 @@ namespace MatterHackers.MatterControl
progressPanel.AddChild(
new TextWidget(ex.Message, pointSize: theme.FontSize9, textColor: errorTextColor));
var closeButton = new TextButton("Close", theme)
var closeButton = new ThemedTextButton("Close", theme)
{
BackgroundColor = theme.SlightShade,
HAnchor = HAnchor.Right,
@ -529,60 +529,11 @@ namespace MatterHackers.MatterControl
ReportStartupProgress(0, "ShowAsSystemWindow");
AddTextWidgetRightClickMenu();
InternalTextEditWidget.AddTextWidgetRightClickMenu(ApplicationController.Instance.MenuTheme);
return rootSystemWindow;
}
public static void AddTextWidgetRightClickMenu()
{
InternalTextEditWidget.DefaultRightClick += (s, e) =>
{
var textEditWidget = s as InternalTextEditWidget;
var theme = ApplicationController.Instance.MenuTheme;
var popupMenu = new PopupMenu(theme);
var cut = popupMenu.CreateMenuItem("Cut".Localize());
cut.Enabled = !string.IsNullOrEmpty(s.Selection);
cut.Click += (s2, e2) =>
{
textEditWidget?.CopySelection();
textEditWidget?.DeleteSelection();
};
var copy = popupMenu.CreateMenuItem("Copy".Localize());
copy.Enabled = !string.IsNullOrEmpty(s.Selection);
copy.Click += (s2, e2) =>
{
textEditWidget?.CopySelection();
};
var paste = popupMenu.CreateMenuItem("Paste".Localize());
paste.Enabled = Clipboard.Instance.ContainsText;
paste.Click += (s2, e2) =>
{
textEditWidget?.PasteFromClipboard();
};
popupMenu.CreateSeparator();
var selectAll = popupMenu.CreateMenuItem("Select All".Localize());
selectAll.Enabled = !string.IsNullOrEmpty(textEditWidget.Text);
selectAll.Click += (s2, e2) =>
{
textEditWidget?.SelectAll();
};
textEditWidget.KeepMenuOpen = true;
popupMenu.Closed += (s3, e3) =>
{
textEditWidget.KeepMenuOpen = false;
};
popupMenu.ShowMenu(s, e);
};
}
private static void SystemWindow_KeyPressed(object sender, KeyPressEventArgs keyEvent)
{
if (sender is SystemWindow systemWindow)

View file

@ -62,7 +62,7 @@ namespace MatterHackers.MatterControl
};
this.AddChild(row);
row.AddChild(new IconButton(StaticData.Instance.LoadIcon("mh-app-logo.png", 16, 16).SetToColor(theme.TextColor), theme)
row.AddChild(new ThemedIconButton(StaticData.Instance.LoadIcon("mh-app-logo.png", 16, 16).SetToColor(theme.TextColor), theme)
{
VAnchor = VAnchor.Center,
Margin = theme.ButtonSpacing,

View file

@ -73,7 +73,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("AddBase")
{
OperationType = typeof(IObject3D),
TitleGetter = () => "Add Base".Localize(),
ResultType = typeof(BaseObject3D),
Action = (sceneContext) =>
@ -100,9 +99,9 @@ namespace MatterHackers.MatterControl
Icon = (theme) => StaticData.Instance.LoadIcon("add_base.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(),
HelpTextGetter = () => "A path must be selected".Localize().Stars(),
// this is for when base is working with generic meshes
//IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && !(sceneContext.Scene.SelectedItem is IPathObject),
//IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && !(sceneContext.Scene.SelectedItem.IsPathObject()),
// this is for when only IPathObjects are working correctly
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.DescendantsAndSelf().Where(i => i is IPathObject).Any(),
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.DescendantsAndSelf().Where(i => i.IsPathObject()).Any(),
};
}
@ -220,7 +219,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("EditComponent")
{
OperationType = typeof(IObject3D),
TitleGetter = () => "Edit Component".Localize(),
ResultType = typeof(ComponentObject3D),
Action = (sceneContext) =>
@ -286,7 +284,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("ImageConverter")
{
OperationType = typeof(ImageObject3D),
TitleGetter = () => "Image Converter".Localize(),
ResultType = typeof(ComponentObject3D),
Action = (sceneContext) =>
@ -350,7 +347,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("ImageToPath")
{
OperationType = typeof(ImageObject3D),
TitleGetter = () => "Image to Path".Localize(),
ResultType = typeof(ImageToPathObject3D_2),
Action = (sceneContext) =>
@ -385,7 +381,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("InflatePath")
{
OperationType = typeof(IPathObject),
TitleGetter = () => "Inflate Path".Localize(),
ResultType = typeof(InflatePathObject3D),
Action = (sceneContext) =>
@ -407,7 +402,7 @@ namespace MatterHackers.MatterControl
},
Icon = (theme) => StaticData.Instance.LoadIcon("inflate_path.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(),
HelpTextGetter = () => "A path must be selected".Localize().Stars(),
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject,
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(),
};
}
@ -415,14 +410,14 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("LinearExtrude")
{
OperationType = typeof(IPathObject),
TitleGetter = () => "Linear Extrude".Localize(),
ResultType = typeof(LinearExtrudeObject3D),
Action = (sceneContext) =>
{
var scene = sceneContext.Scene;
var sceneItem = scene.SelectedItem;
if (sceneItem is IPathObject pathObject)
var pathObject = sceneItem.GetVertexSource();
if (pathObject != null)
{
var extrude = new LinearExtrudeObject3D();
@ -440,7 +435,7 @@ namespace MatterHackers.MatterControl
},
Icon = (theme) => StaticData.Instance.LoadIcon("linear_extrude.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(),
HelpTextGetter = () => "A path must be selected".Localize().Stars(),
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject,
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(),
};
}
@ -448,14 +443,14 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Revolve")
{
OperationType = typeof(IPathObject),
TitleGetter = () => "Revolve".Localize(),
ResultType = typeof(RevolveObject3D),
Action = (sceneContext) =>
{
var scene = sceneContext.Scene;
var sceneItem = scene.SelectedItem;
if (sceneItem is IPathObject pathObject)
var pathObject = sceneItem.GetVertexSource();
if (pathObject != null)
{
var revolve = new RevolveObject3D();
@ -473,7 +468,7 @@ namespace MatterHackers.MatterControl
},
Icon = (theme) => StaticData.Instance.LoadIcon("revolve.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(),
HelpTextGetter = () => "A path must be selected".Localize().Stars(),
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject,
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(),
};
}
@ -529,7 +524,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Mirror")
{
OperationType = typeof(IObject3D),
ResultType = typeof(MirrorObject3D_2),
TitleGetter = () => "Mirror".Localize(),
Action = (sceneContext) =>
@ -546,7 +540,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("OutlinePath")
{
OperationType = typeof(IPathObject),
TitleGetter = () => "Outline Path".Localize(),
ResultType = typeof(OutlinePathObject3D),
Action = (sceneContext) =>
@ -567,7 +560,7 @@ namespace MatterHackers.MatterControl
},
Icon = (theme) => StaticData.Instance.LoadIcon("outline.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(),
HelpTextGetter = () => "A path must be selected".Localize().Stars(),
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject,
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(),
};
}
@ -575,7 +568,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Rotate")
{
OperationType = typeof(IObject3D),
ResultType = typeof(RotateObject3D_2),
TitleGetter = () => "Rotate".Localize(),
Action = (sceneContext) =>
@ -592,7 +584,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Scale")
{
OperationType = typeof(IObject3D),
ResultType = typeof(ScaleObject3D_3),
TitleGetter = () => "Scale".Localize(),
Action = (sceneContext) =>
@ -609,7 +600,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("SmoothPath")
{
OperationType = typeof(IPathObject),
TitleGetter = () => "Smooth Path".Localize(),
ResultType = typeof(SmoothPathObject3D),
Action = (sceneContext) =>
@ -630,7 +620,7 @@ namespace MatterHackers.MatterControl
},
Icon = (theme) => StaticData.Instance.LoadIcon("smooth_path.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(),
HelpTextGetter = () => "A path must be selected".Localize().Stars(),
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject,
IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(),
};
}
@ -638,7 +628,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Translate")
{
OperationType = typeof(IObject3D),
ResultType = typeof(TranslateObject3D),
TitleGetter = () => "Translate".Localize(),
Action = (sceneContext) =>
@ -655,7 +644,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Advanced Array")
{
OperationType = typeof(IObject3D),
ResultType = typeof(ArrayAdvancedObject3D),
TitleGetter = () => "Advanced Array".Localize(),
Action = (sceneContext) =>
@ -676,7 +664,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Align")
{
OperationType = typeof(IObject3D),
ResultType = typeof(AlignObject3D_2),
TitleGetter = () => "Align".Localize(),
Action = (sceneContext) =>
@ -907,7 +894,7 @@ namespace MatterHackers.MatterControl
{
SceneOperations.ById("LinearExtrude"), SceneOperations.ById("Revolve"), SceneOperations.ById("InflatePath"), SceneOperations.ById("OutlinePath")
});
PrimaryOperations.Add(typeof(TextPathObject3D), new List<SceneOperation>
PrimaryOperations.Add(typeof(TextObject3D), new List<SceneOperation>
{
SceneOperations.ById("LinearExtrude"), SceneOperations.ById("Revolve"), SceneOperations.ById("InflatePath"), SceneOperations.ById("OutlinePath")
});
@ -939,7 +926,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Combine")
{
OperationType = typeof(IObject3D),
ResultType = typeof(CombineObject3D_2),
TitleGetter = () => "Combine".Localize(),
Action = (sceneContext) =>
@ -965,7 +951,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Curve")
{
OperationType = typeof(IObject3D),
ResultType = typeof(CurveObject3D_3),
TitleGetter = () => "Curve".Localize(),
Action = (sceneContext) =>
@ -983,7 +968,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Dual Extrusion Align")
{
OperationType = typeof(IObject3D),
TitleGetter = () => "Dual Extrusion Align".Localize(),
Action = (sceneContext) =>
{
@ -1031,7 +1015,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Fit to Bounds")
{
OperationType = typeof(IObject3D),
ResultType = typeof(FitToBoundsObject3D_3),
TitleGetter = () => "Fit to Bounds".Localize(),
Action = async (sceneContext) =>
@ -1053,7 +1036,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Fit to Cylinder")
{
OperationType = typeof(IObject3D),
ResultType = typeof(FitToCylinderObject3D),
TitleGetter = () => "Fit to Cylinder".Localize(),
Action = async (sceneContext) =>
@ -1075,7 +1057,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Group")
{
OperationType = typeof(SelectionGroupObject3D),
ResultType = typeof(GroupHolesAppliedObject3D),
TitleGetter = () => "Group".Localize(),
Action = (sceneContext) =>
@ -1097,7 +1078,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Hollow Out")
{
OperationType = typeof(IObject3D),
ResultType = typeof(HollowOutObject3D),
TitleGetter = () => "Hollow Out".Localize(),
Action = (sceneContext) =>
@ -1115,7 +1095,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Intersect")
{
OperationType = typeof(IObject3D),
ResultType = typeof(IntersectionObject3D_2),
TitleGetter = () => "Intersect".Localize(),
Action = (sceneContext) =>
@ -1141,14 +1120,14 @@ namespace MatterHackers.MatterControl
{
return item != null
&& !(item is ImageObject3D)
&& !(item is IPathObject);
&& !(item.IsPathObject());
}
private static bool IsPathObject(IObject3D item)
{
return item != null
&& !(item is ImageObject3D)
&& (item is IPathObject);
&& (item.IsPathObject());
}
private static SceneOperation LayFlatOperation()
@ -1217,7 +1196,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Linear Array")
{
OperationType = typeof(IObject3D),
ResultType = typeof(ArrayLinearObject3D),
TitleGetter = () => "Linear Array".Localize(),
Action = (sceneContext) =>
@ -1238,7 +1216,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Pinch")
{
OperationType = typeof(IObject3D),
ResultType = typeof(PinchObject3D_3),
TitleGetter = () => "Pinch".Localize(),
Action = (sceneContext) =>
@ -1256,7 +1233,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Plane Cut")
{
OperationType = typeof(IObject3D),
ResultType = typeof(PlaneCutObject3D),
TitleGetter = () => "Plane Cut".Localize(),
Action = (sceneContext) =>
@ -1274,7 +1250,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Find Slice")
{
OperationType = typeof(IObject3D),
ResultType = typeof(PlaneCutObject3D),
TitleGetter = () => "Find Slice".Localize(),
Action = (sceneContext) =>
@ -1292,7 +1267,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Radial Array")
{
OperationType = typeof(IObject3D),
ResultType = typeof(ArrayRadialObject3D),
TitleGetter = () => "Radial Array".Localize(),
Action = (sceneContext) =>
@ -1313,7 +1287,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Reduce")
{
OperationType = typeof(IObject3D),
ResultType = typeof(DecimateObject3D),
TitleGetter = () => "Reduce".Localize(),
Action = (sceneContext) =>
@ -1372,7 +1345,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Repair")
{
OperationType = typeof(IObject3D),
ResultType = typeof(RepairObject3D),
TitleGetter = () => "Repair".Localize(),
Action = (sceneContext) =>
@ -1390,7 +1362,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Subtract & Replace")
{
OperationType = typeof(IObject3D),
ResultType = typeof(SubtractAndReplaceObject3D_2),
TitleGetter = () => "Subtract & Replace".Localize(),
Action = (sceneContext) => new SubtractAndReplaceObject3D_2().WrapSelectedItemAndSelect(sceneContext.Scene),
@ -1404,7 +1375,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Subtract")
{
OperationType = typeof(IObject3D),
ResultType = typeof(SubtractObject3D_2),
TitleGetter = () => "Subtract".Localize(),
Action = (sceneContext) =>
@ -1523,7 +1493,6 @@ namespace MatterHackers.MatterControl
{
return new SceneOperation("Twist")
{
OperationType = typeof(IObject3D),
ResultType = typeof(TwistObject3D),
TitleGetter = () => "Twist".Localize(),
Action = (sceneContext) =>

View file

@ -90,11 +90,11 @@ namespace MatterHackers.MatterControl
menuButton.HoverColor = hoverColor;
break;
case SimpleFlowButton flowButton:
case ThemedFlowButton flowButton:
flowButton.HoverColor = hoverColor;
break;
case SimpleButton button:
case ThemedButton button:
button.HoverColor = hoverColor;
break;
}
@ -161,7 +161,7 @@ namespace MatterHackers.MatterControl
foreach (var actionButton in namedActionButtons.Group)
{
var button = new TextButton(actionButton.Title, theme)
var button = new ThemedTextButton(actionButton.Title, theme)
{
Border = new BorderDouble(1, 0, 0, 0),
BorderColor = theme.MinimalShade,
@ -227,9 +227,9 @@ namespace MatterHackers.MatterControl
return popupMenu;
}
public static RadioTextButton CreateMicroRadioButton(this ThemeConfig theme, string text, IList<GuiWidget> siblingRadioButtonList = null)
public static ThemedRadioTextButton CreateMicroRadioButton(this ThemeConfig theme, string text, IList<GuiWidget> siblingRadioButtonList = null)
{
var radioButton = new RadioTextButton(text, theme, theme.FontSize8)
var radioButton = new ThemedRadioTextButton(text, theme, theme.FontSize8)
{
SiblingRadioButtonList = siblingRadioButtonList,
Padding = new BorderDouble(5, 0),
@ -266,7 +266,7 @@ namespace MatterHackers.MatterControl
public static GuiWidget CreateSearchButton(this ThemeConfig theme)
{
return new IconButton(StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(theme.TextColor), theme)
return new ThemedIconButton(StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Search".Localize(),
};
@ -288,7 +288,7 @@ namespace MatterHackers.MatterControl
GuiWidget innerButton;
if (buttonParams.ButtonText == null)
{
innerButton = new IconButton(buttonParams.Icon, theme)
innerButton = new ThemedIconButton(buttonParams.Icon, theme)
{
Name = buttonParams.ButtonName + " Inner SplitButton",
Enabled = buttonParams.ButtonEnabled,
@ -302,7 +302,7 @@ namespace MatterHackers.MatterControl
{
if (buttonParams.Icon == null)
{
innerButton = new TextButton(buttonParams.ButtonText, theme)
innerButton = new ThemedTextButton(buttonParams.ButtonText, theme)
{
Name = buttonParams.ButtonName,
Enabled = buttonParams.ButtonEnabled,
@ -311,7 +311,7 @@ namespace MatterHackers.MatterControl
}
else
{
innerButton = new TextIconButton(buttonParams.ButtonText, buttonParams.Icon, theme)
innerButton = new ThemedTextIconButton(buttonParams.ButtonText, buttonParams.Icon, theme)
{
Name = buttonParams.ButtonName,
Enabled = buttonParams.ButtonEnabled,
@ -375,11 +375,11 @@ namespace MatterHackers.MatterControl
switch (guiWidget)
{
case SimpleFlowButton flowButton:
case ThemedFlowButton flowButton:
flowButton.HoverColor = parentIsToolbar ? theme.ToolbarButtonHover : Color.Transparent;
break;
case SimpleButton button:
case ThemedButton button:
button.HoverColor = parentIsToolbar ? theme.ToolbarButtonHover : Color.Transparent;
break;
}

View file

@ -425,7 +425,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
if (printer.Connection.Paused)
{
var resumePrintingButton = new TextButton("Resume Printing".Localize(), theme)
var resumePrintingButton = new ThemedTextButton("Resume Printing".Localize(), theme)
{
Name = "Resume Printing Button",
BackgroundColor = theme.MinimalShade,

View file

@ -237,7 +237,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
public DoneUnloadingPage(PrinterSetupWizard setupWizard, int extruderIndex)
: base(setupWizard, "Filament Unloaded".Localize(), "Success!\n\nYour filament should now be unloaded".Localize())
{
var loadFilamentButton = new TextButton("Load Filament".Localize(), theme)
var loadFilamentButton = new ThemedTextButton("Load Filament".Localize(), theme)
{
Name = "Load Filament",
BackgroundColor = theme.MinimalShade,

View file

@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.ActionBar;
using MatterHackers.MatterControl.CustomWidgets;
@ -64,7 +65,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
NextButton.Visible = false;
var loadFilamentButton = new TextButton("Load Filament".Localize(), theme)
var loadFilamentButton = new ThemedTextButton("Load Filament".Localize(), theme)
{
Name = "Load Filament",
BackgroundColor = theme.MinimalShade,
@ -86,7 +87,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling
{
NextButton.Visible = false;
var alreadyLoadedButton = new TextButton("Already Loaded".Localize(), theme)
var alreadyLoadedButton = new ThemedTextButton("Already Loaded".Localize(), theme)
{
Name = "Already Loaded Button",
BackgroundColor = theme.MinimalShade

View file

@ -148,7 +148,7 @@ namespace MatterHackers.MatterControl
public void ShowWizardFinished(Action doneClicked = null)
{
var doneButton = new TextButton("Done".Localize(), theme)
var doneButton = new ThemedTextButton("Done".Localize(), theme)
{
Name = "Done Button",
BackgroundColor = theme.MinimalShade

View file

@ -312,7 +312,7 @@ namespace MatterHackers.MatterControl
base.OnDraw(graphics2D);
}
private class CalibrationPad : IconButton
private class CalibrationPad : ThemedIconButton
{
public event EventHandler<PrinterConnection.Axis> Hovered;

View file

@ -167,7 +167,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
{
string imageFile = this.ControlIsPinned ? "Pushpin.png" : "PushpinUnpin.png";
var pinTabButton = new IconButton(StaticData.Instance.LoadIcon(imageFile, 16, 16).SetToColor(theme.TextColor), theme)
var pinTabButton = new ThemedIconButton(StaticData.Instance.LoadIcon(imageFile, 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "Pin Settings Button",
ToolTipText = this.ControlIsPinned ? "Unpin".Localize() : "Pin".Localize()

View file

@ -156,7 +156,7 @@ namespace MatterHackers.MatterControl
if (plugin is IExportWithOptions pluginWithOptions)
{
var optionPanel = pluginWithOptions.GetOptionsPanel();
var optionPanel = pluginWithOptions.GetOptionsPanel(libraryItems);
if (optionPanel != null)
{
optionPanel.HAnchor = HAnchor.Stretch;

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
this.ActionArea.VAnchor = VAnchor.Stretch;
this.ActionArea.MinimumSize = new Vector2(0, titleText.Height);
var editButton = new IconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme)
var editButton = new ThemedIconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = editToolTipText ?? "Edit".Localize(),
Name = helpArticle.Name + " Edit"

View file

@ -43,7 +43,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
public InlineListItemEdit(string title, ThemeConfig theme, string automationName, bool boldFont = false)
: base(title, theme, automationName, boldFont)
{
var removeButton = new IconButton(StaticData.Instance.LoadIcon("remove.png", 16, 16).SetToColor(theme.TextColor), theme)
var removeButton = new ThemedIconButton(StaticData.Instance.LoadIcon("remove.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Delete".Localize(),
Visible = true,

View file

@ -73,7 +73,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
this.ActionArea.VAnchor = VAnchor.Stretch;
this.ActionArea.MinimumSize = new Vector2(0, titleText.Height);
saveButton = new IconButton(StaticData.Instance.LoadIcon("fa-save_16.png", 16, 16).SetToColor(theme.TextColor), theme)
saveButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-save_16.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Save".Localize(),
Visible = false,
@ -106,7 +106,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
var icon = editable ? StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor) : new ImageBuffer(16, 16);
editButton = new IconButton(icon, theme)
editButton = new ThemedIconButton(icon, theme)
{
ToolTipText = "Edit".Localize(),
Name = automationName + " Edit",

View file

@ -59,7 +59,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
{
this.CloseChildren();
var backButton = new IconButton(StaticData.Instance.LoadIcon(Path.Combine("Library", "back.png"), 20, 20).SetToColor(theme.TextColor), theme)
var backButton = new ThemedIconButton(StaticData.Instance.LoadIcon(Path.Combine("Library", "back.png"), 20, 20).SetToColor(theme.TextColor), theme)
{
VAnchor = VAnchor.Fit | VAnchor.Center,
Enabled = currentContainer.Parent != null,

View file

@ -65,11 +65,6 @@ namespace MatterHackers.Agg.UI
public string Title => this.TitleGetter?.Invoke();
/// <summary>
/// Gets or sets the type that this operation can be applied to
/// </summary>
public Type OperationType { get; set; }
/// <summary>
/// Gets or sets if this operation should be shown in right click and modify menu.
/// </summary>

View file

@ -1,665 +0,0 @@
/*
Copyright (c) 2019, 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 MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.ImageProcessing;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.CustomWidgets
{
public class SimpleButton : GuiWidget
{
protected ThemeConfig theme;
private bool hasKeyboardFocus;
public SimpleButton(ThemeConfig theme)
{
this.theme = theme;
this.HoverColor = theme.SlightShade;
this.MouseDownColor = theme.MinimalShade;
this.Margin = 0;
this.Cursor = Cursors.Hand;
this.TabStop = true;
}
public Color HoverColor { get; set; } = Color.Transparent;
public Color MouseDownColor { get; set; } = Color.Transparent;
public override void OnMouseDown(MouseEventArgs mouseEvent)
{
base.OnMouseDown(mouseEvent);
this.Invalidate();
}
public override void OnMouseUp(MouseEventArgs mouseEvent)
{
base.OnMouseUp(mouseEvent);
this.Invalidate();
}
protected override void OnClick(MouseEventArgs mouseEvent)
{
if (mouseEvent.Button == MouseButtons.Left)
{
base.OnClick(mouseEvent);
}
}
public override void OnKeyUp(KeyEventArgs keyEvent)
{
if (keyEvent.KeyCode == Keys.Enter
|| keyEvent.KeyCode == Keys.Space)
{
UiThread.RunOnIdle(this.InvokeClick);
}
base.OnKeyUp(keyEvent);
}
public override void OnMouseEnterBounds(MouseEventArgs mouseEvent)
{
Invalidate();
base.OnMouseEnterBounds(mouseEvent);
}
public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent)
{
Invalidate();
base.OnMouseLeaveBounds(mouseEvent);
}
public override Color BackgroundColor
{
get
{
var firstWidgetUnderMouse = ContainsFirstUnderMouseRecursive();
if (this.MouseCaptured
&& firstWidgetUnderMouse
&& this.Enabled)
{
return this.MouseDownColor;
}
else if (firstWidgetUnderMouse
&& this.Enabled)
{
return this.HoverColor;
}
else
{
return base.BackgroundColor;
}
}
set => base.BackgroundColor = value;
}
public override void OnFocusChanged(EventArgs e)
{
hasKeyboardFocus = this.Focused && !ContainsFirstUnderMouseRecursive();
this.Invalidate();
base.OnFocusChanged(e);
}
public override void OnDraw(Graphics2D graphics2D)
{
base.OnDraw(graphics2D);
if (this.TabStop
&& hasKeyboardFocus)
{
var bounds = this.LocalBounds;
var stroke = 1 * GuiWidget.DeviceScale;
var expand = stroke / 2;
var rect = new RoundedRect(bounds.Left + expand,
bounds.Bottom + expand,
bounds.Right - expand,
bounds.Top - expand);
rect.radius(BackgroundRadius.SW,
BackgroundRadius.SE,
BackgroundRadius.NE,
BackgroundRadius.NW);
var rectOutline = new Stroke(rect, stroke);
graphics2D.Render(rectOutline, theme.EditFieldColors.Focused.BorderColor);
}
}
}
public class SimpleFlowButton : FlowLayoutWidget
{
private bool mouseInBounds = false;
protected ThemeConfig theme;
public SimpleFlowButton(ThemeConfig theme)
{
this.theme = theme;
this.HoverColor = theme.SlightShade;
this.MouseDownColor = theme.MinimalShade;
this.Margin = 0;
}
public Color HoverColor { get; set; } = Color.Transparent;
public Color MouseDownColor { get; set; } = Color.Transparent;
public override void OnMouseEnterBounds(MouseEventArgs mouseEvent)
{
mouseInBounds = true;
base.OnMouseEnterBounds(mouseEvent);
this.Invalidate();
}
public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent)
{
mouseInBounds = false;
base.OnMouseLeaveBounds(mouseEvent);
this.Invalidate();
}
public override void OnMouseDown(MouseEventArgs mouseEvent)
{
base.OnMouseDown(mouseEvent);
this.Invalidate();
}
public override void OnMouseUp(MouseEventArgs mouseEvent)
{
base.OnMouseUp(mouseEvent);
this.Invalidate();
}
public override Color BackgroundColor
{
get
{
if (this.MouseCaptured
&& mouseInBounds
&& this.Enabled)
{
return this.MouseDownColor;
}
else if (mouseInBounds
&& this.Enabled)
{
return this.HoverColor;
}
else
{
return base.BackgroundColor;
}
}
set => base.BackgroundColor = value;
}
}
public class IconButton : SimpleButton
{
protected ImageWidget imageWidget;
protected ImageBuffer image;
private IconButton(ThemeConfig theme)
: base(theme)
{
}
public IconButton(ImageBuffer icon, ThemeConfig theme)
: base(theme)
{
image = icon;
this.HAnchor = HAnchor.Absolute;
this.VAnchor = VAnchor.Absolute | VAnchor.Center;
this.Height = theme.ButtonHeight;
this.Width = theme.ButtonHeight;
this.BackgroundRadius = theme.ButtonRadius * GuiWidget.DeviceScale;
imageWidget = new ImageWidget(icon, listenForImageChanged: false)
{
HAnchor = HAnchor.Center,
VAnchor = VAnchor.Center,
Selectable = false
};
this.AddChild(imageWidget);
}
public ImageBuffer IconImage => this.Enabled ? image : this.DisabledImage;
internal void SetIcon(ImageBuffer icon)
{
image = icon;
imageWidget.Image = icon;
_disabledImage = null;
}
private ImageBuffer _disabledImage;
public ImageBuffer DisabledImage
{
get
{
// Lazy construct on first access
if (_disabledImage == null)
{
_disabledImage = image.AjustAlpha(0.2);
}
return _disabledImage;
}
}
public override void OnEnabledChanged(EventArgs e)
{
imageWidget.Image = this.Enabled ? image : this.DisabledImage;
this.Invalidate();
base.OnEnabledChanged(e);
}
}
public class RadioIconButton : IconButton, IRadioButton
{
public IList<GuiWidget> SiblingRadioButtonList { get; set; }
public event EventHandler CheckedStateChanged;
public bool ToggleButton { get; set; } = false;
public RadioIconButton(ImageBuffer icon, ThemeConfig theme)
: base(icon, theme)
{
}
protected override void OnClick(MouseEventArgs mouseEvent)
{
base.OnClick(mouseEvent);
bool newValue = this.ToggleButton ? !this.Checked : true;
bool checkStateChanged = newValue != this.Checked;
this.Checked = newValue;
// After setting CheckedState, fire event if different
if (checkStateChanged)
{
OnCheckStateChanged();
}
}
private bool _checked;
public bool Checked
{
get => _checked;
set
{
if (_checked != value)
{
_checked = value;
if (_checked)
{
this.UncheckSiblings();
}
this.BackgroundColor = _checked ? theme.MinimalShade : Color.Transparent;
Invalidate();
}
}
}
public virtual void OnCheckStateChanged()
{
CheckedStateChanged?.Invoke(this, null);
}
public override void OnDraw(Graphics2D graphics2D)
{
if (this.Checked)
{
if (BackgroundRadius.SW + BackgroundRadius.NW == Width)
{
void Render(double startRatio)
{
var stroke = 4 * GuiWidget.DeviceScale;
var angle = MathHelper.Tau / 4;
var start = MathHelper.Tau * startRatio - angle / 2;
var end = MathHelper.Tau * startRatio + angle / 2;
var arc = new Arc(Width / 2, Height / 2, Width / 2 - stroke / 2, Height / 2 - stroke / 2, start, end);
var background = new Stroke(arc, stroke);
graphics2D.Render(background, theme.PrimaryAccentColor.WithAlpha(100));
}
Render(1.0 / 3.0 + .75);
Render(2.0 / 3.0 + .75);
Render(1.0 + .75);
}
else
{
graphics2D.Rectangle(0, 0, LocalBounds.Right, 2 * DeviceScale, theme.PrimaryAccentColor);
}
}
base.OnDraw(graphics2D);
}
}
public class RadioTextButton : TextButton, IRadioButton
{
public IList<GuiWidget> SiblingRadioButtonList { get; set; }
public event EventHandler CheckedStateChanged;
public RadioTextButton(string text, ThemeConfig theme, double pointSize = -1)
: base(text, theme, pointSize)
{
this.SelectedBackgroundColor = theme.SlightShade;
}
public override Color BackgroundColor
{
get
{
var firstWidgetUnderMouse = ContainsFirstUnderMouseRecursive();
if (this.MouseCaptured
&& firstWidgetUnderMouse
&& this.Enabled)
{
if (Checked)
{
return SelectedBackgroundColor.AdjustLightness(.9).ToColor();
}
return this.MouseDownColor;
}
else if (firstWidgetUnderMouse
&& this.Enabled)
{
if (Checked)
{
return SelectedBackgroundColor.AdjustLightness(.8).ToColor();
}
return this.HoverColor;
}
else
{
return base.BackgroundColor;
}
}
set => base.BackgroundColor = value;
}
protected override void OnClick(MouseEventArgs mouseEvent)
{
base.OnClick(mouseEvent);
bool newValue = true;
bool checkStateChanged = newValue != this.Checked;
this.Checked = newValue;
// After setting CheckedState, fire event if different
if (checkStateChanged)
{
OnCheckStateChanged();
}
}
public Color SelectedBackgroundColor { get; set; }
public Color UnselectedBackgroundColor { get; set; }
private bool _checked;
public bool Checked
{
get => _checked;
set
{
if (_checked != value)
{
_checked = value;
if (_checked)
{
this.UncheckSiblings();
}
OnCheckStateChanged();
}
this.BackgroundColor = _checked ? this.SelectedBackgroundColor : this.UnselectedBackgroundColor;
}
}
public bool DrawUnderline { get; set; } = true;
public override void OnMouseEnterBounds(MouseEventArgs mouseEvent)
{
base.OnMouseEnterBounds(mouseEvent);
this.Invalidate();
}
public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent)
{
base.OnMouseLeaveBounds(mouseEvent);
this.Invalidate();
}
public virtual void OnCheckStateChanged()
{
CheckedStateChanged?.Invoke(this, null);
}
public override void OnDraw(Graphics2D graphics2D)
{
if (this.Checked && DrawUnderline)
{
graphics2D.Rectangle(LocalBounds.Left, 0, LocalBounds.Right, 2, theme.PrimaryAccentColor);
}
base.OnDraw(graphics2D);
}
}
public class TextButton : SimpleButton
{
private readonly TextWidget textWidget;
public TextButton(string text, ThemeConfig theme, double pointSize = -1)
: base(theme)
{
this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Absolute | VAnchor.Center;
this.Height = theme.ButtonHeight;
this.Padding = theme.TextButtonPadding;
this.TabStop = true;
this.BackgroundRadius = theme.ButtonRadius * GuiWidget.DeviceScale;
var textSize = (pointSize != -1) ? pointSize : theme.DefaultFontSize;
this.AddChild(textWidget = new TextWidget(text, pointSize: textSize, textColor: theme.TextColor)
{
HAnchor = HAnchor.Center,
VAnchor = VAnchor.Center,
AutoExpandBoundsToText = true
});
}
public Color TextColor
{
get => textWidget.TextColor;
set => textWidget.TextColor = value;
}
public override string Text
{
get => textWidget.Text;
set => textWidget.Text = value;
}
public override bool Enabled
{
get => base.Enabled;
set
{
base.Enabled = value;
textWidget.Enabled = value;
}
}
}
public class TextIconButton : SimpleFlowButton
{
private TextWidget textWidget;
public bool DrawIconOverlayOnDisabled { get; set; } = false;
public TextIconButton(string text, ImageBuffer icon, ThemeConfig theme)
: base(theme)
{
this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Absolute | VAnchor.Center;
this.Height = theme.ButtonHeight;
this.Padding = theme.TextButtonPadding;
this.BackgroundRadius = theme.ButtonRadius * GuiWidget.DeviceScale;
this.AddChild(ImageWidget = new ImageWidget(icon)
{
VAnchor = VAnchor.Center,
Selectable = false
});
// TODO: Only needed because TextWidget violates normal padding/margin rules
var textContainer = new GuiWidget()
{
Padding = new BorderDouble(8, 4, 2, 4),
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Center | VAnchor.Fit,
Selectable = false
};
this.AddChild(textContainer);
textContainer.AddChild(textWidget = new TextWidget(text, pointSize: theme.DefaultFontSize, textColor: theme.TextColor));
}
public override void OnDraw(Graphics2D graphics2D)
{
base.OnDraw(graphics2D);
// now draw an overlay on the image if it is disabled
if (DrawIconOverlayOnDisabled && !ImageWidget.Enabled)
{
graphics2D.Render(new RoundedRect(ImageWidget.TransformToParentSpace(this, ImageWidget.LocalBounds), 0),
theme.BackgroundColor.WithAlpha(200));
}
}
public void SetIcon(ImageBuffer imageBuffer)
{
ImageWidget.Image = imageBuffer;
}
public ImageWidget ImageWidget { get; }
public override string Text { get => textWidget.Text; set => textWidget.Text = value; }
}
public class HoverIconButton : IconButton
{
private ImageBuffer normalImage;
private ImageBuffer hoverImage;
// Single ImageBuffer constructor creates a grayscale copy for use as the normal image
// and uses the original as the hover image
public HoverIconButton(ImageBuffer icon, ThemeConfig theme)
: this(MakeGrayscale(icon), icon, theme)
{
}
public HoverIconButton(ImageBuffer icon, ImageBuffer hoverIcon, ThemeConfig theme)
: base(icon, theme)
{
normalImage = icon;
hoverImage = hoverIcon;
this.HAnchor = HAnchor.Absolute;
this.VAnchor = VAnchor.Absolute | VAnchor.Center;
this.Height = theme.ButtonHeight;
this.Width = theme.ButtonHeight;
imageWidget = new ImageWidget(icon, listenForImageChanged: false)
{
HAnchor = HAnchor.Center,
VAnchor = VAnchor.Center,
};
this.AddChild(imageWidget);
}
public static ImageBuffer MakeGrayscale(ImageBuffer icon)
{
var hoverIcon = new ImageBuffer(icon);
ApplicationController.Instance.MakeGrayscale(hoverIcon);
return hoverIcon;
}
public override void OnMouseEnterBounds(MouseEventArgs mouseEvent)
{
imageWidget.Image = hoverImage;
base.OnMouseEnterBounds(mouseEvent);
this.Invalidate();
}
public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent)
{
imageWidget.Image = normalImage;
base.OnMouseLeaveBounds(mouseEvent);
this.Invalidate();
}
}
}

View file

@ -522,7 +522,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
private readonly ImageBuffer arrowRight;
private readonly ImageBuffer arrowDown;
private readonly ImageBuffer placeholder;
private readonly IconButton imageButton = null;
private readonly ThemedIconButton imageButton = null;
public TreeExpandWidget(ThemeConfig theme)
{
@ -532,7 +532,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
this.Margin = new BorderDouble(right: 4);
imageButton = new IconButton(placeholder, theme)
imageButton = new ThemedIconButton(placeholder, theme)
{
MinimumSize = new Vector2(16 * DeviceScale, 16 * DeviceScale),
VAnchor = VAnchor.Center,

View file

@ -75,7 +75,6 @@ namespace MatterHackers.MatterControl.Plugins.Lithophane
new SceneOperation("Lithophane")
{
TitleGetter = () => "Lithophane".Localize(),
OperationType = typeof(ImageObject3D),
ResultType = typeof(LithophaneObject3D),
Action = (sceneContext) =>
{

View file

@ -195,7 +195,7 @@ namespace MatterHackers.Plugins.EditorTools
if (selectedItem is PathObject3D pathObject)
{
var vertexStorage = pathObject.VertexSource as VertexStorage;
var vertexStorage = pathObject.VertexStorage;
activePoints = vertexStorage.Vertices();

View file

@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.Library
}
else
{
var editButton = new TextButton("Edit".Localize(), theme)
var editButton = new ThemedTextButton("Edit".Localize(), theme)
{
Margin = 5,
ToolTipText = "Edit OpenSCAD script".Localize()
@ -118,7 +118,7 @@ namespace MatterHackers.MatterControl.Library
};
actionButtons.AddChild(editButton);
var updateButton = new TextButton("Update".Localize(), theme)
var updateButton = new ThemedTextButton("Update".Localize(), theme)
{
Margin = 5,
ToolTipText = "Compile model".Localize()

View file

@ -42,7 +42,7 @@ using Polygons = System.Collections.Generic.List<System.Collections.Generic.List
namespace MatterHackers.MatterControl.DesignTools
{
public class FindSliceObject3D : OperationSourceContainerObject3D, IPathObject, IPropertyGridModifier
public class FindSliceObject3D : OperationSourceContainerObject3D, IPropertyGridModifier
{
public FindSliceObject3D()
{
@ -51,8 +51,7 @@ namespace MatterHackers.MatterControl.DesignTools
public double SliceHeight { get; set; } = 10;
public IVertexSource VertexSource { get; set; } = new VertexStorage();
private double cutMargin = .01;
public (Mesh mesh, Polygons polygons) Cut(IObject3D item)
@ -84,7 +83,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
var newPathObject = new PathObject3D()
{
VertexSource = new VertexStorage(this.VertexSource)
VertexStorage = new VertexStorage(this.GetVertexSource())
};
base.Apply(undoBuffer, new IObject3D[] { newPathObject });
@ -151,7 +150,7 @@ namespace MatterHackers.MatterControl.DesignTools
(reporter, cancellationToken) =>
{
var polygons = new Polygons();
VertexSource = polygons.PolygonToPathStorage();
VertexStorage = polygons.PolygonToPathStorage();
var newChildren = new List<Object3D>();
foreach (var sourceItem in SourceContainer.VisibleMeshes())
@ -169,7 +168,7 @@ namespace MatterHackers.MatterControl.DesignTools
newChildren.Add(newMesh);
}
VertexSource = polygons.PolygonToPathStorage();
VertexStorage = polygons.PolygonToPathStorage();
RemoveAllButSource();
SourceContainer.Visible = false;

View file

@ -33,8 +33,6 @@ either expressed or implied, of the FreeBSD Project.
/*********************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using ClipperLib;
@ -57,7 +55,7 @@ using Polygons = System.Collections.Generic.List<System.Collections.Generic.List
namespace MatterHackers.MatterControl.DesignTools
{
[Obsolete("Use ImageToPathObject3D_2 instead", false)]
public class ImageToPathObject3D : Object3D, IPathObject, IEditorDraw, IObject3DControlsProvider
public class ImageToPathObject3D : Object3D, IEditorDraw, IObject3DControlsProvider
{
private ThresholdFunctions _featureDetector = ThresholdFunctions.Silhouette;
@ -179,8 +177,6 @@ namespace MatterHackers.MatterControl.DesignTools
[Slider(0, 1)]
public DoubleOrExpression RangeEnd { get; set; } = 1;
public IVertexSource VertexSource { get; set; } = new VertexStorage();
private IThresholdFunction ThresholdFunction
{
get
@ -281,7 +277,7 @@ namespace MatterHackers.MatterControl.DesignTools
affine *= Affine.NewTranslation(-aabb.XSize / 2, -aabb.YSize / 2);
rawVectorShape.transform(affine);
this.VertexSource = rawVectorShape;
this.VertexStorage = rawVectorShape;
progressReporter?.Invoke(1, null);
}

View file

@ -52,7 +52,7 @@ using Polygons = System.Collections.Generic.List<System.Collections.Generic.List
namespace MatterHackers.MatterControl.DesignTools
{
[HideMeterialAndColor]
public class ImageToPathObject3D_2 : Object3D, IImageProvider, IPathObject, IEditorDraw, IObject3DControlsProvider, IPropertyGridModifier, IEditorWidgetModifier
public class ImageToPathObject3D_2 : Object3D, IImageProvider, IEditorDraw, IObject3DControlsProvider, IPropertyGridModifier, IEditorWidgetModifier
{
public ImageToPathObject3D_2()
{
@ -173,8 +173,6 @@ namespace MatterHackers.MatterControl.DesignTools
[MaxDecimalPlaces(2)]
public double MinSurfaceArea {get; set; } = 1;
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer)
{
object3DControlsLayer.AddControls(ControlTypes.Standard2D);
@ -273,7 +271,7 @@ namespace MatterHackers.MatterControl.DesignTools
affine *= Affine.NewTranslation(-aabb.XSize / 2, -aabb.YSize / 2);
rawVectorShape.transform(affine);
this.VertexSource = rawVectorShape;
this.VertexStorage = rawVectorShape;
progressReporter?.Invoke(1, null);
}

View file

@ -28,34 +28,15 @@ either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace MatterHackers.MatterControl.DesignTools
{
public class PathObject3D : Object3D, IPathObject, IEditorDraw
public class PathObject3D : Object3D, IEditorDraw
{
[JsonIgnore]
private IVertexSource _vertexSource = new VertexStorage();
public IVertexSource VertexSource
{
get => _vertexSource;
set
{
_vertexSource = value;
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
}
}
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
this.DrawPath();

View file

@ -87,6 +87,17 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
public static void RefreshToolBar(this IObject3D item)
{
var sceneContext = item.ContainingScene();
if (sceneContext != null)
{
// deselect than re-select the item
sceneContext.SelectedItem = null;
sceneContext.SelectedItem = item;
}
}
public static void ShowRenameDialog(this IObject3D item, UndoBuffer undoBuffer)
{
DialogWindow.Show(
@ -161,12 +172,12 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public static void FlattenToPathObject(this IObject3D item, UndoBuffer undoBuffer)
{
if (item is IPathObject pathObject)
if (item.GetVertexSource() != null)
{
using (item.RebuildLock())
{
var newPathObject = new PathObject3D();
newPathObject.VertexSource = new VertexStorage(pathObject.VertexSource);
newPathObject.VertexStorage = new VertexStorage(item.GetVertexSource());
// and replace us with the children
var replaceCommand = new ReplaceCommand(new[] { item }, new[] { newPathObject });
@ -187,19 +198,14 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public static void DrawPath(this IObject3D item)
{
if (item is IPathObject pathObject)
if (item.GetVertexSource() != null)
{
if (pathObject.VertexSource == null)
{
return;
}
bool first = true;
var lastPosition = Vector2.Zero;
var maxXYZ = item.GetAxisAlignedBoundingBox().MaxXYZ;
maxXYZ = maxXYZ.Transform(item.Matrix.Inverted);
var firstMove = Vector2.Zero;
foreach (var vertex in pathObject.VertexSource.Vertices())
foreach (var vertex in item.GetVertexSource().Vertices())
{
var position = vertex.position;
if (first)
@ -248,18 +254,13 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
AxisAlignedBoundingBox box = AxisAlignedBoundingBox.Empty();
if (item is IPathObject pathObject)
if (item.GetVertexSource() != null)
{
if (pathObject.VertexSource == null)
{
return box;
}
var lastPosition = Vector2.Zero;
var maxXYZ = item.GetAxisAlignedBoundingBox().MaxXYZ;
maxXYZ = maxXYZ.Transform(item.Matrix.Inverted);
foreach (var vertex in pathObject.VertexSource.Vertices())
foreach (var vertex in item.GetVertexSource().Vertices())
{
var position = vertex.position;

View file

@ -50,17 +50,15 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
Sharp,
}
public class InflatePathObject3D : Object3D, IPathObject, IEditorDraw, IObject3DControlsProvider
public class InflatePathObject3D : Object3D, IEditorDraw, IObject3DControlsProvider
{
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public InflatePathObject3D()
{
Name = "Inflate Path".Localize();
}
[Description("The amount to expand the path lines.")]
public DoubleOrExpression Inflate { get; set; } = 1;
public DoubleOrExpression Inflate { get; set; } = .2;
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public ExpandStyles Style { get; set; } = ExpandStyles.Sharp;
@ -101,7 +99,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
InsetPath();
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
this.Mesh = VertexStorage.Extrude(Constants.PathPolygonsHeight);
}
this.CancelAllParentBuilding();
@ -111,27 +109,27 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
private void InsetPath()
{
var path = this.Children.OfType<IPathObject>()?.FirstOrDefault();
var path = this.CombinedVisibleChildrenPaths();
if (path == null)
{
// clear our existing data
VertexSource = new VertexStorage();
VertexStorage = new VertexStorage();
return;
}
VertexSource = path.VertexSource.Offset(Inflate.Value(this), GetJoinType(Style));
VertexStorage = path.Offset(Inflate.Value(this), GetJoinType(Style));
}
internal static JoinType GetJoinType(ExpandStyles style)
public static JoinType GetJoinType(ExpandStyles style)
{
ClipperLib.JoinType joinType = ClipperLib.JoinType.jtMiter;
ClipperLib.JoinType joinType = JoinType.jtMiter;
switch (style)
{
case ExpandStyles.Flat:
joinType = ClipperLib.JoinType.jtSquare;
joinType = JoinType.jtSquare;
break;
case ExpandStyles.Round:
joinType = ClipperLib.JoinType.jtRound;
joinType = JoinType.jtRound;
break;
}

View file

@ -75,19 +75,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public override bool CanApply => true;
[JsonIgnore]
private IVertexSource VertexSource
public override IVertexSource GetVertexSource()
{
get
{
var item = this.Descendants().Where((d) => d is IPathObject).FirstOrDefault();
if (item is IPathObject pathItem)
{
return pathItem.VertexSource;
}
return null;
}
return this.CombinedVisibleChildrenPaths();
}
public override void Apply(UndoBuffer undoBuffer)
@ -162,7 +152,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
null,
(reporter, cancellationToken) =>
{
var vertexSource = this.VertexSource;
var vertexSource = this.GetVertexSource();
List<(double height, double inset)> bevel = null;
#if DEBUG
if (BevelTop)
@ -178,12 +168,18 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
#endif
Mesh = VertexSourceToMesh.Extrude(this.VertexSource, height, bevel);
if (Mesh.Vertices.Count == 0)
if (this.GetVertexSource() != null)
{
Mesh = null;
Mesh = VertexSourceToMesh.Extrude(this.GetVertexSource(), height, bevel);
if (Mesh.Vertices.Count == 0)
{
Mesh = null;
}
}
else
{
Mesh = null;
}
UiThread.RunOnIdle(() =>
{

View file

@ -43,7 +43,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class MergePathObject3D : OperationSourceContainerObject3D, IPathObject, IEditorDraw, IObject3DControlsProvider
public class MergePathObject3D : OperationSourceContainerObject3D, IEditorDraw, IObject3DControlsProvider
{
private ClipperLib.ClipType clipType;
private string operationName;
@ -55,8 +55,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
Name = name;
}
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
this.DrawPath();
@ -102,7 +100,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
this.Mesh = this.GetVertexSource().Extrude(Constants.PathPolygonsHeight);
UiThread.RunOnIdle(() =>
{
@ -135,7 +133,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
var first = participants.First();
var resultsVertexSource = (first as IPathObject).VertexSource.Transform(first.Matrix);
var resultsVertexSource = first.GetVertexSource().Transform(first.Matrix);
var totalOperations = participants.Count() - 1;
double amountPerOperation = 1.0 / totalOperations;
@ -145,9 +143,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
foreach (var item in participants)
{
if (item != first
&& item is IPathObject pathItem)
&& item.GetVertexSource() != null)
{
var itemVertexSource = pathItem.VertexSource.Transform(item.Matrix);
var itemVertexSource = item.GetVertexSource().Transform(item.Matrix);
resultsVertexSource = resultsVertexSource.MergePaths(itemVertexSource, clipType);
@ -157,7 +155,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
this.VertexSource = resultsVertexSource;
this.VertexStorage = new VertexStorage(resultsVertexSource);
SourceContainer.Visible = false;
}

View file

@ -45,19 +45,18 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class OutlinePathObject3D : Object3D, IPathObject, IEditorDraw, IObject3DControlsProvider
public class OutlinePathObject3D : Object3D, IEditorDraw, IObject3DControlsProvider
{
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public OutlinePathObject3D()
{
Name = "Outline Path".Localize();
}
[Description("The with of the outline.")]
public DoubleOrExpression OutlineWidth { get; set; } = 3;
public DoubleOrExpression OutlineWidth { get; set; } = .5;
public DoubleOrExpression Ratio { get; set; } = .5;
[Description("The offset of the outside of the outline as a ratio of the width.")]
public DoubleOrExpression Offset { get; set; } = .5;
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public ExpandStyles InnerStyle { get; set; } = ExpandStyles.Sharp;
@ -110,7 +109,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
InsetPath();
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
this.Mesh = VertexStorage.Extrude(Constants.PathPolygonsHeight);
}
Invalidate(InvalidateType.DisplayValues);
@ -122,20 +121,20 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
private void InsetPath()
{
var path = this.Children.OfType<IPathObject>().FirstOrDefault();
var path = this.CombinedVisibleChildrenPaths();
if (path == null)
{
// clear our existing data
VertexSource = new VertexStorage();
VertexStorage = new VertexStorage();
return;
}
var aPolys = path.VertexSource.CreatePolygons();
var aPolys = path.CreatePolygons();
var offseter = new ClipperOffset();
var outlineWidth = OutlineWidth.Value(this);
var ratio = Ratio.Value(this);
var ratio = Offset.Value(this);
offseter.AddPaths(aPolys, InflatePathObject3D.GetJoinType(OuterStyle), EndType.etClosedPolygon);
var outerLoops = new List<List<IntPoint>>();
@ -150,9 +149,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
var allLoops = outerLoops;
allLoops.AddRange(innerLoops);
VertexSource = allLoops.CreateVertexStorage();
VertexStorage = allLoops.CreateVertexStorage();
(VertexSource as VertexStorage).Add(0, 0, ShapePath.FlagsAndCommand.Stop);
VertexStorage.Add(0, 0, ShapePath.FlagsAndCommand.Stop);
}
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)

View file

@ -27,7 +27,6 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -50,10 +49,15 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public class RevolveObject3D : Object3D, IEditorDraw
{
[MaxDecimalPlaces(2)]
[Slider(0, 360, snapDistance: 1)]
public DoubleOrExpression Rotation { get; set; } = 0;
[MaxDecimalPlaces(2)]
[Slider(-30, 30, snapDistance: 1)]
public DoubleOrExpression AxisPosition { get; set; } = 0;
[MaxDecimalPlaces(2)]
[Slider(3, 360, snapDistance: 1)]
[Slider(0, 360, snapDistance: 1)]
public DoubleOrExpression StartingAngle { get; set; } = 0;
[MaxDecimalPlaces(2)]
@ -65,21 +69,6 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public override bool CanApply => true;
[JsonIgnore]
private IVertexSource VertexSource
{
get
{
var item = this.Descendants().Where((d) => d is IPathObject).FirstOrDefault();
if (item is IPathObject pathItem)
{
return pathItem.VertexSource;
}
return null;
}
}
public override void Apply(UndoBuffer undoBuffer)
{
if (Mesh == null)
@ -131,11 +120,11 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
(Vector3, Vector3) GetStartEnd(IPathObject pathObject)
(Vector3, Vector3) GetStartEnd(IObject3D pathObject, IVertexSource path)
{
// draw the line that is the rotation point
var aabb = this.GetAxisAlignedBoundingBox();
var vertexSource = this.VertexSource.Transform(Matrix);
var vertexSource = path.Transform(Matrix);
var bounds = vertexSource.GetBounds();
var lineX = bounds.Left + AxisPosition.Value(this);
@ -146,10 +135,10 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
var child = this.Children.FirstOrDefault();
if (child is IPathObject pathObject)
var path = this.CombinedVisibleChildrenPaths();
if (path != null)
{
var (start, end) = GetStartEnd(pathObject);
var (start, end) = GetStartEnd(this, path);
layer.World.Render3DLine(start, end, Color.Red, true);
layer.World.Render3DLine(start, end, Color.Red.WithAlpha(20), false);
}
@ -157,14 +146,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer)
{
var child = this.Children.FirstOrDefault();
if (child is IPathObject pathObject)
{
var (start, end) = GetStartEnd(pathObject);
return new AxisAlignedBoundingBox(new Vector3[] { start, end });
}
return AxisAlignedBoundingBox.Empty();
return this.GetWorldspaceAabbOfDrawPath();
}
private CancellationTokenSource cancellationToken;
@ -185,7 +167,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
this.DebugDepth("Rebuild");
bool valuesChanged = false;
var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
var rotation = MathHelper.DegreesToRadians(Rotation.ClampIfNotCalculated(this, 0, 360, ref valuesChanged));
var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged);
var endingAngle = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged);
var sides = Sides.Value(this);
var axisPosition = AxisPosition.Value(this);
@ -209,8 +192,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
(reporter, cancellationTokenSource) =>
{
this.cancellationToken = cancellationTokenSource as CancellationTokenSource;
var vertexSource = this.VertexSource;
var pathBounds = vertexSource.GetBounds();
var vertexSource = this.CombinedVisibleChildrenPaths();
vertexSource = vertexSource.Rotate(rotation);
var pathBounds = vertexSource.GetBounds();
vertexSource = vertexSource.Translate(-pathBounds.Left - axisPosition, 0);
Mesh mesh = VertexSourceToMesh.Revolve(vertexSource,
sides,
@ -218,8 +202,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
MathHelper.DegreesToRadians(360 - startingAngle),
false);
var transform = Matrix4X4.CreateTranslation(pathBounds.Left + axisPosition, 0, 0) * Matrix4X4.CreateRotationZ(-rotation);
// take the axis offset out
mesh.Transform(Matrix4X4.CreateTranslation(pathBounds.Left + axisPosition, 0, 0));
mesh.Transform(transform);
if (mesh.Vertices.Count == 0)
{

View file

@ -28,9 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using ClipperLib;
using MatterHackers.Agg.UI;
@ -46,10 +44,8 @@ using Polygons = System.Collections.Generic.List<System.Collections.Generic.List
namespace MatterHackers.MatterControl.DesignTools.Operations
{
public class SmoothPathObject3D : Object3D, IPathObject, IEditorDraw, IObject3DControlsProvider
public class SmoothPathObject3D : Object3D, IEditorDraw, IObject3DControlsProvider
{
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public SmoothPathObject3D()
{
Name = "Smooth Path".Localize();
@ -105,7 +101,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
DoSmoothing((long)(SmoothDistance.Value(this) * 1000), Iterations.Value(this));
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
this.Mesh = VertexStorage.Extrude(Constants.PathPolygonsHeight);
UiThread.RunOnIdle(() =>
{
@ -121,15 +117,15 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
private void DoSmoothing(long maxDist, int interations)
{
bool closedPath = true;
var path = this.Children.OfType<IPathObject>().FirstOrDefault();
var path = this.CombinedVisibleChildrenPaths();
if (path == null)
{
// clear our existing data
VertexSource = new VertexStorage();
VertexStorage = new VertexStorage();
return;
}
var sourceVertices = path.VertexSource;
var sourceVertices = path;
var inputPolygons = sourceVertices.CreatePolygons();
@ -180,7 +176,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
outputPolygons = ClipperLib.Clipper.CleanPolygons(outputPolygons, Math.Max(maxDist / 10, 1.415));
}
VertexSource = outputPolygons.CreateVertexStorage();
VertexStorage = outputPolygons.CreateVertexStorage();
}
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)

View file

@ -39,6 +39,7 @@ using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters2D;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.PolygonMesh.Csg;
using MatterHackers.PolygonMesh.Processors;
@ -90,6 +91,9 @@ namespace MatterHackers.MatterControl.DesignTools
[Slider(0, 10, Easing.EaseType.Quadratic, snapDistance: .1)]
public DoubleOrExpression InfillAmount { get; set; } = 3;
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public ExpandStyles Style { get; set; } = ExpandStyles.Round;
[DisplayName("Height")]
[Slider(1, 50, Easing.EaseType.Quadratic, useSnappingGrid: true)]
public DoubleOrExpression ExtrusionHeight { get; set; } = 5;
@ -130,7 +134,27 @@ namespace MatterHackers.MatterControl.DesignTools
base.Cancel(undoBuffer);
}
private (IVertexSource vertexSource, double height) meshVertexCache;
private double cacheHeight;
public override IVertexSource GetVertexSource()
{
var paths = this.CombinedVisibleChildrenPaths();
if (paths == null)
{
var calculationHeight = CalculationHeight.Value(this);
if (VertexStorage == null || cacheHeight != calculationHeight)
{
var aabb = this.GetAxisAlignedBoundingBox();
var cutPlane = new Plane(Vector3.UnitZ, new Vector3(0, 0, aabb.MinXYZ.Z + calculationHeight));
VertexStorage = new VertexStorage(GetSlicePaths(this, cutPlane));
cacheHeight = calculationHeight;
}
return VertexStorage;
}
return paths;
}
public static IVertexSource GetSlicePaths(IObject3D source, Plane plane)
{
@ -146,50 +170,6 @@ namespace MatterHackers.MatterControl.DesignTools
return totalSlice.CreateVertexStorage();
}
private bool OutlineIsFromMesh
{
get
{
var vertexSource = (IPathObject)this.Descendants<IObject3D>().FirstOrDefault((i) => i is IPathObject);
var hasMesh = this.Descendants<IObject3D>().Where(m => m.Mesh != null).Any();
return vertexSource?.VertexSource == null && hasMesh;
}
}
[JsonIgnore]
public IVertexSource VertexSource
{
get
{
if (OutlineIsFromMesh)
{
var calculationHeight = CalculationHeight.Value(this);
if (meshVertexCache.vertexSource == null || meshVertexCache.height != calculationHeight)
{
var aabb = this.GetAxisAlignedBoundingBox();
var cutPlane = new Plane(Vector3.UnitZ, new Vector3(0, 0, aabb.MinXYZ.Z + calculationHeight));
meshVertexCache.vertexSource = GetSlicePaths(this, cutPlane);
meshVertexCache.height = calculationHeight;
}
return meshVertexCache.vertexSource;
}
var vertexSource = (IPathObject)this.Descendants<IObject3D>().FirstOrDefault((i) => i is IPathObject);
return vertexSource?.VertexSource;
}
set
{
var vertexSource = this.Children.OfType<IPathObject>().FirstOrDefault();
if (vertexSource != null)
{
vertexSource.VertexSource = value;
}
}
}
public static async Task<BaseObject3D> Create()
{
var item = new BaseObject3D();
@ -207,7 +187,7 @@ namespace MatterHackers.MatterControl.DesignTools
&& !RebuildLocked)
{
// make sure we clear our cache
meshVertexCache.vertexSource = null;
VertexStorage = null;
await Rebuild();
}
else if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateArgs.Source == this))
@ -248,7 +228,7 @@ namespace MatterHackers.MatterControl.DesignTools
});
// and create the base
var vertexSource = this.VertexSource;
var vertexSource = GetVertexSource();
// Convert VertexSource into expected Polygons
Polygons polygonShape = (vertexSource == null) ? null : vertexSource.CreatePolygons();
@ -317,9 +297,10 @@ namespace MatterHackers.MatterControl.DesignTools
}
else
{
var outsidePolygons = new List<List<IntPoint>>();
var outsidePolygons = new Polygons();
// remove all holes from the polygons so we only center the major outlines
var polygons = VertexSource.CreatePolygons();
var polygons = GetVertexSource().CreatePolygons();
polygons = polygons.GetCorrectedWinding();
foreach (var polygon in polygons)
{
@ -391,18 +372,19 @@ namespace MatterHackers.MatterControl.DesignTools
var infillAmount = InfillAmount.Value(this);
var baseSize = BaseSize.Value(this);
var extrusionHeight = ExtrusionHeight.Value(this);
var joinType = InflatePathObject3D.GetJoinType(Style);
if (BaseType == BaseTypes.Outline
&& infillAmount > 0)
{
basePolygons = polysToOffset.Offset((baseSize + infillAmount) * scalingForClipper);
basePolygons = basePolygons.Offset(-infillAmount * scalingForClipper);
basePolygons = polysToOffset.Offset((baseSize + infillAmount) * scalingForClipper, joinType);
basePolygons = basePolygons.Offset(-infillAmount * scalingForClipper, joinType);
}
else
{
basePolygons = polysToOffset.Offset(baseSize * scalingForClipper);
basePolygons = polysToOffset.Offset(baseSize * scalingForClipper, joinType);
}
basePolygons = ClipperLib.Clipper.CleanPolygons(basePolygons, 10);
basePolygons = Clipper.CleanPolygons(basePolygons, 10);
VertexStorage rawVectorShape = basePolygons.PolygonToPathStorage();
var vectorShape = new VertexSourceApplyTransform(rawVectorShape, Affine.NewScaling(1.0 / scalingForClipper));
@ -437,9 +419,10 @@ namespace MatterHackers.MatterControl.DesignTools
changeSet.Add(nameof(InfillAmount), BaseType == BaseTypes.Outline);
changeSet.Add(nameof(Centering), BaseType == BaseTypes.Circle);
changeSet.Add(nameof(ExtrusionHeight), BaseType != BaseTypes.None);
changeSet.Add(nameof(Style), BaseType != BaseTypes.Circle);
var vertexSource = (IPathObject)this.Descendants<IObject3D>().FirstOrDefault((i) => i is IPathObject);
var meshSource = this.Descendants<IObject3D>().Where((i) => i.Mesh != null);
var vertexSource = GetVertexSource();
var meshSource = this.Descendants<IObject3D>().Where((i) => i.Mesh != null);
changeSet.Add(nameof(CalculationHeight), vertexSource == null && meshSource.Where(m => m.Mesh != null).Any());
@ -464,9 +447,9 @@ namespace MatterHackers.MatterControl.DesignTools
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
if (OutlineIsFromMesh)
if (GetVertexSource() != null)
{
layer.World.RenderPathOutline(CalcTransform(), VertexSource, Agg.Color.Red, 5);
layer.World.RenderPathOutline(CalcTransform(), GetVertexSource(), Agg.Color.Red, 5);
// turn the lighting back on
GL.Enable(EnableCap.Lighting);
@ -475,10 +458,10 @@ namespace MatterHackers.MatterControl.DesignTools
public AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer)
{
if (OutlineIsFromMesh)
if (GetVertexSource() != null)
{
// TODO: Untested.
return layer.World.GetWorldspaceAabbOfRenderPathOutline(CalcTransform(), VertexSource, 5);
return layer.World.GetWorldspaceAabbOfRenderPathOutline(CalcTransform(), GetVertexSource(), 5);
}
return AxisAlignedBoundingBox.Empty();
}

View file

@ -27,7 +27,6 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using System.Threading.Tasks;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
@ -35,14 +34,12 @@ using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.PolygonMesh;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
namespace MatterHackers.MatterControl.DesignTools
{
public class BoxPathObject3D : PrimitiveObject3D, IPathObject, IObject3DControlsProvider, IEditorDraw
public class BoxPathObject3D : PrimitiveObject3D, IObject3DControlsProvider, IEditorDraw
{
public BoxPathObject3D()
{
@ -52,21 +49,6 @@ namespace MatterHackers.MatterControl.DesignTools
public override string ThumbnailName => "Box";
[JsonIgnore]
private IVertexSource _vertexSource = new VertexStorage();
public IVertexSource VertexSource
{
get => _vertexSource;
set
{
_vertexSource = value;
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
}
}
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
this.DrawPath();
@ -128,9 +110,12 @@ namespace MatterHackers.MatterControl.DesignTools
{
using (new CenterAndHeightMaintainer(this))
{
var width = Width.Value(this);
var depth = Depth.Value(this);
VertexSource = new RoundedRect(-width / 2, -depth / 2, width / 2, depth / 2, 0);
bool valuesChanged = false;
var width = Width.ClampIfNotCalculated(this, .01, 10000, ref valuesChanged);
var depth = Depth.ClampIfNotCalculated(this, .01, 10000, ref valuesChanged);
VertexStorage = new VertexStorage(new RoundedRect(-width / 2, -depth / 2, width / 2, depth / 2, 0));
this.Mesh = VertexStorage.Extrude(Constants.PathPolygonsHeight);
}
}

View file

@ -29,14 +29,28 @@ either expressed or implied, of the FreeBSD Project.
using System.Threading.Tasks;
using DualContouring;
using g3;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.PolygonMesh;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.DesignTools
{
public class DualContouringObject3D : Object3D
{
public enum Shapes
{
Box,
[EnumName("2 Boxes")]
Box_And_Sphere,
[EnumName("3 Boxes")]
Boxes_3,
Sphere,
Cylinder,
}
public DualContouringObject3D()
{
Name = "Dual Contouring".Localize();
@ -50,20 +64,21 @@ namespace MatterHackers.MatterControl.DesignTools
return item;
}
public Shapes Shape { get; set; } = Shapes.Box;
public OuptutTypes Ouptput { get; set; }
public int Iterations { get; set; } = 5;
public double Size { get; set; } = 15;
public double Threshold { get; set; } = .001;
public enum Shapes
{
Box,
Sphere
}
public Shapes Shape { get; set; } = Shapes.Box;
public enum OuptutTypes
{
DualContouring,
MarchingCubes,
}
public override async void OnInvalidate(InvalidateArgs invalidateArgs)
{
@ -91,18 +106,68 @@ namespace MatterHackers.MatterControl.DesignTools
{
using (new CenterAndHeightMaintainer(this))
{
#if true
ISdf shape = new Sphere()
ISdf shape = null;
switch (Shape)
{
Radius = Size
};
case Shapes.Box:
shape = new Box()
{
Size = new Vector3(Size, Size, Size)
};
break;
if (Shape == Shapes.Box)
{
shape = new Box()
{
Size = new Vector3(Size, Size, Size)
};
case Shapes.Boxes_3:
shape = new Union()
{
Items = new ISdf[]
{
new Transform(new Box()
{
Size = new Vector3(Size, Size, Size)
}, Matrix4X4.CreateRotationZ(MathHelper.Tau * .2) * Matrix4X4.CreateRotationX(MathHelper.Tau * .2)),
new Box()
{
Size = new Vector3(Size, Size, Size)
},
new Transform(new Box()
{
Size = new Vector3(Size, Size, Size)
}, Matrix4X4.CreateRotationY(MathHelper.Tau * .2) * Matrix4X4.CreateRotationX(MathHelper.Tau * .3)),
}
};
break;
case Shapes.Box_And_Sphere:
shape = new Union()
{
Items = new ISdf[]
{
new Transform(new Sphere()
{
Radius = Size / 2
}, Matrix4X4.CreateTranslation(-3, -2, 0)),
new Transform(new Box()
{
Size = new Vector3(Size, Size, Size)
}, Matrix4X4.CreateRotationZ(MathHelper.Tau * .2)),
}
};
break;
case Shapes.Sphere:
shape = new Sphere()
{
Radius = Size
};
break;
case Shapes.Cylinder:
shape = new Cylinder()
{
Radius = Size,
Height = Size
};
break;
}
var bounds = shape.Bounds;
@ -111,15 +176,13 @@ namespace MatterHackers.MatterControl.DesignTools
{
Iterations = 7;
}
var root = Octree.BuildOctree(shape.Sdf, bounds.MinXYZ, bounds.Size, Iterations, Threshold);
Mesh = Octree.GenerateMeshFromOctree(root);
#else
var c = new MarchingCubes();
c.Generate();
MeshNormals.QuickCompute(c.Mesh); // generate normals
Mesh = c.Mesh.ToMesh();
#endif
if (Ouptput == OuptutTypes.DualContouring)
{
var root = Octree.BuildOctree(shape.Sdf, bounds.MinXYZ, bounds.Size, Iterations, Threshold);
Mesh = Octree.GenerateMeshFromOctree(root);
}
}
}
@ -130,5 +193,19 @@ namespace MatterHackers.MatterControl.DesignTools
return Task.CompletedTask;
});
}
public class SdfToImplicit : ImplicitFunction3d
{
public ISdf Sdf { get; set; }
public SdfToImplicit(ISdf sdf)
{
Sdf = sdf;
}
public double Value(ref Vector3d pt)
{
return Sdf.Sdf(new Vector3(pt.x, pt.y, pt.z));
}
}
}
}

View file

@ -40,6 +40,7 @@ using MatterHackers.DataConverters3D;
using MatterHackers.DataConverters3D.UndoCommands;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.PolygonMesh;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
@ -48,10 +49,22 @@ using Newtonsoft.Json.Converters;
namespace MatterHackers.MatterControl.DesignTools
{
public enum OutputDimensions
{
[EnumNameAttribute("2D")]
[DescriptionAttribute("Create a 2D Path")]
Output2D,
[EnumNameAttribute("3D")]
[DescriptionAttribute("Create a 3D Mesh")]
Output3D
}
[HideChildrenFromTreeView]
public class TextObject3D : Object3D, IPropertyGridModifier
public class TextObject3D : Object3D, IPropertyGridModifier, IEditorDraw
{
[JsonConverter(typeof(StringEnumConverter))]
private bool refreshToolBar;
[JsonConverter(typeof(StringEnumConverter))]
public enum TextAlign
{
Left,
@ -65,10 +78,15 @@ namespace MatterHackers.MatterControl.DesignTools
Color = Operations.Object3DExtensions.PrimitiveColors["Text"];
}
public static async Task<TextObject3D> Create()
public static async Task<TextObject3D> Create(bool setTo2D = false)
{
var item = new TextObject3D();
if (!setTo2D)
{
item.Output = OutputDimensions.Output2D;
}
await item.Rebuild();
return item;
@ -97,9 +115,22 @@ namespace MatterHackers.MatterControl.DesignTools
[JsonConverter(typeof(StringEnumConverter))]
public NamedTypeFace Font { get; set; } = NamedTypeFace.Nunito_Bold;
[EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)]
public OutputDimensions Output { get; set; } = OutputDimensions.Output3D;
public override bool CanApply => true;
public override void Apply(UndoBuffer undoBuffer)
public override IVertexSource GetVertexSource()
{
if (Output == OutputDimensions.Output2D)
{
return this.CombinedVisibleChildrenPaths();
}
return null;
}
public override void Apply(UndoBuffer undoBuffer)
{
// change this from a text object to a group
var newContainer = new GroupObject3D();
@ -159,6 +190,7 @@ namespace MatterHackers.MatterControl.DesignTools
else
{
Mesh = null;
var extrusionHeight = Output == OutputDimensions.Output2D ? Constants.PathPolygonsHeight : this.Height.Value(this);
this.Children.Modify(list =>
{
list.Clear();
@ -212,10 +244,16 @@ namespace MatterHackers.MatterControl.DesignTools
default:
letterObject = new Object3D()
{
Mesh = VertexSourceToMesh.Extrude(scaledLetterPrinter, this.Height.Value(this)),
Mesh = VertexSourceToMesh.Extrude(scaledLetterPrinter, extrusionHeight),
Matrix = Matrix4X4.CreateTranslation(offset.X, 0, 0),
Name = leterNumber.ToString("000") + " - '" + letter.ToString() + "'"
};
if (Output == OutputDimensions.Output2D)
{
letterObject.VertexStorage = new VertexStorage(
new VertexSourceApplyTransform(
new VertexStorage(scaledLetterPrinter), Affine.NewTranslation(offset.X, offset.Y)));
}
offset.X += letterPrinter.GetSize(letter.ToString()).X * pointsToMm;
break;
}
@ -274,6 +312,10 @@ namespace MatterHackers.MatterControl.DesignTools
Invalidate(InvalidateType.DisplayValues);
this.CancelAllParentBuilding();
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
if (refreshToolBar)
{
this.RefreshToolBar();
}
});
});
}
@ -283,6 +325,21 @@ namespace MatterHackers.MatterControl.DesignTools
change.SetRowVisible(nameof(MultiLineText), () => MultiLine);
change.SetRowVisible(nameof(Alignment), () => MultiLine);
change.SetRowVisible(nameof(NameToWrite), () => !MultiLine);
change.SetRowVisible(nameof(Height), () => Output == OutputDimensions.Output3D);
if (change.Changed == nameof(Output))
{
refreshToolBar = true;
}
}
public void DrawEditor(Object3DControlsLayer object3DControlLayer, DrawEventArgs e)
{
this.DrawPath();
}
public AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer)
{
return this.GetWorldspaceAabbOfDrawPath();
}
}
}

View file

@ -1,208 +0,0 @@
/*
Copyright (c) 2018, 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.ComponentModel;
using System.Threading.Tasks;
using MatterHackers.Agg.Font;
using MatterHackers.Agg.Transform;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D;
using MatterHackers.DataConverters3D.UndoCommands;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.PolygonMesh;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace MatterHackers.MatterControl.DesignTools
{
public class TextPathObject3D : Object3D, IPathObject, IEditorDraw
{
public TextPathObject3D()
{
Name = "Text".Localize();
Color = Operations.Object3DExtensions.PrimitiveColors["Text"];
}
public static async Task<TextPathObject3D> Create()
{
var item = new TextPathObject3D();
await item.Rebuild();
return item;
}
[DisplayName("Text")]
public StringOrExpression Text { get; set; } = "Text";
public DoubleOrExpression PointSize { get; set; } = 24;
[Sortable]
[JsonConverter(typeof(StringEnumConverter))]
public NamedTypeFace Font { get; set; } = new NamedTypeFace();
public override bool CanApply => true;
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public override void Apply(UndoBuffer undoBuffer)
{
// change this from a text object to a group
var newContainer = new GroupObject3D();
newContainer.CopyProperties(this, Object3DPropertyFlags.All);
foreach (var child in this.Children)
{
newContainer.Children.Add(child.Clone());
}
undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { newContainer }));
}
public override async void OnInvalidate(InvalidateArgs invalidateArgs)
{
if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Children)
|| invalidateArgs.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateArgs.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateArgs.Source != this
&& !RebuildLocked)
{
await Rebuild();
}
else if ((invalidateArgs.InvalidateType.HasFlag(InvalidateType.Properties) && invalidateArgs.Source == this))
{
await Rebuild();
}
else if (SheetObject3D.NeedsRebuild(this, invalidateArgs))
{
await Rebuild();
}
else
{
base.OnInvalidate(invalidateArgs);
}
}
public override Task Rebuild()
{
this.DebugDepth("Rebuild");
using (RebuildLock())
{
double pointsToMm = 0.352778;
var printer = new TypeFacePrinter(Text.Value(this), new StyledTypeFace(ApplicationController.GetTypeFace(Font), PointSize.Value(this)))
{
ResolutionScale = 10
};
var scaledLetterPrinter = new VertexSourceApplyTransform(printer, Affine.NewScaling(pointsToMm));
var vertexSource = new VertexStorage();
foreach (var vertex in scaledLetterPrinter.Vertices())
{
if (vertex.IsMoveTo)
{
vertexSource.MoveTo(vertex.position);
}
else if (vertex.IsLineTo)
{
vertexSource.LineTo(vertex.position);
}
else if (vertex.IsClose)
{
vertexSource.ClosePolygon();
}
}
vertexSource = (VertexStorage)vertexSource.Union(vertexSource);
this.VertexSource = vertexSource;
// set the mesh to show the path
this.Mesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
}
this.CancelAllParentBuilding();
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Path));
return Task.CompletedTask;
}
public override Mesh Mesh
{
get
{
if (base.Mesh == null)
{
using (this.RebuildLock())
{
var bounds = this.VertexSource.GetBounds();
if (bounds.Width == 0 || bounds.Height == 0)
{
bounds = new Agg.RectangleDouble(0, 0, 60, 20);
}
var center = bounds.Center;
var mesh = PlatonicSolids.CreateCube(Math.Max(8, bounds.Width), Math.Max(8, bounds.Height), 0.2);
mesh.Translate(new Vector3(center.X, center.Y, 0));
base.Mesh = mesh;
}
}
return base.Mesh;
}
}
private Mesh InitMesh()
{
if (!string.IsNullOrWhiteSpace(Text.Value(this)))
{
}
return null;
}
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
this.DrawPath();
}
public AxisAlignedBoundingBox GetEditorWorldspaceAABB(Object3DControlsLayer layer)
{
return this.GetWorldspaceAabbOfDrawPath();
}
}
}

View file

@ -162,7 +162,7 @@ namespace MatterHackers.MatterControl.DesignTools
var showUpdate = context.item.GetType().GetCustomAttributes(typeof(ShowUpdateButtonAttribute), true).FirstOrDefault() as ShowUpdateButtonAttribute;
if (showUpdate?.Show == true)
{
var updateButton = new TextButton("Update".Localize(), theme)
var updateButton = new ThemedTextButton("Update".Localize(), theme)
{
Margin = 5,
BackgroundColor = theme.MinimalShade,
@ -192,7 +192,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
foreach (var editorButtonData in editorButtonProvider.GetEditorButtonsData())
{
var editorButton = new TextButton(editorButtonData.Name, theme)
var editorButton = new ThemedTextButton(editorButtonData.Name, theme)
{
Margin = 5,
ToolTipText = editorButtonData.HelpText,
@ -984,7 +984,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
// This is the AssetPath property of an asset object, add a button to set the AssetPath from a file
// Change button
var changeButton = new TextButton(property.Description, theme)
var changeButton = new ThemedTextButton(property.Description, theme)
{
BackgroundColor = theme.MinimalShade,
Margin = 3
@ -1254,7 +1254,7 @@ namespace MatterHackers.MatterControl.DesignTools
VAnchor = VAnchor.Center
};
searchRow.AddChild(searchField);
var searchButton = new IconButton(StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(theme.TextColor), theme)
var searchButton = new ThemedIconButton(StaticData.Instance.LoadIcon("icon_search_24x24.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Search".Localize(),
};
@ -1499,7 +1499,7 @@ namespace MatterHackers.MatterControl.DesignTools
public static GuiWidget GetUnlockRow(ThemeConfig theme, string url)
{
var detailsLink = new TextIconButton("Unlock".Localize(), StaticData.Instance.LoadIcon("locked.png", 16, 16).SetToColor(theme.TextColor), theme)
var detailsLink = new ThemedTextIconButton("Unlock".Localize(), StaticData.Instance.LoadIcon("locked.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Margin = 5,
ToolTipText = "Visit MatterHackers.com to Purchase".Localize()
@ -1517,7 +1517,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
if (item.GetType().GetCustomAttributes(typeof(WebPageLinkAttribute), true).FirstOrDefault() is WebPageLinkAttribute unlockLink)
{
var detailsLink = new TextIconButton(unlockLink.ButtonName.Localize(), StaticData.Instance.LoadIcon("internet.png", 16, 16).SetToColor(theme.TextColor), theme)
var detailsLink = new ThemedTextIconButton(unlockLink.ButtonName.Localize(), StaticData.Instance.LoadIcon("internet.png", 16, 16).SetToColor(theme.TextColor), theme)
{
BackgroundColor = theme.MinimalShade,
ToolTipText = unlockLink.Url,

View file

@ -131,7 +131,7 @@ namespace MatterHackers.MatterControl.DesignTools
}
}
public static ITraceable CreateTraceData(FaceList faceList, List<Vector3Float> vertexList, BvhCreationOptions bvhCreationOptions = BvhCreationOptions.LegacySlowConstructionFastTracing)
public static ITraceable CreateTraceData(FaceList faceList, List<Vector3Float> vertexList, BvhCreationOptions bvhCreationOptions = BvhCreationOptions.BottomUpClustering)
{
var allPolys = new List<ITraceable>();

View file

@ -127,7 +127,7 @@ namespace MatterHackers.MatterControl
foreach (var item in data.OrderBy(i => i.Name))
{
var linkButton = new IconButton(linkIcon, theme);
var linkButton = new ThemedIconButton(linkIcon, theme);
linkButton.Click += (s, e) => UiThread.RunOnIdle(() =>
{
ApplicationController.LaunchBrowser(item.Url);

View file

@ -109,8 +109,8 @@ namespace MatterHackers.MatterControl
graphics = pulseImage.NewGraphics2D();
graphics.ImageRenderQuality = Graphics2D.TransformQuality.Best;
graphics.RenderMaxSize(pulseLogo, pulseImage.Width / 2 - logoWidth / 2, pulseImage.Height * .42, logoWidth, bounds.Height, out _, preScale: false);
IconButton lastButton = null;
buttonRow.AddChild(AddButtonText(lastButton = new IconButton(pulseImage, theme)
ThemedIconButton lastButton = null;
buttonRow.AddChild(AddButtonText(lastButton = new ThemedIconButton(pulseImage, theme)
{
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Fit,
@ -135,7 +135,7 @@ namespace MatterHackers.MatterControl
return printerImage;
}
buttonRow.AddChild(AddButtonText(lastButton = new IconButton(CreateButtonImage("3d_printer.png"), theme)
buttonRow.AddChild(AddButtonText(lastButton = new ThemedIconButton(CreateButtonImage("3d_printer.png"), theme)
{
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Fit,
@ -147,7 +147,7 @@ namespace MatterHackers.MatterControl
this.DialogWindow.Close();
});
buttonRow.AddChild(AddButtonText(lastButton = new IconButton(CreateButtonImage("edit_design.png"), theme)
buttonRow.AddChild(AddButtonText(lastButton = new ThemedIconButton(CreateButtonImage("edit_design.png"), theme)
{
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Fit,

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl
this.AddChild(new HorizontalSpacer());
checkUpdateButton = new IconButton(StaticData.Instance.LoadIcon("fa-refresh_14.png", 14, 14).SetToColor(theme.TextColor), theme)
checkUpdateButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-refresh_14.png", 14, 14).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Check for Update".Localize(),
BackgroundColor = theme.MinimalShade,
@ -76,7 +76,7 @@ namespace MatterHackers.MatterControl
this.MinimumSize = new Vector2(0, checkUpdateButton.Height);
downloadButton = new TextButton("Download Update".Localize(), theme)
downloadButton = new ThemedTextButton("Download Update".Localize(), theme)
{
BackgroundColor = theme.MinimalShade,
Visible = false
@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl
};
this.AddChild(downloadButton);
installButton = new TextButton("Install Update".Localize(), theme)
installButton = new ThemedTextButton("Install Update".Localize(), theme)
{
BackgroundColor = theme.MinimalShade,
Visible = false

View file

@ -57,7 +57,7 @@ namespace MatterHackers.MatterControl.Library.Export
var firstItem = libraryItems.OfType<ILibraryAsset>().FirstOrDefault();
if (firstItem is ILibraryAsset libraryItem)
{
bool exportSuccessful = await MeshExport.ExportMesh(libraryItem, outputPath, progress);
bool exportSuccessful = await MeshExport.ExportMesh(libraryItem, outputPath, true, progress);
if (exportSuccessful)
{
return null;

View file

@ -110,7 +110,7 @@ namespace MatterHackers.MatterControl.Library.Export
public virtual bool ExportPossible(ILibraryAsset libraryItem) => true;
public GuiWidget GetOptionsPanel()
public GuiWidget GetOptionsPanel(IEnumerable<ILibraryItem> libraryItems)
{
var container = new FlowLayoutWidget()
{
@ -132,7 +132,7 @@ namespace MatterHackers.MatterControl.Library.Export
}
else
{
spiralVaseOverride = SpiralVaseOptions.FORCE_ON;
spiralVaseOverride = SpiralVaseOptions.USE_SETTINGS;
}
};
container.AddChild(spiralVaseCheckbox);

View file

@ -62,6 +62,6 @@ namespace MatterHackers.MatterControl
public interface IExportWithOptions : IExportPlugin
{
GuiWidget GetOptionsPanel();
GuiWidget GetOptionsPanel(IEnumerable<ILibraryItem> libraryItems);
}
}

View file

@ -40,7 +40,7 @@ namespace MatterHackers.MatterControl.Library.Export
{
public static class MeshExport
{
public static async Task<bool> ExportMesh(ILibraryItem source, string filePathToSave, IProgress<ProgressStatus> progress)
public static async Task<bool> ExportMesh(ILibraryItem source, string filePathToSave, bool mergeMeshes, IProgress<ProgressStatus> progress)
{
try
{
@ -53,7 +53,7 @@ namespace MatterHackers.MatterControl.Library.Export
{
// If the content is an IObject3D, then we need to load it and MeshFileIO save to the target path
var content = await contentItem.GetObject3D(null);
return Object3D.Save(content, filePathToSave, CancellationToken.None, reportProgress: (ratio, name) =>
return Object3D.Save(content, filePathToSave, mergeMeshes, CancellationToken.None, reportProgress: (ratio, name) =>
{
status.Progress0To1 = ratio;
progress.Report(status);
@ -82,7 +82,7 @@ namespace MatterHackers.MatterControl.Library.Export
IObject3D item = Object3D.Load(result.Stream, Path.GetExtension(streamContent.FileName), CancellationToken.None);
if (item != null)
{
return Object3D.Save(item, filePathToSave, CancellationToken.None, reportProgress: (ratio, name) =>
return Object3D.Save(item, filePathToSave, mergeMeshes, CancellationToken.None, reportProgress: (ratio, name) =>
{
status.Progress0To1 = ratio;
progress.Report(status);

View file

@ -37,13 +37,16 @@ using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
namespace MatterHackers.MatterControl.Library.Export
{
public class StlExport : IExportPlugin
public class StlExport : IExportPlugin, IExportWithOptions
{
public int Priority => 2;
private bool mergeMeshes = true;
public int Priority => 2;
public string ButtonText => "STL File".Localize();
@ -79,7 +82,7 @@ namespace MatterHackers.MatterControl.Library.Export
first = false;
}
if (!await MeshExport.ExportMesh(item, filename, progress))
if (!await MeshExport.ExportMesh(item, filename, mergeMeshes, progress))
{
badExports.Add(item.Name);
}
@ -99,5 +102,44 @@ namespace MatterHackers.MatterControl.Library.Export
}
};
}
public GuiWidget GetOptionsPanel(IEnumerable<ILibraryItem> libraryItems)
{
var exportMeshCount = 0;
foreach (var item in libraryItems.OfType<ILibraryAsset>())
{
if (item is ILibraryObject3D contentItem)
{
var object3D = contentItem.GetObject3D(null).Result;
exportMeshCount += object3D.VisibleMeshes().Count();
}
}
if (exportMeshCount < 2)
{
return null;
}
var container = new FlowLayoutWidget()
{
Margin = new BorderDouble(left: 40, bottom: 10),
};
var theme = AppContext.Theme;
var unionAllPartsCheckbox = new CheckBox("Merge faces into single mesh".Localize(), theme.TextColor, 10)
{
Checked = true,
Cursor = Cursors.Hand,
ToolTipText = "Disable to expart all faces without merging".Localize()
};
unionAllPartsCheckbox.CheckedStateChanged += (s, e) =>
{
mergeMeshes = unionAllPartsCheckbox.Checked;
};
container.AddChild(unionAllPartsCheckbox);
return container;
}
}
}

View file

@ -96,10 +96,6 @@ namespace MatterHackers.MatterControl.Library
"Calibration Face".Localize(),
async () => await XyCalibrationFaceObject3D.Create())
{ DateCreated = new System.DateTime(index++) },
new GeneratorItem(
"Text2".Localize(),
async () => await TextPathObject3D.Create())
{ DateCreated = new System.DateTime(index++) },
new GeneratorItem(
"Path".Localize(),
() =>
@ -112,7 +108,7 @@ namespace MatterHackers.MatterControl.Library
var path = new PathObject3D()
{
VertexSource = storage
VertexStorage = storage
};
return Task.FromResult<IObject3D>(path);

View file

@ -81,7 +81,7 @@ namespace MatterHackers.MatterControl.Library
{ DateCreated = new DateTime(index++) },
new GeneratorItem(
"Text".Localize(),
async () => await TextObject3D.Create())
async () => await TextObject3D.Create(true))
{ DateCreated = new DateTime(index++) },
new GeneratorItem(
"Cylinder".Localize(),
@ -218,7 +218,7 @@ namespace MatterHackers.MatterControl.Library
{ DateCreated = new DateTime(index++) },
new GeneratorItem(
"Text".Localize(),
async () => await TextPathObject3D.Create())
async () => await TextObject3D.Create())
{ DateCreated = new DateTime(index++) },
new GeneratorItem(
"Oval".Localize(),

View file

@ -76,7 +76,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
// Must come before pathButton.Click definition
RadioButton copyAndCalibrateOption = null;
var openButton = new IconButton(StaticData.Instance.LoadIcon("fa-folder-open_16.png", 16, 16).SetToColor(theme.TextColor), theme)
var openButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-folder-open_16.png", 16, 16).SetToColor(theme.TextColor), theme)
{
BackgroundColor = theme.MinimalShade,
Margin = new BorderDouble(left: 8),

View file

@ -41,7 +41,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
{
public event EventHandler CheckedStateChanged;
private IconButton imageButton;
private ThemedIconButton imageButton;
private ImageBuffer arrowRight;
@ -58,7 +58,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
arrowRight = StaticData.Instance.LoadIcon("fa-angle-right_12.png", 12, 12).SetToColor(theme.TextColor);
arrowDown = StaticData.Instance.LoadIcon("fa-angle-down_12.png", 12, 12).SetToColor(theme.TextColor);
imageButton = new IconButton(arrowRight, theme)
imageButton = new ThemedIconButton(arrowRight, theme)
{
MinimumSize = new Vector2(theme.ButtonHeight, theme.ButtonHeight),
VAnchor = VAnchor.Center,

View file

@ -68,7 +68,7 @@ namespace MatterHackers.MatterControl.Library.Widgets.HardwarePage
if (showOpenButton)
{
var openButton = new TextButton("Open".Localize(), theme)
var openButton = new ThemedTextButton("Open".Localize(), theme)
{
BackgroundColor = theme.AccentMimimalOverlay,
Margin = Margin.Clone(right: 17)

View file

@ -74,7 +74,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
mainRow.AddChild(new HorizontalSpacer());
// add in the create pulse button
var createPulse = new IconButton(StaticData.Instance.LoadIcon("pulse_logo.png", 18, 18).SetToColor(theme.TextColor), theme)
var createPulse = new ThemedIconButton(StaticData.Instance.LoadIcon("pulse_logo.png", 18, 18).SetToColor(theme.TextColor), theme)
{
Name = "Setup Pulse",
VAnchor = VAnchor.Center,
@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
mainRow.AddChild(createPulse);
// add in the create printer button
var createPrinter = new IconButton(StaticData.Instance.LoadIcon("md-add-circle_18.png", 18, 18).SetToColor(theme.TextColor), theme)
var createPrinter = new ThemedIconButton(StaticData.Instance.LoadIcon("md-add-circle_18.png", 18, 18).SetToColor(theme.TextColor), theme)
{
Name = "Create Printer",
VAnchor = VAnchor.Center,
@ -106,7 +106,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
mainRow.AddChild(createPrinter);
// add in the import printer button
var importPrinter = new IconButton(StaticData.Instance.LoadIcon("md-import_18.png", 18, 18).SetToColor(theme.TextColor), theme)
var importPrinter = new ThemedIconButton(StaticData.Instance.LoadIcon("md-import_18.png", 18, 18).SetToColor(theme.TextColor), theme)
{
VAnchor = VAnchor.Center,
Margin = theme.ButtonSpacing,

View file

@ -87,7 +87,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
DoubleClickBehavior = LibraryListView.DoubleClickBehaviors.PreviewItem
};
navBar = new OverflowBar(theme)
navBar = new OverflowBar(theme, "File".Localize())
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit,

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Kevin Pope, John Lewin
Copyright (c) 2022, Kevin Pope, John Lewin, Lars Brubaker
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
Border = new BorderDouble(top: 1)
};
navBar = new OverflowBar(theme)
navBar = new OverflowBar(theme, "File".Localize())
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit,

View file

@ -95,7 +95,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
if (content.group_items.Count > maxStuff)
{
var moreButton = new TextButton("More".Localize() + "...", theme)
var moreButton = new ThemedTextButton("More".Localize() + "...", theme)
{
BackgroundColor = theme.MinimalShade,
Margin = new BorderDouble(right: leftRightMargin),

View file

@ -222,7 +222,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
{
// add the article group button to the button group
// add a content section connected to the button
var sectionButton = new TextButton(content.group_title, theme);
var sectionButton = new ThemedTextButton(content.group_title, theme);
sectionSelectButtons.AddChild(sectionButton);
var articleSection = new ArticleSection(content, theme)
{
@ -242,7 +242,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
case "product_group":
{
var sectionButton = new TextButton(content.group_title, theme);
var sectionButton = new ThemedTextButton(content.group_title, theme);
sectionSelectButtons.AddChild(sectionButton);
var exploreSection = new ProductSection(content, theme)
{

View file

@ -41,7 +41,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
private List<ProductItem> allIconViews = new List<ProductItem>();
private FeedSectionData content;
private ThemeConfig theme;
private TextButton moreButton;
private ThemedTextButton moreButton;
public ProductSection(FeedSectionData content, ThemeConfig theme)
{

View file

@ -190,7 +190,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var expandedImage = StaticData.Instance.LoadIcon("expand.png", 16, 16).SetToColor(theme.TextColor);
var collapsedImage = StaticData.Instance.LoadIcon("collapse.png", 16, 16).SetToColor(theme.TextColor);
var expandBarButton = new IconButton(expanded ? collapsedImage : expandedImage, theme)
var expandBarButton = new ThemedIconButton(expanded ? collapsedImage : expandedImage, theme)
{
HAnchor = HAnchor.Center,
VAnchor = VAnchor.Absolute | VAnchor.Bottom,

View file

@ -35,7 +35,7 @@ using MatterHackers.MatterControl.CustomWidgets;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class DropButton : SimpleButton
public class DropButton : ThemedButton
{
public bool MenuVisible { get; private set; }

View file

@ -43,9 +43,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class GCodeOptionsPanel : FlowLayoutWidget
{
private RadioIconButton speedsButton;
private RadioIconButton materialsButton;
private RadioIconButton noColorButton;
private ThemedRadioIconButton speedsButton;
private ThemedRadioIconButton materialsButton;
private ThemedRadioIconButton noColorButton;
private View3DConfig gcodeOptions;
public GCodeOptionsPanel(ISceneContext sceneContext, PrinterConfig printer, ThemeConfig theme)
@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var buttonGroup = new ObservableCollection<GuiWidget>();
speedsButton = new RadioIconButton(StaticData.Instance.LoadIcon("speeds.png", 16, 16).SetToColor(theme.TextColor), theme)
speedsButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("speeds.png", 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroup,
Name = "Speeds Button",
@ -74,7 +74,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
buttonPanel.AddChild(speedsButton);
materialsButton = new RadioIconButton(StaticData.Instance.LoadIcon("materials.png", 16, 16).SetToColor(theme.TextColor), theme)
materialsButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("materials.png", 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroup,
Name = "Materials Button",
@ -87,7 +87,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
buttonPanel.AddChild(materialsButton);
noColorButton = new RadioIconButton(StaticData.Instance.LoadIcon("no-color.png", 16, 16).SetToColor(theme.TextColor), theme)
noColorButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("no-color.png", 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroup,
Name = "No Color Button",

View file

@ -145,7 +145,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
VAnchor = VAnchor.Fit
});
var copyButton = new TextButton("copy".Localize(), theme, 8)
var copyButton = new ThemedTextButton("copy".Localize(), theme, 8)
{
Padding = 5,
Margin = new BorderDouble(0, 0, 15, 0),

View file

@ -241,7 +241,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
}
var resetButton = rightContent.AddChild(new TextIconButton("Clear".Localize(), StaticData.Instance.LoadIcon("transparent_grid.png", 16, 16), theme)
var resetButton = rightContent.AddChild(new ThemedTextIconButton("Clear".Localize(), StaticData.Instance.LoadIcon("transparent_grid.png", 16, 16), theme)
{
Margin = new BorderDouble(0, 0, 0, 3),
HAnchor = HAnchor.Fit | HAnchor.Left,
@ -258,7 +258,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (getPickedColor != null)
{
var selectButton = rightContent.AddChild(new TextIconButton("Select".Localize(), StaticData.Instance.LoadIcon("eye_dropper.png", 16, 16).SetToColor(theme.TextColor), theme)
var selectButton = rightContent.AddChild(new ThemedTextIconButton("Select".Localize(), StaticData.Instance.LoadIcon("eye_dropper.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Margin = 0,
HAnchor = HAnchor.Fit | HAnchor.Left,

View file

@ -830,7 +830,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
moveButtons.AddChild(textWidget);
var buttonSize = 24 * DeviceScale;
var moveLeftButton = new IconButton(StaticData.Instance.LoadIcon("fa-angle-right_12.png", 14, 14).SetToColor(theme.TextColor).MirrorX(), theme)
var moveLeftButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-angle-right_12.png", 14, 14).SetToColor(theme.TextColor).MirrorX(), theme)
{
Width = buttonSize,
Height = buttonSize,
@ -846,7 +846,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
moveButtons.AddChild(moveLeftButton);
var moveRightButton = new IconButton(StaticData.Instance.LoadIcon("fa-angle-right_12.png", 14, 14).SetToColor(theme.TextColor), theme)
var moveRightButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-angle-right_12.png", 14, 14).SetToColor(theme.TextColor), theme)
{
Width = buttonSize,
Height = buttonSize,

View file

@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.VAnchor = VAnchor.Center;
this.theme = theme;
IconButton = new IconButton(imageBuffer, theme)
IconButton = new ThemedIconButton(imageBuffer, theme)
{
HAnchor = HAnchor.Left,
Height = theme.MicroButtonHeight,
@ -105,6 +105,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public ITab LastTab { get; set; }
public IconButton IconButton { get; }
public ThemedIconButton IconButton { get; }
}
}

View file

@ -32,7 +32,7 @@ using MatterHackers.MatterControl.CustomWidgets;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class OperationIconButton : IconButton
public class OperationIconButton : ThemedIconButton
{
private SceneOperation sceneOperation;
private ISceneContext sceneContext;

View file

@ -56,12 +56,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
public PopupMenuButton(ImageBuffer imageBuffer, ThemeConfig theme)
: this(new IconButton(imageBuffer, theme), theme)
: this(new ThemedIconButton(imageBuffer, theme), theme)
{
}
public PopupMenuButton(string text, ImageBuffer imageBuffer, ThemeConfig theme)
: this(new TextIconButton(text, imageBuffer, theme)
: this(new ThemedTextIconButton(text, imageBuffer, theme)
{
Padding = new BorderDouble(5, 0, 5, 0),
}, theme)
@ -86,7 +86,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
public PopupMenuButton(string text, ThemeConfig theme)
: this(new TextButton(text, theme)
: this(new ThemedTextButton(text, theme)
{
Selectable = false,
Padding = theme.TextButtonPadding.Clone(right: 5)

View file

@ -306,7 +306,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
UiThread.RunOnIdle(() =>
{
var unloadFilamentButton = new TextButton("Unload Filament".Localize(), theme)
var unloadFilamentButton = new ThemedTextButton("Unload Filament".Localize(), theme)
{
Name = "unload Filament",
BackgroundColor = theme.MinimalShade,
@ -680,7 +680,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// add in the move up button
var babyStepAmount = .02;
var upButton = babySteppingControls.AddChild(new IconButton(StaticData.Instance.LoadIcon("Up Arrow.png", 32, 32).SetToColor(theme.TextColor), theme)
var upButton = babySteppingControls.AddChild(new ThemedIconButton(StaticData.Instance.LoadIcon("Up Arrow.png", 32, 32).SetToColor(theme.TextColor), theme)
{
HAnchor = HAnchor.Center,
VAnchor = VAnchor.Absolute,
@ -719,7 +719,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
});
// add in the move down button
var downButton = babySteppingControls.AddChild(new IconButton(StaticData.Instance.LoadIcon("Down Arrow.png", 32, 32).SetToColor(theme.TextColor), theme)
var downButton = babySteppingControls.AddChild(new ThemedIconButton(StaticData.Instance.LoadIcon("Down Arrow.png", 32, 32).SetToColor(theme.TextColor), theme)
{
HAnchor = HAnchor.Center,
VAnchor = VAnchor.Absolute,
@ -765,7 +765,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// we can only reslice on 64 bit, because in 64 bit we always have the gcode loaded
if (IntPtr.Size == 8 || ApplicationController.Instance.Allow32BitReSlice)
{
var resliceButton = new TextButton("Re-Slice", theme)
var resliceButton = new ThemedTextButton("Re-Slice", theme)
{
VAnchor = VAnchor.Center,
HAnchor = HAnchor.Right,
@ -842,7 +842,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
resliceMessageRow.AddChild(switchButtonRow);
var switchButton = new TextButton("Switch", theme)
var switchButton = new ThemedTextButton("Switch", theme)
{
VAnchor = VAnchor.Center,
Margin = new BorderDouble(5),
@ -865,7 +865,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
resliceMessageRow.Visible = false;
};
var cancelButton = new TextButton("Cancel", theme)
var cancelButton = new ThemedTextButton("Cancel", theme)
{
VAnchor = VAnchor.Center,
Margin = new BorderDouble(0, 5),

View file

@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Fit;
this.AddChild(new IconButton(StaticData.Instance.LoadIcon("web.png", 16, 16), theme)
this.AddChild(new ThemedIconButton(StaticData.Instance.LoadIcon("web.png", 16, 16), theme)
{
Selectable = false
});

View file

@ -227,7 +227,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
if (string.IsNullOrEmpty(buttonText))
{
return new IconButton(StaticData.Instance.LoadIcon(iconFilename, 12, 12).SetToColor(theme.TextColor), theme)
return new ThemedIconButton(StaticData.Instance.LoadIcon(iconFilename, 12, 12).SetToColor(theme.TextColor), theme)
{
Margin = theme.ButtonSpacing,
Enabled = clickAction != null,
@ -239,7 +239,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
var oldSize = theme.DefaultFontSize;
theme.DefaultFontSize = 8;
var pauseButton = new TextIconButton(buttonText, StaticData.Instance.LoadIcon(iconFilename, 12, 12).SetToColor(theme.TextColor), theme)
var pauseButton = new ThemedTextIconButton(buttonText, StaticData.Instance.LoadIcon(iconFilename, 12, 12).SetToColor(theme.TextColor), theme)
{
Margin = new BorderDouble(marginX, 0),
Padding = new BorderDouble(7, 3),
@ -255,7 +255,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
ToolTipText = toolTip,
Name = name,
};
((TextIconButton)pauseButton).BackgroundRadius = pauseButton.Height / 2;
((ThemedTextIconButton)pauseButton).BackgroundRadius = pauseButton.Height / 2;
theme.DefaultFontSize = oldSize;
return pauseButton;

View file

@ -121,7 +121,7 @@ namespace MatterHackers.MatterControl
contentRow.AddChild(folderButtonRow);
// add a create folder button
var createFolderButton = new TextIconButton("Create Folder".Localize(), icon, theme)
var createFolderButton = new ThemedTextIconButton("Create Folder".Localize(), icon, theme)
{
Enabled = isEnabled,
VAnchor = VAnchor.Absolute,
@ -130,7 +130,7 @@ namespace MatterHackers.MatterControl
createFolderButton.Name = "Create Folder In Button";
folderButtonRow.AddChild(createFolderButton);
var refreshButton = new IconButton(StaticData.Instance.LoadIcon("fa-refresh_14.png", 16, 16).SetToColor(theme.TextColor), theme)
var refreshButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-refresh_14.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Refresh Folder".Localize(),
Enabled = isEnabled,

View file

@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// put in a make permanent button
var icon = StaticData.Instance.LoadIcon("apply.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply();
applyButton = new IconButton(icon, theme)
applyButton = new ThemedIconButton(icon, theme)
{
Margin = theme.ButtonSpacing,
ToolTipText = "Apply".Localize(),
@ -115,7 +115,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
toolbar.AddChild(applyButton);
// put in a remove button
cancelButton = new IconButton(StaticData.Instance.LoadIcon("cancel.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(), theme)
cancelButton = new ThemedIconButton(StaticData.Instance.LoadIcon("cancel.png", 16, 16).SetToColor(theme.TextColor).SetPreMultiply(), theme)
{
Margin = theme.ButtonSpacing,
ToolTipText = "Cancel".Localize(),
@ -174,8 +174,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public GuiWidget ContentPanel { get; set; }
private readonly JsonPathContext pathGetter = new JsonPathContext();
private readonly IconButton applyButton;
private readonly IconButton cancelButton;
private readonly ThemedIconButton applyButton;
private readonly ThemedIconButton cancelButton;
private readonly PopupMenuButton overflowButton;
private readonly InteractiveScene scene;
private readonly FlowLayoutWidget primaryActionsPanel;
@ -214,7 +214,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
foreach (var primaryAction in primaryActions)
{
// TODO: Run visible/enable rules on actions, conditionally add/enable as appropriate
var button = new IconButton(primaryAction.Icon(theme), theme)
var button = new ThemedIconButton(primaryAction.Icon(theme), theme)
{
// Name = namedAction.Title + " Button",
ToolTipText = primaryAction.Title,
@ -648,7 +648,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
private class OperationButton : TextButton
private class OperationButton : ThemedTextButton
{
private readonly SceneOperation sceneOperation;
private readonly ISceneContext sceneContext;

View file

@ -47,7 +47,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
{
public class SubtractPathObject3D : OperationSourceContainerObject3D, IPathObject, IEditorDraw, IObject3DControlsProvider
public class SubtractPathObject3D : OperationSourceContainerObject3D, IEditorDraw, IObject3DControlsProvider
{
public SubtractPathObject3D()
{
@ -57,8 +57,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
[DisplayName("Part(s) to Subtract")]
public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren();
public IVertexSource VertexSource { get; set; } = new VertexStorage();
public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e)
{
this.DrawPath();
@ -125,14 +123,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
// set the mesh to show the path
var extrudeMesh = this.VertexSource.Extrude(Constants.PathPolygonsHeight);
if(extrudeMesh.Vertices.Count() > 5)
if (this.GetVertexSource() != null)
{
this.Mesh = extrudeMesh;
}
else
{
this.Mesh = null;
var extrudeMesh = this.GetVertexSource().Extrude(Constants.PathPolygonsHeight);
if (extrudeMesh.Vertices.Count() > 5)
{
this.Mesh = extrudeMesh;
}
else
{
this.Mesh = null;
}
}
UiThread.RunOnIdle(() =>
@ -198,11 +199,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
bool first = true;
foreach (var keep in keepVisibleItems)
{
var resultsVertexSource = (keep as IPathObject).VertexSource.Transform(keep.Matrix);
var resultsVertexSource = keep.GetVertexSource().Transform(keep.Matrix);
foreach (var remove in removeVisibleItems)
{
resultsVertexSource = resultsVertexSource.MergePaths(((IPathObject)remove).VertexSource.Transform(remove.Matrix), ClipperLib.ClipType.ctDifference);
resultsVertexSource = resultsVertexSource.MergePaths(remove.GetVertexSource().Transform(remove.Matrix), ClipperLib.ClipType.ctDifference);
// report our progress
ratioCompleted += amountPerOperation;
@ -212,12 +213,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
if (first)
{
this.VertexSource = resultsVertexSource;
this.VertexStorage = new VertexStorage(resultsVertexSource);
first = false;
}
else
{
this.VertexSource.MergePaths(resultsVertexSource, ClipperLib.ClipType.ctUnion);
this.GetVertexSource().MergePaths(resultsVertexSource, ClipperLib.ClipType.ctUnion);
}
}

View file

@ -69,7 +69,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
switch (rowIndex)
{
case 0:
var resetButton = new IconButton(StaticData.Instance.LoadIcon("transparent_grid.png"), theme)
var resetButton = new ThemedIconButton(StaticData.Instance.LoadIcon("transparent_grid.png"), theme)
{
Width = scaledButtonSize,
Height = scaledButtonSize,

View file

@ -49,7 +49,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var gridDistance = object3DControlLayer.SnapGridDistance;
textButton = this.AddChild(new TextButton(gridDistance.ToString(), theme)
textButton = this.AddChild(new ThemedTextButton(gridDistance.ToString(), theme)
{
Selectable = false,
HAnchor = HAnchor.Center

View file

@ -221,7 +221,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return exportPanel;
};
this.AddChild(new TextButton("Export".Localize(), theme)
this.AddChild(new ThemedTextButton("Export".Localize(), theme)
{
Selectable = false,
Padding = theme.TextButtonPadding.Clone(right: 5)

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2018, Lars Brubaker, John Lewin
Copyright (c) 2022, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -33,11 +33,9 @@ using System.IO;
using System.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.ImageProcessing;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.ImageProcessing;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.Library.Widgets;
namespace MatterHackers.MatterControl.PartPreviewWindow
@ -47,8 +45,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
protected static HashSet<Type> ignoredTypes = new HashSet<Type> { typeof(HorizontalLine), typeof(TextEditWithInlineCancel) };
protected static HashSet<Type> ignoredInMenuTypes = new HashSet<Type> { typeof(VerticalLine), typeof(HorizontalLine), typeof(TextEditWithInlineCancel), typeof(HorizontalSpacer) };
public OverflowBar(ThemeConfig theme)
: this(null, theme)
public OverflowBar(ThemeConfig theme, string text = null)
: this(null, theme, text)
{ }
public OverflowBar(ImageBuffer icon, ThemeConfig theme, string text = null)
@ -153,7 +151,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
PopupMenu.MenuItem menuItem;
var iconButton = widget as IconButton;
var iconButton = widget as ThemedIconButton;
var iconImage = iconButton?.IconImage;

View file

@ -303,7 +303,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return printPanel;
};
this.AddChild(new TextButton("Print".Localize(), theme)
this.AddChild(new ThemedTextButton("Print".Localize(), theme)
{
Selectable = false,
Padding = theme.TextButtonPadding.Clone(right: 5)
@ -318,7 +318,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// Enable print option when no validation Errors exists
printEnabled = printer.PrintButtonEnabled();
var startPrintButton = new TextButton(buttonText, theme)
var startPrintButton = new ThemedTextButton(buttonText, theme)
{
Name = "Start Print Button",
Enabled = printEnabled

View file

@ -57,11 +57,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
internal GuiWidget sliceButton;
private RadioIconButton layers2DButton;
internal RadioIconButton layers3DButton;
internal RadioIconButton modelViewButton;
private ThemedRadioIconButton layers2DButton;
internal ThemedRadioIconButton layers3DButton;
internal ThemedRadioIconButton modelViewButton;
private Dictionary<PartViewMode, RadioIconButton> viewModes = new Dictionary<PartViewMode, RadioIconButton>();
private Dictionary<PartViewMode, ThemedRadioIconButton> viewModes = new Dictionary<PartViewMode, ThemedRadioIconButton>();
public PrinterActionsBar(PrinterConfig printer, PrinterTabPage printerTabPage, ThemeConfig theme)
: base(null, theme, "Printer Options".Localize())
@ -80,7 +80,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// add the reset button first (if there is one)
if (printer.Settings.GetValue<bool>(SettingsKey.show_reset_connection))
{
var resetConnectionButton = new TextIconButton(
var resetConnectionButton = new ThemedTextIconButton(
"Reset".Localize(),
StaticData.Instance.LoadIcon("e_stop.png", 14, 14).SetToColor(theme.TextColor),
theme)
@ -154,7 +154,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var buttonGroupB = new ObservableCollection<GuiWidget>();
var iconPath = Path.Combine("ViewTransformControls", "model.png");
modelViewButton = new RadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16).SetToColor(theme.TextColor), theme)
modelViewButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupB,
Name = "Model View Button",
@ -170,7 +170,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
viewModes.Add(PartViewMode.Model, modelViewButton);
iconPath = Path.Combine("ViewTransformControls", "gcode_3d.png");
layers3DButton = new RadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16).SetToColor(theme.TextColor), theme)
layers3DButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupB,
Name = "Layers3D Button",
@ -187,7 +187,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.AddChild(layers3DButton);
iconPath = Path.Combine("ViewTransformControls", "gcode_2d.png");
layers2DButton = new RadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16).SetToColor(theme.TextColor), theme)
layers2DButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupB,
Name = "Layers2D Button",
@ -239,8 +239,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
printer.ViewState.ViewModeChanged += (s, e) =>
{
if (viewModes[e.ViewMode] is RadioIconButton activeButton
&& viewModes[e.PreviousMode] is RadioIconButton previousButton
if (viewModes[e.ViewMode] is ThemedRadioIconButton activeButton
&& viewModes[e.PreviousMode] is ThemedRadioIconButton previousButton
&& !buttonIsBeingClicked)
{
// Show slide to animation from previous to current, on completion update view to current by setting active.Checked

View file

@ -54,7 +54,7 @@ namespace MatterHackers.MatterControl.ActionBar
this.Margin = 0;
this.Padding = 0;
connectButton = new TextIconButton(
connectButton = new ThemedTextIconButton(
"Connect".Localize(),
StaticData.Instance.LoadIcon("connect.png", 14, 14).SetToColor(theme.TextColor),
theme)
@ -75,7 +75,7 @@ namespace MatterHackers.MatterControl.ActionBar
theme.ApplyPrimaryActionStyle(connectButton);
// add the cancel stop button
cancelConnectButton = new TextIconButton(
cancelConnectButton = new ThemedTextIconButton(
"Cancel".Localize(),
StaticData.Instance.LoadIcon("connect.png", 14, 14).SetToColor(theme.TextColor),
theme)
@ -92,7 +92,7 @@ namespace MatterHackers.MatterControl.ActionBar
});
this.AddChild(cancelConnectButton);
disconnectButton = new TextIconButton(
disconnectButton = new ThemedTextIconButton(
"Disconnect".Localize(),
StaticData.Instance.LoadIcon("connect.png", 14, 14).SetToColor(theme.TextColor),
theme)

View file

@ -38,7 +38,7 @@ using System.Threading.Tasks;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class SliceButton : TextButton
public class SliceButton : ThemedTextButton
{
private PrinterConfig printer;
private PrinterTabPage printerTabPage;

View file

@ -117,7 +117,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
else
{
// Show info indicator hinting that hover will reveal additional details
row.AddChild(new IconButton(infoImage, theme)
row.AddChild(new ThemedIconButton(infoImage, theme)
{
Selectable = false
});

View file

@ -69,7 +69,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
flashBackground.Start();
}
public static void SlideToNewState(this RadioIconButton widget, RadioIconButton newActiveButton, OverflowBar parent, Action animationComplete, ThemeConfig theme)
public static void SlideToNewState(this ThemedRadioIconButton widget, ThemedRadioIconButton newActiveButton, OverflowBar parent, Action animationComplete, ThemeConfig theme)
{
double displayTime = 600;
double elapsedMs = 0;

View file

@ -100,10 +100,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public PrinterConfig Printer { get; private set; }
private readonly PrinterTabPage printerTabPage;
private RadioIconButton translateButton;
private RadioIconButton rotateButton;
private RadioIconButton zoomButton;
private RadioIconButton partSelectButton;
private ThemedRadioIconButton translateButton;
private ThemedRadioIconButton rotateButton;
private ThemedRadioIconButton zoomButton;
private ThemedRadioIconButton partSelectButton;
public View3DWidget(PrinterConfig printer, ISceneContext sceneContext, ViewToolBarControls viewControls3D, ThemeConfig theme, DesignTabPage printerTabBase, Object3DControlsLayer.EditorType editorType = Object3DControlsLayer.EditorType.Part)
{
@ -247,7 +247,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
titleAndTreeView.AddChild(treeView);
workspaceName.ActionArea.AddChild(
new IconButton(StaticData.Instance.LoadIcon("fa-angle-right_12.png", 12, 12).SetToColor(theme.TextColor), theme)
new ThemedIconButton(StaticData.Instance.LoadIcon("fa-angle-right_12.png", 12, 12).SetToColor(theme.TextColor), theme)
{
Enabled = false
},
@ -257,7 +257,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
workspaceName.ActionArea.Children<TextWidget>().First().Margin = 0;
// Resize buttons
foreach (var iconButton in workspaceName.Descendants<IconButton>())
foreach (var iconButton in workspaceName.Descendants<ThemedIconButton>())
{
iconButton.Height = 26;
iconButton.Width = 26;
@ -355,7 +355,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// add the view controls
var buttonGroupA = new ObservableCollection<GuiWidget>();
partSelectButton = new RadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "partSelect.png"), 16, 16).SetToColor(theme.TextColor), theme)
partSelectButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "partSelect.png"), 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupA,
ToolTipText = "Select Parts".Localize(),
@ -368,7 +368,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
partSelectButton.Click += (s, e) => viewControls3D.ActiveButton = ViewControls3DButtons.PartSelect;
buttonGroupA.Add(partSelectButton);
rotateButton = new RadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "rotate.png"), 16, 16).SetToColor(theme.TextColor), theme)
rotateButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "rotate.png"), 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupA,
ToolTipText = "Rotate View".Localize(),
@ -380,7 +380,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
rotateButton.Click += (s, e) => viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
buttonGroupA.Add(rotateButton);
translateButton = new RadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "translate.png"), 16, 16).SetToColor(theme.TextColor), theme)
translateButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "translate.png"), 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupA,
ToolTipText = "Move View".Localize(),
@ -392,7 +392,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
translateButton.Click += (s, e) => viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
buttonGroupA.Add(translateButton);
zoomButton = new RadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "scale.png"), 16, 16).SetToColor(theme.TextColor), theme)
zoomButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon(Path.Combine("ViewTransformControls", "scale.png"), 16, 16).SetToColor(theme.TextColor), theme)
{
SiblingRadioButtonList = buttonGroupA,
ToolTipText = "Zoom View".Localize(),
@ -465,7 +465,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
// add the home button
var homeButton = new IconButton(StaticData.Instance.LoadIcon("fa-home_16.png", 16, 16).SetToColor(theme.TextColor), theme)
var homeButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-home_16.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Reset View".Localize(),
Margin = theme.ButtonSpacing
@ -474,7 +474,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
homeButton.MouseLeaveBounds += (s1, e1) => ApplicationController.Instance.UiHint = "";
AddRoundButton(homeButton, RotatedMargin(homeButton, MathHelper.Tau * .3)).Click += (s, e) => viewControls3D.NotifyResetView();
var zoomToSelectionButton = new IconButton(StaticData.Instance.LoadIcon("select.png", 16, 16).SetToColor(theme.TextColor), theme)
var zoomToSelectionButton = new ThemedIconButton(StaticData.Instance.LoadIcon("select.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "Zoom to selection button",
ToolTipText = "Zoom to Selection".Localize(),
@ -496,7 +496,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var turntableEnabled = UserSettings.Instance.get(UserSettingsKey.TurntableMode) != "False";
TrackballTumbleWidget.TurntableEnabled = turntableEnabled;
var turnTableButton = new RadioIconButton(StaticData.Instance.LoadIcon("spin.png", 16, 16).SetToColor(theme.TextColor), theme)
var turnTableButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("spin.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Turntable Mode".Localize(),
Margin = theme.ButtonSpacing,
@ -522,7 +522,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var perspectiveEnabled = UserSettings.Instance.get(UserSettingsKey.PerspectiveMode) != false.ToString();
TrackballTumbleWidget.ChangeProjectionMode(perspectiveEnabled, false);
var projectionButton = new RadioIconButton(StaticData.Instance.LoadIcon("perspective.png", 16, 16).SetToColor(theme.TextColor), theme)
var projectionButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("perspective.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "Projection mode button",
ToolTipText = "Perspective Mode".Localize(),
@ -551,7 +551,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
cubeCenterFromRightTop.X -= bottomButtonOffset;
// put in the bed and build volume buttons
var bedButton = new RadioIconButton(StaticData.Instance.LoadIcon("bed.png", 16, 16).SetToColor(theme.TextColor), theme)
var bedButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("bed.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "Bed Button",
ToolTipText = "Show Print Bed".Localize(),
@ -560,7 +560,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
SiblingRadioButtonList = new List<GuiWidget>(),
};
AddRoundButton(bedButton, new Vector2((cubeCenterFromRightTop.X + 18 * scale - bedButton.Width / 2) / scale, startHeight));
var printAreaButton = new RadioIconButton(StaticData.Instance.LoadIcon("print_area.png", 16, 16).SetToColor(theme.TextColor), theme)
var printAreaButton = new ThemedRadioIconButton(StaticData.Instance.LoadIcon("print_area.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "Bed Button",
ToolTipText = BuildHeightValid() ? "Show Print Area".Localize() : "Define printer build height to enable",

View file

@ -42,7 +42,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class ViewStyleButton : DropButton
{
private IconButton iconButton;
private ThemedIconButton iconButton;
private ISceneContext sceneContext;
private Dictionary<RenderTypes, (ImageBuffer image, string toolTip)> viewData;
@ -67,7 +67,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
var renderType = sceneContext.ViewState.RenderType;
this.AddChild(iconButton = new IconButton(viewData[renderType].image, theme)
this.AddChild(iconButton = new ThemedIconButton(viewData[renderType].image, theme)
{
Selectable = false
});

View file

@ -88,8 +88,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private MainViewWidget mainViewWidget = null;
private readonly PopupMenuButton bedMenuButton;
private readonly UndoBuffer undoBuffer;
private readonly IconButton undoButton;
private readonly IconButton redoButton;
private readonly ThemedIconButton undoButton;
private readonly ThemedIconButton redoButton;
public ViewToolBarControls(PartWorkspace workspace, ThemeConfig theme, UndoBuffer undoBuffer, bool isPrinterType, bool showPrintButton)
{
@ -123,7 +123,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.AddChild(new ToolbarSeparator(theme.GetBorderColor(50), theme.SeparatorMargin));
undoButton = new IconButton(StaticData.Instance.LoadIcon("undo.png", 16, 16).SetToColor(theme.TextColor), theme)
undoButton = new ThemedIconButton(StaticData.Instance.LoadIcon("undo.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "3D View Undo",
ToolTipText = "Undo".Localize(),
@ -140,7 +140,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
this.AddChild(undoButton);
redoButton = new IconButton(StaticData.Instance.LoadIcon("redo.png", 16, 16).SetToColor(theme.TextColor), theme)
redoButton = new ThemedIconButton(StaticData.Instance.LoadIcon("redo.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "3D View Redo",
Margin = theme.ButtonSpacing,
@ -159,7 +159,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (showPrintButton)
{
var printButton = new TextButton("Print", theme)
var printButton = new ThemedTextButton("Print", theme)
{
Name = "Print Button",
BackgroundColor = theme.AccentMimimalOverlay
@ -253,7 +253,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (namedAction.Icon != null)
{
button = new IconButton(namedAction.Icon(theme), theme)
button = new ThemedIconButton(namedAction.Icon(theme), theme)
{
Name = namedAction.Title + " Button",
ToolTipText = namedAction.Title,
@ -271,7 +271,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
else
{
button = new TextButton(namedAction.Title, theme)
button = new ThemedTextButton(namedAction.Title, theme)
{
Name = namedAction.Title + " Button",
Margin = theme.ButtonSpacing,
@ -484,7 +484,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
buttonGroup.AddChild(operationButton);
}
var collapseButton = buttonGroup.AddChild(new IconButton(StaticData.Instance.LoadIcon("collapse_single.png", 8, 16).SetToColor(theme.TextColor), theme));
var collapseButton = buttonGroup.AddChild(new ThemedIconButton(StaticData.Instance.LoadIcon("collapse_single.png", 8, 16).SetToColor(theme.TextColor), theme));
collapseButton.Width = 16 * DeviceScale;
collapseButton.ToolTipText = "Collapse".Localize();
@ -536,7 +536,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (defaultOperation != operation)
{
// Update button
var iconButton = actionAndDropDown.Children.OfType<IconButton>().First();
var iconButton = actionAndDropDown.Children.OfType<ThemedIconButton>().First();
iconButton.SetIcon(operation.Icon(theme));
iconButton.ToolTipText = operation.HelpText ?? operation.Title;
@ -743,7 +743,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
popupMenu.DrawArrow = true;
openLibraryButton.Selectable = true;
if (popupMenu.Children<SimpleButton>().FirstOrDefault() is SimpleButton simpleButton)
if (popupMenu.Children<ThemedButton>().FirstOrDefault() is ThemedButton simpleButton)
{
simpleButton.Padding = 0;
};
@ -779,7 +779,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (operation is OperationGroup operationGroup
&& button is PopupMenuButton splitButton
&& button.Descendants<IconButton>().FirstOrDefault() is IconButton iconButton)
&& button.Descendants<ThemedIconButton>().FirstOrDefault() is ThemedIconButton iconButton)
{
var defaultOperation = operationGroup.GetDefaultOperation();
iconButton.Enabled = defaultOperation.IsEnabled(sceneContext);

View file

@ -59,7 +59,7 @@ namespace MatterHackers.MatterControl.PrinterControls
null,
theme));
var runWizardButton = new IconButton(StaticData.Instance.LoadIcon("compass.png", 16, 16).SetToColor(theme.TextColor), theme)
var runWizardButton = new ThemedIconButton(StaticData.Instance.LoadIcon("compass.png", 16, 16).SetToColor(theme.TextColor), theme)
{
VAnchor = VAnchor.Center,
Margin = theme.ButtonSpacing,

View file

@ -89,7 +89,7 @@ namespace MatterHackers.MatterControl.PrinterControls
{
foreach (GCodeMacro macro in printer.Settings.Macros)
{
var macroButton = new TextButton(GCodeMacro.FixMacroName(macro.Name), theme)
var macroButton = new ThemedTextButton(GCodeMacro.FixMacroName(macro.Name), theme)
{
BackgroundColor = theme.MinimalShade,
Margin = new BorderDouble(right: 5)
@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.PrinterControls
{
var widget = new MacroControls(printer, theme);
var editButton = new IconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme);
var editButton = new ThemedIconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme);
editButton.Click += (s, e) =>
{
DialogWindow.Show(new MacroListPage(printer.Settings));

View file

@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.PrinterControls
{
var widget = new MovementControls(printer, new XYZColors(theme), theme);
var editButton = new IconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme);
var editButton = new ThemedIconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme);
editButton.Click += (s, e) => widget.EditOptions();
return new SectionWidget(
@ -130,7 +130,7 @@ namespace MatterHackers.MatterControl.PrinterControls
Margin = new BorderDouble(bottom: 10)
};
var homeIcon = new IconButton(StaticData.Instance.LoadIcon("fa-home_16.png", 16, 16).SetToColor(theme.TextColor), theme)
var homeIcon = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-home_16.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Home X, Y and Z".Localize(),
BackgroundColor = theme.MinimalShade,
@ -139,7 +139,7 @@ namespace MatterHackers.MatterControl.PrinterControls
homeIcon.Click += (s, e) => printer.Connection.HomeAxis(PrinterConnection.Axis.XYZ);
toolbar.AddChild(homeIcon);
var homeXButton = new TextButton("X", theme)
var homeXButton = new ThemedTextButton("X", theme)
{
ToolTipText = "Home X".Localize(),
BackgroundColor = theme.MinimalShade,
@ -148,7 +148,7 @@ namespace MatterHackers.MatterControl.PrinterControls
homeXButton.Click += (s, e) => printer.Connection.HomeAxis(PrinterConnection.Axis.X);
toolbar.AddChild(homeXButton);
var homeYButton = new TextButton("Y", theme)
var homeYButton = new ThemedTextButton("Y", theme)
{
ToolTipText = "Home Y".Localize(),
BackgroundColor = theme.MinimalShade,
@ -157,7 +157,7 @@ namespace MatterHackers.MatterControl.PrinterControls
homeYButton.Click += (s, e) => printer.Connection.HomeAxis(PrinterConnection.Axis.Y);
toolbar.AddChild(homeYButton);
var homeZButton = new TextButton("Z", theme)
var homeZButton = new ThemedTextButton("Z", theme)
{
ToolTipText = "Home Z".Localize(),
BackgroundColor = theme.MinimalShade,
@ -168,7 +168,7 @@ namespace MatterHackers.MatterControl.PrinterControls
if (printer.Settings.GetValue<bool>(SettingsKey.has_c_axis))
{
var homeCButton = new TextButton("C", theme)
var homeCButton = new ThemedTextButton("C", theme)
{
ToolTipText = "Home C".Localize(),
BackgroundColor = theme.MinimalShade,
@ -196,7 +196,7 @@ namespace MatterHackers.MatterControl.PrinterControls
toolbar.AddChild(new HorizontalSpacer());
// Create 'Release' button
var disableMotors = new TextButton("Release".Localize(), theme)
var disableMotors = new ThemedTextButton("Release".Localize(), theme)
{
BackgroundColor = theme.MinimalShade,
};

View file

@ -168,7 +168,7 @@ namespace MatterHackers.MatterControl
MinimumSize = new Vector2(125, 0)
});
var editButton = new IconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme)
var editButton = new ThemedIconButton(StaticData.Instance.LoadIcon("icon_edit.png", 16, 16).SetToColor(theme.TextColor), theme)
{
Name = "Edit Leveling Data Button",
ToolTipText = "Edit Leveling Data".Localize(),
@ -345,7 +345,7 @@ namespace MatterHackers.MatterControl
private GuiWidget AddRunStageButton(string title, ThemeConfig theme, ISetupWizard stage, FlowLayoutWidget leftToRight)
{
var runStage = leftToRight.AddChild(new TextButton(title, theme)
var runStage = leftToRight.AddChild(new ThemedTextButton(title, theme)
{
VAnchor = VAnchor.Bottom,
Enabled = printer.Connection.IsConnected && !printer.Connection.Printing && !printer.Connection.Paused,

View file

@ -42,8 +42,8 @@ namespace MatterHackers.MatterControl.PrinterControls
public class TemperatureControls : FlowLayoutWidget
{
private PrinterConfig printer;
private TextButton preHeatButton;
private TextButton offButton;
private ThemedTextButton preHeatButton;
private ThemedTextButton offButton;
private TemperatureControls(PrinterConfig printer, ThemeConfig theme)
: base(FlowDirection.TopToBottom)
@ -89,7 +89,7 @@ namespace MatterHackers.MatterControl.PrinterControls
var container = new FlowLayoutWidget();
heatersRow.AddChild(container);
preHeatButton = new TextButton("Preheat".Localize(), theme)
preHeatButton = new ThemedTextButton("Preheat".Localize(), theme)
{
BackgroundColor = theme.MinimalShade,
Margin = new BorderDouble(right: 10)
@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.PrinterControls
printer.Connection.TurnOffBedAndExtruders(TurnOff.AfterDelay);
};
offButton = new TextButton("Off".Localize(), theme)
offButton = new ThemedTextButton("Off".Localize(), theme)
{
BackgroundColor = theme.MinimalShade,
};

View file

@ -287,7 +287,7 @@ namespace MatterHackers.MatterControl
Margin = new BorderDouble(left: 10)
};
keyboardImage = new IconButton(StaticData.Instance.LoadIcon("hot_key_small_white.png", 19, 12).SetToColor(theme.TextColor), theme)
keyboardImage = new ThemedIconButton(StaticData.Instance.LoadIcon("hot_key_small_white.png", 19, 12).SetToColor(theme.TextColor), theme)
{
HAnchor = HAnchor.Center,
Margin = new BorderDouble(5),
@ -699,7 +699,7 @@ namespace MatterHackers.MatterControl
return xyGrid;
}
public class MoveButton : TextButton
public class MoveButton : ThemedTextButton
{
//Amounts in millimeters
public double MoveAmount { get; set; } = 10;
@ -743,7 +743,7 @@ namespace MatterHackers.MatterControl
}
}
public class ExtrudeButton : TextButton
public class ExtrudeButton : ThemedTextButton
{
//Amounts in millimeters
public double MoveAmount = 10;

View file

@ -117,7 +117,7 @@ namespace MatterHackers.MatterControl
theme.ApplyBoxStyle(generalSection);
// Print Notifications
var configureNotificationsButton = new IconButton(configureIcon, theme)
var configureNotificationsButton = new ThemedIconButton(configureIcon, theme)
{
Name = "Configure Notification Settings Button",
ToolTipText = "Configure Notifications".Localize(),
@ -267,7 +267,7 @@ namespace MatterHackers.MatterControl
TextWidget sectionLabel = null;
var textSizeApplyButton = new TextButton("Apply".Localize(), theme)
var textSizeApplyButton = new ThemedTextButton("Apply".Localize(), theme)
{
VAnchor = VAnchor.Center,
BackgroundColor = theme.SlightShade,
@ -351,7 +351,7 @@ namespace MatterHackers.MatterControl
true,
false);
var openCacheButton = new IconButton(StaticData.Instance.LoadIcon("fa-link_16.png", 16, 16).SetToColor(theme.TextColor), theme)
var openCacheButton = new ThemedIconButton(StaticData.Instance.LoadIcon("fa-link_16.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Open Folder".Localize(),
};
@ -367,7 +367,7 @@ namespace MatterHackers.MatterControl
theme),
advancedPanel);
var clearCacheButton = new HoverIconButton(StaticData.Instance.LoadIcon("remove.png", 16, 16).SetToColor(theme.TextColor), theme)
var clearCacheButton = new ThemedHoverIconButton(StaticData.Instance.LoadIcon("remove.png", 16, 16).SetToColor(theme.TextColor), theme)
{
ToolTipText = "Clear Cache".Localize(),
};
@ -386,7 +386,7 @@ namespace MatterHackers.MatterControl
#if DEBUG
var configureIcon = StaticData.Instance.LoadIcon("fa-cog_16.png", 16, 16).SetToColor(theme.TextColor);
var configurePluginsButton = new IconButton(configureIcon, theme)
var configurePluginsButton = new ThemedIconButton(configureIcon, theme)
{
ToolTipText = "Configure Plugins".Localize(),
Margin = 0

View file

@ -190,7 +190,7 @@ namespace MatterHackers.MatterControl
};
generalPanel.AddChild(buttonContainer);
var updateButton = new TextButton("Update Setting".Localize(), theme)
var updateButton = new ThemedTextButton("Update Setting".Localize(), theme)
{
Margin = new BorderDouble(0, 3, 20, 0),
Name = setting.key + " Update",

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
Copyright (c) 2022, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl
theme.ApplyBottomBorder(toolbar);
toolbar.AddChild(new TextButton("MatterControl Help".Localize(), theme)
toolbar.AddChild(new ThemedTextButton("MatterControl Help".Localize(), theme)
{
Padding = new BorderDouble(6, 0),
Selectable = false

View file

@ -112,7 +112,7 @@ namespace MatterHackers.MatterControl
public abstract class SelectablePrinterPage : DialogPage
{
protected TextButton nextButton;
protected ThemedTextButton nextButton;
protected TreeNode rootPrintersNode;
public SelectablePrinterPage(string continueButtonText)
@ -129,7 +129,7 @@ namespace MatterHackers.MatterControl
treeView.ScrollArea.HAnchor = HAnchor.Stretch;
contentRow.AddChild(treeView);
nextButton = new TextButton(continueButtonText, theme)
nextButton = new ThemedTextButton(continueButtonText, theme)
{
Enabled = false
};

View file

@ -258,7 +258,7 @@ namespace MatterHackers.MatterControl.Tour
return new RectangleDouble(0, 0, totalWidth, totalHeight);
}
private class ArrowButton : TextButton
private class ArrowButton : ThemedTextButton
{
public ArrowButton(string text, ArrowDirection arrowDirection, ThemeConfig theme, double pointSize = -1)
: base(text, theme, pointSize)

Some files were not shown because too many files have changed in this diff Show more