private CalibrationControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.printer = printer; // add in the controls for configuring auto leveling { SettingsRow settingsRow; this.AddChild(settingsRow = new SettingsRow( "Printer Calibration".Localize(), null, theme)); // run leveling button var runWizardButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, Name = "Run Leveling Button", ToolTipText = "Run Calibration".Localize() }; runWizardButton.Click += (s, e) => { UiThread.RunOnIdle(() => { DialogWindow.Show(new PrinterCalibrationWizard(printer, theme)); }); }; settingsRow.AddChild(runWizardButton); // only show the switch if leveling can be turned off (it can't if it is required). if (!printer.Settings.GetValue <bool>(SettingsKey.print_leveling_required_to_print)) { // put in the switch printLevelingSwitch = new RoundedToggleSwitch(theme) { VAnchor = VAnchor.Center, Margin = new BorderDouble(left: 16), Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled) }; printLevelingSwitch.CheckedStateChanged += (sender, e) => { printer.Settings.Helpers.DoPrintLeveling(printLevelingSwitch.Checked); }; // TODO: Why is this listener conditional? If the leveling changes somehow, shouldn't we be updated the UI to reflect that? // Register listeners printer.Settings.PrintLevelingEnabledChanged += Settings_PrintLevelingEnabledChanged; settingsRow.AddChild(printLevelingSwitch); } } // Register listeners printer.Connection.CommunicationStateChanged += PrinterStatusChanged; SetVisibleControls(); }
public NozzleOffsetCalibrationResultsPage(ISetupWizard setupWizard, PrinterConfig printer, double xOffset, double yOffset) : base(setupWizard) { this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); this.HeaderText = "Nozzle Offset Calibration".Localize() + ":"; this.Name = "Nozzle Offset Calibration Wizard"; this.CreateTextField("Congratulations, your nozzle offsets have been collected and are ready to be saved. Click next to save and finish the wizard".Localize()); var row = new SettingsRow( "X Offset".Localize(), null, theme, AggContext.StaticData.LoadIcon("probing_32x32.png", 16, 16, theme.InvertIcons)); contentRow.AddChild(row); row.AddChild(new TextWidget(xOffset.ToString("0.###") + "mm", pointSize: theme.DefaultFontSize, textColor: theme.TextColor) { VAnchor = VAnchor.Center, Margin = new BorderDouble(right: 10) }); row = new SettingsRow( "Y Offset".Localize(), null, theme, AggContext.StaticData.LoadIcon("probing_32x32.png", 16, 16, theme.InvertIcons)); contentRow.AddChild(row); row.AddChild(new TextWidget(yOffset.ToString("0.###") + "mm", pointSize: theme.DefaultFontSize, textColor: theme.TextColor) { VAnchor = VAnchor.Center, Margin = new BorderDouble(right: 10) }); this.NextButton.Visible = false; var nextButton = theme.CreateDialogButton("Finish".Localize()); nextButton.Name = "FinishCalibration"; nextButton.Click += (s, e) => { // TODO: removed fixed index var hotendOffset = printer.Settings.Helpers.ExtruderOffset(1); hotendOffset.X += xOffset; hotendOffset.Y += yOffset; printer.Settings.Helpers.SetExtruderOffset(1, hotendOffset); this.DialogWindow.CloseOnIdle(); }; theme.ApplyPrimaryActionStyle(nextButton); this.AddPageAction(nextButton); }
private CalibrationControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.printer = printer; // add in the controls for configuring auto leveling { SettingsRow calibrationRow; this.AddChild(calibrationRow = new SettingsRow( "Printer Calibration".Localize(), null, theme)); var runWizardButton = new IconButton(StaticData.Instance.LoadIcon("compass.png", 16, 16, theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, Name = "Printer Calibration Button", ToolTipText = "Run Calibration".Localize() }; runWizardButton.Click += (s, e) => { UiThread.RunOnIdle(() => { DialogWindow.Show(new PrinterCalibrationWizard(printer, theme)); }); }; calibrationRow.AddChild(runWizardButton); } // Register listeners printer.Connection.CommunicationStateChanged += PrinterStatusChanged; SetVisibleControls(); }
private AdjustmentControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { double sliderWidth = 300 * GuiWidget.DeviceScale; double sliderThumbWidth = 10 * GuiWidget.DeviceScale; this.printer = printer; SettingsRow settingsRow; { this.AddChild(settingsRow = new SettingsRow( "Speed Multiplier".Localize(), null, theme)); // Remove the HorizontalSpacer settingsRow.Children.Last().Close(); feedRateRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, theme, minFeedRateRatio, maxFeedRateRatio) { Name = "Feed Rate Slider", Margin = new BorderDouble(5, 0), Value = FeedRateMultiplyerStream.FeedRateRatio, HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center, TotalWidthInPixels = sliderWidth, }; theme.ApplySliderStyle(feedRateRatioSlider); feedRateRatioSlider.ValueChanged += (sender, e) => { feedRateValue.ActuallNumberEdit.Value = Math.Round(feedRateRatioSlider.Value, 2); }; feedRateRatioSlider.SliderReleased += (s, e) => { // Update state for runtime use FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.feedrate_ratio, FeedRateMultiplyerStream.FeedRateRatio.ToString()); }; settingsRow.AddChild(feedRateRatioSlider); feedRateValue = new MHNumberEdit(Math.Round(FeedRateMultiplyerStream.FeedRateRatio, 2), theme, allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale) { Name = "Feed Rate NumberEdit", SelectAllOnFocus = true, Margin = new BorderDouble(0, 0, 5, 0), VAnchor = VAnchor.Center | VAnchor.Fit, Padding = 0 }; feedRateValue.ActuallNumberEdit.EditComplete += (sender, e) => { feedRateRatioSlider.Value = feedRateValue.ActuallNumberEdit.Value; // Update state for runtime use FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.feedrate_ratio, FeedRateMultiplyerStream.FeedRateRatio.ToString()); }; settingsRow.AddChild(feedRateValue); } { this.AddChild(settingsRow = new SettingsRow( "Extrusion Multiplier".Localize(), null, theme)); // Remove the HorizontalSpacer settingsRow.Children.Last().Close(); extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, theme, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal) { Name = "Extrusion Multiplier Slider", TotalWidthInPixels = sliderWidth, HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center, Margin = new BorderDouble(5, 0), Value = ExtrusionMultiplyerStream.ExtrusionRatio }; theme.ApplySliderStyle(extrusionRatioSlider); extrusionRatioSlider.ValueChanged += (sender, e) => { extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatioSlider.Value, 2); }; extrusionRatioSlider.SliderReleased += (s, e) => { // Update state for runtime use ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.extrusion_ratio, ExtrusionMultiplyerStream.ExtrusionRatio.ToString()); }; settingsRow.AddChild(extrusionRatioSlider); extrusionValue = new MHNumberEdit(Math.Round(ExtrusionMultiplyerStream.ExtrusionRatio, 2), theme, allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale) { Name = "Extrusion Multiplier NumberEdit", SelectAllOnFocus = true, Margin = new BorderDouble(0, 0, 5, 0), VAnchor = VAnchor.Center | VAnchor.Fit, Padding = 0 }; extrusionValue.ActuallNumberEdit.EditComplete += (sender, e) => { extrusionRatioSlider.Value = extrusionValue.ActuallNumberEdit.Value; // Update state for runtime use ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.extrusion_ratio, ExtrusionMultiplyerStream.ExtrusionRatio.ToString()); }; settingsRow.AddChild(extrusionValue); } // Register listeners printer.Settings.SettingChanged += Printer_SettingChanged; }
private CalibrationControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.printer = printer; // add in the controls for configuring auto leveling { SettingsRow settingsRow; this.AddChild(settingsRow = new SettingsRow( "Print Leveling Plane".Localize(), null, theme, AggContext.StaticData.LoadIcon("leveling_32x32.png", 16, 16, theme.InvertIcons))); // run leveling button var runWizardButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, ToolTipText = "Print Leveling Wizard - Can be re-calculated anytime there seems to be a problem with initial layer consistency".Localize() }; runWizardButton.Click += (s, e) => { UiThread.RunOnIdle(() => { LevelingWizard.ShowPrintLevelWizard(printer, theme); }); }; settingsRow.AddChild(runWizardButton); // only show the switch if leveling can be turned off (it can't if it is required). if (!printer.Settings.GetValue <bool>(SettingsKey.print_leveling_required_to_print)) { // put in the switch var printLevelingSwitch = new RoundedToggleSwitch(theme) { VAnchor = VAnchor.Center, Margin = new BorderDouble(left: 16), Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled) }; printLevelingSwitch.CheckedStateChanged += (sender, e) => { printer.Settings.Helpers.DoPrintLeveling(printLevelingSwitch.Checked); }; printer.Settings.PrintLevelingEnabledChanged.RegisterEvent((sender, e) => { printLevelingSwitch.Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled); }, ref unregisterEvents); settingsRow.AddChild(printLevelingSwitch); } // add in the controls for configuring probe offset if (printer.Settings.GetValue <bool>(SettingsKey.has_z_probe) && printer.Settings.GetValue <bool>(SettingsKey.use_z_probe)) { this.AddChild(settingsRow = new SettingsRow( "Print Leveling Probe".Localize(), null, theme, AggContext.StaticData.LoadIcon("probing_32x32.png", 16, 16, theme.InvertIcons))); var runCalibrateProbeButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, ToolTipText = "Probe Calibration Wizard - needed for initial setup - normally should remain calibrated unless there are changes to hardware.".Localize() }; runCalibrateProbeButton.Click += (s, e) => { UiThread.RunOnIdle(() => { LevelingWizard.ShowProbeCalibrationWizard(printer, theme); }); }; settingsRow.BorderColor = Color.Transparent; settingsRow.AddChild(runCalibrateProbeButton); } } printer.Connection.CommunicationStateChanged.RegisterEvent(PrinterStatusChanged, ref unregisterEvents); printer.Connection.EnableChanged.RegisterEvent(PrinterStatusChanged, ref unregisterEvents); SetVisibleControls(); }
public ValidationErrorsPanel(IEnumerable <ValidationError> errors, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Absolute; this.VAnchor = VAnchor.Fit | VAnchor; this.BackgroundColor = theme.ResolveColor(theme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)); var errorImage = StaticData.Instance.LoadIcon("SettingsGroupError_16x.png", 16, 16).SetToColor(theme.TextColor); var warningImage = StaticData.Instance.LoadIcon("SettingsGroupWarning_16x.png", 16, 16).SetToColor(theme.TextColor); var infoImage = StaticData.Instance.LoadIcon("StatusInfoTip_16x.png", 16, 16); foreach (var validationError in errors.OrderByDescending(e => e.ErrorLevel)) { if (validationError.ErrorLevel == ValidationErrorLevel.Warning && UserSettings.Instance.get($"Ignore_{validationError.ID}") == "true") { continue; } string errorText, errorDetails; if (validationError is SettingsValidationError settingsValidationError) { errorText = string.Format( "{0} {1}", settingsValidationError.PresentationName, validationError.ErrorLevel == ValidationErrorLevel.Error ? "Error".Localize() : "Warning".Localize()); errorDetails = validationError.Error + "\n\n" + settingsValidationError.Location; } else { errorText = validationError.Error; errorDetails = validationError.Details ?? ""; } var row = new SettingsRow(errorText, errorDetails, theme, validationError.ErrorLevel == ValidationErrorLevel.Error ? errorImage : warningImage, fullRowSelect: true) { ArrowDirection = ArrowDirection.Left, Name = validationError.ID + " Row" }; if (validationError.FixAction is NamedAction action) { // Show fix button var button = new LinkLabel(action.Title, theme, pointSize: theme.FontSize10) { VAnchor = VAnchor.Center, Margin = new BorderDouble(right: 8), Enabled = action.IsEnabled == null || action.IsEnabled(), Name = validationError.ID + " Button" }; if (!string.IsNullOrEmpty(action.ID)) { button.Name = action.ID; } button.Click += (s, e) => { // Invoke FixAction action.Action.Invoke(); this.ClosePopup(); }; row.AddChild(button); row.ActionWidget = button; row.FullRowSelect = true; } else { // Show info indicator hinting that hover will reveal additional details row.AddChild(new IconButton(infoImage, theme) { Selectable = false }); } if (validationError.ErrorLevel == ValidationErrorLevel.Warning) { var dismissButton = theme.CreateSmallResetButton(); dismissButton.HAnchor = HAnchor.Absolute; dismissButton.Margin = new BorderDouble(right: theme.ButtonHeight / 2 - dismissButton.Width / 2); dismissButton.Name = "Dismiss " + validationError.ID; dismissButton.ToolTipText = "Dismiss".Localize(); dismissButton.Click += (sender, e) => { UserSettings.Instance.set($"Ignore_{validationError.ID}", "true"); this.ClosePopup(); }; row.AddChild(dismissButton); // Enable selection without regard to FullRowSelect dismissButton.Selectable = true; } this.AddChild(row); } }
public RenderOptionsButton(ThemeConfig theme, InteractionLayer interactionLayer) : base(theme) { this.HAnchor = HAnchor.Fit; this.VAnchor = VAnchor.Fit; this.AddChild(new IconButton(AggContext.StaticData.LoadIcon("web.png", theme.InvertIcons), theme) { Selectable = false }); this.PopupContent = () => { var menuTheme = AppContext.MenuTheme; var subPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Padding = theme.DefaultContainerPadding, BackgroundColor = menuTheme.BackgroundColor, HAnchor = HAnchor.Absolute, VAnchor = VAnchor.Fit }; subPanel.BoundsChanged += (s, e) => { Console.WriteLine(); }; foreach (var drawable in ApplicationController.Instance.DragDropData.View3DWidget.InteractionLayer.Drawables) { var row = new SettingsRow(drawable.Title, drawable.Description, theme); subPanel.AddChild(row); var toggleSwitch = new RoundedToggleSwitch(theme) { Checked = drawable.Enabled }; toggleSwitch.CheckedStateChanged += (s, e) => { drawable.Enabled = toggleSwitch.Checked; }; row.AddChild(toggleSwitch); } foreach (var drawable in ApplicationController.Instance.DragDropData.View3DWidget.InteractionLayer.ItemDrawables) { var row = new SettingsRow(drawable.Title, drawable.Description, theme); subPanel.AddChild(row); var toggleSwitch = new RoundedToggleSwitch(theme) { Checked = drawable.Enabled }; toggleSwitch.CheckedStateChanged += (s, e) => { drawable.Enabled = toggleSwitch.Checked; }; row.AddChild(toggleSwitch); } subPanel.Width = 400; return(subPanel); }; }
public ValidationErrorsPanel(IEnumerable <ValidationError> errors, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Absolute; this.VAnchor = VAnchor.Fit | VAnchor; this.BackgroundColor = theme.ResolveColor(theme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)); var errorImage = AggContext.StaticData.LoadIcon("SettingsGroupError_16x.png", 16, 16, theme.InvertIcons); var warningImage = AggContext.StaticData.LoadIcon("SettingsGroupWarning_16x.png", 16, 16, theme.InvertIcons); var infoImage = AggContext.StaticData.LoadIcon("StatusInfoTip_16x.png", 16, 16); var fixIcon = AggContext.StaticData.LoadIcon("noun_1306.png", 16, 16, theme.InvertIcons); foreach (var validationError in errors.OrderByDescending(e => e.ErrorLevel)) { if (validationError.ErrorLevel == ValidationErrorLevel.Warning && UserSettings.Instance.get($"Ignore_{validationError.ID}") == "true") { continue; } string errorText, errorDetails; var settingsValidationError = validationError as SettingsValidationError; if (settingsValidationError != null) { errorText = string.Format( "{0} {1}", settingsValidationError.PresentationName, validationError.ErrorLevel == ValidationErrorLevel.Error ? "Error".Localize() : "Warning".Localize()); errorDetails = validationError.Error; } else { errorText = validationError.Error; errorDetails = validationError.Details ?? ""; } var row = new SettingsRow(errorText, errorDetails, theme, validationError.ErrorLevel == ValidationErrorLevel.Error ? errorImage : warningImage) { ArrowDirection = ArrowDirection.Left }; if (validationError.FixAction is NamedAction action) { // Show fix button var button = new LinkLabel(action.Title, theme, pointSize: theme.FontSize10) { VAnchor = VAnchor.Center, Margin = new BorderDouble(right: 8), Enabled = action.IsEnabled == null || action.IsEnabled() }; if (!string.IsNullOrEmpty(action.ID)) { button.Name = action.ID; } button.Click += (s, e) => { // Invoke FixAction action.Action.Invoke(); // Close popup on FixAction button click if (this.Parents <PopupWidget>().FirstOrDefault() is PopupWidget popupWidget) { UiThread.RunOnIdle(popupWidget.CloseMenu); } }; row.AddChild(button); } else { // Show info indicator hinting that hover will reveal additional details var button = new IconButton(infoImage, theme) { Selectable = false }; row.AddChild(button); } if (validationError.ErrorLevel == ValidationErrorLevel.Warning) { var dismissButton = theme.CreateSmallResetButton(); dismissButton.HAnchor = HAnchor.Absolute; dismissButton.Margin = new BorderDouble(right: theme.ButtonHeight / 2 - dismissButton.Width / 2); dismissButton.Name = "Dismiss " + validationError.ID; dismissButton.ToolTipText = "Dismiss".Localize(); dismissButton.Click += (sender, e) => { UserSettings.Instance.set($"Ignore_{validationError.ID}", "true"); }; row.AddChild(dismissButton); } this.AddChild(row); } }
private FanControls(PrinterConnection printerConnection, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Stretch; this.HAnchor = HAnchor.Stretch; //Matt's test editing to add a on/off toggle switch bool fanActive = printerConnection.FanSpeed0To255 != 0; Stopwatch timeSinceLastManualSend = new Stopwatch(); var settingsRow = new SettingsRow( "Part Cooling Fan".Localize(), null, theme, fullRowSelect: true); this.AddChild(settingsRow); var container = new FlowLayoutWidget(); settingsRow.AddChild(container); settingsRow.BorderColor = Color.Transparent; fanSpeedDisplay = new EditableNumberDisplay(0, "100") { DisplayFormat = "{0:0}", Value = printerConnection.FanSpeed0To255 * 100 / 255 }; fanSpeedDisplay.ValueChanged += (sender, e) => { // limit the rate we can send this message to 2 per second so we don't get in a crazy toggle state. if (!timeSinceLastManualSend.IsRunning || timeSinceLastManualSend.ElapsedMilliseconds > 500) { timeSinceLastManualSend.Restart(); printerConnection.FanSpeed0To255 = (int)(fanSpeedDisplay.Value * 255 / 100 + .5); } }; container.AddChild(fanSpeedDisplay); container.Selectable = true; // put in % container.AddChild(new TextWidget("%", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor) { VAnchor = VAnchor.Center }); var toggleSwitch = new RoundedToggleSwitch(theme) { Margin = new BorderDouble(5, 0), VAnchor = VAnchor.Center }; toggleSwitch.CheckedStateChanged += (s, e) => { if (!timeSinceLastManualSend.IsRunning || timeSinceLastManualSend.ElapsedMilliseconds > 500) { timeSinceLastManualSend.Restart(); if (toggleSwitch.Checked) { printerConnection.FanSpeed0To255 = 255; } else { printerConnection.FanSpeed0To255 = 0; } } }; container.AddChild(toggleSwitch); settingsRow.ActionWidget = toggleSwitch; // CreateFanControls printerConnection.FanSpeedSet.RegisterEvent((s, e) => { if ((int)printerConnection.FanSpeed0To255 > 0) { toggleSwitch.Checked = true; } else { toggleSwitch.Checked = false; } fanSpeedDisplay.Value = printerConnection.FanSpeed0To255 * 100 / 255; } , ref unregisterEvents); }
private CalibrationControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.printer = printer; // add in the controls for configuring auto leveling { SettingsRow settingsRow; this.AddChild(settingsRow = new SettingsRow( "Bed Leveling".Localize(), null, theme, AggContext.StaticData.LoadIcon("leveling_32x32.png", 16, 16, theme.InvertIcons))); // run leveling button var runWizardButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, Name = "Run Leveling Button", ToolTipText = "Run Calibration".Localize() }; runWizardButton.Click += (s, e) => { UiThread.RunOnIdle(() => { LevelingWizard.ShowPrintLevelWizard(printer, theme); }); }; settingsRow.AddChild(runWizardButton); // only show the switch if leveling can be turned off (it can't if it is required). if (!printer.Settings.GetValue <bool>(SettingsKey.print_leveling_required_to_print)) { // put in the switch var printLevelingSwitch = new RoundedToggleSwitch(theme) { VAnchor = VAnchor.Center, Margin = new BorderDouble(left: 16), Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled) }; printLevelingSwitch.CheckedStateChanged += (sender, e) => { printer.Settings.Helpers.DoPrintLeveling(printLevelingSwitch.Checked); }; void Settings_PrintLevelingEnabledChanged(object sender, EventArgs e) { printLevelingSwitch.Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled); } printer.Settings.PrintLevelingEnabledChanged += Settings_PrintLevelingEnabledChanged; this.Closed += (s, e) => { printer.Settings.PrintLevelingEnabledChanged -= Settings_PrintLevelingEnabledChanged; }; settingsRow.AddChild(printLevelingSwitch); } // add in the controls for configuring probe offset if (printer.Settings.GetValue <bool>(SettingsKey.has_z_probe) && printer.Settings.GetValue <bool>(SettingsKey.use_z_probe)) { this.AddChild(settingsRow = new SettingsRow( "Calibrate Probe Offset".Localize(), null, theme, AggContext.StaticData.LoadIcon("probing_32x32.png", 16, 16, theme.InvertIcons))); var runCalibrateProbeButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, ToolTipText = "Run Calibration".Localize() }; runCalibrateProbeButton.Click += (s, e) => { UiThread.RunOnIdle(() => { LevelingWizard.ShowProbeCalibrationWizard(printer, theme); }); }; settingsRow.BorderColor = Color.Transparent; settingsRow.AddChild(runCalibrateProbeButton); } } printer.Connection.CommunicationStateChanged.RegisterEvent(PrinterStatusChanged, ref unregisterEvents); printer.Connection.EnableChanged.RegisterEvent(PrinterStatusChanged, ref unregisterEvents); SetVisibleControls(); }
private TemperatureControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Stretch; this.HAnchor = HAnchor.Stretch; this.printer = printer; int hotendCount = printer.Settings.Helpers.HotendCount(); // add in the hotend controls for (int extruderIndex = 0; extruderIndex < hotendCount; extruderIndex++) { var settingsRow = new SettingsRow( hotendCount == 1 ? "Hotend".Localize() : "Hotend {0}".Localize().FormatWith(extruderIndex + 1), null, theme); settingsRow.AddChild(new TemperatureWidgetHotend(printer, extruderIndex, theme, hotendCount)); this.AddChild(settingsRow); } if (printer.Settings.GetValue <bool>(SettingsKey.has_heated_bed)) { var settingsRow = new SettingsRow( "Bed".Localize(), null, theme); settingsRow.AddChild(new TemperatureWidgetBed(printer, theme)); this.AddChild(settingsRow); } // add in the all heaters section var heatersRow = new SettingsRow( "All Heaters".Localize(), null, theme); this.AddChild(heatersRow); var container = new FlowLayoutWidget(); heatersRow.AddChild(container); preHeatButton = new TextButton("Preheat".Localize(), theme) { BackgroundColor = theme.MinimalShade, Margin = new BorderDouble(right: 10) }; container.AddChild(preHeatButton); preHeatButton.Click += (s, e) => { // turn on the bed printer.Connection.TargetBedTemperature = printer.Settings.GetValue <double>(SettingsKey.bed_temperature); for (int extruderIndex = 0; extruderIndex < hotendCount; extruderIndex++) { printer.Connection.SetTargetHotendTemperature(extruderIndex, printer.Settings.Helpers.ExtruderTargetTemperature(extruderIndex)); } printer.Connection.TurnOffBedAndExtruders(TurnOff.AfterDelay); }; offButton = new TextButton("Off".Localize(), theme) { BackgroundColor = theme.MinimalShade, }; container.AddChild(offButton); offButton.Click += (s, e) => { printer.Connection.TurnOffBedAndExtruders(TurnOff.Now); }; if (printer.Settings.GetValue <bool>(SettingsKey.has_fan_per_extruder)) { for (int i = 0; i < printer.Settings.GetValue <int>(SettingsKey.extruder_count); i++) { this.AddChild(new FanControlsRow(i, $"Part Cooling Fan {i}".Localize(), printer, theme)); } } else // just add one { this.AddChild(new FanControlsRow(0, "Part Cooling Fan".Localize(), printer, theme)); } // Register listeners printer.Connection.CommunicationStateChanged += Printer_StatusChanged; SetVisibleControls(); }
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; }
private AdjustmentControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { double sliderWidth = 300 * GuiWidget.DeviceScale; double sliderThumbWidth = 10 * GuiWidget.DeviceScale; Color sliderTrackColor = theme.Colors.IsDarkTheme ? new Color(theme.Shade, 65) : theme.SlightShade; SettingsRow settingsRow; { this.AddChild(settingsRow = new SettingsRow( "Speed Multiplier".Localize(), null, theme)); // Remove the HorizontalSpacer settingsRow.Children.Last().Close(); feedRateRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minFeedRateRatio, maxFeedRateRatio) { Name = "Feed Rate Slider", Margin = new BorderDouble(5, 0), Value = FeedRateMultiplyerStream.FeedRateRatio, HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center, TotalWidthInPixels = sliderWidth, }; feedRateRatioSlider.View.TrackColor = sliderTrackColor; feedRateRatioSlider.View.TrackRadius = 4; feedRateRatioSlider.ValueChanged += (sender, e) => { feedRateValue.ActuallNumberEdit.Value = Math.Round(feedRateRatioSlider.Value, 2); }; feedRateRatioSlider.SliderReleased += (s, e) => { // Update state for runtime use FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.feedrate_ratio, FeedRateMultiplyerStream.FeedRateRatio.ToString()); }; settingsRow.AddChild(feedRateRatioSlider); feedRateValue = new MHNumberEdit(Math.Round(FeedRateMultiplyerStream.FeedRateRatio, 2), allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale) { Name = "Feed Rate NumberEdit", SelectAllOnFocus = true, Margin = new BorderDouble(0, 0, 5, 0), VAnchor = VAnchor.Center | VAnchor.Fit, Padding = 0 }; feedRateValue.ActuallNumberEdit.EditComplete += (sender, e) => { feedRateRatioSlider.Value = feedRateValue.ActuallNumberEdit.Value; // Update state for runtime use FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.feedrate_ratio, FeedRateMultiplyerStream.FeedRateRatio.ToString()); }; settingsRow.AddChild(feedRateValue); } { this.AddChild(settingsRow = new SettingsRow( "Extrusion Multiplier".Localize(), null, theme)); // Remove the HorizontalSpacer settingsRow.Children.Last().Close(); extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal) { Name = "Extrusion Multiplier Slider", TotalWidthInPixels = sliderWidth, HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center, Margin = new BorderDouble(5, 0), Value = ExtrusionMultiplyerStream.ExtrusionRatio }; extrusionRatioSlider.View.TrackColor = sliderTrackColor; extrusionRatioSlider.View.TrackRadius = 4; extrusionRatioSlider.ValueChanged += (sender, e) => { extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatioSlider.Value, 2); }; extrusionRatioSlider.SliderReleased += (s, e) => { // Update state for runtime use ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.extrusion_ratio, ExtrusionMultiplyerStream.ExtrusionRatio.ToString()); }; settingsRow.AddChild(extrusionRatioSlider); extrusionValue = new MHNumberEdit(Math.Round(ExtrusionMultiplyerStream.ExtrusionRatio, 2), allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale) { Name = "Extrusion Multiplier NumberEdit", SelectAllOnFocus = true, Margin = new BorderDouble(0, 0, 5, 0), VAnchor = VAnchor.Center | VAnchor.Fit, Padding = 0 }; extrusionValue.ActuallNumberEdit.EditComplete += (sender, e) => { extrusionRatioSlider.Value = extrusionValue.ActuallNumberEdit.Value; // Update state for runtime use ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2); // Persist data for future use printer.Settings.SetValue( SettingsKey.extrusion_ratio, ExtrusionMultiplyerStream.ExtrusionRatio.ToString()); }; settingsRow.AddChild(extrusionValue); } ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) => { var eventArgs = e as StringEventArgs; if (eventArgs?.Data == SettingsKey.extrusion_ratio) { double extrusionRatio = printer.Settings.GetValue <double>(SettingsKey.extrusion_ratio); extrusionRatioSlider.Value = extrusionRatio; extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatio, 2); } else if (eventArgs?.Data == SettingsKey.feedrate_ratio) { double feedrateRatio = printer.Settings.GetValue <double>(SettingsKey.feedrate_ratio); feedRateRatioSlider.Value = feedrateRatio; feedRateValue.ActuallNumberEdit.Value = Math.Round(feedrateRatio, 2); } }, ref unregisterEvents); }
public ValidationErrorsPanel(IEnumerable <ValidationError> errors, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.HAnchor = HAnchor.Absolute; this.VAnchor = VAnchor.Fit | VAnchor; this.BackgroundColor = theme.ResolveColor(theme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)); var errorImage = AggContext.StaticData.LoadIcon("SettingsGroupError_16x.png", 16, 16, theme.InvertIcons); var warningImage = AggContext.StaticData.LoadIcon("SettingsGroupWarning_16x.png", 16, 16, theme.InvertIcons); var infoImage = AggContext.StaticData.LoadIcon("StatusInfoTip_16x.png", 16, 16); var fixIcon = AggContext.StaticData.LoadIcon("noun_1306.png", 16, 16, theme.InvertIcons); foreach (var validationError in errors.OrderByDescending(e => e.ErrorLevel)) { string errorText, errorDetails; var settingsValidationError = validationError as SettingsValidationError; if (settingsValidationError != null) { errorText = string.Format( "{0} {1}", settingsValidationError.PresentationName, validationError.ErrorLevel == ValidationErrorLevel.Error ? "Error".Localize() : "Warning".Localize()); errorDetails = validationError.Error; } else { errorText = validationError.Error; errorDetails = validationError.Details ?? ""; } var row = new SettingsRow(errorText, errorDetails, theme, validationError.ErrorLevel == ValidationErrorLevel.Error ? errorImage : warningImage) { ArrowDirection = ArrowDirection.Left }; if (validationError.FixAction is NamedAction action) { // Show fix button var button = new IconButton(fixIcon, theme) { ToolTipText = action.Title }; if (!string.IsNullOrEmpty(action.ID)) { button.Name = action.ID; } button.Click += (s, e) => { action.Action.Invoke(); }; row.AddChild(button); } else { // Show info indicator hinting that hover will reveal additional details var button = new IconButton(infoImage, theme) { Selectable = false }; row.AddChild(button); } this.AddChild(row); } }
private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth, int extruderIndex) { GuiWidget container = new GuiWidget(); this.HAnchor = HAnchor.ParentLeftRight; string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName); var settingsRow = new SettingsRow() { SettingsKey = settingData.SlicerConfigName, SettingsValue = sliceSettingValue }; if (!ActiveSliceSettings.Instance.InBaseConfig(settingData.SlicerConfigName)) { // the setting we think we are adding is not in the config.ini it may have been deprecated 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); settingsRow.AddChild(settingName); settingsRow.BackgroundColor = RGBA_Bytes.Red; } else { int intEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5); int doubleEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5); if (settingData.QuickMenuSettings.Count > 0) { doubleEditWidth = (int)(35 * TextWidget.GlobalPointSizeScaleRatio + .5); } int vectorXYEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5); int multiLineEditHeight = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5); if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT) { var nameHolder = new GuiWidget(HAnchor.AbsolutePosition, VAnchor.FitToChildren | VAnchor.ParentCenter) { Width = minSettingNameWidth, Padding = new BorderDouble(0, 0, 5, 0), }; nameHolder.AddChild(new WrappedTextWidget( settingData.PresentationName.Localize(), minSettingNameWidth, pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)); settingsRow.AddChild(nameHolder); } switch (settingData.DataEditType) { case OrganizerSettingsData.DataEditTypes.INT: { int currentValue; int.TryParse(sliceSettingValue, out currentValue); var intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(intEditWidget); settingsRow.AddChild(GetExtraSettingsWidget(settingData)); settingsRow.ValueChanged = (text) => intEditWidget.Text = text; } break; case OrganizerSettingsData.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) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(doubleEditWidget); settingsRow.AddChild(GetExtraSettingsWidget(settingData)); settingsRow.ValueChanged = (text) => { double currentValue2 = 0; double.TryParse(text, out currentValue2); doubleEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case OrganizerSettingsData.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 = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[0]); for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++) { string nextSetting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[i]); 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) { SaveSetting(setting, numberEdit.Value.ToString() + "mm"); } } // also always save to the local setting SaveSetting(settingData.SlicerConfigName, numberEdit.Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; content.AddChild(doubleEditWidget); content.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { settingsRow.AddChild(CreateQuickMenu(settingData, content, doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget)); } else { settingsRow.AddChild(content); } settingsRow.ValueChanged = (text) => { double currentValue2 = 0; double.TryParse(text, out currentValue2); doubleEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case OrganizerSettingsData.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) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(doubleEditWidget); settingsRow.AddChild(GetExtraSettingsWidget(settingData)); settingsRow.ValueChanged = (text) => { double currentValue2; double.TryParse(text, out currentValue2); doubleEditWidget.ActuallNumberEdit.Value = currentValue2; }; } break; case OrganizerSettingsData.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; SaveSetting(settingData.SlicerConfigName, textEditWidget.Text); 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); content.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { settingsRow.AddChild(CreateQuickMenu(settingData, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget)); } else { settingsRow.AddChild(content); } settingsRow.ValueChanged = (text) => stringEdit.Text = text; } break; case OrganizerSettingsData.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; } SaveSetting(settingData.SlicerConfigName, textEditWidget.Text); 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); content.AddChild(GetExtraSettingsWidget(settingData)); if (settingData.QuickMenuSettings.Count > 0) { settingsRow.AddChild(CreateQuickMenu(settingData, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget)); } else { settingsRow.AddChild(content); } settingsRow.ValueChanged = (text) => stringEdit.Text = text; } break; case OrganizerSettingsData.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.CheckedStateChanged += (sender, e) => { bool isChecked = ((CheckBox)sender).Checked; SaveSetting(settingData.SlicerConfigName, isChecked ? "1" : "0"); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(checkBoxWidget); settingsRow.ValueChanged = (text) => checkBoxWidget.Checked = text == "1"; } break; case OrganizerSettingsData.DataEditTypes.STRING: { var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++); stringEdit.ToolTipText = settingData.HelpText; stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(stringEdit); settingsRow.ValueChanged = (text) => stringEdit.Text = text; } break; case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT: { string convertedNewLines = sliceSettingValue.Replace("\\n", "\n"); var 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")); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(stringEdit); settingsRow.ValueChanged = (text) => stringEdit.Text = text.Replace("\\n", "\n"); } break; case OrganizerSettingsData.DataEditTypes.LIST: { var selectableOptions = new StyledDropDownList("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); SaveSetting(settingData.SlicerConfigName, menuItem.Text); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; } settingsRow.AddChild(selectableOptions); settingsRow.ValueChanged = (text) => selectableOptions.SelectedLabel = text; } break; case OrganizerSettingsData.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.CheckedStateChanged += (sender, e) => { bool isChecked = ((CheckBox)sender).Checked; SaveSetting(settingData.SlicerConfigName, isChecked ? "1" : "0"); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(checkBoxWidget); settingsRow.ValueChanged = (text) => checkBoxWidget.Checked = text == "1"; } break; case OrganizerSettingsData.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, Margin = new BorderDouble(0, 0, 30 * TextWidget.GlobalPointSizeScaleRatio, 0), 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 }; xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(xEditWidget); yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(yEditWidget); 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 OrganizerSettingsData.DataEditTypes.OFFSET2: { Vector2 offset = ActiveSliceSettings.Instance.GetOffset(extruderIndex); var xEditWidget = new MHNumberEdit(offset.x, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true, Margin = new BorderDouble(0, 0, 30 * TextWidget.GlobalPointSizeScaleRatio, 0) }; var yEditWidget = new MHNumberEdit(offset.y, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++) { ToolTipText = settingData.HelpText, SelectAllOnFocus = true }; xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { int extruderIndexLocal = extruderIndex; SaveCommaSeparatedIndexSetting(extruderIndexLocal, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(xEditWidget); yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { int extruderIndexLocal = extruderIndex; SaveCommaSeparatedIndexSetting(extruderIndexLocal, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); settingsRow.UpdateStyle(); OnSettingsChanged(settingData); }; settingsRow.AddChild(yEditWidget); settingsRow.ValueChanged = (text) => { Vector2 offset2 = ActiveSliceSettings.Instance.GetOffset(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 }; settingsRow.AddChild(missingSetting); break; } } container.HAnchor = HAnchor.ParentLeftRight; container.VAnchor = VAnchor.FitToChildren; var 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(); }; settingsRow.AddChild(new GuiWidget(HAnchor.ParentLeftRight)); settingsRow.AddChild(restoreButton); container.AddChild(settingsRow); // Define the UpdateStyle implementation settingsRow.UpdateStyle = () => { if (persistenceLayer.ContainsKey(settingData.SlicerConfigName)) { switch (this.viewFilter) { case NamedSettingsLayers.All: settingsRow.BackgroundColor = userSettingBackgroundColor; break; case NamedSettingsLayers.Material: settingsRow.BackgroundColor = materialSettingBackgroundColor; break; case NamedSettingsLayers.Quality: settingsRow.BackgroundColor = qualitySettingBackgroundColor; break; } restoreButton.Visible = true; } else if (layerFilters == 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; } restoreButton.Visible = false; } else { restoreButton.Visible = false; settingsRow.BackgroundColor = RGBA_Bytes.Transparent; } }; // Invoke the UpdateStyle implementation settingsRow.UpdateStyle(); return container; }