using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; using MatterHackers.Agg; using MatterHackers.Agg.UI; using MatterHackers.VectorMath; using MatterHackers.Agg.Font; using MatterHackers.Localizations; namespace MatterHackers.MatterControl { public class SliceSettingsWidget : GuiWidget { public class UiState { public class WhichItem { public int index = 0; public string name = ""; } public string userLevel = "Beginner"; public bool showHelp = false; public WhichItem selectedCategory = new WhichItem(); public WhichItem selectedGroup = new WhichItem(); public UiState() { } public UiState(SliceSettingsWidget settingsToCopy) { showHelp = settingsToCopy.ShowingHelp; userLevel = settingsToCopy.UserLevel; settingsToCopy.CurrentlyActiveCategory(out selectedCategory.index, out selectedCategory.name); settingsToCopy.CurrentlyActiveGroup(out selectedGroup.index, out selectedGroup.name); } } TabControl categoryTabs; GroupBox noConnectionMessageContainer; FlowLayoutWidget settingsControlBar; CheckBox showHelpBox; CheckBox showAllDetails; public SliceSettingsWidget(UiState uiState) { AddControls(uiState); } public bool ShowingHelp { get { return showHelpBox.Checked; } } public string UserLevel { get { if (showAllDetails.Checked) { return "Advanced"; } return "Beginner"; } } public void CurrentlyActiveCategory(out int index, out string name) { index = categoryTabs.SelectedTabIndex; name = categoryTabs.SelectedTabName; } public void CurrentlyActiveGroup(out int index, out string name) { index = 0; name = ""; TabPage currentPage = categoryTabs.GetActivePage(); TabControl currentGroup = null; if (currentPage.Children.Count > 0) { currentGroup = currentPage.Children[0] as TabControl; } if (currentGroup != null) { index = currentGroup.SelectedTabIndex; name = currentGroup.SelectedTabName; } } void AddControls(UiState uiState) { int minSettingNameWidth = 220; showHelpBox = new CheckBox(new LocalizedString("Show Help").Translated); showHelpBox.Checked = uiState.showHelp; showAllDetails = new CheckBox(new LocalizedString("Show All Settings").Translated); showAllDetails.Checked = uiState.userLevel == "Advanced"; FlowLayoutWidget pageTopToBottomLayout = new FlowLayoutWidget(FlowDirection.TopToBottom, vAnchor: Agg.UI.VAnchor.ParentTop); pageTopToBottomLayout.AnchorAll(); pageTopToBottomLayout.Padding = new BorderDouble(3, 0); this.AddChild(pageTopToBottomLayout); settingsControlBar = new SettingsControlBar(); pageTopToBottomLayout.AddChild(settingsControlBar); noConnectionMessageContainer = new GroupBox(new LocalizedString("No Printer Selected").Translated); noConnectionMessageContainer.Margin = new BorderDouble(top: 10); noConnectionMessageContainer.TextColor = ActiveTheme.Instance.PrimaryTextColor; noConnectionMessageContainer.BorderColor = ActiveTheme.Instance.PrimaryTextColor; noConnectionMessageContainer.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; noConnectionMessageContainer.Height = 80; TextWidget noConnectionMessage = new TextWidget(new LocalizedString("No printer is currently selected. Select printer to edit slice settings.").Translated); noConnectionMessage.Margin = new BorderDouble(5); noConnectionMessage.TextColor = ActiveTheme.Instance.PrimaryTextColor; noConnectionMessage.VAnchor = VAnchor.ParentCenter; noConnectionMessageContainer.AddChild(noConnectionMessage); pageTopToBottomLayout.AddChild(noConnectionMessageContainer); categoryTabs = new TabControl(); categoryTabs.TabBar.BorderColor = RGBA_Bytes.White; categoryTabs.Margin = new BorderDouble(top: 8); categoryTabs.AnchorAll(); List sideTabBarsListForLayout = new List(); for (int categoryIndex = 0; categoryIndex < SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList.Count; categoryIndex++) { OrganizerCategory category = SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList[categoryIndex]; string categoryPageLbl = new LocalizedString (category.Name).Translated; TabPage categoryPage = new TabPage(categoryPageLbl); SimpleTextTabWidget textTabWidget = new SimpleTextTabWidget(categoryPage, 16, ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes()); categoryPage.AnchorAll(); categoryTabs.AddTab(textTabWidget); TabControl sideTabs = CreateSideTabsAndPages(minSettingNameWidth, category, uiState); sideTabBarsListForLayout.Add(sideTabs.TabBar); categoryPage.AddChild(sideTabs); } if(showAllDetails.Checked && PrinterCommunication.Instance.ActiveSliceEngine == PrinterCommunication.SlicingEngine.Slic3r) { TabPage extraSettingsPage = new TabPage("Other"); SimpleTextTabWidget extraSettingsTextTabWidget = new SimpleTextTabWidget(extraSettingsPage, 16, ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes()); extraSettingsPage.AnchorAll(); int count; TabControl extraSettingsSideTabs = CreateExtraSettingsSideTabsAndPages(minSettingNameWidth, categoryTabs, out count); if (count > 0) { categoryTabs.AddTab(extraSettingsTextTabWidget); sideTabBarsListForLayout.Add(extraSettingsSideTabs.TabBar); extraSettingsPage.AddChild(extraSettingsSideTabs); } } double sideTabBarsMinimumWidth = 0; foreach (TabBar tabBar in sideTabBarsListForLayout) { sideTabBarsMinimumWidth = Math.Max(sideTabBarsMinimumWidth, tabBar.Width); } foreach (TabBar tabBar in sideTabBarsListForLayout) { tabBar.MinimumSize = new Vector2(sideTabBarsMinimumWidth, tabBar.MinimumSize.y); } // space before checkboxes (hold the right aligned) { GuiWidget hSpacer = new GuiWidget(); hSpacer.HAnchor = HAnchor.ParentLeftRight; categoryTabs.TabBar.AddChild(hSpacer); } // add in the ability to turn on and off all details settings { showAllDetails.TextColor = RGBA_Bytes.White; showAllDetails.Margin = new BorderDouble(right: 8); showAllDetails.VAnchor = VAnchor.ParentCenter; showAllDetails.Cursor = Cursors.Hand; showAllDetails.CheckedStateChanged += new CheckBox.CheckedStateChangedEventHandler(RebuildSlicerSettings); categoryTabs.TabBar.AddChild(showAllDetails); } // add in the ability to turn on and off help text { showHelpBox.TextColor = RGBA_Bytes.White; showHelpBox.Margin = new BorderDouble(right: 3); showHelpBox.VAnchor = VAnchor.ParentCenter; showHelpBox.Cursor = Cursors.Hand; showHelpBox.CheckedStateChanged += new CheckBox.CheckedStateChangedEventHandler(RebuildSlicerSettings); categoryTabs.TabBar.AddChild(showHelpBox); } pageTopToBottomLayout.AddChild(categoryTabs); AddHandlers(); SetVisibleControls(); if (!categoryTabs.SelectTab(uiState.selectedCategory.name)) { categoryTabs.SelectTab(uiState.selectedCategory.index); } } void RebuildSlicerSettings(object sender, EventArgs e) { CheckBox checkBox = sender as CheckBox; if (checkBox != null) { MainSlidePanel.Instance.ReloadBackPanel(); } } internal class ExtraSettingTextWidget : MHTextEditWidget { internal string itemKey { get; set; } internal ExtraSettingTextWidget(string itemKey, string itemValue) : base(itemValue) { this.itemKey = itemKey; } } event EventHandler unregisterEvents; private void AddHandlers() { PrinterCommunication.Instance.ConnectionStateChanged.RegisterEvent(onPrinterStatusChanged, ref unregisterEvents); PrinterCommunication.Instance.ActivePrinterChanged.RegisterEvent(onPrinterStatusChanged, ref unregisterEvents); PrinterCommunication.Instance.EnableChanged.RegisterEvent(onPrinterStatusChanged, ref unregisterEvents); } public override void OnClosed(EventArgs e) { if (unregisterEvents != null) { unregisterEvents(this, null); } base.OnClosed(e); } private void onPrinterStatusChanged(object sender, EventArgs e) { SetVisibleControls(); this.Invalidate(); } private void SetVisibleControls() { if (PrinterCommunication.Instance.ActivePrinter != null) { categoryTabs.Visible = true; settingsControlBar.Visible = true; noConnectionMessageContainer.Visible = false; } else { categoryTabs.Visible = false; settingsControlBar.Visible = false; noConnectionMessageContainer.Visible = true; } } int tabIndexForItem = 0; private TabControl CreateSideTabsAndPages(int minSettingNameWidth, OrganizerCategory category, UiState uiState) { TabControl groupTabs = new TabControl(Orientation.Vertical); groupTabs.Margin = new BorderDouble(0, 0, 0, 5); groupTabs.TabBar.BorderColor = RGBA_Bytes.White; foreach (OrganizerGroup group in category.GroupsList) { tabIndexForItem = 0; string groupTabLbl = new LocalizedString (group.Name).Translated; TabPage groupTabPage = new TabPage(groupTabLbl); SimpleTextTabWidget groupTabWidget = new SimpleTextTabWidget(groupTabPage, 14, ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes()); FlowLayoutWidget subGroupLayoutTopToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom); subGroupLayoutTopToBottom.AnchorAll(); bool needToAddSubGroup = false; foreach (OrganizerSubGroup subGroup in group.SubGroupsList) { bool addedSettingToSubGroup = false; FlowLayoutWidget topToBottomSettings = new FlowLayoutWidget(FlowDirection.TopToBottom); topToBottomSettings.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; foreach (OrganizerSettingsData settingInfo in subGroup.SettingDataList) { if (PrinterCommunication.Instance.ActiveSliceEngine == PrinterCommunication.SlicingEngine.Slic3r || CuraEngineMappings.MapContains(settingInfo.SlicerConfigName)) { addedSettingToSubGroup = true; GuiWidget controlsForThisSetting = CreateSettingInfoUIControls(settingInfo, minSettingNameWidth); topToBottomSettings.AddChild(controlsForThisSetting); if (showHelpBox.Checked) { AddInHelpText(topToBottomSettings, settingInfo); } } } if (addedSettingToSubGroup) { needToAddSubGroup = true; string groupBoxLbl = new LocalizedString (subGroup.Name).Translated; GroupBox groupBox = new GroupBox (groupBoxLbl); groupBox.TextColor = ActiveTheme.Instance.PrimaryTextColor; groupBox.BorderColor = ActiveTheme.Instance.PrimaryTextColor; groupBox.AddChild(topToBottomSettings); groupBox.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; subGroupLayoutTopToBottom.AddChild(groupBox); } } if (needToAddSubGroup) { ScrollableWidget scrollOnGroupTab = new ScrollableWidget(true); scrollOnGroupTab.AnchorAll(); subGroupLayoutTopToBottom.HAnchor = HAnchor.Max_FitToChildren_ParentWidth; subGroupLayoutTopToBottom.VAnchor = VAnchor.FitToChildren; //subGroupLayoutTopToBottom.DebugShowBounds = true; //scrollOnGroupTab.DebugShowBounds = true; scrollOnGroupTab.AddChild(subGroupLayoutTopToBottom); groupTabPage.AddChild(scrollOnGroupTab); groupTabs.AddTab(groupTabWidget); } } if (!groupTabs.SelectTab(uiState.selectedGroup.name)) { groupTabs.SelectTab(uiState.selectedGroup.index); } return groupTabs; } private void AddInHelpText(FlowLayoutWidget topToBottomSettings, OrganizerSettingsData settingInfo) { FlowLayoutWidget allText = new FlowLayoutWidget(FlowDirection.TopToBottom); double textRegionWidth = 380; allText.Margin = new BorderDouble(3); allText.Padding = new BorderDouble(5); allText.BackgroundColor = ActiveTheme.Instance.TransparentDarkOverlay; double helpPointSize = 10; string[] wrappedText = TypeFacePrinter.WrapText(settingInfo.HelpText, textRegionWidth - allText.Padding.Width, helpPointSize); foreach(string line in wrappedText) { GuiWidget helpWidget = new TextWidget(line, pointSize: helpPointSize, textColor: RGBA_Bytes.White); allText.AddChild(helpWidget); } allText.MinimumSize = new Vector2(textRegionWidth, allText.MinimumSize.y); if (wrappedText.Length > 0) { topToBottomSettings.AddChild(allText); } } private TabControl CreateExtraSettingsSideTabsAndPages(int minSettingNameWidth, TabControl categoryTabs, out int count) { count = 0; TabControl sideTabs = new TabControl(Orientation.Vertical); sideTabs.Margin = new BorderDouble(0, 0, 0, 5); sideTabs.TabBar.BorderColor = RGBA_Bytes.White; { TabPage groupTabPage = new TabPage("Extra Settings"); SimpleTextTabWidget groupTabWidget = new SimpleTextTabWidget(groupTabPage, 14, ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes()); sideTabs.AddTab(groupTabWidget); FlowLayoutWidget subGroupLayoutTopToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom); subGroupLayoutTopToBottom.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; subGroupLayoutTopToBottom.VAnchor = VAnchor.FitToChildren; FlowLayoutWidget topToBottomSettings = new FlowLayoutWidget(FlowDirection.TopToBottom); topToBottomSettings.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; foreach (KeyValuePair item in ActiveSliceSettings.Instance.DefaultSettings) { if (!SliceSettingsOrganizer.Instance.Contains(UserLevel, item.Key)) { OrganizerSettingsData settingInfo = new OrganizerSettingsData(item.Key, item.Key, OrganizerSettingsData.DataEditTypes.STRING); GuiWidget controlsForThisSetting = CreateSettingInfoUIControls(settingInfo, minSettingNameWidth); topToBottomSettings.AddChild(controlsForThisSetting); count++; } } GroupBox groupBox = new GroupBox(new LocalizedString("Extra").Translated); groupBox.TextColor = ActiveTheme.Instance.PrimaryTextColor; groupBox.BorderColor = ActiveTheme.Instance.PrimaryTextColor; groupBox.AddChild(topToBottomSettings); groupBox.VAnchor = VAnchor.FitToChildren; groupBox.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; subGroupLayoutTopToBottom.AddChild(groupBox); ScrollableWidget scrollOnGroupTab = new ScrollableWidget(true); scrollOnGroupTab.AnchorAll(); scrollOnGroupTab.AddChild(subGroupLayoutTopToBottom); groupTabPage.AddChild(scrollOnGroupTab); } return sideTabs; } private TextWidget getSettingInfoData(OrganizerSettingsData settingData) { string extraSettings = settingData.ExtraSettings; extraSettings = extraSettings.Replace("\\n", "\n"); TextWidget dataTypeInfo = new TextWidget(extraSettings, pointSize:10); dataTypeInfo.TextColor = ActiveTheme.Instance.PrimaryTextColor; dataTypeInfo.Margin = new BorderDouble(5, 0); return dataTypeInfo; } private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth) { FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget(); if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName)) { int intEditWidth = 60; int doubleEditWidth = 60; int vectorXYEditWidth = 60; int multiLineEditHeight = 60; string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName); leftToRightLayout.Margin = new BorderDouble(0, 5); leftToRightLayout.HAnchor |= Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT) { string convertedNewLines = settingData.PresentationName.Replace("\\n ", "\n"); convertedNewLines = convertedNewLines.Replace("\\n", "\n"); convertedNewLines = new LocalizedString (convertedNewLines).Translated; TextWidget settingName = new TextWidget(convertedNewLines); settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor; settingName.Width = minSettingNameWidth; //settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y); leftToRightLayout.AddChild(settingName); } switch (settingData.DataEditType) { case OrganizerSettingsData.DataEditTypes.INT: { int currentValue = 0; int.TryParse(sliceSettingValue, out currentValue); MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++); intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); }; leftToRightLayout.AddChild(intEditWidget); leftToRightLayout.AddChild(getSettingInfoData(settingData)); } break; case OrganizerSettingsData.DataEditTypes.DOUBLE: { double currentValue = 0; double.TryParse(sliceSettingValue, out currentValue); MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++); doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); }; leftToRightLayout.AddChild(doubleEditWidget); leftToRightLayout.AddChild(getSettingInfoData(settingData)); } break; case OrganizerSettingsData.DataEditTypes.POSITVE_DOUBLE: { double currentValue = 0; double.TryParse(sliceSettingValue, out currentValue); MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++); doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); }; leftToRightLayout.AddChild(doubleEditWidget); leftToRightLayout.AddChild(getSettingInfoData(settingData)); } break; case OrganizerSettingsData.DataEditTypes.OFFSET: { double currentValue = 0; double.TryParse(sliceSettingValue, out currentValue); MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++); doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); }; leftToRightLayout.AddChild(doubleEditWidget); leftToRightLayout.AddChild(getSettingInfoData(settingData)); } break; case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT: { MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++); stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { TextEditWidget textEditWidget = (TextEditWidget)sender; string text = textEditWidget.Text; text = text.Trim(); bool isPercent = text.Contains("%"); if(isPercent) { text = text.Substring(0, text.IndexOf("%")); } double result; double.TryParse(text, out result); text = result.ToString(); if (isPercent) { text += "%"; } textEditWidget.Text = text; SaveSetting(settingData.SlicerConfigName, textEditWidget.Text); }; leftToRightLayout.AddChild(stringEdit); leftToRightLayout.AddChild(getSettingInfoData(settingData)); } break; case OrganizerSettingsData.DataEditTypes.CHECK_BOX: { CheckBox checkBoxWidget = new CheckBox(""); checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom; checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor; checkBoxWidget.Checked = (sliceSettingValue == "1"); checkBoxWidget.CheckedStateChanged += (sender, e) => { if (((CheckBox)sender).Checked) { SaveSetting(settingData.SlicerConfigName, "1"); } else { SaveSetting(settingData.SlicerConfigName, "0"); } }; leftToRightLayout.AddChild(checkBoxWidget); } break; case OrganizerSettingsData.DataEditTypes.STRING: { MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++); stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); }; leftToRightLayout.AddChild(stringEdit); } break; case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT: { string convertedNewLines = sliceSettingValue.Replace("\\n", "\n"); MHTextEditWidget stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++); stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); }; leftToRightLayout.AddChild(stringEdit); } break; case OrganizerSettingsData.DataEditTypes.LIST: { StyledDropDownList selectableOptions = new StyledDropDownList("None", Direction.Up); selectableOptions.Margin = new BorderDouble(); string[] listItems = settingData.ExtraSettings.Split(','); foreach (string listItem in listItems) { MenuItem newItem = selectableOptions.AddItem(listItem); if (newItem.Text == sliceSettingValue) { selectableOptions.SelectedValue = sliceSettingValue; } newItem.Selected += (sender, e) => { MenuItem menuItem = ((MenuItem)sender); SaveSetting(settingData.SlicerConfigName, menuItem.Text); }; } leftToRightLayout.AddChild(selectableOptions); } break; case OrganizerSettingsData.DataEditTypes.VECTOR2: { string[] xyValueStrings = sliceSettingValue.Split(','); if (xyValueStrings.Length != 2) { xyValueStrings = new string[] { "0", "0" }; } double currentXValue = 0; double.TryParse(xyValueStrings[0], out currentXValue); MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++); double currentYValue = 0; double.TryParse(xyValueStrings[1], out currentYValue); MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++); { xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); }; leftToRightLayout.AddChild(xEditWidget); TextWidget xText = new TextWidget("x"); xText.TextColor = ActiveTheme.Instance.PrimaryTextColor; xText.Margin = new BorderDouble(5, 0); leftToRightLayout.AddChild(xText); } { yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); }; leftToRightLayout.AddChild(yEditWidget); TextWidget yText = new TextWidget("y"); yText.TextColor = ActiveTheme.Instance.PrimaryTextColor; yText.Margin = new BorderDouble(5, 0); leftToRightLayout.AddChild(yText); } } break; case OrganizerSettingsData.DataEditTypes.OFFSET2: { string[] xyValueStrings = sliceSettingValue.Split('x'); if (xyValueStrings.Length != 2) { xyValueStrings = new string[] { "0", "0" }; } double currentXValue = 0; double.TryParse(xyValueStrings[0], out currentXValue); MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++); double currentYValue = 0; double.TryParse(xyValueStrings[1], out currentYValue); MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++); { xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); }; leftToRightLayout.AddChild(xEditWidget); TextWidget xText = new TextWidget("x"); xText.TextColor = ActiveTheme.Instance.PrimaryTextColor; xText.Margin = new BorderDouble(5, 0); leftToRightLayout.AddChild(xText); } { yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); }; leftToRightLayout.AddChild(yEditWidget); TextWidget yText = new TextWidget("y"); yText.TextColor = ActiveTheme.Instance.PrimaryTextColor; yText.Margin = new BorderDouble(5, 0); leftToRightLayout.AddChild(yText); } } break; default: TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString())); missingSetting.TextColor = ActiveTheme.Instance.PrimaryTextColor; missingSetting.BackgroundColor = RGBA_Bytes.Red; leftToRightLayout.AddChild(missingSetting); break; } } else // the setting we think we are adding is not in the config.ini it may have been depricated { TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName)); settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor; settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y); leftToRightLayout.AddChild(settingName); leftToRightLayout.BackgroundColor = RGBA_Bytes.Red; } return leftToRightLayout; } private void SaveSetting(string slicerConfigName, string value) { //Hacky solution prevents saves when no printer is loaded if (PrinterCommunication.Instance.ActivePrinter != null) { SliceSettingsLayerSelector.Instance.SaveSetting(slicerConfigName, value); } } public override void OnDraw(Graphics2D graphics2D) { base.OnDraw(graphics2D); } } }