From d86a8ff664d51765b7206d7f47ead5d73532f92e Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 07:28:47 -0700 Subject: [PATCH 01/12] Clean up whitespace --- DesignTools/Braille/BrailleGrade2.cs | 73 +++++++++++++--------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/DesignTools/Braille/BrailleGrade2.cs b/DesignTools/Braille/BrailleGrade2.cs index 0672015ce..d27f29c20 100644 --- a/DesignTools/Braille/BrailleGrade2.cs +++ b/DesignTools/Braille/BrailleGrade2.cs @@ -27,8 +27,6 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using MatterHackers.Agg.UI; -using MatterHackers.MatterControl.PluginSystem; using System; using System.Collections.Generic; using System.Text; @@ -77,7 +75,7 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder { string numConversion = ("#" + converted); - foreach(TextMapping keyValue in numberMappngs) + foreach (TextMapping keyValue in numberMappngs) { numConversion = numConversion.Replace(keyValue.Key, keyValue.Value); } @@ -93,10 +91,8 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder } } - if(converted[0] != '#') - { - - + if (converted[0] != '#') + { // put in commas before capitals converted = Regex.Replace(converted, "([A-Z])", ",$1"); converted = converted.ToLower(); @@ -123,12 +119,12 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder } // do the replacements that must come after other characters - string tempBeforeLastCharacter = converted.Substring(0,converted.Length-1); + string tempBeforeLastCharacter = converted.Substring(0, converted.Length - 1); foreach (TextMapping keyValue in beforeTextMappings) { if (tempBeforeLastCharacter.Contains(keyValue.Key)) { - converted = tempBeforeLastCharacter.Replace(keyValue.Key, keyValue.Value) + converted[converted.Length-1]; + converted = tempBeforeLastCharacter.Replace(keyValue.Key, keyValue.Value) + converted[converted.Length - 1]; tempBeforeLastCharacter = converted.Substring(0, converted.Length - 1); } } @@ -150,7 +146,7 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder { if (tempMiddleCharacters.Contains(keyValue.Key)) { - converted = converted.Substring(0, 1) + tempMiddleCharacters.Replace(keyValue.Key, keyValue.Value) + converted.Substring(converted.Length-1, 1); + converted = converted.Substring(0, 1) + tempMiddleCharacters.Replace(keyValue.Key, keyValue.Value) + converted.Substring(converted.Length - 1, 1); } } } @@ -171,7 +167,7 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder } private static bool compareStringIgnoringPunctuation(string possiblyPunctuatedString, string targetExactMatch) - { + { string punctuationStrippedString = possiblyPunctuatedString; if (Char.IsPunctuation(punctuationStrippedString[0])) @@ -184,7 +180,6 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder punctuationStrippedString = punctuationStrippedString.TrimEnd(punctuationStrippedString[punctuationStrippedString.Length - 1]); } - return punctuationStrippedString == targetExactMatch; } @@ -224,7 +219,7 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder finalString.Append(" "); skipSpace = false; } - skipSpace = checkSkipSpace(word, wordIndex != numWords?words[wordIndex]: null); + skipSpace = checkSkipSpace(word, wordIndex != numWords ? words[wordIndex] : null); finalString.Append(ConvertWord(word, wordIndex == numWords)); first = false; @@ -238,7 +233,7 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder private static bool checkSkipSpace(string word, string nextWord) { bool skipSpace = false; - if(nextWord != null) + if (nextWord != null) { foreach (TextMapping keyValue in beforeWordsMappings) { @@ -248,36 +243,36 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder } } - if(skipSpace)//Special Case: The word 'for' only skips if followed by the word 'the' - { - skipSpace = word != "for"|| nextWord == "the"; + if (skipSpace)//Special Case: The word 'for' only skips if followed by the word 'the' + { + skipSpace = word != "for" || nextWord == "the"; } - } + } return skipSpace; } private static void ConvertMappingStringToList() { - string[] conversions = BrailleGrade2Mapping.mappingTable.Split('\n'); + string[] conversions = BrailleGrade2Mapping.mappingTable.Split('\n'); - foreach(string inLine in conversions) + foreach (string inLine in conversions) { string line = inLine.Replace("\r", "").Trim(); - if(line != null && line.Length>0) + if (line != null && line.Length > 0) { string[] keyConversionPair = line.Split(' '); - if(keyConversionPair.Length == 2 && keyConversionPair[0] != null && keyConversionPair[0].Length > 0 && keyConversionPair[1] != null && keyConversionPair[1].Length >0) + if (keyConversionPair.Length == 2 && keyConversionPair[0] != null && keyConversionPair[0].Length > 0 && keyConversionPair[1] != null && keyConversionPair[1].Length > 0) { - if(keyConversionPair[0] != "//") + if (keyConversionPair[0] != "//") { - TextMapping mapping = new TextMapping(keyConversionPair[0],keyConversionPair[1]); + TextMapping mapping = new TextMapping(keyConversionPair[0], keyConversionPair[1]); - if(IsNumeric(mapping.Key)) + if (IsNumeric(mapping.Key)) { numberMappngs.Add(mapping); - } - else if(mapping.Key == mapping.Key.ToUpper())//if in all caps it is an exact match + } + else if (mapping.Key == mapping.Key.ToUpper())//if in all caps it is an exact match { mapping.Key = mapping.Key.ToLower(); if (mapping.Key.Contains("*")) @@ -297,26 +292,26 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder { exactTextMappings.Add(mapping); } - + } - else if(mapping.Key[0] == '+' && mapping.Key[mapping.Key.Length-1] == '+')//check between + else if (mapping.Key[0] == '+' && mapping.Key[mapping.Key.Length - 1] == '+')//check between { mapping.Key = mapping.Key.Trim('+'); betweenTextMappings.Add(mapping); } - else if (mapping.Key[0] == '+') + else if (mapping.Key[0] == '+') { mapping.Key = mapping.Key.Trim('+'); afterTextMappings.Add(mapping); } - else if(mapping.Key[mapping.Key.Length-1] == '+') + else if (mapping.Key[mapping.Key.Length - 1] == '+') { mapping.Key = mapping.Key.Trim('+'); beforeTextMappings.Add(mapping); } - else if(mapping.Key.Contains("*")) - { - if(mapping.Key[0] == '*') + else if (mapping.Key.Contains("*")) + { + if (mapping.Key[0] == '*') { mapping.Key = mapping.Key.Trim('*'); postWordPunctuationMappings.Add(mapping); @@ -326,7 +321,7 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder mapping.Key = mapping.Key.Trim('*'); beforeWordsMappings.Add(mapping); } - + } else//if not a special type then it is an anyPositionMapping { @@ -336,21 +331,19 @@ namespace MatterHackers.MatterControl.Plugins.BrailleBuilder } } } - } private static bool IsNumeric(string p) - { + { bool isNumeric = true; - for(int i = 0; i < p.Length && isNumeric; i++) + for (int i = 0; i < p.Length && isNumeric; i++) { char current = p[i]; isNumeric = (Char.IsNumber(current) || char.IsPunctuation(current)) && current != '*'; } - + return isNumeric; } - } } \ No newline at end of file From b17ac901c37a32d4db8717c54e93bef1f8ba7be2 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 07:31:20 -0700 Subject: [PATCH 02/12] Simplify --- SlicerConfiguration/UIFields/ListStringField.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/SlicerConfiguration/UIFields/ListStringField.cs b/SlicerConfiguration/UIFields/ListStringField.cs index 17ffe7ed2..abf2a6407 100644 --- a/SlicerConfiguration/UIFields/ListStringField.cs +++ b/SlicerConfiguration/UIFields/ListStringField.cs @@ -28,12 +28,10 @@ either expressed or implied, of the FreeBSD Project. */ using System.Collections.Generic; -using System.Linq; using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; using MatterHackers.MatterControl.CustomWidgets; -using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.SlicerConfiguration { @@ -48,15 +46,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public override void Initialize(int tabIndex) { - var column = new FlowLayoutWidget(FlowDirection.TopToBottom) + this.Content = new FlowLayoutWidget(FlowDirection.TopToBottom) { Margin = new BorderDouble(20, 0, 0, 0), HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, }; - this.Content = column; - base.Initialize(tabIndex); } From 0f88e7aab73e7fc21e00ee02bd468a14e90654f2 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 07:35:17 -0700 Subject: [PATCH 03/12] Rename TitleChanged event to ValueChanged --- CustomWidgets/ConfigurePrinterWidget.cs | 2 +- CustomWidgets/InlineTitleEdit.cs | 6 +++--- .../SlicePresetsWindow/SlicePresetsWindow.cs | 2 +- SlicerConfiguration/UIFields/ListStringField.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CustomWidgets/ConfigurePrinterWidget.cs b/CustomWidgets/ConfigurePrinterWidget.cs index f899ad8db..a8149c45c 100644 --- a/CustomWidgets/ConfigurePrinterWidget.cs +++ b/CustomWidgets/ConfigurePrinterWidget.cs @@ -39,7 +39,7 @@ namespace MatterHackers.MatterControl : base(FlowDirection.TopToBottom) { var inlineTitleEdit = new InlineTitleEdit(printer.Settings.GetValue(SettingsKey.printer_name), theme, "Printer Name", boldFont: true); - inlineTitleEdit.TitleChanged += (s, e) => + inlineTitleEdit.ValueChanged += (s, e) => { printer.Settings.SetValue(SettingsKey.printer_name, inlineTitleEdit.Text); }; diff --git a/CustomWidgets/InlineTitleEdit.cs b/CustomWidgets/InlineTitleEdit.cs index 36f7962a5..b369cb40f 100644 --- a/CustomWidgets/InlineTitleEdit.cs +++ b/CustomWidgets/InlineTitleEdit.cs @@ -40,7 +40,7 @@ namespace MatterHackers.MatterControl.CustomWidgets { public class InlineTitleEdit : Toolbar { - public event EventHandler TitleChanged; + public event EventHandler ValueChanged; private TextWidget titleText; protected FlowLayoutWidget rightPanel; @@ -83,7 +83,7 @@ namespace MatterHackers.MatterControl.CustomWidgets { this.Text = searchPanel.Text; this.SetVisibility(showEditPanel: false); - this.TitleChanged?.Invoke(this, null); + this.ValueChanged?.Invoke(this, null); }; searchPanel.searchInput.Name = automationName + " Field"; @@ -114,7 +114,7 @@ namespace MatterHackers.MatterControl.CustomWidgets { this.Text = searchPanel.Text; this.SetVisibility(showEditPanel: false); - this.TitleChanged?.Invoke(this, null); + this.ValueChanged?.Invoke(this, null); }; rightPanel.AddChild(saveButton); diff --git a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs index 9077a9467..66b406e78 100644 --- a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs +++ b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs @@ -83,7 +83,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration contentRow.BackgroundColor = Color.Transparent; var inlineTitleEdit = new InlineTitleEdit(presetsContext.PersistenceLayer.Name, theme, presetsContext.LayerType.ToString() + " Name", boldFont: true); - inlineTitleEdit.TitleChanged += (s, e) => + inlineTitleEdit.ValueChanged += (s, e) => { printer.Settings.SetValue(SettingsKey.layer_name, inlineTitleEdit.Text, presetsContext.PersistenceLayer); }; diff --git a/SlicerConfiguration/UIFields/ListStringField.cs b/SlicerConfiguration/UIFields/ListStringField.cs index abf2a6407..da3d359b9 100644 --- a/SlicerConfiguration/UIFields/ListStringField.cs +++ b/SlicerConfiguration/UIFields/ListStringField.cs @@ -80,7 +80,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration var localIndex = i; - inlineEdit.TitleChanged += (s, e) => + inlineEdit.ValueChanged += (s, e) => { _list[localIndex] = inlineEdit.Text; }; From 2bfa6f22871ba7a839d2f6f3e4f96d3370f8be02 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 07:38:47 -0700 Subject: [PATCH 04/12] Rename type to match more general use case --- CustomWidgets/ConfigurePrinterWidget.cs | 8 ++++---- CustomWidgets/InlineListItemEdit.cs | 2 +- .../{InlineTitleEdit.cs => InlineStringEdit.cs} | 4 ++-- MatterControl.csproj | 2 +- .../SlicePresetsWindow/SlicePresetsWindow.cs | 12 ++++++------ 5 files changed, 14 insertions(+), 14 deletions(-) rename CustomWidgets/{InlineTitleEdit.cs => InlineStringEdit.cs} (96%) diff --git a/CustomWidgets/ConfigurePrinterWidget.cs b/CustomWidgets/ConfigurePrinterWidget.cs index a8149c45c..91881f01b 100644 --- a/CustomWidgets/ConfigurePrinterWidget.cs +++ b/CustomWidgets/ConfigurePrinterWidget.cs @@ -38,12 +38,12 @@ namespace MatterHackers.MatterControl public ConfigurePrinterWidget(SettingsContext settingsContext, PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { - var inlineTitleEdit = new InlineTitleEdit(printer.Settings.GetValue(SettingsKey.printer_name), theme, "Printer Name", boldFont: true); - inlineTitleEdit.ValueChanged += (s, e) => + var inlineNameEdit = new InlineStringEdit(printer.Settings.GetValue(SettingsKey.printer_name), theme, "Printer Name", boldFont: true); + inlineNameEdit.ValueChanged += (s, e) => { - printer.Settings.SetValue(SettingsKey.printer_name, inlineTitleEdit.Text); + printer.Settings.SetValue(SettingsKey.printer_name, inlineNameEdit.Text); }; - this.AddChild(inlineTitleEdit); + this.AddChild(inlineNameEdit); this.AddChild( new SliceSettingsTabView( diff --git a/CustomWidgets/InlineListItemEdit.cs b/CustomWidgets/InlineListItemEdit.cs index d21fefb38..e709ed7ab 100644 --- a/CustomWidgets/InlineListItemEdit.cs +++ b/CustomWidgets/InlineListItemEdit.cs @@ -34,7 +34,7 @@ using MatterHackers.Localizations; namespace MatterHackers.MatterControl.CustomWidgets { - public class InlineListItemEdit : InlineTitleEdit + public class InlineListItemEdit : InlineStringEdit { public event EventHandler ItemDeleted; diff --git a/CustomWidgets/InlineTitleEdit.cs b/CustomWidgets/InlineStringEdit.cs similarity index 96% rename from CustomWidgets/InlineTitleEdit.cs rename to CustomWidgets/InlineStringEdit.cs index b369cb40f..93c047f49 100644 --- a/CustomWidgets/InlineTitleEdit.cs +++ b/CustomWidgets/InlineStringEdit.cs @@ -38,7 +38,7 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.CustomWidgets { - public class InlineTitleEdit : Toolbar + public class InlineStringEdit : Toolbar { public event EventHandler ValueChanged; @@ -48,7 +48,7 @@ namespace MatterHackers.MatterControl.CustomWidgets private GuiWidget saveButton; private SearchInputBox searchPanel; - public InlineTitleEdit(string title, ThemeConfig theme, string automationName, bool boldFont = false) + public InlineStringEdit(string title, ThemeConfig theme, string automationName, bool boldFont = false) : base(theme) { this.Padding = theme.ToolbarPadding; diff --git a/MatterControl.csproj b/MatterControl.csproj index e4218e639..2bb439563 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -86,6 +86,7 @@ + @@ -201,7 +202,6 @@ - diff --git a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs index 66b406e78..ba23fd237 100644 --- a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs +++ b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs @@ -82,12 +82,12 @@ namespace MatterHackers.MatterControl.SlicerConfiguration contentRow.BackgroundColor = Color.Transparent; - var inlineTitleEdit = new InlineTitleEdit(presetsContext.PersistenceLayer.Name, theme, presetsContext.LayerType.ToString() + " Name", boldFont: true); - inlineTitleEdit.ValueChanged += (s, e) => + var inlineNameEdit = new InlineStringEdit(presetsContext.PersistenceLayer.Name, theme, presetsContext.LayerType.ToString() + " Name", boldFont: true); + inlineNameEdit.ValueChanged += (s, e) => { - printer.Settings.SetValue(SettingsKey.layer_name, inlineTitleEdit.Text, presetsContext.PersistenceLayer); + printer.Settings.SetValue(SettingsKey.layer_name, inlineNameEdit.Text, presetsContext.PersistenceLayer); }; - contentRow.AddChild(inlineTitleEdit); + contentRow.AddChild(inlineNameEdit); var sliceSettingsWidget = CreateSliceSettingsWidget(printer, presetsContext.PersistenceLayer); contentRow.AddChild(sliceSettingsWidget); @@ -97,7 +97,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { UiThread.RunOnIdle(() => { - string sanitizedName = numberMatch.Replace(inlineTitleEdit.Text, "").Trim(); + string sanitizedName = numberMatch.Replace(inlineNameEdit.Text, "").Trim(); string newProfileName = agg_basics.GetNonCollidingName(sanitizedName, presetsContext.PresetLayers.Select(preset => preset.ValueOrDefault(SettingsKey.layer_name))); var clonedLayer = presetsContext.PersistenceLayer.Clone(); @@ -111,7 +111,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration sliceSettingsWidget = CreateSliceSettingsWidget(printer, clonedLayer); contentRow.AddChild(sliceSettingsWidget); - inlineTitleEdit.Text = newProfileName; + inlineNameEdit.Text = newProfileName; }); }; this.AddPageAction(duplicateButton); From acbd5a538037c693f079e32be71bce1bbf6674eb Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 08:26:22 -0700 Subject: [PATCH 05/12] Add support for overridable Edit action --- CustomWidgets/InlineStringEdit.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/CustomWidgets/InlineStringEdit.cs b/CustomWidgets/InlineStringEdit.cs index 93c047f49..efeb08aee 100644 --- a/CustomWidgets/InlineStringEdit.cs +++ b/CustomWidgets/InlineStringEdit.cs @@ -48,14 +48,14 @@ namespace MatterHackers.MatterControl.CustomWidgets private GuiWidget saveButton; private SearchInputBox searchPanel; - public InlineStringEdit(string title, ThemeConfig theme, string automationName, bool boldFont = false) + public InlineStringEdit(string stringValue, ThemeConfig theme, string automationName, bool boldFont = false) : base(theme) { this.Padding = theme.ToolbarPadding; this.HAnchor = HAnchor.Stretch; this.VAnchor = VAnchor.Fit; - titleText = new TextWidget(title, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: theme.DefaultFontSize, bold: boldFont) + titleText = new TextWidget(stringValue, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: theme.DefaultFontSize, bold: boldFont) { VAnchor = VAnchor.Center, AutoExpandBoundsToText = true, @@ -105,8 +105,15 @@ namespace MatterHackers.MatterControl.CustomWidgets }; editButton.Click += (s, e) => { - searchPanel.Text = this.Text; - this.SetVisibility(showEditPanel: true); + if (this.EditOverride != null) + { + this.EditOverride.Invoke(); + } + else + { + searchPanel.Text = this.Text; + this.SetVisibility(showEditPanel: true); + } }; rightPanel.AddChild(editButton); @@ -114,7 +121,6 @@ namespace MatterHackers.MatterControl.CustomWidgets { this.Text = searchPanel.Text; this.SetVisibility(showEditPanel: false); - this.ValueChanged?.Invoke(this, null); }; rightPanel.AddChild(saveButton); @@ -123,6 +129,8 @@ namespace MatterHackers.MatterControl.CustomWidgets this.ActionArea.Margin = this.ActionArea.Margin.Clone(right: rightPanel.Width + 5); } + public Action EditOverride { get; set; } + public override string Text { get => titleText.Text; @@ -131,6 +139,7 @@ namespace MatterHackers.MatterControl.CustomWidgets if (titleText.Text != value) { titleText.Text = value; + this.ValueChanged?.Invoke(this, null); } } } From 117826aa682f17b031bcc0eee4b872ab508aafdd Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 09:49:07 -0700 Subject: [PATCH 06/12] Editor wip --- CustomWidgets/InlineStringEdit.cs | 4 +- DesignTools/PublicPropertyEditor.cs | 4 +- MatterControl.csproj | 2 + .../UIFields/ListStringField.cs | 3 +- .../UIFields/SurfacedEditorPage.cs | 179 ++++++++++++++++++ .../UIFields/SurfacedEditorsField.cs | 75 ++++++++ 6 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 SlicerConfiguration/UIFields/SurfacedEditorPage.cs create mode 100644 SlicerConfiguration/UIFields/SurfacedEditorsField.cs diff --git a/CustomWidgets/InlineStringEdit.cs b/CustomWidgets/InlineStringEdit.cs index efeb08aee..a87dad98e 100644 --- a/CustomWidgets/InlineStringEdit.cs +++ b/CustomWidgets/InlineStringEdit.cs @@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.CustomWidgets { if (this.EditOverride != null) { - this.EditOverride.Invoke(); + this.EditOverride.Invoke(this, null); } else { @@ -129,7 +129,7 @@ namespace MatterHackers.MatterControl.CustomWidgets this.ActionArea.Margin = this.ActionArea.Margin.Clone(right: rightPanel.Width + 5); } - public Action EditOverride { get; set; } + public event EventHandler EditOverride; public override string Text { diff --git a/DesignTools/PublicPropertyEditor.cs b/DesignTools/PublicPropertyEditor.cs index eaad4d5a7..9ea6f56e7 100644 --- a/DesignTools/PublicPropertyEditor.cs +++ b/DesignTools/PublicPropertyEditor.cs @@ -315,7 +315,9 @@ namespace MatterHackers.MatterControl.DesignTools } else if (propertyValue is List stringList) { - var field = new ListStringField(theme); + var selectedItem = ApplicationController.Instance.DragDropData.SceneContext.Scene.SelectedItem; + + var field = new SurfacedEditorsField(theme, selectedItem); field.Initialize(0); field.ListValue = stringList; field.ValueChanged += (s, e) => diff --git a/MatterControl.csproj b/MatterControl.csproj index 2bb439563..f391e6409 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -284,6 +284,8 @@ + + diff --git a/SlicerConfiguration/UIFields/ListStringField.cs b/SlicerConfiguration/UIFields/ListStringField.cs index da3d359b9..551a59b4b 100644 --- a/SlicerConfiguration/UIFields/ListStringField.cs +++ b/SlicerConfiguration/UIFields/ListStringField.cs @@ -27,6 +27,7 @@ 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.Platform; @@ -68,7 +69,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration } } - private void Rebuild() + protected virtual void Rebuild() { this.Content.CloseAllChildren(); diff --git a/SlicerConfiguration/UIFields/SurfacedEditorPage.cs b/SlicerConfiguration/UIFields/SurfacedEditorPage.cs new file mode 100644 index 000000000..c13003748 --- /dev/null +++ b/SlicerConfiguration/UIFields/SurfacedEditorPage.cs @@ -0,0 +1,179 @@ +/* +Copyright (c) 2018, 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.Linq; +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.CustomWidgets; +using MatterHackers.MatterControl.DesignTools; +using MatterHackers.MatterControl.PartPreviewWindow; + +namespace MatterHackers.MatterControl.SlicerConfiguration +{ + public class SurfacedEditorPage : DialogPage + { + private MHTextEditWidget editWidget; + + public SurfacedEditorPage(UIField uiField, IObject3D selectedItem) + { + this.WindowTitle = "MatterControl - " + "Editor Selector".Localize(); + this.HeaderText = "Surfaced Editor".Localize(); + + var tabControl = new SimpleTabs(theme, new GuiWidget()) + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Stretch, + }; + tabControl.TabBar.BackgroundColor = theme.TabBarBackground; + tabControl.TabBar.Padding = 0; + + contentRow.AddChild(tabControl); + contentRow.Padding = 0; + + var editContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) + { + HAnchor = HAnchor.Stretch, + VAnchor = VAnchor.Stretch, + Padding = theme.DefaultContainerPadding, + BackgroundColor = theme.ActiveTabColor + }; + + editWidget = new MHTextEditWidget("", multiLine: true) + { + HAnchor = HAnchor.Stretch, + Name = this.Name + }; + editWidget.DrawFromHintedCache(); + //editWidget.ActualTextEditWidget.VAnchor = VAnchor.Stretch; + + editContainer.AddChild(editWidget); + + // add the tree view + var treeView = new TreeView(theme) + { + Margin = new BorderDouble(left: 18), + }; + treeView.AfterSelect += (s, e) => + { + if (treeView.SelectedNode.Tag is IObject3D contextNode) + { + Console.WriteLine(contextNode.Name); + } + }; + treeView.ScrollArea.ChildAdded += (s, e) => + { + if (e is GuiWidgetEventArgs childEventArgs + && childEventArgs.Child is TreeNode treeNode) + { + treeNode.AlwaysExpandable = true; + } + }; + + treeView.Click += (s, e) => + { + if (treeView.IsDoubleClick(e)) + { + Console.WriteLine(); + } + }; + + treeView.ScrollArea.CloseAllChildren(); + + var rootNode = Object3DTreeBuilder.BuildTree(selectedItem, theme); + treeView.AddChild(rootNode); + rootNode.TreeView = treeView; + + editContainer.AddChild(treeView); + + var createButton = new TextButton("Create from selection", theme); + createButton.VAnchor = VAnchor.Absolute; + createButton.HAnchor = HAnchor.Left; + createButton.BackgroundColor = theme.MinimalShade; + createButton.Click += (s, e) => + { + if (treeView.SelectedNode.Tag is IObject3D contextNode) + { + editWidget.Text = "$." + string.Join(".", contextNode.AncestorsAndSelf().TakeWhile(o => !(o is ComponentObject3D)).Select(o => $"Children<{o.GetType().Name.ToString()}>").Reverse().ToArray()); + } + }; + + editContainer.AddChild(createButton); + + var dummyWidget = new GuiWidget() + { + BackgroundColor = Color.Red + }; + + var editTab = new ToolTab("Edit".Localize(), tabControl, editContainer, theme, hasClose: false) + { + Name = "Edit Tab" + }; + tabControl.AddTab(editTab); + + var previewTab = new ToolTab("Preview".Localize(), tabControl, dummyWidget, theme, hasClose: false) + { + Name = "Preview Tab" + }; + tabControl.AddTab(previewTab); + + tabControl.ActiveTabChanged += (s, e) => + { + if (tabControl.SelectedTabIndex == 1) + { + // dummyWidget.Markdown = editWidget.Text; + } + }; + + tabControl.SelectedTabIndex = 0; + + var saveButton = theme.CreateDialogButton("Save".Localize()); + saveButton.Click += (s, e) => + { + uiField.SetValue( + editWidget.Text.Replace("\n", "\\n"), + userInitiated: true); + + this.DialogWindow.CloseOnIdle(); + }; + this.AddPageAction(saveButton); + } + + public string EditorString + { + get => editWidget.Text; + set + { + editWidget.Text = value; + } + } + } +} diff --git a/SlicerConfiguration/UIFields/SurfacedEditorsField.cs b/SlicerConfiguration/UIFields/SurfacedEditorsField.cs new file mode 100644 index 000000000..ee25df9f8 --- /dev/null +++ b/SlicerConfiguration/UIFields/SurfacedEditorsField.cs @@ -0,0 +1,75 @@ +/* +Copyright (c) 2018, 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 MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.MatterControl.CustomWidgets; + +namespace MatterHackers.MatterControl.SlicerConfiguration +{ + public class SurfacedEditorsField : ListStringField + { + private IObject3D selectedItem; + + public SurfacedEditorsField(ThemeConfig theme, IObject3D selectedItem) + : base(theme) + { + this.selectedItem = selectedItem; + } + + protected override void Rebuild() + { + base.Rebuild(); + + foreach(var inlineEdit in this.Content.Children()) + { + inlineEdit.EditOverride += InlineEdit_EditOverride; + } + } + + private void InlineEdit_EditOverride(object sender, EventArgs e) + { + if (sender is InlineStringEdit inlineEdit) + { + var uifield = new TextField(); + uifield.Initialize(0); + uifield.ValueChanged += (s, e2) => + { + inlineEdit.Text = uifield.Value; + }; + + DialogWindow.Show(new SurfacedEditorPage(uifield, selectedItem) + { + EditorString = inlineEdit.Text, + }); + } + } + } +} From 2473bb05773489192047f2e666b2cecc4e818a36 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 12:18:08 -0700 Subject: [PATCH 07/12] Revise mouse hit and active cursor --- .../ResizeContainer/BottomResizeContainer.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/CustomWidgets/ResizeContainer/BottomResizeContainer.cs b/CustomWidgets/ResizeContainer/BottomResizeContainer.cs index 464a9df9a..c5528eeda 100644 --- a/CustomWidgets/ResizeContainer/BottomResizeContainer.cs +++ b/CustomWidgets/ResizeContainer/BottomResizeContainer.cs @@ -45,7 +45,6 @@ namespace MatterHackers.MatterControl.CustomWidgets : base (FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Absolute; - this.Cursor = Cursors.HSplit; this.SplitterHeight = theme.SplitterWidth; this.SpliterBarColor = theme.SplitterBackground; } @@ -80,7 +79,8 @@ namespace MatterHackers.MatterControl.CustomWidgets public override void OnMouseDown(MouseEventArgs mouseEvent) { - if (mouseEvent.Position.Y < this.SplitterHeight) + if (mouseEvent.Position.Y <= this.LocalBounds.Bottom + this.SplitterHeight + && mouseEvent.Position.Y >= this.LocalBounds.Bottom) { mouseDownOnBar = true; mouseDownY = TransformToScreenSpace(mouseEvent.Position).Y; @@ -99,6 +99,26 @@ namespace MatterHackers.MatterControl.CustomWidgets Height = downHeight + mouseDownY - currentMouseY; }); } + + var currentCursor = this.Cursor; + + if (mouseEvent.Position.Y <= this.LocalBounds.Bottom + this.SplitterHeight + && mouseEvent.Position.Y >= this.LocalBounds.Bottom) + { + this.Cursor = Cursors.HSplit; + + } + else + { + this.Cursor = Cursors.Default; + } + + if (this.FirstWidgetUnderMouse + && this.Cursor != currentCursor) + { + this.SetCursor(this.Cursor); + } + base.OnMouseMove(mouseEvent); } From 7a7585da664753946e1c53c30cf30642f07592bb Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 12:20:56 -0700 Subject: [PATCH 08/12] Add "Edit Component" operation --- ApplicationView/ApplicationController.cs | 29 ++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index fce6e79dc..dd5afa3d2 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -763,7 +763,6 @@ namespace MatterHackers.MatterControl }, iconCollector: (theme) => AggContext.StaticData.LoadIcon(Path.Combine("ViewTransformControls", "rotate.png"), 16, 16, theme.InvertIcons)); -#if DEBUG // when this is working (Component and ComponentPicker work), enable it. this.Graph.RegisterOperation( typeof(IObject3D), typeof(ComponentObject3D), @@ -806,7 +805,33 @@ namespace MatterHackers.MatterControl && sceneItem.DescendantsAndSelf().All(d => !(d is ComponentObject3D)); }, iconCollector: (theme) => AggContext.StaticData.LoadIcon("scale_32x32.png", 16, 16, theme.InvertIcons)); -#endif + + this.Graph.RegisterOperation( + typeof(IObject3D), + typeof(ComponentObject3D), + "Edit Component".Localize(), + (sceneItem, scene) => + { + if (sceneItem is ComponentObject3D componentObject) + { + // Enable editing mode + componentObject.Finalized = false; + + // Force editor rebuild + scene.SelectedItem = null; + scene.SelectedItem = componentObject; + } + + return Task.CompletedTask; + }, + isVisible: (sceneItem) => + { + return sceneItem.Parent.Parent == null + && sceneItem is ComponentObject3D componentObject + && componentObject.Finalized; + }, + iconCollector: (theme) => AggContext.StaticData.LoadIcon("scale_32x32.png", 16, 16, theme.InvertIcons)); + this.Graph.RegisterOperation( typeof(IObject3D), From db84a6ec833bf61dbab32a2e65db69a27d2c72f9 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 12:21:18 -0700 Subject: [PATCH 09/12] Simplify --- .../UIFields/SurfacedEditorPage.cs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/SlicerConfiguration/UIFields/SurfacedEditorPage.cs b/SlicerConfiguration/UIFields/SurfacedEditorPage.cs index c13003748..8628734e3 100644 --- a/SlicerConfiguration/UIFields/SurfacedEditorPage.cs +++ b/SlicerConfiguration/UIFields/SurfacedEditorPage.cs @@ -73,7 +73,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration Name = this.Name }; editWidget.DrawFromHintedCache(); - //editWidget.ActualTextEditWidget.VAnchor = VAnchor.Stretch; editContainer.AddChild(editWidget); @@ -86,7 +85,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { if (treeView.SelectedNode.Tag is IObject3D contextNode) { - Console.WriteLine(contextNode.Name); + editWidget.Text = "$." + string.Join(".", contextNode.AncestorsAndSelf().TakeWhile(o => !(o is ComponentObject3D)).Select(o => $"Children<{o.GetType().Name.ToString()}>").Reverse().ToArray()); } }; treeView.ScrollArea.ChildAdded += (s, e) => @@ -113,21 +112,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration rootNode.TreeView = treeView; editContainer.AddChild(treeView); - - var createButton = new TextButton("Create from selection", theme); - createButton.VAnchor = VAnchor.Absolute; - createButton.HAnchor = HAnchor.Left; - createButton.BackgroundColor = theme.MinimalShade; - createButton.Click += (s, e) => - { - if (treeView.SelectedNode.Tag is IObject3D contextNode) - { - editWidget.Text = "$." + string.Join(".", contextNode.AncestorsAndSelf().TakeWhile(o => !(o is ComponentObject3D)).Select(o => $"Children<{o.GetType().Name.ToString()}>").Reverse().ToArray()); - } - }; - - editContainer.AddChild(createButton); - var dummyWidget = new GuiWidget() { BackgroundColor = Color.Red From 523a218d476b72b49c4a7921fc239bc33c3e667d Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 13:00:15 -0700 Subject: [PATCH 10/12] Use event pattern --- SlicerConfiguration/Slicer.cs | 2 +- .../UIFields/SurfacedEditorPage.cs | 8 ++++---- .../UIFields/SurfacedEditorsField.cs | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/SlicerConfiguration/Slicer.cs b/SlicerConfiguration/Slicer.cs index 8b1abec48..bead6fb40 100644 --- a/SlicerConfiguration/Slicer.cs +++ b/SlicerConfiguration/Slicer.cs @@ -261,7 +261,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration ActiveSliceSettings.Instance.SetValue("boolean_operations", mergeRules); - var matrixAndMeshArgs = new StringBuilder(); ; + var matrixAndMeshArgs = new StringBuilder(); foreach (var matrixAndFile in stlFileLocations) { var matrixString = ""; diff --git a/SlicerConfiguration/UIFields/SurfacedEditorPage.cs b/SlicerConfiguration/UIFields/SurfacedEditorPage.cs index 8628734e3..17c3e4fd3 100644 --- a/SlicerConfiguration/UIFields/SurfacedEditorPage.cs +++ b/SlicerConfiguration/UIFields/SurfacedEditorPage.cs @@ -41,9 +41,11 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public class SurfacedEditorPage : DialogPage { + public event EventHandler ValueChanged; + private MHTextEditWidget editWidget; - public SurfacedEditorPage(UIField uiField, IObject3D selectedItem) + public SurfacedEditorPage(IObject3D selectedItem) { this.WindowTitle = "MatterControl - " + "Editor Selector".Localize(); this.HeaderText = "Surfaced Editor".Localize(); @@ -142,9 +144,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration var saveButton = theme.CreateDialogButton("Save".Localize()); saveButton.Click += (s, e) => { - uiField.SetValue( - editWidget.Text.Replace("\n", "\\n"), - userInitiated: true); + this.ValueChanged?.Invoke(this, null); this.DialogWindow.CloseOnIdle(); }; diff --git a/SlicerConfiguration/UIFields/SurfacedEditorsField.cs b/SlicerConfiguration/UIFields/SurfacedEditorsField.cs index ee25df9f8..dc77fc219 100644 --- a/SlicerConfiguration/UIFields/SurfacedEditorsField.cs +++ b/SlicerConfiguration/UIFields/SurfacedEditorsField.cs @@ -58,17 +58,17 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { if (sender is InlineStringEdit inlineEdit) { - var uifield = new TextField(); - uifield.Initialize(0); - uifield.ValueChanged += (s, e2) => - { - inlineEdit.Text = uifield.Value; - }; - - DialogWindow.Show(new SurfacedEditorPage(uifield, selectedItem) + var editorPage = new SurfacedEditorPage(selectedItem) { EditorString = inlineEdit.Text, - }); + }; + + editorPage.ValueChanged += (s, e2) => + { + inlineEdit.Text = editorPage.EditorString; + }; + + DialogWindow.Show(editorPage); } } } From 74f15d225d06b08f66463a91698eb3c5d836f33f Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 13:49:28 -0700 Subject: [PATCH 11/12] Add required test stub --- .../MatterControl/SliceSettingsFieldTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs b/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs index 17381d481..1e3f322ba 100644 --- a/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/SliceSettingsFieldTests.cs @@ -404,6 +404,12 @@ namespace MatterControl.Tests.MatterControl Assert.Fail(); } + [Test, Ignore("Not Implemented")] + public async Task SurfacedEditorsFieldTest() + { + Assert.Fail(); + } + public class ValueMap { [DebuggerStepThrough] From 84a1d5608584c81660a38ad7d6726f0f4e1208f3 Mon Sep 17 00:00:00 2001 From: John Lewin Date: Fri, 3 Aug 2018 14:20:24 -0700 Subject: [PATCH 12/12] Conditional compile for SurfacedEditorsField --- DesignTools/PublicPropertyEditor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DesignTools/PublicPropertyEditor.cs b/DesignTools/PublicPropertyEditor.cs index 9ea6f56e7..d01c4cb08 100644 --- a/DesignTools/PublicPropertyEditor.cs +++ b/DesignTools/PublicPropertyEditor.cs @@ -313,6 +313,7 @@ namespace MatterHackers.MatterControl.DesignTools rowContainer = CreateSettingsColumn(property, field); } +#if !__ANDROID__ else if (propertyValue is List stringList) { var selectedItem = ApplicationController.Instance.DragDropData.SceneContext.Scene.SelectedItem; @@ -329,6 +330,7 @@ namespace MatterHackers.MatterControl.DesignTools rowContainer.Descendants().FirstOrDefault()?.Close(); } +#endif else if (propertyValue is Vector3 vector3) { var field = new Vector3Field();