Exemplo n.º 1
0
        public static GuiWidget PrintProgressWidget(PrinterConfig printer, ThemeConfig theme)
        {
            var bodyRow = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Top | VAnchor.Fit,
                // BackgroundColor = new Color(theme.Colors.PrimaryBackgroundColor, 128),
                MinimumSize = new Vector2(275, 140),
            };

            // Progress section
            var expandingContainer = new HorizontalSpacer()
            {
                VAnchor = VAnchor.Fit | VAnchor.Center
            };

            bodyRow.AddChild(expandingContainer);

            var topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                VAnchor = VAnchor.Center | VAnchor.Fit,
                HAnchor = HAnchor.Stretch,
            };

            expandingContainer.AddChild(topToBottom);

            var progressRow = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };

            topToBottom.AddChild(progressRow);

            var progressDial = new ProgressDial(theme)
            {
                HAnchor = HAnchor.Center,
                VAnchor = VAnchor.Center,
                Height  = 200 * DeviceScale,
                Width   = 200 * DeviceScale,
                Name    = "Print Progress Dial"
            };

            progressRow.AddChild(progressDial);

            // create a set of controls to do baby stepping on the first layer
            var babySteppingControls = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Right,
                VAnchor = VAnchor.Center | VAnchor.Fit,
            };

            babySteppingControls.Width = 80 * GuiWidget.DeviceScale;

            progressRow.AddChild(babySteppingControls);

            // add in the move up button
            var babyStepAmount = .02;
            var upButton       = babySteppingControls.AddChild(new IconButton(StaticData.Instance.LoadIcon("Up Arrow.png", 32, 32).SetToColor(theme.TextColor), theme)
            {
                HAnchor          = HAnchor.Center,
                VAnchor          = VAnchor.Absolute,
                Margin           = 0,
                BackgroundRadius = theme.ButtonRadius,
                ToolTipText      = "Raise extruder".Localize() + "\n\n*" + "First layer only".Localize() + "*",
            });

            upButton.Click += (s, e) =>
            {
                printer.Settings.ForTools <double>(SettingsKey.baby_step_z_offset, (key, value, i) =>
                {
                    if (printer.Connection.ActiveExtruderIndex == i)
                    {
                        var currentZ = value + babyStepAmount;
                        printer.Settings.SetValue(key, currentZ.ToString("0.##"));
                    }
                });
            };

            // add in the current position display
            var zTuning = babySteppingControls.AddChild(new ZTuningWidget(printer, theme, false)
            {
                HAnchor = HAnchor.Center | HAnchor.Fit,
                VAnchor = VAnchor.Fit,
                Margin  = new BorderDouble(0, 3, 0, 0),
                Padding = 0,
            });

            babySteppingControls.AddChild(new TextWidget("Z Offset".Localize(), pointSize: 8)
            {
                TextColor = theme.TextColor,
                Margin    = new BorderDouble(0, 0, 0, 3),
                AutoExpandBoundsToText = true,
                HAnchor = HAnchor.Center,
            });

            // add in the move down button
            var downButton = babySteppingControls.AddChild(new IconButton(StaticData.Instance.LoadIcon("Down Arrow.png", 32, 32).SetToColor(theme.TextColor), theme)
            {
                HAnchor          = HAnchor.Center,
                VAnchor          = VAnchor.Absolute,
                Margin           = 0,
                BackgroundRadius = new RadiusCorners(theme.ButtonRadius, theme.ButtonRadius, 0, 0),
                ToolTipText      = "Lower extruder".Localize() + "\n\n*" + "First layer only".Localize() + "*",
            });

            downButton.Click += (s, e) =>
            {
                printer.Settings.ForTools <double>(SettingsKey.baby_step_z_offset, (key, value, i) =>
                {
                    if (printer.Connection.ActiveExtruderIndex == i)
                    {
                        var currentZ = value - babyStepAmount;
                        printer.Settings.SetValue(key, currentZ.ToString("0.##"));
                    }
                });
            };

            // build the bottom row to hold re-slice
            var bottomRow = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };

            topToBottom.AddChild(bottomRow);

            var resliceMessageRow = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Visible = false
            };

            topToBottom.AddChild(resliceMessageRow);

            var timeContainer = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Center | HAnchor.Fit,
                Margin  = 3
            };

            bottomRow.AddChild(timeContainer);

            // we can only reslice on 64 bit, because in 64 bit we always have the gcode loaded
            if (IntPtr.Size == 8 || ApplicationController.Instance.Allow32BitReSlice)
            {
                var resliceButton = new TextButton("Re-Slice", theme)
                {
                    VAnchor     = VAnchor.Center,
                    HAnchor     = HAnchor.Right,
                    Margin      = new BorderDouble(0, 0, 7, 0),
                    Name        = "Re-Slice Button",
                    ToolTipText = "Apply changes to this print".Localize() + "\n\n*" + "Plating and settings changes can be applied".Localize() + "*"
                };
                theme.MakeRoundedButton(resliceButton);
                bool activelySlicing = false;
                resliceButton.Click += (s, e) =>
                {
                    resliceButton.Enabled = false;
                    UiThread.RunOnIdle(async() =>
                    {
                        bool doSlicing = !activelySlicing && printer.Bed.EditContext.SourceItem != null;
                        if (doSlicing)
                        {
                            var errors = printer.ValidateSettings();
                            if (errors.Any(err => err.ErrorLevel == ValidationErrorLevel.Error))
                            {
                                doSlicing = false;
                                ApplicationController.Instance.ShowValidationErrors("Slicing Error".Localize(), errors);
                            }
                        }

                        if (doSlicing)
                        {
                            activelySlicing = true;
                            if (bottomRow.Name == null)
                            {
                                bottomRow.Name = await printer.Bed.EditContext.GCodeFilePath(printer);
                            }

                            await ApplicationController.Instance.Tasks.Execute("Saving".Localize(), printer, printer.Bed.SaveChanges);

                            // start up a new slice on a background thread
                            await ApplicationController.Instance.SliceItemLoadOutput(
                                printer,
                                printer.Bed.Scene,
                                await printer.Bed.EditContext.GCodeFilePath(printer));

                            // Switch to the 3D layer view if on Model view
                            if (printer.ViewState.ViewMode == PartViewMode.Model)
                            {
                                printer.ViewState.ViewMode = PartViewMode.Layers3D;
                            }

                            resliceMessageRow.Visible = true;
                            resliceMessageRow.VAnchor = VAnchor.Absolute;
                            resliceMessageRow.VAnchor = VAnchor.Fit;
                        }
                        else
                        {
                            resliceButton.Enabled = true;
                        }
                    });
                };
                bottomRow.AddChild(resliceButton);

                // setup the message row
                {
                    // when it is done queue it to the change to gcode stream
                    var switchMessage = "Switch to new G-Code?\n\nBefore you switch, check that you are seeing the changes you expect.".Localize();
                    resliceMessageRow.AddChild(new WrappedTextWidget(switchMessage, theme.DefaultFontSize, textColor: theme.TextColor)
                    {
                        Margin = new BorderDouble(7, 3)
                    });

                    var switchButtonRow = new FlowLayoutWidget(FlowDirection.RightToLeft)
                    {
                        HAnchor = HAnchor.Stretch
                    };

                    resliceMessageRow.AddChild(switchButtonRow);

                    var switchButton = new TextButton("Switch", theme)
                    {
                        VAnchor = VAnchor.Center,
                        Margin  = new BorderDouble(5),
                        Name    = "Switch Button"
                    };
                    theme.MakeRoundedButton(switchButton);

                    switchButtonRow.AddChild(switchButton);
                    switchButton.Click += async(s, e) =>
                    {
                        if (printer.Connection != null &&
                            (printer.Connection.Printing || printer.Connection.Paused))
                        {
                            printer.Connection.SwitchToGCode(await printer.Bed.EditContext.GCodeFilePath(printer));
                            bottomRow.Name = await printer.Bed.EditContext.GCodeFilePath(printer);
                        }

                        activelySlicing           = false;
                        resliceButton.Enabled     = true;
                        resliceMessageRow.Visible = false;
                    };

                    var cancelButton = new TextButton("Cancel", theme)
                    {
                        VAnchor = VAnchor.Center,
                        Margin  = new BorderDouble(0, 5),
                        Name    = "Cancel Re-Slice Button"
                    };
                    theme.MakeRoundedButton(cancelButton);

                    switchButtonRow.AddChild(cancelButton);
                    cancelButton.Click += async(s, e) =>
                    {
                        await ApplicationController.Instance.SliceItemLoadOutput(
                            printer,
                            printer.Bed.Scene,
                            bottomRow.Name);

                        activelySlicing           = false;
                        resliceButton.Enabled     = true;
                        resliceMessageRow.Visible = false;
                    };
                }
            }

            timeContainer.AddChild(new ImageWidget(StaticData.Instance.LoadIcon("fa-clock_24.png", 24, 24).SetToColor(theme.TextColor))
            {
                VAnchor = VAnchor.Center
            });

            var timeStack = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                Margin  = new BorderDouble(10, 0, 0, 0),
                Padding = new BorderDouble(5, 0, 0, 0),
                VAnchor = VAnchor.Center | VAnchor.Fit
            };

            timeContainer.AddChild(timeStack);

            var timePrinted = new TextWidget("", pointSize: 16, textColor: theme.TextColor)
            {
                AutoExpandBoundsToText = true,
                HAnchor = HAnchor.Center,
            };

            timeStack.AddChild(timePrinted);

            var timeToEnd = new TextWidget("", pointSize: 9, textColor: theme.TextColor)
            {
                AutoExpandBoundsToText = true,
                HAnchor = HAnchor.Center,
            };

            timeStack.AddChild(timeToEnd);

            var runningInterval = UiThread.SetInterval(() =>
            {
                int totalSecondsPrinted = printer.Connection.SecondsPrinted;

                int hoursPrinted   = totalSecondsPrinted / (60 * 60);
                int minutesPrinted = totalSecondsPrinted / 60 - hoursPrinted * 60;
                var secondsPrinted = totalSecondsPrinted % 60;

                // TODO: Consider if the consistency of a common time format would look and feel better than changing formats based on elapsed duration
                timePrinted.Text = GetFormatedTime(hoursPrinted, minutesPrinted, secondsPrinted);

                int totalSecondsToEnd = printer.Connection.SecondsToEnd;

                int hoursToEnd   = totalSecondsToEnd / (60 * 60);
                int minutesToEnd = totalSecondsToEnd / 60 - hoursToEnd * 60;
                var secondsToEnd = totalSecondsToEnd % 60;

                timeToEnd.Text = GetFormatedTime(hoursToEnd, minutesToEnd, secondsToEnd);

                progressDial.LayerIndex = printer.Connection.CurrentlyPrintingLayer;
                if (progressDial.LayerIndex > 0)
                {
                    babySteppingControls.Visible = false;
                }

                progressDial.LayerCompletedRatio = printer.Connection.RatioIntoCurrentLayerSeconds;
                progressDial.CompletedRatio      = printer.Connection.PercentComplete / 100;

                switch (printer.Connection.CommunicationState)
                {
                case CommunicationStates.PreparingToPrint:
                case CommunicationStates.Printing:
                case CommunicationStates.Paused:
                    bodyRow.Visible = true;
                    break;

                default:
                    bodyRow.Visible = false;
                    break;
                }
            }, 1);

            bodyRow.Closed += (s, e) => UiThread.ClearInterval(runningInterval);

            bodyRow.Visible = false;

            return(bodyRow);
        }