private int extruderIndex; //For multiple materials public PresetSelectorWidget(string label, RGBA_Bytes accentColor, NamedSettingsLayers layerType, int extruderIndex) : base(FlowDirection.TopToBottom) { this.extruderIndex = extruderIndex; this.layerType = layerType; this.HAnchor = HAnchor.ParentLeftRight; this.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight; this.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; GuiWidget accentBar = new GuiWidget(7, 5) { BackgroundColor = accentColor, HAnchor = HAnchor.ParentLeftRight }; TextWidget labelText = new TextWidget(label.Localize().ToUpper()) { TextColor = ActiveTheme.Instance.PrimaryTextColor, HAnchor = Agg.UI.HAnchor.ParentCenter, Margin = new BorderDouble(0, 3, 0, 6) }; this.AddChild(labelText); this.AddChild(GetPulldownContainer()); this.AddChild(new VerticalSpacer()); this.AddChild(accentBar); }
public PresetSelectorWidget(PrinterConfig printer, string label, Color accentColor, NamedSettingsLayers layerType, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.layerType = layerType; this.printer = printer; this.Name = label; this.theme = theme; this.HAnchor = HAnchor.Stretch; this.VAnchor = VAnchor.Fit; this.BackgroundColor = theme.MinimalShade; this.Padding = theme.DefaultContainerPadding; // Section Label this.AddChild(new TextWidget(label, pointSize: theme.DefaultFontSize, textColor: theme.TextColor) { HAnchor = HAnchor.Left, Margin = new BorderDouble(0) }); pullDownContainer = new GuiWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Border = new BorderDouble(left: 3), BorderColor = accentColor, Margin = new BorderDouble(top: 6), Padding = new BorderDouble(left: (accentColor != Color.Transparent) ? 6 : 0) }; pullDownContainer.AddChild(this.GetPulldownContainer()); this.AddChild(pullDownContainer); // Register listeners printer.Settings.MaterialPresetChanged += ActiveSliceSettings_MaterialPresetChanged; printer.Settings.SettingChanged += Printer_SettingChanged; }
/// <summary> /// Returns whether or not the setting is overridden by the active layer /// </summary> public bool SettingExistsInLayer(string sliceSetting, NamedSettingsLayers layer) { switch (layer) { case NamedSettingsLayers.Quality: return(QualityLayer?.ContainsKey(sliceSetting) == true); case NamedSettingsLayers.Material: return(MaterialLayer?.ContainsKey(sliceSetting) == true); case NamedSettingsLayers.User: return(UserLayer?.ContainsKey(sliceSetting) == true); default: return(false); } }
private int extruderIndex; //For multiple materials public PresetSelectorWidget(string label, RGBA_Bytes accentColor, NamedSettingsLayers layerType, int extruderIndex) : base(FlowDirection.TopToBottom) { Name = label; ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) => { StringEventArgs stringEvent = e as StringEventArgs; if (stringEvent != null && stringEvent.Data == SettingsKey.layer_name) { RebuildDropDownList(); } }, ref unregisterEvents); this.extruderIndex = extruderIndex; this.layerType = layerType; this.HAnchor = HAnchor.ParentLeftRight; this.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight; this.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; GuiWidget accentBar = new GuiWidget(7, 5) { BackgroundColor = accentColor, HAnchor = HAnchor.ParentLeftRight }; TextWidget labelText = new TextWidget(label.Localize().ToUpper()) { TextColor = ActiveTheme.Instance.PrimaryTextColor, HAnchor = Agg.UI.HAnchor.ParentCenter, Margin = new BorderDouble(0, 3, 0, 6) }; this.AddChild(labelText); pullDownContainer = new GuiWidget() { HAnchor = HAnchor.ParentLeftRight, VAnchor = VAnchor.FitToChildren }; pullDownContainer.AddChild(GetPulldownContainer()); this.AddChild(pullDownContainer); this.AddChild(new VerticalSpacer()); this.AddChild(accentBar); }
public PresetSelectorWidget(PrinterConfig printer, string label, Color accentColor, NamedSettingsLayers layerType, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.layerType = layerType; this.printer = printer; this.Name = label; this.theme = theme; this.HAnchor = HAnchor.Stretch; this.VAnchor = VAnchor.Fit; this.BackgroundColor = theme.MinimalShade; this.Padding = theme.DefaultContainerPadding; // Section Label this.AddChild(new TextWidget(label, pointSize: theme.DefaultFontSize, textColor: theme.Colors.PrimaryTextColor) { HAnchor = HAnchor.Left, Margin = new BorderDouble(0) }); pullDownContainer = new GuiWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Border = new BorderDouble(left: 3), BorderColor = accentColor, Margin = new BorderDouble(top: 6), Padding = new BorderDouble(left: (accentColor != Color.Transparent) ? 6 : 0) }; pullDownContainer.AddChild(this.GetPulldownContainer()); this.AddChild(pullDownContainer); ActiveSliceSettings.MaterialPresetChanged += ActiveSliceSettings_MaterialPresetChanged; ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) => { if (e is StringEventArgs stringEvent && (stringEvent.Data == SettingsKey.default_material_presets || stringEvent.Data == SettingsKey.layer_name)) { RebuildDropDownList(); } }, ref unregisterEvents); }
private int extruderIndex; //For multiple materials public PresetSelectorWidget(string label, RGBA_Bytes accentColor, NamedSettingsLayers layerType, int extruderIndex) : base(FlowDirection.TopToBottom) { SliceSettingsWidget.SettingChanged.RegisterEvent((s, e) => { StringEventArgs stringEvent = e as StringEventArgs; if (stringEvent != null && stringEvent.Data == SettingsKey.layer_name) { RebuildDropDownList(); } }, ref unregisterEvents); this.extruderIndex = extruderIndex; this.layerType = layerType; this.HAnchor = HAnchor.ParentLeftRight; this.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight; this.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; GuiWidget accentBar = new GuiWidget(7, 5) { BackgroundColor = accentColor, HAnchor = HAnchor.ParentLeftRight }; TextWidget labelText = new TextWidget(label.Localize().ToUpper()) { TextColor = ActiveTheme.Instance.PrimaryTextColor, HAnchor = Agg.UI.HAnchor.ParentCenter, Margin = new BorderDouble(0, 3, 0, 6) }; this.AddChild(labelText); pullDownContainer = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren); pullDownContainer.AddChild(GetPulldownContainer()); this.AddChild(pullDownContainer); this.AddChild(new VerticalSpacer()); this.AddChild(accentBar); }
/// <summary> /// Returns whether or not the setting is overridden by the active layer /// </summary> public bool SettingExistsInLayer(string sliceSetting, NamedSettingsLayers layer) { if (layeredProfile == null) { return(false); } switch (layer) { case NamedSettingsLayers.Quality: return(layeredProfile?.QualityLayer?.ContainsKey(sliceSetting) == true); case NamedSettingsLayers.Material: return(layeredProfile?.MaterialLayer?.ContainsKey(sliceSetting) == true); case NamedSettingsLayers.User: return(layeredProfile?.UserLayer?.ContainsKey(sliceSetting) == true); default: return(false); } }
/// <summary> /// Returns whether or not the setting is overridden by the active layer /// </summary> public bool SettingExistsInLayer(string sliceSetting, NamedSettingsLayers layer) { if (layeredProfile == null) { return false; } switch (layer) { case NamedSettingsLayers.Quality: return layeredProfile?.QualityLayer?.ContainsKey(sliceSetting) == true; case NamedSettingsLayers.Material: return layeredProfile?.MaterialLayer?.ContainsKey(sliceSetting) == true; case NamedSettingsLayers.User: return layeredProfile?.UserLayer?.ContainsKey(sliceSetting) == true; default: return false; } }
public SettingsContext(PrinterConfig printer, IEnumerable <PrinterSettingsLayer> layerCascade, NamedSettingsLayers viewFilter) { this.printer = printer; this.layerCascade = layerCascade; this.ViewFilter = viewFilter; // When editing presets, LayerCascade contains a filtered list of settings layers. If the list is null we're in the primarySettingsView this.IsPrimarySettingsView = layerCascade == null; // The last layer of the layerFilters is the target persistence this.persistenceLayer = layerCascade?.First() ?? printer.Settings.UserLayer; }
public SliceSettingsWidget(List<PrinterSettingsLayer> layerCascade = null, NamedSettingsLayers viewFilter = NamedSettingsLayers.All) { this.layerCascade = layerCascade; this.viewFilter = viewFilter; // The last layer of the layerFilters is the target persistence layer persistenceLayer = layerCascade?.First() ?? ActiveSliceSettings.Instance.UserLayer; textImageButtonFactory = new TextImageButtonFactory(); textImageButtonFactory.normalFillColor = RGBA_Bytes.Transparent; textImageButtonFactory.FixedHeight = 15 * GuiWidget.DeviceScale; textImageButtonFactory.fontSize = 8; textImageButtonFactory.borderWidth = 1; textImageButtonFactory.normalBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200); textImageButtonFactory.hoverBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200); this.textImageButtonFactory.disabledTextColor = RGBA_Bytes.Gray; this.textImageButtonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor; this.textImageButtonFactory.normalTextColor = ActiveTheme.Instance.SecondaryTextColor; this.textImageButtonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor; buttonFactory.FixedHeight = 20 * GuiWidget.DeviceScale; buttonFactory.fontSize = 10; buttonFactory.normalFillColor = RGBA_Bytes.White; buttonFactory.normalTextColor = RGBA_Bytes.DarkGray; 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() { HAnchor = HAnchor.ParentLeftRight, BackgroundColor = ActiveTheme.Instance.TransparentDarkOverlay, Padding = new BorderDouble(8, 12, 8, 8) }; pageTopToBottomLayout.AddChild(settingsControlBar); noConnectionMessageContainer = new AltGroupBox(new TextWidget("No Printer Selected".Localize(), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor)); noConnectionMessageContainer.Margin = new BorderDouble(top: 10); noConnectionMessageContainer.BorderColor = ActiveTheme.Instance.PrimaryTextColor; noConnectionMessageContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight; noConnectionMessageContainer.Height = 90; string noConnectionString = "No printer is currently selected. Please select a printer to edit slice settings.".Localize(); noConnectionString += "\n\n" + "NOTE: You need to select a printer, but do not need to connect to it.".Localize(); TextWidget noConnectionMessage = new TextWidget(noConnectionString, pointSize: 10); noConnectionMessage.Margin = new BorderDouble(5); noConnectionMessage.TextColor = ActiveTheme.Instance.PrimaryTextColor; noConnectionMessage.VAnchor = VAnchor.ParentCenter; noConnectionMessageContainer.AddChild(noConnectionMessage); pageTopToBottomLayout.AddChild(noConnectionMessageContainer); topCategoryTabs = new TabControl(); topCategoryTabs.TabBar.BorderColor = ActiveTheme.Instance.PrimaryTextColor; topCategoryTabs.Margin = new BorderDouble(top: 8); topCategoryTabs.AnchorAll(); sliceSettingsDetailControl = new SliceSettingsDetailControl(layerCascade); List<TabBar> sideTabBarsListForLayout = new List<TabBar>(); for (int topCategoryIndex = 0; topCategoryIndex < SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList.Count; topCategoryIndex++) { OrganizerCategory category = SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList[topCategoryIndex]; string categoryPageLabel = category.Name.Localize(); TabPage categoryPage = new TabPage(categoryPageLabel); SimpleTextTabWidget textTabWidget = new SimpleTextTabWidget(categoryPage, category.Name + " Tab", 16, ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes()); categoryPage.AnchorAll(); topCategoryTabs.AddTab(textTabWidget); TabControl sideTabs = CreateSideTabsAndPages(category); sideTabBarsListForLayout.Add(sideTabs.TabBar); categoryPage.AddChild(sideTabs); } topCategoryTabs.TabBar.AddChild(new HorizontalSpacer()); topCategoryTabs.TabBar.AddChild(sliceSettingsDetailControl); if (sliceSettingsDetailControl.SelectedValue == "Advanced" && ActiveSliceSettings.Instance.Helpers.ActiveSliceEngineType() == SlicingEngineTypes.Slic3r) { TabPage extraSettingsPage = new TabPage("Other"); SimpleTextTabWidget extraSettingsTextTabWidget = new SimpleTextTabWidget(extraSettingsPage, "Other Tab", 16, ActiveTheme.Instance.TabLabelSelected, new RGBA_Bytes(), ActiveTheme.Instance.TabLabelUnselected, new RGBA_Bytes()); extraSettingsPage.AnchorAll(); int count; TabControl extraSettingsSideTabs = CreateExtraSettingsSideTabsAndPages(topCategoryTabs, out count); if (count > 0) { topCategoryTabs.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); } // check if there is only one left side tab. If so hide the left tabs and expand the content. foreach(var tabList in sideTabBarsListForLayout) { if(tabList.CountVisibleChildren() == 1) { tabList.MinimumSize = new Vector2(0, 0); tabList.Width = 0; } } pageTopToBottomLayout.AddChild(topCategoryTabs); AddHandlers(); SetVisibleControls(); // Make sure we are on the right tab when we create this view { string settingsName = "SliceSettingsWidget_CurrentTab"; string selectedTab = UserSettings.Instance.get(settingsName); topCategoryTabs.SelectTab(selectedTab); topCategoryTabs.TabBar.TabIndexChanged += (object sender, EventArgs e) => { string selectedTabName = topCategoryTabs.TabBar.SelectedTabName; if (!string.IsNullOrEmpty(selectedTabName)) { if (layerCascade == null) { UserSettings.Instance.set(settingsName, selectedTabName); } } }; } this.AnchorAll(); }
private static GuiWidget CreateSettingInfoUIControls(SliceSettingData settingData, List<PrinterSettingsLayer> layerCascade, PrinterSettingsLayer persistenceLayer, NamedSettingsLayers viewFilter, int extruderIndex, out bool addControl, ref int tabIndexForItem) { addControl = true; GuiWidget container = new GuiWidget(); string sliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade); GuiWidget nameArea = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter); var dataArea = new FlowLayoutWidget(); GuiWidget unitsArea = new GuiWidget(HAnchor.AbsolutePosition, VAnchor.FitToChildren | VAnchor.ParentCenter) { Width = settingData.ShowAsOverride ? 50 * GuiWidget.DeviceScale : 5, }; GuiWidget restoreArea = new GuiWidget(HAnchor.AbsolutePosition, VAnchor.FitToChildren | VAnchor.ParentCenter) { Width = settingData.ShowAsOverride ? 30 * GuiWidget.DeviceScale : 0, }; var settingsRow = new SettingsRow(layerCascade) { SettingsKey = settingData.SlicerConfigName, SettingsValue = sliceSettingValue, }; settingsRow.AddChild(nameArea); settingsRow.AddChild(dataArea); settingsRow.AddChild(unitsArea); settingsRow.AddChild(restoreArea); settingsRow.Name = settingData.SlicerConfigName + " Edit Field"; if (!PrinterSettings.KnownSettings.Contains(settingData.SlicerConfigName)) { // the setting we think we are adding is not in the known settings it may have been deprecated TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in known settings", settingData.SlicerConfigName)); settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor; //settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y); nameArea.AddChild(settingName); nameArea.BackgroundColor = RGBA_Bytes.Red; } else { int intEditWidth = (int)(60 * GuiWidget.DeviceScale + .5); int doubleEditWidth = (int)(60 * GuiWidget.DeviceScale + .5); int vectorXYEditWidth = (int)(60 * GuiWidget.DeviceScale + .5); int multiLineEditHeight = (int)(120 * GuiWidget.DeviceScale + .5); if (settingData.DataEditType != SliceSettingData.DataEditTypes.MULTI_LINE_TEXT) { var nameHolder = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter) { Padding = new BorderDouble(0, 0, 5, 0), HAnchor = HAnchor.ParentLeftRight, }; nameHolder.AddChild(new WrappedTextWidget(settingData.PresentationName.Localize(), pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)); nameArea.AddChild(nameHolder); } switch (settingData.DataEditType) { case SliceSettingData.DataEditTypes.INT: { FlowLayoutWidget content = new FlowLayoutWidget(); int currentValue; int.TryParse(sliceSettingValue, out currentValue); var intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true, Name = settingData.PresentationName + " Edit", }; intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; content.AddChild(intEditWidget); unitsArea.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, intEditWidget.ActuallNumberEdit.InternalTextEditWidget, layerCascade)); } else { dataArea.AddChild(content); } settingsRow.ValueChanged = (text) => { intEditWidget.Text = text; }; } break; case SliceSettingData.DataEditTypes.DOUBLE: { double currentValue; double.TryParse(sliceSettingValue, out currentValue); var doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(doubleEditWidget); unitsArea.AddChild(GetExtraSettingsWidget(settingData)); settingsRow.ValueChanged = (text) => { double currentValue2 = 0; double.TryParse(text, out currentValue2); doubleEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case SliceSettingData.DataEditTypes.POSITIVE_DOUBLE: { const string multiValuesAreDiffernt = "-"; FlowLayoutWidget content = new FlowLayoutWidget(); var doubleEditWidget = new MHNumberEdit(0, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, Name = settingData.PresentationName + " Textbox", SelectAllOnFocus = true }; double currentValue; bool ChangesMultipleOtherSettings = settingData.SetSettingsOnChange.Count > 0; if (ChangesMultipleOtherSettings) { bool allTheSame = true; string setting = GetActiveValue(settingData.SetSettingsOnChange[0], layerCascade); for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++) { string nextSetting = GetActiveValue(settingData.SetSettingsOnChange[i], layerCascade); if (setting != nextSetting) { allTheSame = false; break; } } if (allTheSame && setting.EndsWith("mm")) { double.TryParse(setting.Substring(0, setting.Length - 2), out currentValue); doubleEditWidget.ActuallNumberEdit.Value = currentValue; } else { doubleEditWidget.ActuallNumberEdit.InternalNumberEdit.Text = multiValuesAreDiffernt; } } else // just set the setting normally { double.TryParse(sliceSettingValue, out currentValue); doubleEditWidget.ActuallNumberEdit.Value = currentValue; } doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget.MarkAsStartingState(); doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { NumberEdit numberEdit = (NumberEdit)sender; // If this setting sets other settings, then do that. if (ChangesMultipleOtherSettings && numberEdit.Text != multiValuesAreDiffernt) { foreach (string setting in settingData.SetSettingsOnChange) { ActiveSliceSettings.Instance.SetValue(setting, numberEdit.Value.ToString() + "mm", persistenceLayer); } } // also always save to the local setting ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, numberEdit.Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; content.AddChild(doubleEditWidget); unitsArea.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget, layerCascade)); } else { dataArea.AddChild(content); } settingsRow.ValueChanged = (text) => { double currentValue2 = 0; double.TryParse(text, out currentValue2); doubleEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case SliceSettingData.DataEditTypes.OFFSET: { double currentValue; double.TryParse(sliceSettingValue, out currentValue); var doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(doubleEditWidget); unitsArea.AddChild(GetExtraSettingsWidget(settingData)); settingsRow.ValueChanged = (text) => { double currentValue2; double.TryParse(text, out currentValue2); doubleEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case SliceSettingData.DataEditTypes.DOUBLE_OR_PERCENT: { FlowLayoutWidget content = new FlowLayoutWidget(); var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { var textEditWidget = (TextEditWidget)sender; string text = textEditWidget.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; ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, textEditWidget.Text, persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) => { // select everything up to the % (if present) InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender; int percentIndex = textEditWidget.Text.IndexOf("%"); if (percentIndex != -1) { textEditWidget.SetSelection(0, percentIndex - 1); } }; content.AddChild(stringEdit); unitsArea.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget, layerCascade)); } else { dataArea.AddChild(content); } settingsRow.ValueChanged = (text) => { stringEdit.Text = text; }; } break; case SliceSettingData.DataEditTypes.INT_OR_MM: { FlowLayoutWidget content = new FlowLayoutWidget(); var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; string startingText = stringEdit.Text; stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { TextEditWidget textEditWidget = (TextEditWidget)sender; // only validate when we lose focus if (!textEditWidget.ContainsFocus) { string text = textEditWidget.Text; text = text.Trim(); bool isMm = text.Contains("mm"); if (isMm) { text = text.Substring(0, text.IndexOf("mm")); } double result; double.TryParse(text, out result); text = result.ToString(); if (isMm) { text += "mm"; } else { result = (int)result; text = result.ToString(); } textEditWidget.Text = text; startingText = stringEdit.Text; } ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, textEditWidget.Text, persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); // make sure we are still looking for the final validation before saving. if (textEditWidget.ContainsFocus) { UiThread.RunOnIdle(() => { string currentText = textEditWidget.Text; int cursorIndex = textEditWidget.InternalTextEditWidget.CharIndexToInsertBefore; textEditWidget.Text = startingText; textEditWidget.InternalTextEditWidget.MarkAsStartingState(); textEditWidget.Text = currentText; textEditWidget.InternalTextEditWidget.CharIndexToInsertBefore = cursorIndex; }); } }; stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) => { // select everything up to the mm (if present) InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender; int mMIndex = textEditWidget.Text.IndexOf("mm"); if (mMIndex != -1) { textEditWidget.SetSelection(0, mMIndex - 1); } }; content.AddChild(stringEdit); unitsArea.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget, layerCascade)); } else { dataArea.AddChild(content); } settingsRow.ValueChanged = (text) => { stringEdit.Text = text; }; } break; case SliceSettingData.DataEditTypes.CHECK_BOX: { var checkBoxWidget = new CheckBox("") { Name = settingData.PresentationName + " Checkbox", ToolTipText = settingData.HelpText, VAnchor = Agg.UI.VAnchor.ParentBottom, TextColor = ActiveTheme.Instance.PrimaryTextColor, Checked = sliceSettingValue == "1" }; checkBoxWidget.Click += (sender, e) => { bool isChecked = ((CheckBox)sender).Checked; ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, isChecked ? "1" : "0", persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(checkBoxWidget); settingsRow.ValueChanged = (text) => { checkBoxWidget.Checked = text == "1"; }; } break; case SliceSettingData.DataEditTypes.STRING: { var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: settingData.ShowAsOverride ? 120 : 200, tabIndex: tabIndexForItem++) { Name = settingData.PresentationName + " Edit", }; stringEdit.ToolTipText = settingData.HelpText; stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((TextEditWidget)sender).Text, persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(stringEdit); settingsRow.ValueChanged = (text) => { stringEdit.Text = text; }; } break; case SliceSettingData.DataEditTypes.MULTI_LINE_TEXT: { string convertedNewLines = sliceSettingValue.Replace("\\n", "\n"); var stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++, typeFace: ApplicationController.MonoSpacedTypeFace) { HAnchor = HAnchor.ParentLeftRight, }; stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n"), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; nameArea.HAnchor = HAnchor.AbsolutePosition; nameArea.Width = 0; dataArea.AddChild(stringEdit); dataArea.HAnchor = HAnchor.ParentLeftRight; settingsRow.ValueChanged = (text) => { stringEdit.Text = text.Replace("\\n", "\n"); }; } break; case SliceSettingData.DataEditTypes.COM_PORT: { #if __ANDROID__ addControl = false; #endif // The COM_PORT control is unique in its approach to the SlicerConfigName. It uses "com_port" settings name to // bind to a context that will place it in the SliceSetting view but it binds its values to a machine // specific dictionary key that is not exposed in the UI. At runtime we lookup and store to '<machinename>_com_port' // ensuring that a single printer can be shared across different devices and we'll select the correct com port in each case var selectableOptions = new DropDownList("None", maxHeight: 200) { ToolTipText = settingData.HelpText, Margin = new BorderDouble(), Name = "Com Port Dropdown" }; selectableOptions.Click += (s, e) => { AddComMenuItems(settingData, persistenceLayer, settingsRow, selectableOptions); }; AddComMenuItems(settingData, persistenceLayer, settingsRow, selectableOptions); dataArea.AddChild(selectableOptions); settingsRow.ValueChanged = (text) => { // Lookup the machine specific comport value rather than the passed in text value selectableOptions.SelectedLabel = ActiveSliceSettings.Instance.Helpers.ComPort(); }; } break; case SliceSettingData.DataEditTypes.LIST: { var selectableOptions = new DropDownList("None", maxHeight: 200) { ToolTipText = settingData.HelpText, Margin = new BorderDouble() }; foreach (string listItem in settingData.ExtraSettings.Split(',')) { MenuItem newItem = selectableOptions.AddItem(listItem); if (newItem.Text == sliceSettingValue) { selectableOptions.SelectedLabel = sliceSettingValue; } newItem.Selected += (sender, e) => { MenuItem menuItem = ((MenuItem)sender); ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, menuItem.Text, persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; } dataArea.AddChild(selectableOptions); settingsRow.ValueChanged = (text) => { selectableOptions.SelectedLabel = text; }; } break; case SliceSettingData.DataEditTypes.HARDWARE_PRESENT: { var checkBoxWidget = new CheckBox("") { Name = settingData.PresentationName + " Checkbox", ToolTipText = settingData.HelpText, VAnchor = Agg.UI.VAnchor.ParentBottom, TextColor = ActiveTheme.Instance.PrimaryTextColor, Checked = sliceSettingValue == "1" }; checkBoxWidget.Click += (sender, e) => { bool isChecked = ((CheckBox)sender).Checked; ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, isChecked ? "1" : "0", persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(checkBoxWidget); settingsRow.ValueChanged = (text) => { checkBoxWidget.Checked = text == "1"; }; } break; case SliceSettingData.DataEditTypes.VECTOR2: { string[] xyValueStrings = sliceSettingValue.Split(','); if (xyValueStrings.Length != 2) { xyValueStrings = new string[] { "0", "0" }; } double currentXValue; double.TryParse(xyValueStrings[0], out currentXValue); var xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; double currentYValue; double.TryParse(xyValueStrings[1], out currentYValue); var yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true, Margin = new BorderDouble(20, 0, 0, 0), }; xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(xEditWidget); dataArea.AddChild(new TextWidget("X", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor) { VAnchor = VAnchor.ParentCenter, Margin = new BorderDouble(5, 0), }); yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(yEditWidget); var yLabel = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter) { Padding = new BorderDouble(5, 0), HAnchor = HAnchor.ParentLeftRight, }; yLabel.AddChild(new WrappedTextWidget("Y", pointSize: 9, textColor: ActiveTheme.Instance.PrimaryTextColor)); unitsArea.AddChild(yLabel); settingsRow.ValueChanged = (text) => { double currentValue2; string[] xyValueStrings2 = text.Split(','); if (xyValueStrings2.Length != 2) { xyValueStrings2 = new string[] { "0", "0" }; } double.TryParse(xyValueStrings2[0], out currentValue2); xEditWidget.ActuallNumberEdit.Value = currentValue2; double.TryParse(xyValueStrings2[1], out currentValue2); yEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case SliceSettingData.DataEditTypes.OFFSET2: { Vector2 offset = ActiveSliceSettings.Instance.Helpers.ExtruderOffset(extruderIndex); var xEditWidget = new MHNumberEdit(offset.x, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true, }; var yEditWidget = new MHNumberEdit(offset.y, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true, Margin = new BorderDouble(20, 0, 0, 0), }; xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { int extruderIndexLocal = extruderIndex; SaveCommaSeparatedIndexSetting(extruderIndexLocal, layerCascade, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(xEditWidget); dataArea.AddChild(new TextWidget("X", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor) { VAnchor = VAnchor.ParentCenter, Margin = new BorderDouble(5, 0), }); yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { int extruderIndexLocal = extruderIndex; SaveCommaSeparatedIndexSetting(extruderIndexLocal, layerCascade, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; dataArea.AddChild(yEditWidget); var yLabel = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter) { Padding = new BorderDouble(5, 0), HAnchor = HAnchor.ParentLeftRight, }; yLabel.AddChild(new WrappedTextWidget("Y", pointSize: 9, textColor: ActiveTheme.Instance.PrimaryTextColor)); unitsArea.AddChild(yLabel); settingsRow.ValueChanged = (text) => { Vector2 offset2 = ActiveSliceSettings.Instance.Helpers.ExtruderOffset(extruderIndex); xEditWidget.ActuallNumberEdit.Value = offset2.x; yEditWidget.ActuallNumberEdit.Value = offset2.y; }; } break; default: var missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString())) { TextColor = ActiveTheme.Instance.PrimaryTextColor, BackgroundColor = RGBA_Bytes.Red }; dataArea.AddChild(missingSetting); break; } } container.HAnchor = HAnchor.ParentLeftRight; container.VAnchor = VAnchor.FitToChildren; Button restoreButton = null; if (settingData.ShowAsOverride) { restoreButton = new Button(new ButtonViewStates(new ImageWidget(restoreNormal), new ImageWidget(restoreHover), new ImageWidget(restorePressed), new ImageWidget(restoreNormal))) { Name = "Restore " + settingData.SlicerConfigName, VAnchor = VAnchor.ParentCenter, Margin = new BorderDouble(0, 0, 5, 0), ToolTipText = "Restore Default".Localize() }; restoreButton.Click += (sender, e) => { // Revert the user override if (persistenceLayer == null) { ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName); } else { ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName, persistenceLayer); } settingsRow.RefreshValue(layerCascade); OnSettingsChanged(settingData); }; restoreArea.AddChild(restoreButton); } container.AddChild(settingsRow); // Define the UpdateStyle implementation settingsRow.UpdateStyle = () => { if (persistenceLayer.ContainsKey(settingData.SlicerConfigName)) { switch (viewFilter) { case NamedSettingsLayers.All: if (settingData.ShowAsOverride) { settingsRow.BackgroundColor = userSettingBackgroundColor; } break; case NamedSettingsLayers.Material: settingsRow.BackgroundColor = materialSettingBackgroundColor; break; case NamedSettingsLayers.Quality: settingsRow.BackgroundColor = qualitySettingBackgroundColor; break; } if(restoreButton != null) restoreButton.Visible = true; } else if (layerCascade == null) { if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Material)) { settingsRow.BackgroundColor = materialSettingBackgroundColor; } else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Quality)) { settingsRow.BackgroundColor = qualitySettingBackgroundColor; } else { settingsRow.BackgroundColor = RGBA_Bytes.Transparent; } if (restoreButton != null) restoreButton.Visible = false; } else { if (restoreButton != null) restoreButton.Visible = false; settingsRow.BackgroundColor = RGBA_Bytes.Transparent; } }; // Invoke the UpdateStyle implementation settingsRow.UpdateStyle(); return container; }