protected void SetButtonStates() { // If we don't have leveling data and we need it bool showSetupButton = PrintLevelingData.NeedsToBeRun(printer); switch (printer.Connection.CommunicationState) { case CommunicationStates.FinishedPrint: case CommunicationStates.Connected: if (showSetupButton) { startPrintButton.Visible = false; finishSetupButton.Visible = true; finishSetupButton.Enabled = true; theme.ApplyPrimaryActionStyle(finishSetupButton); } else { startPrintButton.Visible = true; startPrintButton.Enabled = true; finishSetupButton.Visible = false; theme.ApplyPrimaryActionStyle(startPrintButton); } break; case CommunicationStates.PrintingFromSd: case CommunicationStates.Printing: case CommunicationStates.Paused: default: if (showSetupButton) { startPrintButton.Visible = false; finishSetupButton.Visible = true; finishSetupButton.Enabled = false; theme.RemovePrimaryActionStyle(finishSetupButton); } else { startPrintButton.Visible = true; startPrintButton.Enabled = false; finishSetupButton.Visible = false; theme.RemovePrimaryActionStyle(startPrintButton); } break; } }
public static GuiWidget GetUnlockRow(ThemeConfig theme, string url) { var detailsLink = new TextIconButton("Unlock".Localize(), StaticData.Instance.LoadIcon("locked.png", 16, 16, theme.InvertIcons), theme) { Margin = 5, ToolTipText = "Visit MatterHackers.com to Purchase".Localize() }; detailsLink.Click += (s, e) => { ApplicationController.LaunchBrowser(url); }; theme.ApplyPrimaryActionStyle(detailsLink); return(new SettingsRow("Demo Mode".Localize(), null, detailsLink, theme)); }
public static FlowLayoutWidget GetUnlockRow(ThemeConfig theme, string unlockLinkUrl) { var row = CreateSettingsRow("Demo Mode".Localize()); var detailsLink = new TextIconButton("Unlock".Localize(), AggContext.StaticData.LoadIcon("locked.png", 16, 16, theme.InvertIcons), theme) { Margin = 5 }; detailsLink.Click += (s, e) => { ApplicationController.Instance.LaunchBrowser(UnlockLinkAttribute.UnlockPageBaseUrl + unlockLinkUrl); }; row.AddChild(detailsLink); theme.ApplyPrimaryActionStyle(detailsLink); return(row); }
private void AddUnlockLinkIfRequired(PPEContext context, FlowLayoutWidget editControlsContainer, ThemeConfig theme) { var unlockLink = context.item.GetType().GetCustomAttributes(typeof(UnlockLinkAttribute), true).FirstOrDefault() as UnlockLinkAttribute; if (unlockLink != null && !string.IsNullOrEmpty(unlockLink.UnlockPageLink) && !context.item.Persistable) { var row = CreateSettingsRow(context.item.Persistable ? "Registered".Localize() : "Demo Mode".Localize()); var detailsLink = new TextIconButton("Unlock".Localize(), AggContext.StaticData.LoadIcon("locked.png", 16, 16, theme.InvertIcons), theme) { Margin = 5 }; detailsLink.Click += (s, e) => { ApplicationController.Instance.LaunchBrowser(UnlockLinkAttribute.UnlockPageBaseUrl + unlockLink.UnlockPageLink); }; row.AddChild(detailsLink); theme.ApplyPrimaryActionStyle(detailsLink); editControlsContainer.AddChild(row); } }
public PrinterActionsBar(PrinterConfig printer, PrinterTabPage printerTabPage, ThemeConfig theme) : base(theme) { this.printer = printer; this.printerTabPage = printerTabPage; this.HAnchor = HAnchor.Stretch; this.VAnchor = VAnchor.Fit; var defaultMargin = theme.ButtonSpacing; // add the reset button first (if there is one) if (printer.Settings.GetValue <bool>(SettingsKey.show_reset_connection)) { var resetConnectionButton = new TextIconButton( "Reset".Localize(), AggContext.StaticData.LoadIcon("e_stop.png", 14, 14, theme.InvertIcons), theme) { ToolTipText = "Reboots the firmware on the controller".Localize(), Margin = defaultMargin }; resetConnectionButton.Click += (s, e) => { UiThread.RunOnIdle(printer.Connection.RebootBoard); }; this.AddChild(resetConnectionButton); } this.AddChild(new PrinterConnectButton(printer, theme)); // add the start print button GuiWidget startPrintButton; this.AddChild(startPrintButton = new PrintPopupMenu(printer, theme) { Margin = theme.ButtonSpacing }); void SetPrintButtonStyle(object s, EventArgs e) { switch (printer.Connection.CommunicationState) { case CommunicationStates.FinishedPrint: case CommunicationStates.Connected: theme.ApplyPrimaryActionStyle(startPrintButton); break; default: theme.RemovePrimaryActionStyle(startPrintButton); break; } } // make sure the buttons state is set correctly printer.Connection.CommunicationStateChanged += SetPrintButtonStyle; startPrintButton.Closed += (s, e) => printer.Connection.CommunicationStateChanged -= SetPrintButtonStyle; // and set the style right now SetPrintButtonStyle(this, null); this.AddChild(new SliceButton(printer, printerTabPage, theme) { Name = "Generate Gcode Button", Margin = theme.ButtonSpacing, }); // Add vertical separator this.AddChild(new ToolbarSeparator(theme) { VAnchor = VAnchor.Absolute, Height = theme.ButtonHeight, }); var buttonGroupB = new ObservableCollection <GuiWidget>(); var iconPath = Path.Combine("ViewTransformControls", "model.png"); modelViewButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 16, 16, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupB, Name = "Model View Button", Checked = printer?.ViewState.ViewMode == PartViewMode.Model || printer == null, ToolTipText = "Model View".Localize(), Margin = theme.ButtonSpacing }; modelViewButton.Click += SwitchModes_Click; buttonGroupB.Add(modelViewButton); AddChild(modelViewButton); viewModes.Add(PartViewMode.Model, modelViewButton); iconPath = Path.Combine("ViewTransformControls", "gcode_3d.png"); layers3DButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 16, 16, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupB, Name = "Layers3D Button", Checked = printer?.ViewState.ViewMode == PartViewMode.Layers3D, ToolTipText = "3D Layer View".Localize(), Margin = theme.ButtonSpacing }; layers3DButton.Click += SwitchModes_Click; buttonGroupB.Add(layers3DButton); viewModes.Add(PartViewMode.Layers3D, layers3DButton); if (!UserSettings.Instance.IsTouchScreen) { this.AddChild(layers3DButton); } iconPath = Path.Combine("ViewTransformControls", "gcode_2d.png"); layers2DButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 16, 16, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupB, Name = "Layers2D Button", Checked = printer?.ViewState.ViewMode == PartViewMode.Layers2D, ToolTipText = "2D Layer View".Localize(), Margin = theme.ButtonSpacing, }; layers2DButton.Click += SwitchModes_Click; buttonGroupB.Add(layers2DButton); this.AddChild(layers2DButton); viewModes.Add(PartViewMode.Layers2D, layers2DButton); this.AddChild(new HorizontalSpacer()); int hotendCount = printer.Settings.Helpers.HotendCount(); if (!printer.Settings.GetValue <bool>(SettingsKey.sla_printer)) { for (int extruderIndex = 0; extruderIndex < hotendCount; extruderIndex++) { this.AddChild(new TemperatureWidgetHotend(printer, extruderIndex, theme, hotendCount) { Margin = new BorderDouble(right: 10) }); } } if (printer.Settings.GetValue <bool>(SettingsKey.has_heated_bed)) { this.AddChild(new TemperatureWidgetBed(printer, theme)); } this.OverflowButton.Name = "Printer Overflow Menu"; this.ExtendOverflowMenu = (popupMenu) => { this.GeneratePrinterOverflowMenu(popupMenu, ApplicationController.Instance.MenuTheme); }; printer.ViewState.ViewModeChanged += (s, e) => { if (viewModes[e.ViewMode] is RadioIconButton activeButton && viewModes[e.PreviousMode] is RadioIconButton previousButton && !buttonIsBeingClicked) { // Show slide to animation from previous to current, on completion update view to current by setting active.Checked previousButton.SlideToNewState( activeButton, this, () => { activeButton.Checked = true; }, theme); } }; // Register listeners printer.Connection.ConnectionSucceeded += CheckForPrintRecovery; // if we are already connected than check if there is a print recovery right now if (printer.Connection.CommunicationState == CommunicationStates.Connected) { CheckForPrintRecovery(null, null); } }
public GenerateSupportPanel(ThemeConfig theme, InteractiveScene scene, double minimumSupportHeight) : base(FlowDirection.TopToBottom) { supportGenerator = new SupportGenerator(scene, minimumSupportHeight); this.VAnchor = VAnchor.Fit; this.HAnchor = HAnchor.Absolute; this.Width = 300 * GuiWidget.DeviceScale; this.BackgroundColor = theme.BackgroundColor; this.Padding = theme.DefaultContainerPadding; // Add an editor field for the SupportGenerator.SupportType PropertyInfo propertyInfo = typeof(SupportGenerator).GetProperty(nameof(SupportGenerator.SupportType)); var editor = PublicPropertyEditor.CreatePropertyEditor( new EditableProperty(propertyInfo, supportGenerator), null, new PPEContext(), theme); if (editor != null) { this.AddChild(editor); } // put in support pillar size var pillarSizeField = new DoubleField(theme); pillarSizeField.Initialize(0); pillarSizeField.DoubleValue = supportGenerator.PillarSize; pillarSizeField.ValueChanged += (s, e) => { supportGenerator.PillarSize = pillarSizeField.DoubleValue; // in case it was corrected set it back again if (pillarSizeField.DoubleValue != supportGenerator.PillarSize) { pillarSizeField.DoubleValue = supportGenerator.PillarSize; } }; // pillar rows this.AddChild( new SettingsRow( "Pillar Size".Localize(), "The width and depth of the support pillars".Localize(), pillarSizeField.Content, theme)); // put in the angle setting var overHangField = new DoubleField(theme); overHangField.Initialize(0); overHangField.DoubleValue = supportGenerator.MaxOverHangAngle; overHangField.ValueChanged += (s, e) => { supportGenerator.MaxOverHangAngle = overHangField.DoubleValue; // in case it was corrected set it back again if (overHangField.DoubleValue != supportGenerator.MaxOverHangAngle) { overHangField.DoubleValue = supportGenerator.MaxOverHangAngle; } }; // overhang row this.AddChild( new SettingsRow( "Overhang Angle".Localize(), "The angle to generate support for".Localize(), overHangField.Content, theme)); // Button Row var buttonRow = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = new BorderDouble(top: 5) }; this.AddChild(buttonRow); buttonRow.AddChild(new HorizontalSpacer()); // add 'Remove Auto Supports' button var removeButton = theme.CreateDialogButton("Remove".Localize()); removeButton.ToolTipText = "Remove all auto generated supports".Localize(); removeButton.Click += (s, e) => supportGenerator.RemoveExisting(); buttonRow.AddChild(removeButton); // add 'Generate Supports' button var generateButton = theme.CreateDialogButton("Generate".Localize()); generateButton.Name = "Generate Support Button"; generateButton.ToolTipText = "Find and create supports where needed".Localize(); generateButton.Click += (s, e) => Rebuild(); buttonRow.AddChild(generateButton); theme.ApplyPrimaryActionStyle(generateButton); }
public PrintPopupMenu(PrinterConfig printer, ThemeConfig theme) : base(theme) { this.printer = printer; this.DrawArrow = true; this.BackgroundColor = theme.ToolbarButtonBackground; this.HoverColor = theme.ToolbarButtonHover; this.MouseDownColor = theme.ToolbarButtonDown; this.Name = "PrintPopupMenu"; this.HAnchor = HAnchor.Fit; this.VAnchor = VAnchor.Fit; settingsContext = new SettingsContext(printer, null, NamedSettingsLayers.All); this.PopupHAnchor = HAnchor.Fit; this.PopupVAnchor = VAnchor.Fit; this.MakeScrollable = false; this.DynamicPopupContent = () => { var menuTheme = ApplicationController.Instance.MenuTheme; int tabIndex = 0; allUiFields.Clear(); var printPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Padding = theme.DefaultContainerPadding, BackgroundColor = menuTheme.BackgroundColor }; printPanel.AddChild(new TextWidget("Options".Localize(), textColor: menuTheme.TextColor, pointSize: theme.DefaultFontSize) { HAnchor = HAnchor.Left }); var optionsPanel = new IgnoredFlowLayout() { Name = "PrintPopupMenu Panel", HAnchor = HAnchor.Fit | HAnchor.Left, VAnchor = VAnchor.Fit, Padding = 5, MinimumSize = new Vector2(400, 65), }; printPanel.AddChild(optionsPanel); foreach (var key in new[] { SettingsKey.layer_height, SettingsKey.fill_density, SettingsKey.create_raft }) { var settingsData = PrinterSettings.SettingsData[key]; var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); if (row is SliceSettingsRow settingsRow) { settingsRow.ArrowDirection = ArrowDirection.Left; } optionsPanel.AddChild(row); } var subPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Margin = new BorderDouble(2, 0) }; bool anySettingOverridden = false; anySettingOverridden |= printer.Settings.GetValue <bool>(SettingsKey.spiral_vase); anySettingOverridden |= !string.IsNullOrWhiteSpace(printer.Settings.GetValue(SettingsKey.layer_to_pause)); var sectionWidget = new SectionWidget("Advanced".Localize(), subPanel, menuTheme, expanded: anySettingOverridden) { Name = "Advanced Section", HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = 0 }; printPanel.AddChild(sectionWidget); foreach (var key in new[] { SettingsKey.spiral_vase, SettingsKey.layer_to_pause }) { var advancedRow = SliceSettingsTabView.CreateItemRow( PrinterSettings.SettingsData[key], settingsContext, printer, menuTheme, ref tabIndex, allUiFields); if (advancedRow is SliceSettingsRow settingsRow) { settingsRow.ArrowDirection = ArrowDirection.Left; } subPanel.AddChild(advancedRow); } menuTheme.ApplyBoxStyle(sectionWidget); sectionWidget.Margin = new BorderDouble(0, 10); sectionWidget.ContentPanel.Children <SettingsRow>().First().Border = new BorderDouble(0, 1); sectionWidget.ContentPanel.Children <SettingsRow>().Last().Border = 0; var printerReadyToTakeCommands = printer.Connection.CommunicationState == PrinterCommunication.CommunicationStates.FinishedPrint || printer.Connection.CommunicationState == PrinterCommunication.CommunicationStates.Connected; // add the start print button var setupRow = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch }; // Perform validation before popup var errors = printer.Validate(); // Enable print option when no validation Errors exists var printEnabled = !errors.Any(err => err.ErrorLevel == ValidationErrorLevel.Error); var startPrintButton = new TextButton("Start Print".Localize(), menuTheme) { Name = "Start Print Button", Enabled = printEnabled }; startPrintButton.Click += (s, e) => { // Exit if the bed is not GCode and the bed has no printable items if (!printer.Bed.EditContext.IsGGCodeSource && !printer.PrintableItems(printer.Bed.Scene).Any()) { return; } UiThread.RunOnIdle(async() => { // Save any pending changes before starting print operation await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer, printer.Bed.SaveChanges); await ApplicationController.Instance.PrintPart( printer.Bed.EditContext, printer, null, CancellationToken.None); }); this.CloseMenu(); }; var hasErrors = errors.Any(e => e.ErrorLevel == ValidationErrorLevel.Error); var hasWarnings = errors.Any(e => e.ErrorLevel == ValidationErrorLevel.Warning && UserSettings.Instance.get($"Ignore_{e.ID}") != "true"); var hasErrorsOrWarnings = hasErrors || hasWarnings; if (hasErrorsOrWarnings) { string label = hasErrors ? "Action Required".Localize() : "Action Recommended".Localize(); setupRow.AddChild(new TextWidget(label, textColor: hasErrors ? Color.Red : theme.PrimaryAccentColor, pointSize: theme.DefaultFontSize) { VAnchor = VAnchor.Bottom, AutoExpandBoundsToText = true, }); } setupRow.AddChild(new HorizontalSpacer()); // Export button {{ bool isSailfish = printer.Settings.GetValue <bool>("enable_sailfish_communication"); var exportPlugins = PluginFinder.CreateInstancesOf <IExportPlugin>(); var targetPluginType = isSailfish ? typeof(X3GExport) : typeof(GCodeExport); // Find the first export plugin with the target type if (exportPlugins.FirstOrDefault(p => p.GetType() == targetPluginType) is IExportPlugin exportPlugin) { string exportType = isSailfish ? "Export X3G".Localize() : "Export G-Code".Localize(); exportPlugin.Initialize(printer); var exportGCodeButton = menuTheme.CreateDialogButton("Export".Localize()); exportGCodeButton.Name = "Export Gcode Button"; exportGCodeButton.Enabled = exportPlugin.Enabled; exportGCodeButton.ToolTipText = exportPlugin.Enabled ? exportType : exportPlugin.DisabledReason; exportGCodeButton.Click += (s, e) => { ExportPrintItemPage.DoExport( new[] { new InMemoryLibraryItem(printer.Bed.Scene) }, printer, exportPlugin); }; setupRow.AddChild(exportGCodeButton); } // Export button }} setupRow.AddChild(startPrintButton); printPanel.AddChild(setupRow); if (printEnabled) { theme.ApplyPrimaryActionStyle(startPrintButton); } else { startPrintButton.BackgroundColor = theme.MinimalShade; } if (hasErrorsOrWarnings) { var errorsPanel = new ValidationErrorsPanel(errors, menuTheme); // Conditional layout for right or bottom errors panel alignment var layoutStyle = FlowDirection.TopToBottom; if (layoutStyle == FlowDirection.LeftToRight) { errorsPanel.HAnchor = HAnchor.Absolute; errorsPanel.VAnchor = VAnchor.Fit | VAnchor.Top; errorsPanel.BackgroundColor = theme.ResolveColor(menuTheme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)); errorsPanel.Width = 350; errorsPanel.Load += (s, e) => { errorsPanel.Parent.BackgroundColor = Color.Transparent; }; } else { errorsPanel.HAnchor = HAnchor.Stretch; errorsPanel.VAnchor = VAnchor.Fit; errorsPanel.Margin = 3; } // Instead of the typical case where the print panel is returned, wrap and append validation errors panel var errorsContainer = new FlowLayoutWidget(layoutStyle) { HAnchor = HAnchor.Fit, VAnchor = VAnchor.Fit, BackgroundColor = layoutStyle == FlowDirection.TopToBottom ? printPanel.BackgroundColor : Color.Transparent }; // Clear bottom padding printPanel.Padding = printPanel.Padding.Clone(bottom: 2); errorsContainer.AddChild(printPanel); errorsContainer.AddChild(errorsPanel); return(errorsContainer); } return(printPanel); }; this.AddChild(new TextButton("Print".Localize(), theme) { Selectable = false, Padding = theme.TextButtonPadding.Clone(right: 5) }); // Register listeners printer.Settings.SettingChanged += Printer_SettingChanged; }
public PrinterConnectButton(PrinterConfig printer, ThemeConfig theme) { this.printer = printer; this.HAnchor = HAnchor.Left | HAnchor.Fit; this.VAnchor = VAnchor.Fit; this.Margin = 0; this.Padding = 0; connectButton = new TextIconButton( "Connect".Localize(), AggContext.StaticData.LoadIcon("connect.png", 14, 14, theme.InvertIcons), theme) { Name = "Connect to printer button", ToolTipText = "Connect to the currently selected printer".Localize(), MouseDownColor = theme.ToolbarButtonDown, }; connectButton.Click += (s, e) => { if (connectButton.Enabled) { ApplicationController.Instance.ConnectToPrinter(printer); } }; this.AddChild(connectButton); theme.ApplyPrimaryActionStyle(connectButton); // add the cancel stop button cancelConnectButton = new TextIconButton( "Cancel".Localize(), AggContext.StaticData.LoadIcon("connect.png", 14, 14, theme.InvertIcons), theme) { ToolTipText = "Stop trying to connect to the printer.".Localize(), BackgroundColor = theme.ToolbarButtonBackground, HoverColor = theme.ToolbarButtonHover, MouseDownColor = theme.ToolbarButtonDown, }; cancelConnectButton.Click += (s, e) => UiThread.RunOnIdle(() => { printer.CancelPrint(); cancelConnectButton.Enabled = false; }); this.AddChild(cancelConnectButton); disconnectButton = new TextIconButton( "Disconnect".Localize(), AggContext.StaticData.LoadIcon("connect.png", 14, 14, theme.InvertIcons), theme) { Name = "Disconnect from printer button", Visible = false, ToolTipText = "Disconnect from current printer".Localize(), BackgroundColor = theme.ToolbarButtonBackground, HoverColor = theme.ToolbarButtonHover, MouseDownColor = theme.ToolbarButtonDown, }; disconnectButton.Click += (s, e) => UiThread.RunOnIdle(() => { if (printer.Connection.Printing) { StyledMessageBox.ShowMessageBox( (bool disconnectCancel) => { if (disconnectCancel) { printer.Connection.Stop(false); printer.Connection.Disable(); } }, "WARNING: Disconnecting will stop the current print.\n\nAre you sure you want to disconnect?".Localize(), "Disconnect and stop the current print?".Localize(), StyledMessageBox.MessageType.YES_NO, "Disconnect".Localize(), "Stay Connected".Localize()); } else { printer.Connection.Disable(); } }); this.AddChild(disconnectButton); foreach (var child in Children) { child.VAnchor = VAnchor.Center; child.Cursor = Cursors.Hand; child.Margin = theme.ButtonSpacing; } // Register listeners printer.Connection.CommunicationStateChanged += Connection_CommunicationStateChanged; this.SetVisibleStates(); }
public PrintPopupMenu(PrinterConfig printer, ThemeConfig theme) : base(theme) { this.printer = printer; this.DrawArrow = true; this.BackgroundColor = theme.ToolbarButtonBackground; this.HoverColor = theme.ToolbarButtonHover; this.MouseDownColor = theme.ToolbarButtonDown; this.Name = "PrintPopupMenu"; this.HAnchor = HAnchor.Fit; this.VAnchor = VAnchor.Fit; settingsContext = new SettingsContext(printer, null, NamedSettingsLayers.All); this.DynamicPopupContent = () => { var menuTheme = ApplicationController.Instance.MenuTheme; int tabIndex = 0; allUiFields.Clear(); var column = new FlowLayoutWidget(FlowDirection.TopToBottom) { Padding = 10, BackgroundColor = menuTheme.Colors.PrimaryBackgroundColor }; column.AddChild(new TextWidget("Options".Localize(), textColor: menuTheme.Colors.PrimaryTextColor) { HAnchor = HAnchor.Left }); var optionsPanel = new IgnoredFlowLayout() { Name = "PrintPopupMenu Panel", HAnchor = HAnchor.Fit | HAnchor.Left, VAnchor = VAnchor.Fit, Padding = 5, MinimumSize = new Vector2(400, 65), Margin = new BorderDouble(top: 10), }; column.AddChild(optionsPanel); foreach (var key in new[] { "layer_height", "fill_density", "support_material", "create_raft" }) { var settingsData = SettingsOrganizer.Instance.GetSettingsData(key); var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); SliceSettingsRow.AddBordersToEditFields(row); optionsPanel.AddChild(row); } var subPanel = new FlowLayoutWidget(FlowDirection.TopToBottom); var sectionWidget = new SectionWidget("Advanced", subPanel, menuTheme, expanded: true) { Name = "Advanced Section", HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = 0 }; column.AddChild(sectionWidget); bool anySettingOverridden = false; anySettingOverridden |= printer.Settings.GetValue <bool>(SettingsKey.spiral_vase); anySettingOverridden |= !string.IsNullOrWhiteSpace(printer.Settings.GetValue(SettingsKey.layer_to_pause)); sectionWidget.Load += (s, e) => { sectionWidget.Checkbox.Checked = anySettingOverridden; }; foreach (var key in new[] { SettingsKey.spiral_vase, SettingsKey.layer_to_pause }) { var settingsData = SettingsOrganizer.Instance.GetSettingsData(key); var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); SliceSettingsRow.AddBordersToEditFields(row); subPanel.AddChild(row); } theme.ApplyBoxStyle(sectionWidget); sectionWidget.Margin = new BorderDouble(0, 10); sectionWidget.ContentPanel.Children <SettingsRow>().First().Border = new BorderDouble(0, 1); sectionWidget.ContentPanel.Children <SettingsRow>().Last().Border = 0; var button = new TextButton("Start Print".Localize(), menuTheme) { Name = "Start Print Button", HAnchor = HAnchor.Right, VAnchor = VAnchor.Absolute, }; button.Click += (s, e) => { // Exit if the bed is not GCode and the bed has no printable items if ((printer.Bed.EditContext.SourceItem as ILibraryAsset)?.ContentType != "gcode" && !printer.PrintableItems(printer.Bed.EditContext.Content).Any()) { return; } UiThread.RunOnIdle(async() => { // Save any pending changes before starting print operation await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer.Bed.SaveChanges); await ApplicationController.Instance.PrintPart( printer.Bed.EditContext, printer, null, CancellationToken.None); }); }; column.AddChild(button); theme.ApplyPrimaryActionStyle(button); return(column); }; this.AddChild(new TextButton("Print".Localize(), theme) { Selectable = false, Padding = theme.TextButtonPadding.Clone(right: 5) }); PrinterSettings.SettingChanged.RegisterEvent((s, e) => { if (e is StringEventArgs stringEvent) { string settingsKey = stringEvent.Data; if (allUiFields.TryGetValue(settingsKey, out UIField uifield)) { string currentValue = settingsContext.GetValue(settingsKey); if (uifield.Value != currentValue || settingsKey == "com_port") { uifield.SetValue( currentValue, userInitiated: false); } } } }, ref unregisterEvents); }
public PrinterConnectButton(PrinterConfig printer, ThemeConfig theme) { this.printer = printer; this.HAnchor = HAnchor.Left | HAnchor.Fit; this.VAnchor = VAnchor.Fit; this.Margin = 0; this.Padding = 0; connectButton = new TextIconButton( "Connect".Localize(), AggContext.StaticData.LoadIcon("connect.png", 14, 14, theme.InvertIcons), theme) { Name = "Connect to printer button", ToolTipText = "Connect to the currently selected printer".Localize(), MouseDownColor = theme.ToolbarButtonDown, }; connectButton.Click += (s, e) => { if (connectButton.Enabled) { if (printer.Settings.PrinterSelected) { UserRequestedConnectToActivePrinter(); } } }; this.AddChild(connectButton); theme.ApplyPrimaryActionStyle(connectButton); // add the cancel stop button cancelConnectButton = new TextIconButton( "Cancel".Localize(), AggContext.StaticData.LoadIcon("connect.png", 14, 14, theme.InvertIcons), theme) { ToolTipText = "Stop trying to connect to the printer.".Localize(), BackgroundColor = theme.ToolbarButtonBackground, HoverColor = theme.ToolbarButtonHover, MouseDownColor = theme.ToolbarButtonDown, }; cancelConnectButton.Click += (s, e) => UiThread.RunOnIdle(() => { listenForConnectFailed = false; ApplicationController.Instance.ConditionalCancelPrint(); cancelConnectButton.Enabled = false; }); this.AddChild(cancelConnectButton); disconnectButton = new TextIconButton( "Disconnect".Localize(), AggContext.StaticData.LoadIcon("connect.png", 14, 14, theme.InvertIcons), theme) { Name = "Disconnect from printer button", Visible = false, ToolTipText = "Disconnect from current printer".Localize(), BackgroundColor = theme.ToolbarButtonBackground, HoverColor = theme.ToolbarButtonHover, MouseDownColor = theme.ToolbarButtonDown, }; disconnectButton.Click += (s, e) => UiThread.RunOnIdle(() => { if (printer.Connection.PrinterIsPrinting) { StyledMessageBox.ShowMessageBox( (bool disconnectCancel) => { if (disconnectCancel) { printer.Connection.Stop(false); printer.Connection.Disable(); } }, "WARNING: Disconnecting will stop the current print.\n\nAre you sure you want to disconnect?".Localize(), "Disconnect and stop the current print?".Localize(), StyledMessageBox.MessageType.YES_NO, "Disconnect".Localize(), "Stay Connected".Localize()); } else { printer.Connection.Disable(); } }); this.AddChild(disconnectButton); foreach (var child in Children) { child.VAnchor = VAnchor.Center; child.Cursor = Cursors.Hand; child.Margin = theme.ButtonSpacing; } printer.Connection.EnableChanged.RegisterEvent((s, e) => SetVisibleStates(), ref unregisterEvents); printer.Connection.CommunicationStateChanged.RegisterEvent((s, e) => SetVisibleStates(), ref unregisterEvents); printer.Connection.ConnectionFailed.RegisterEvent((s, e) => { #if !__ANDROID__ // TODO: Someday this functionality should be revised to an awaitable Connect() call in the Connect button that // shows troubleshooting on failed attempts, rather than hooking the failed event and trying to determine if the // Connect button started the task if (listenForConnectFailed && UiThread.CurrentTimerMs - connectStartMs < 25000) { UiThread.RunOnIdle(() => { // User initiated connect attempt failed, show port selection dialog DialogWindow.Show(new SetupStepComPortOne(printer)); }); } #endif listenForConnectFailed = false; }, ref unregisterEvents); this.SetVisibleStates(); }
public ExportSlaPopupMenu(PrinterConfig printer, ThemeConfig theme) : base(theme) { this.printer = printer; this.DrawArrow = true; this.BackgroundColor = theme.ToolbarButtonBackground; this.HoverColor = theme.ToolbarButtonHover; this.MouseDownColor = theme.ToolbarButtonDown; this.Name = "ExportSlaPopupMenu"; this.HAnchor = HAnchor.Fit; this.VAnchor = VAnchor.Fit; settingsContext = new SettingsContext(printer, null, NamedSettingsLayers.All); this.PopupHAnchor = HAnchor.Fit; this.PopupVAnchor = VAnchor.Fit; this.MakeScrollable = false; this.DynamicPopupContent = () => { var menuTheme = ApplicationController.Instance.MenuTheme; int tabIndex = 0; allUiFields.Clear(); var exportPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Padding = theme.DefaultContainerPadding, BackgroundColor = menuTheme.BackgroundColor }; exportPanel.AddChild(new TextWidget("Options".Localize(), textColor: menuTheme.TextColor, pointSize: theme.DefaultFontSize) { HAnchor = HAnchor.Left }); var optionsPanel = new IgnoredFlowLayout() { Name = "ExportSlaPopupMenu Panel", HAnchor = HAnchor.Fit | HAnchor.Left, VAnchor = VAnchor.Fit, Padding = 5, MinimumSize = new Vector2(400 * GuiWidget.DeviceScale, 65 * GuiWidget.DeviceScale), }; exportPanel.AddChild(optionsPanel); var settingsToAdd = new[] { SettingsKey.sla_layer_height, SettingsKey.sla_create_raft, SettingsKey.sla_auto_support }; foreach (var key in settingsToAdd) { var settingsData = PrinterSettings.SettingsData[key]; var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); if (row is SliceSettingsRow settingsRow) { settingsRow.ArrowDirection = ArrowDirection.Left; } optionsPanel.AddChild(row); } // add the export print button var setupRow = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch }; // Perform validation before popup var errors = printer.Validate(); var hasErrors = errors.Any(e => e.ErrorLevel == ValidationErrorLevel.Error); var hasWarnings = errors.Any(e => e.ErrorLevel == ValidationErrorLevel.Warning && UserSettings.Instance.get($"Ignore_{e.ID}") != "true"); var hasErrorsOrWarnings = hasErrors || hasWarnings; if (hasErrorsOrWarnings) { string label = hasErrors ? "Action Required".Localize() : "Action Recommended".Localize(); setupRow.AddChild(new TextWidget(label, textColor: hasErrors ? Color.Red : theme.PrimaryAccentColor, pointSize: theme.DefaultFontSize) { VAnchor = VAnchor.Bottom, AutoExpandBoundsToText = true, }); } setupRow.AddChild(new HorizontalSpacer()); // Export button {{ var exportPlugins = PluginFinder.CreateInstancesOf <IExportPlugin>(); // set target as SLA export var targetPluginType = typeof(GCodeExport); // Find the first export plugin with the target type if (exportPlugins.FirstOrDefault(p => p.GetType() == targetPluginType) is IExportPlugin exportPlugin) { string exportType = "Export Photon File".Localize(); exportPlugin.Initialize(printer); var exportButton = menuTheme.CreateDialogButton("Export".Localize()); theme.ApplyPrimaryActionStyle(exportButton); exportButton.Name = "Export SLA Button"; exportButton.Enabled = exportPlugin.Enabled; exportButton.ToolTipText = exportPlugin.Enabled ? exportType : exportPlugin.DisabledReason; exportButton.Click += (s, e) => { this.CloseMenu(); ExportPrintItemPage.DoExport( new[] { new InMemoryLibraryItem(printer.Bed.Scene) }, printer, exportPlugin); }; setupRow.AddChild(exportButton); } // Export button exportPanel.AddChild(setupRow); if (hasErrorsOrWarnings) { var errorsPanel = new ValidationErrorsPanel(errors, menuTheme); // Conditional layout for right or bottom errors panel alignment var layoutStyle = FlowDirection.TopToBottom; if (layoutStyle == FlowDirection.LeftToRight) { errorsPanel.HAnchor = HAnchor.Absolute; errorsPanel.VAnchor = VAnchor.Fit | VAnchor.Top; errorsPanel.BackgroundColor = theme.ResolveColor(menuTheme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)); errorsPanel.Width = 350; errorsPanel.Load += (s, e) => { errorsPanel.Parent.BackgroundColor = Color.Transparent; }; } else { errorsPanel.HAnchor = HAnchor.Stretch; errorsPanel.VAnchor = VAnchor.Fit; errorsPanel.Margin = 3; } // Instead of the typical case where the print panel is returned, wrap and append validation errors panel var errorsContainer = new FlowLayoutWidget(layoutStyle) { HAnchor = HAnchor.Fit, VAnchor = VAnchor.Fit, BackgroundColor = layoutStyle == FlowDirection.TopToBottom ? exportPanel.BackgroundColor : Color.Transparent }; // Clear bottom padding exportPanel.Padding = exportPanel.Padding.Clone(bottom: 2); errorsContainer.AddChild(exportPanel); errorsContainer.AddChild(errorsPanel); return(errorsContainer); } return(exportPanel); }; this.AddChild(new TextButton("Export".Localize(), theme) { Selectable = false, Padding = theme.TextButtonPadding.Clone(right: 5) }); }