public override void PageIsBecomingActive()
        {
            bedStartingTemp = printer.Connection.ActualBedTemperature;

            runningInterval = UiThread.SetInterval(ShowTempChangeProgress, 1);

            if (bedTargetTemp > 0)
            {
                // start heating the bed and show our progress
                printer.Connection.TargetBedTemperature = bedTargetTemp;
            }

            if (hotEndTargetTemp > 0)
            {
                // start heating the hot end and show our progress
                printer.Connection.SetTargetHotendTemperature(0, hotEndTargetTemp);
            }

            NextButton.Enabled = false;

            // if we are trying to go to a temp of 0 than just move on to next window
            if (bedTargetTemp == 0 && hotEndTargetTemp == 0)
            {
                // advance to the next page
                UiThread.RunOnIdle(() => NextButton.InvokeClick());
            }

            base.PageIsBecomingActive();
        }
        public override void OnMouseUp(MouseEventArgs mouseEvent)
        {
            if (CurrentTrackingType != TrackBallTransformType.None)
            {
                if (CurrentTrackingType == TrackBallTransformType.Rotation)
                {
                    EndRotateAroundOrigin();

                    // try and preserve some of the velocity
                    motionQueue.AddMoveToMotionQueue(mouseEvent.Position, UiThread.CurrentTimerMs);
                    if (!Keyboard.IsKeyDown(Keys.ShiftKey))
                    {
                        currentVelocityPerMs = motionQueue.GetVelocityPixelsPerMs();
                        if (currentVelocityPerMs.LengthSquared > 0)
                        {
                            Vector2 center = LocalBounds.Center;
                            StartRotateAroundOrigin(center);
                            runningInterval = UiThread.SetInterval(ApplyVelocity, 1.0 / updatesPerSecond);
                        }
                    }
                }

                CurrentTrackingType = TrackBallTransformType.None;
            }

            base.OnMouseUp(mouseEvent);
        }
Пример #3
0
        private void WaitToRefresh()
        {
            if (UiThread.CurrentTimerMs > lastTimeContentsChanged + 500 &&
                waitingForRefresh != null)
            {
                UiThread.ClearInterval(waitingForRefresh);

                waitingForRefresh = null;
                this.ReloadContent();
            }
        }
Пример #4
0
        private void DirectoryContentsChanged(object sender, EventArgs e)
        {
            // Flag for reload
            isDirty = true;

            lastTimeContentsChanged = UiThread.CurrentTimerMs;

            // Only refresh content if we're the active container
            if (isActiveContainer &&
                waitingForRefresh == null)
            {
                waitingForRefresh = UiThread.SetInterval(WaitToRefresh, .5);
            }
        }
Пример #5
0
        public FindBedHeight(ISetupWizard setupWizard,
                             string pageDescription,
                             string setZHeightCoarseInstruction1,
                             string setZHeightCoarseInstruction2,
                             double moveDistance,
                             List <PrintLevelingWizard.ProbePosition> probePositions,
                             int probePositionsBeingEditedIndex)
            : base(setupWizard, pageDescription, setZHeightCoarseInstruction1)
        {
            this.probePositions                 = probePositions;
            this.moveAmount                     = moveDistance;
            this.lastReportedPosition           = printer.Connection.LastReportedPosition;
            this.probePositionsBeingEditedIndex = probePositionsBeingEditedIndex;

            GuiWidget spacer = new GuiWidget(15, 15);

            contentRow.AddChild(spacer);

            FlowLayoutWidget zButtonsAndInfo = new FlowLayoutWidget();

            zButtonsAndInfo.HAnchor |= Agg.UI.HAnchor.Center;
            FlowLayoutWidget zButtons = CreateZButtons();

            zButtonsAndInfo.AddChild(zButtons);

            zButtonsAndInfo.AddChild(new GuiWidget(15, 10));

            // textFields
            TextWidget zPosition = new TextWidget("Z: 0.0      ", pointSize: 12, textColor: theme.TextColor)
            {
                VAnchor = VAnchor.Center,
                Margin  = new BorderDouble(10, 0),
            };

            runningInterval = UiThread.SetInterval(() =>
            {
                Vector3 destinationPosition = printer.Connection.CurrentDestination;
                zPosition.Text = "Z: {0:0.00}".FormatWith(destinationPosition.Z);
            }, .3);

            zButtonsAndInfo.AddChild(zPosition);

            contentRow.AddChild(zButtonsAndInfo);

            contentRow.AddChild(
                this.CreateTextField(setZHeightCoarseInstruction2));
        }
Пример #6
0
        public InlineEditControl(string defaultSizeString = "-0000.00", Agg.Font.Justification justification = Agg.Font.Justification.Left)
        {
            theme        = AppContext.Theme;
            base.Visible = false;

            double pointSize = 12;

            numberDisplay = new TextWidget(defaultSizeString, 0, 0, pointSize, justification: justification, textColor: theme.TextColor)
            {
                Visible = false,
                VAnchor = VAnchor.Bottom,
                HAnchor = HAnchor.Left,
                Text    = "0",
            };
            AddChild(numberDisplay);

            numberEdit = new MHNumberEdit(0, theme, pixelWidth: numberDisplay.Width, allowNegatives: true, allowDecimals: true)
            {
                Visible          = false,
                VAnchor          = VAnchor.Bottom,
                HAnchor          = HAnchor.Left,
                SelectAllOnFocus = true,
            };
            numberEdit.ActuallNumberEdit.InternalNumberEdit.TextChanged += (s, e) =>
            {
                numberDisplay.Text = GetDisplayString == null ? "None" : GetDisplayString.Invoke(Value);
                base.OnTextChanged(e);
            };
            numberEdit.ActuallNumberEdit.InternalNumberEdit.MaxDecimalsPlaces = 2;

            numberEdit.ActuallNumberEdit.EditComplete += (s, e) =>
            {
                EditComplete?.Invoke(this, e);
                timeSinceMouseUp.Restart();
                numberEdit.Visible    = false;
                numberDisplay.Visible = true;
            };

            AddChild(numberEdit);

            VAnchor = VAnchor.Fit;
            HAnchor = HAnchor.Fit;

            runningInterval = UiThread.SetInterval(HideIfApplicable, .1);
        }
        private void LookForTempRequest(object sender, EventArgs e)
        {
            var stringEvent = e as StringEventArgs;

            if (stringEvent != null &&
                stringEvent.Data.Contains("M104"))
            {
                startingTemp = printer.Connection.GetActualHotendTemperature(0);
                RunningInterval runningInterval = null;
                runningInterval = UiThread.SetInterval(() =>
                {
                    runningInterval.Continue  = !HasBeenClosed && progressBar.RatioComplete < 1;
                    progressBar.Visible       = true;
                    double targetTemp         = printer.Connection.GetTargetHotendTemperature(0);
                    double actualTemp         = printer.Connection.GetActualHotendTemperature(0);
                    double totalDelta         = targetTemp - startingTemp;
                    double currentDelta       = actualTemp - startingTemp;
                    double ratioDone          = totalDelta != 0 ? (currentDelta / totalDelta) : 1;
                    progressBar.RatioComplete = Math.Min(Math.Max(0, ratioDone), 1);
                    progressBarText.Text      = $"Temperature: {actualTemp:0} / {targetTemp:0}";
                }, 1);
            }
        }
Пример #8
0
        public override void OnMouseUp(MouseEventArgs mouseEvent)
        {
            if (!LockTrackBall && TrackBallController.CurrentTrackingType != TrackBallTransformType.None)
            {
                if (TrackBallController.CurrentTrackingType == TrackBallTransformType.Rotation)
                {
                    // try and preserve some of the velocity
                    motionQueue.AddMoveToMotionQueue(mouseEvent.Position, UiThread.CurrentTimerMs);

                    if (!Keyboard.IsKeyDown(Keys.ShiftKey))
                    {
                        currentVelocityPerMs = motionQueue.GetVelocityPixelsPerMs();
                        if (currentVelocityPerMs.LengthSquared > 0)
                        {
                            runningInterval = UiThread.SetInterval(ApplyVelocity, 1.0 / updatesPerSecond);
                        }
                    }
                }

                TrackBallController.OnMouseUp();
            }

            base.OnMouseUp(mouseEvent);
        }
Пример #9
0
        public override void OnLoad(EventArgs args)
        {
            // hook our parent so we can turn off the bed when we are done with leveling
            this.DialogWindow.Closed += WizardWindow_Closed;

            bedStartingTemp = printer.Connection.ActualBedTemperature;

            runningInterval = UiThread.SetInterval(ShowTempChangeProgress, 1);

            if (bedTargetTemp > 0)
            {
                // start heating the bed and show our progress
                printer.Connection.TargetBedTemperature = bedTargetTemp;
            }

            for (int i = 0; i < targetHotendTemps.Length; i++)
            {
                if (targetHotendTemps[i] > 0)
                {
                    // start heating the hot end and show our progress
                    printer.Connection.SetTargetHotendTemperature(i, targetHotendTemps[i]);
                }
            }

            NextButton.Enabled = false;

            // if we are trying to go to a temp of 0 than just move on to next window
            if (bedTargetTemp == 0 &&
                targetHotendTemps.All(i => i == 0))
            {
                // advance to the next page
                UiThread.RunOnIdle(() => NextButton.InvokeClick());
            }

            base.OnLoad(args);
        }
Пример #10
0
        protected override IEnumerator <PrinterSetupWizardPage> GetWizardSteps()
        {
            var levelingStrings = new LevelingStrings(printer.Settings);

            var title        = "Select Material".Localize();
            var instructions = "Please select the material you will be printing with.".Localize();

            if (onlyLoad)
            {
                title        = "Load Material".Localize();
                instructions = "Please select the material you want to load.".Localize();
            }

            // select the material
            yield return(new SelectMaterialPage(this, title, instructions, onlyLoad ? "Load".Localize() : "Select".Localize(), onlyLoad));

            var theme = ApplicationController.Instance.Theme;

            // show the trim filament message
            {
                PrinterSetupWizardPage trimFilamentPage = null;
                trimFilamentPage = new PrinterSetupWizardPage(
                    this,
                    "Trim Filament".Localize(),
                    "")
                {
                    BecomingActive = () =>
                    {
                        // start heating up the extruder
                        printer.Connection.SetTargetHotendTemperature(0, printer.Settings.GetValue <double>(SettingsKey.temperature));

                        var markdownText   = printer.Settings.GetValue(SettingsKey.trim_filament_markdown);
                        var markdownWidget = new MarkdownWidget(theme);
                        markdownWidget.Markdown = markdownText = markdownText.Replace("\\n", "\n");
                        trimFilamentPage.ContentRow.AddChild(markdownWidget);
                    }
                };
                yield return(trimFilamentPage);
            }

            // show the insert filament page
            {
                RunningInterval        runningGCodeCommands = null;
                PrinterSetupWizardPage insertFilamentPage   = null;
                insertFilamentPage = new PrinterSetupWizardPage(
                    this,
                    "Insert Filament".Localize(),
                    "")
                {
                    BecomingActive = () =>
                    {
                        var markdownText   = printer.Settings.GetValue(SettingsKey.insert_filament_markdown2);
                        var markdownWidget = new MarkdownWidget(theme);
                        markdownWidget.Markdown = markdownText = markdownText.Replace("\\n", "\n");
                        insertFilamentPage.ContentRow.AddChild(markdownWidget);

                        // turn off the fan
                        printer.Connection.FanSpeed0To255 = 0;
                        // Allow extrusion at any temperature. S0 only works on Marlin S1 works on repetier and marlin
                        printer.Connection.QueueLine("M302 S1");

                        var runningTime = Stopwatch.StartNew();
                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                printer.Connection.MoveRelative(PrinterCommunication.PrinterConnection.Axis.E, .2, 80);
                                int secondsToRun = 300;
                                if (runningTime.ElapsedMilliseconds > secondsToRun * 1000)
                                {
                                    UiThread.ClearInterval(runningGCodeCommands);
                                }
                            }
                        },
                                                                    .1);
                    },
                    BecomingInactive = () =>
                    {
                        if (runningGCodeCommands != null)
                        {
                            UiThread.ClearInterval(runningGCodeCommands);
                        }
                    }
                };
                insertFilamentPage.Closed += (s, e) =>
                {
                    if (runningGCodeCommands != null)
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };

                yield return(insertFilamentPage);
            }

            // show the loading filament progress bar
            {
                RunningInterval        runningGCodeCommands = null;
                PrinterSetupWizardPage loadingFilamentPage  = null;
                loadingFilamentPage = new PrinterSetupWizardPage(
                    this,
                    "Loading Filament".Localize(),
                    "")
                {
                    BecomingActive = () =>
                    {
                        loadingFilamentPage.NextButton.Enabled = false;

                        // add the progress bar
                        var holder = new FlowLayoutWidget()
                        {
                            Margin = new BorderDouble(3, 0, 0, 10),
                        };
                        var progressBar = new ProgressBar((int)(150 * GuiWidget.DeviceScale), (int)(15 * GuiWidget.DeviceScale))
                        {
                            FillColor       = theme.PrimaryAccentColor,
                            BorderColor     = theme.TextColor,
                            BackgroundColor = Color.White,
                            VAnchor         = VAnchor.Center,
                        };
                        var progressBarText = new TextWidget("", pointSize: 10, textColor: theme.TextColor)
                        {
                            AutoExpandBoundsToText = true,
                            Margin  = new BorderDouble(5, 0, 0, 0),
                            VAnchor = VAnchor.Center,
                        };
                        holder.AddChild(progressBar);
                        holder.AddChild(progressBarText);
                        loadingFilamentPage.ContentRow.AddChild(holder);

                        // Allow extrusion at any temperature. S0 only works on Marlin S1 works on repetier and marlin
                        printer.Connection.QueueLine("M302 S1");
                        // send a dwel to empty out the current move commands
                        printer.Connection.QueueLine("G4 P1");
                        // put in a second one to use as a signal for the first being processed
                        printer.Connection.QueueLine("G4 P1");
                        // start heating up the extruder
                        printer.Connection.SetTargetHotendTemperature(0, printer.Settings.GetValue <double>(SettingsKey.temperature));

                        var loadingSpeedMmPerS     = printer.Settings.GetValue <double>(SettingsKey.load_filament_speed);
                        var loadLengthMm           = Math.Max(1, printer.Settings.GetValue <double>(SettingsKey.load_filament_length));
                        var remainingLengthMm      = loadLengthMm;
                        var maxSingleExtrudeLength = 20;

                        Stopwatch runningTime   = null;
                        var       expectedTimeS = loadLengthMm / loadingSpeedMmPerS;

                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                if (runningTime == null)
                                {
                                    runningTime = Stopwatch.StartNew();
                                }

                                if (progressBar.RatioComplete < 1)
                                {
                                    var thisExtrude = Math.Min(remainingLengthMm, maxSingleExtrudeLength);
                                    var currentE    = printer.Connection.CurrentExtruderDestination;
                                    printer.Connection.QueueLine("G1 E{0:0.###} F{1}".FormatWith(currentE + thisExtrude, loadingSpeedMmPerS * 60));
                                    remainingLengthMm        -= thisExtrude;
                                    var elapsedSeconds        = runningTime.Elapsed.TotalSeconds;
                                    progressBar.RatioComplete = Math.Min(1, elapsedSeconds / expectedTimeS);
                                    progressBarText.Text      = $"Loading Filament: {Math.Max(0, expectedTimeS - elapsedSeconds):0}";
                                }
                            }

                            if (progressBar.RatioComplete == 1 &&
                                remainingLengthMm <= .001)
                            {
                                UiThread.ClearInterval(runningGCodeCommands);
                                loadingFilamentPage.NextButton.InvokeClick();
                            }
                        },
                                                                    .1);
                    },
                    BecomingInactive = () =>
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };
                loadingFilamentPage.Closed += (s, e) =>
                {
                    UiThread.ClearInterval(runningGCodeCommands);
                };

                yield return(loadingFilamentPage);
            }

            // wait for extruder to heat
            {
                double targetHotendTemp = printer.Settings.Helpers.ExtruderTemperature(0);
                yield return(new WaitForTempPage(
                                 this,
                                 "Waiting For Printer To Heat".Localize(),
                                 "Waiting for the hotend to heat to ".Localize() + targetHotendTemp + "°C.\n"
                                 + "This will ensure that filament is able to flow through the nozzle.".Localize() + "\n"
                                 + "\n"
                                 + "Warning! The tip of the nozzle will be HOT!".Localize() + "\n"
                                 + "Avoid contact with your skin.".Localize(),
                                 0,
                                 targetHotendTemp));
            }

            // extrude slowly so that we can prime the extruder
            {
                RunningInterval        runningGCodeCommands = null;
                PrinterSetupWizardPage runningCleanPage     = null;
                runningCleanPage = new PrinterSetupWizardPage(
                    this,
                    "Wait For Running Clean".Localize(),
                    "")
                {
                    BecomingActive = () =>
                    {
                        var markdownText   = printer.Settings.GetValue(SettingsKey.running_clean_markdown2);
                        var markdownWidget = new MarkdownWidget(theme);
                        markdownWidget.Markdown = markdownText = markdownText.Replace("\\n", "\n");
                        runningCleanPage.ContentRow.AddChild(markdownWidget);

                        var runningTime = Stopwatch.StartNew();
                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                printer.Connection.MoveRelative(PrinterCommunication.PrinterConnection.Axis.E, .35, 140);
                                int secondsToRun = 90;
                                if (runningTime.ElapsedMilliseconds > secondsToRun * 1000)
                                {
                                    UiThread.ClearInterval(runningGCodeCommands);
                                }
                            }
                        },
                                                                    .1);
                    },
                    BecomingInactive = () =>
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };
                runningCleanPage.Closed += (s, e) =>
                {
                    UiThread.ClearInterval(runningGCodeCommands);
                    printer.Settings.SetValue(SettingsKey.filament_has_been_loaded, "1");
                };

                yield return(runningCleanPage);
            }

            // put up a success message
            PrinterSetupWizardPage finalPage = null;

            finalPage = new PrinterSetupWizardPage(this, "Success".Localize(), "Success!\n\nYour filament should now be loaded".Localize())
            {
                BecomingActive = () =>
                {
                    finalPage.ShowWizardFinished();
                }
            };

            yield return(finalPage);
        }
        protected override IEnumerator <WizardPage> GetPages()
        {
            var extruderCount = printer.Settings.GetValue <int>(SettingsKey.extruder_count);

            var levelingStrings = new LevelingStrings();

            var title        = "Unload Material".Localize();
            var instructions = "Please select the material you want to unload.".Localize();

            if (extruderCount > 1)
            {
                instructions = "Please select the material you want to unload from extruder {0}.".Localize().FormatWith(extruderIndex + 1);
            }

            // select the material
            yield return(new SelectMaterialPage(this, title, instructions, "Unload".Localize(), extruderIndex, false, false)
            {
                WindowTitle = Title
            });

            var theme = ApplicationController.Instance.Theme;

            // wait for extruder to heat
            {
                var targetHotendTemp = printer.Settings.Helpers.ExtruderTargetTemperature(extruderIndex);
                var temps            = new double[4];
                temps[extruderIndex] = targetHotendTemp;
                yield return(new WaitForTempPage(
                                 this,
                                 "Waiting For Printer To Heat".Localize(),
                                 (extruderCount > 1 ? "Waiting for hotend {0} to heat to ".Localize().FormatWith(extruderIndex + 1) : "Waiting for the hotend to heat to ".Localize()) + targetHotendTemp + "°C.\n"
                                 + "This will ensure that filament is able to flow through the nozzle.".Localize() + "\n"
                                 + "\n"
                                 + "Warning! The tip of the nozzle will be HOT!".Localize() + "\n"
                                 + "Avoid contact with your skin.".Localize(),
                                 0,
                                 temps));
            }

            // show the unloading filament progress bar
            {
                int extruderPriorToUnload = printer.Connection.ActiveExtruderIndex;

                RunningInterval runningGCodeCommands  = null;
                var             unloadingFilamentPage = new WizardPage(this, "Unloading Filament".Localize(), "")
                {
                    PageLoad = (page) =>
                    {
                        page.NextButton.Enabled = false;

                        // add the progress bar
                        var holder = new FlowLayoutWidget()
                        {
                            Margin = new BorderDouble(3, 0, 0, 10),
                        };
                        var progressBar = new ProgressBar((int)(150 * GuiWidget.DeviceScale), (int)(15 * GuiWidget.DeviceScale))
                        {
                            FillColor       = theme.PrimaryAccentColor,
                            BorderColor     = theme.TextColor,
                            BackgroundColor = Color.White,
                            VAnchor         = VAnchor.Center,
                        };
                        var progressBarText = new TextWidget("", pointSize: 10, textColor: theme.TextColor)
                        {
                            AutoExpandBoundsToText = true,
                            Margin  = new BorderDouble(5, 0, 0, 0),
                            VAnchor = VAnchor.Center,
                        };
                        holder.AddChild(progressBar);
                        holder.AddChild(progressBarText);
                        page.ContentRow.AddChild(holder);

                        if (extruderCount > 1)
                        {
                            // reset the extruder that was active
                            printer.Connection.QueueLine($"T{extruderIndex}");
                        }

                        // reset the extrusion amount so this is easier to debug
                        printer.Connection.QueueLine("G92 E0");

                        // Allow extrusion at any temperature. S0 only works on Marlin S1 works on repetier and marlin
                        printer.Connection.QueueLine("M302 S1");
                        // send a dwell to empty out the current move commands
                        printer.Connection.QueueLine("G4 P1");
                        // put in a second one to use as a signal for the first being processed
                        printer.Connection.QueueLine("G4 P1");
                        // start heating up the extruder
                        if (extruderIndex == 0)
                        {
                            printer.Connection.SetTargetHotendTemperature(0, printer.Settings.GetValue <double>(SettingsKey.temperature));
                        }
                        else
                        {
                            printer.Connection.SetTargetHotendTemperature(extruderIndex, printer.Settings.GetValue <double>(SettingsKey.temperature + extruderIndex.ToString()));
                        }

                        var loadingSpeedMmPerS     = printer.Settings.GetValue <double>(SettingsKey.load_filament_speed);
                        var loadLengthMm           = Math.Max(1, printer.Settings.GetValue <double>(SettingsKey.unload_filament_length));
                        var remainingLengthMm      = loadLengthMm;
                        var maxSingleExtrudeLength = 20;

                        Stopwatch runningTime   = null;
                        var       expectedTimeS = loadLengthMm / loadingSpeedMmPerS;

                        // push some out first
                        var currentE = printer.Connection.CurrentExtruderDestination;
                        printer.Connection.QueueLine("G1 E{0:0.###} F600".FormatWith(currentE + 15));

                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                if (runningTime == null)
                                {
                                    runningTime = Stopwatch.StartNew();
                                }

                                if (progressBar.RatioComplete < 1 ||
                                    remainingLengthMm >= .001)
                                {
                                    var thisExtrude = Math.Min(remainingLengthMm, maxSingleExtrudeLength);
                                    currentE        = printer.Connection.CurrentExtruderDestination;
                                    printer.Connection.QueueLine("G1 E{0:0.###} F{1}".FormatWith(currentE - thisExtrude, loadingSpeedMmPerS * 60));
                                    // make sure we wait for this command to finish so we can cancel the unload at any time without delay
                                    printer.Connection.QueueLine("G4 P1");
                                    remainingLengthMm        -= thisExtrude;
                                    var elapsedSeconds        = runningTime.Elapsed.TotalSeconds;
                                    progressBar.RatioComplete = Math.Min(1, elapsedSeconds / expectedTimeS);
                                    progressBarText.Text      = $"Unloading Filament: {Math.Max(0, expectedTimeS - elapsedSeconds):0}";
                                }
                            }

                            if (progressBar.RatioComplete == 1 &&
                                remainingLengthMm <= .001)
                            {
                                UiThread.ClearInterval(runningGCodeCommands);
                                page.NextButton.InvokeClick();
                            }
                        },
                                                                    .1);
                    },
                    PageClose = () =>
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };
                unloadingFilamentPage.Closed += (s, e) =>
                {
                    UiThread.ClearInterval(runningGCodeCommands);
                    if (extruderCount > 1)
                    {
                        // reset the extruder that was active
                        printer.Connection.QueueLine($"T{extruderPriorToUnload}");
                    }
                    printer.Connection.QueueLine("G92 E0");
                };

                yield return(unloadingFilamentPage);
            }

            // put up a success message
            yield return(new DoneUnloadingPage(this, extruderIndex));
        }
Пример #12
0
        private IEnumerator <WizardPage> GetPages()
        {
            var extruderCount = printer.Settings.GetValue <int>(SettingsKey.extruder_count);

            var levelingStrings = new LevelingStrings();

            var instructions = "Please select the material you want to load.".Localize();

            if (extruderCount > 1)
            {
                instructions = "Please select the material you want to load into extruder {0}.".Localize().FormatWith(extruderIndex + 1);
            }

            // select the material
            yield return(new SelectMaterialPage(this, "Load Material".Localize(), instructions, "Select".Localize(), extruderIndex, true, showAlreadyLoadedButton)
            {
                WindowTitle = WindowTitle
            });

            var theme = ApplicationController.Instance.Theme;

            // show the trim filament message
            {
                var trimFilamentPage = new WizardPage(this, "Trim Filament".Localize(), "")
                {
                    PageLoad = (page) =>
                    {
                        // start heating up the extruder
                        printer.Connection.SetTargetHotendTemperature(extruderIndex, printer.Settings.GetValue <double>(SettingsKey.temperature));

                        var markdownText   = printer.Settings.GetValue(SettingsKey.trim_filament_markdown);
                        var markdownWidget = new MarkdownWidget(theme);
                        markdownWidget.Markdown = markdownText = markdownText.Replace("\\n", "\n");
                        page.ContentRow.AddChild(markdownWidget);
                    }
                };
                yield return(trimFilamentPage);
            }

            if (extruderCount > 1)
            {
                // reset the extruder that was active
                printer.Connection.QueueLine($"T{extruderIndex}");
            }

            // reset the extrusion amount so this is easier to debug
            printer.Connection.QueueLine("G92 E0");

            // show the insert filament page
            {
                RunningInterval runningGCodeCommands = null;
                var             insertFilamentPage   = new WizardPage(this, "Insert Filament".Localize(), "")
                {
                    PageLoad = (page) =>
                    {
                        var markdownText = printer.Settings.GetValue(SettingsKey.insert_filament_markdown2);
                        if (extruderIndex == 1)
                        {
                            markdownText = printer.Settings.GetValue(SettingsKey.insert_filament_1_markdown);
                        }
                        var markdownWidget = new MarkdownWidget(theme);
                        markdownWidget.Markdown = markdownText = markdownText.Replace("\\n", "\n");
                        page.ContentRow.AddChild(markdownWidget);

                        // turn off the fan
                        printer.Connection.FanSpeed0To255 = 0;
                        // Allow extrusion at any temperature. S0 only works on Marlin S1 works on repetier and marlin
                        printer.Connection.QueueLine("M302 S1");

                        int maxSecondsToStartLoading = 300;
                        var runningTime = Stopwatch.StartNew();
                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                printer.Connection.MoveRelative(PrinterCommunication.PrinterConnection.Axis.E, 1, 80);
                                // send a dwell to empty out the current move commands
                                printer.Connection.QueueLine("G4 P1");

                                if (runningTime.ElapsedMilliseconds > maxSecondsToStartLoading * 1000)
                                {
                                    UiThread.ClearInterval(runningGCodeCommands);
                                }
                            }
                        },
                                                                    .1);
                    },
                    PageClose = () =>
                    {
                        if (runningGCodeCommands != null)
                        {
                            UiThread.ClearInterval(runningGCodeCommands);
                        }
                    }
                };
                insertFilamentPage.Closed += (s, e) =>
                {
                    if (runningGCodeCommands != null)
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };

                yield return(insertFilamentPage);
            }

            // show the loading filament progress bar
            {
                RunningInterval runningGCodeCommands = null;
                var             loadingFilamentPage  = new WizardPage(this, "Loading Filament".Localize(), "")
                {
                    PageLoad = (page) =>
                    {
                        page.NextButton.Enabled = false;

                        // add the progress bar
                        var holder = new FlowLayoutWidget()
                        {
                            Margin = new BorderDouble(3, 0, 0, 10),
                        };
                        var progressBar = new ProgressBar((int)(150 * GuiWidget.DeviceScale), (int)(15 * GuiWidget.DeviceScale))
                        {
                            FillColor       = theme.PrimaryAccentColor,
                            BorderColor     = theme.TextColor,
                            BackgroundColor = Color.White,
                            VAnchor         = VAnchor.Center,
                        };
                        var progressBarText = new TextWidget("", pointSize: 10, textColor: theme.TextColor)
                        {
                            AutoExpandBoundsToText = true,
                            Margin  = new BorderDouble(5, 0, 0, 0),
                            VAnchor = VAnchor.Center,
                        };
                        holder.AddChild(progressBar);
                        holder.AddChild(progressBarText);
                        page.ContentRow.AddChild(holder);

                        // Allow extrusion at any temperature. S0 only works on Marlin S1 works on repetier and marlin
                        printer.Connection.QueueLine("M302 S1");
                        // send a dwell to empty out the current move commands
                        printer.Connection.QueueLine("G4 P1");
                        // put in a second one to use as a signal for the first being processed
                        printer.Connection.QueueLine("G4 P1");
                        // start heating up the extruder
                        printer.Connection.SetTargetHotendTemperature(extruderIndex, printer.Settings.GetValue <double>(SettingsKey.temperature));

                        var loadingSpeedMmPerS     = printer.Settings.GetValue <double>(SettingsKey.load_filament_speed);
                        var loadLengthMm           = Math.Max(1, printer.Settings.GetValue <double>(SettingsKey.load_filament_length));
                        var remainingLengthMm      = loadLengthMm;
                        var maxSingleExtrudeLength = 20;

                        Stopwatch runningTime   = null;
                        var       expectedTimeS = loadLengthMm / loadingSpeedMmPerS;

                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                if (runningTime == null)
                                {
                                    runningTime = Stopwatch.StartNew();
                                }

                                if (progressBar.RatioComplete < 1 ||
                                    remainingLengthMm >= .001)
                                {
                                    var thisExtrude = Math.Min(remainingLengthMm, maxSingleExtrudeLength);
                                    var currentE    = printer.Connection.CurrentExtruderDestination;
                                    printer.Connection.QueueLine("G1 E{0:0.###} F{1}".FormatWith(currentE + thisExtrude, loadingSpeedMmPerS * 60));
                                    // make sure we wait for this command to finish so we can cancel the unload at any time without delay
                                    printer.Connection.QueueLine("G4 P1");
                                    remainingLengthMm        -= thisExtrude;
                                    var elapsedSeconds        = runningTime.Elapsed.TotalSeconds;
                                    progressBar.RatioComplete = Math.Min(1, elapsedSeconds / expectedTimeS);
                                    progressBarText.Text      = $"Loading Filament: {Math.Max(0, expectedTimeS - elapsedSeconds):0}";
                                }
                            }

                            if (progressBar.RatioComplete == 1 &&
                                remainingLengthMm <= .001)
                            {
                                UiThread.ClearInterval(runningGCodeCommands);
                                page.NextButton.InvokeClick();
                            }
                        },
                                                                    .1);
                    },
                    PageClose = () =>
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };
                loadingFilamentPage.Closed += (s, e) =>
                {
                    UiThread.ClearInterval(runningGCodeCommands);
                };

                yield return(loadingFilamentPage);
            }

            // wait for extruder to heat
            {
                var targetHotendTemp = printer.Settings.Helpers.ExtruderTargetTemperature(extruderIndex);
                var temps            = new double[4];
                temps[extruderIndex] = targetHotendTemp;
                yield return(new WaitForTempPage(
                                 this,
                                 "Waiting For Printer To Heat".Localize(),
                                 "Waiting for the hotend to heat to ".Localize() + targetHotendTemp + "°C.\n"
                                 + "This will ensure that filament is able to flow through the nozzle.".Localize() + "\n"
                                 + "\n"
                                 + "Warning! The tip of the nozzle will be HOT!".Localize() + "\n"
                                 + "Avoid contact with your skin.".Localize(),
                                 0,
                                 temps));
            }

            // extrude slowly so that we can prime the extruder
            {
                RunningInterval runningGCodeCommands = null;
                var             runningCleanPage     = new WizardPage(this, "Wait For Running Clean".Localize(), "")
                {
                    PageLoad = (page) =>
                    {
                        var markdownText = printer.Settings.GetValue(SettingsKey.running_clean_markdown2);
                        if (extruderIndex == 1)
                        {
                            markdownText = printer.Settings.GetValue(SettingsKey.running_clean_1_markdown);
                        }
                        var markdownWidget = new MarkdownWidget(theme);
                        markdownWidget.Markdown = markdownText = markdownText.Replace("\\n", "\n");
                        page.ContentRow.AddChild(markdownWidget);

                        var runningTime = Stopwatch.StartNew();
                        runningGCodeCommands = UiThread.SetInterval(() =>
                        {
                            if (printer.Connection.NumQueuedCommands == 0)
                            {
                                printer.Connection.MoveRelative(PrinterCommunication.PrinterConnection.Axis.E, 2, 140);
                                // make sure we wait for this command to finish so we can cancel the unload at any time without delay
                                printer.Connection.QueueLine("G4 P1");
                                int secondsToRun = 90;
                                if (runningTime.ElapsedMilliseconds > secondsToRun * 1000)
                                {
                                    UiThread.ClearInterval(runningGCodeCommands);
                                }
                            }
                        },
                                                                    .1);
                    },
                    PageClose = () =>
                    {
                        UiThread.ClearInterval(runningGCodeCommands);
                    }
                };
                runningCleanPage.Closed += (s, e) =>
                {
                    switch (extruderIndex)
                    {
                    case 0:
                        printer.Settings.SetValue(SettingsKey.filament_has_been_loaded, "1");
                        break;

                    case 1:
                        printer.Settings.SetValue(SettingsKey.filament_1_has_been_loaded, "1");
                        break;
                    }
                    printer.Settings.SetValue(SettingsKey.filament_has_been_loaded, "1");
                };

                yield return(runningCleanPage);
            }

            // put up a success message
            yield return(new DoneLoadingPage(this, extruderIndex));
        }
Пример #13
0
        public RunningTaskRow(string title, RunningTaskDetails taskDetails, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.taskDetails = taskDetails;
            this.theme       = theme;

            this.MinimumSize = new Vector2(100, 20);

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

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

            this.AddChild(rowContainer);

            var topRow = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Padding = 0,
            };

            rowContainer.AddChild(topRow);

            progressBar = new ProgressBar()
            {
                HAnchor         = HAnchor.Stretch,
                Height          = 2,
                VAnchor         = VAnchor.Absolute | VAnchor.Bottom,
                FillColor       = ActiveTheme.Instance.PrimaryAccentColor,
                BorderColor     = Color.Transparent,
                BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor,
                Margin          = new BorderDouble(32, 7, theme.ButtonHeight * 2 + 14, 0),
            };
            rowContainer.AddChild(progressBar);

            expandButton = new ExpandCheckboxButton(!string.IsNullOrWhiteSpace(title) ? title : taskDetails.Title, theme, 10)
            {
                VAnchor = VAnchor.Center | VAnchor.Fit,
                HAnchor = HAnchor.Stretch,
                Checked = false,
                Padding = 0
            };
            expandButton.CheckedStateChanged += (s, e) =>
            {
                taskDetails.IsExpanded = expandButton.Checked;
                SetExpansionMode(theme, detailsPanel, expandButton.Checked);
            };
            topRow.AddChild(expandButton);

            IconButton resumeButton = null;

            var pauseButton = new IconButton(AggContext.StaticData.LoadIcon("fa-pause_12.png", theme.InvertIcons), theme)
            {
                Margin      = theme.ButtonSpacing,
                Enabled     = taskDetails.Options?.PauseAction != null,
                ToolTipText = taskDetails.Options?.PauseToolTip ?? "Pause".Localize()
            };

            if (taskDetails.Options?.IsPaused != null)
            {
                RunningInterval runningInterval = null;
                runningInterval = UiThread.SetInterval(() =>
                {
                    if (taskDetails.Options.IsPaused())
                    {
                        pauseButton.Visible  = false;
                        resumeButton.Visible = true;
                    }
                    else
                    {
                        pauseButton.Visible  = true;
                        resumeButton.Visible = false;
                    }
                    if (this.HasBeenClosed)
                    {
                        runningInterval.Continue = false;
                    }
                }, .2);
            }
            pauseButton.Click += (s, e) =>
            {
                taskDetails.Options?.PauseAction();
                pauseButton.Visible  = false;
                resumeButton.Visible = true;
            };
            topRow.AddChild(pauseButton);

            resumeButton = new IconButton(AggContext.StaticData.LoadIcon("fa-play_12.png", theme.InvertIcons), theme)
            {
                Visible     = false,
                Margin      = theme.ButtonSpacing,
                ToolTipText = taskDetails.Options?.ResumeToolTip ?? "Resume".Localize(),
                Name        = "Resume Task Button"
            };
            resumeButton.Click += (s, e) =>
            {
                taskDetails.Options?.ResumeAction();
                pauseButton.Visible  = true;
                resumeButton.Visible = false;
            };
            topRow.AddChild(resumeButton);

            var stopButton = new IconButton(AggContext.StaticData.LoadIcon("fa-stop_12.png", theme.InvertIcons), theme)
            {
                Margin      = theme.ButtonSpacing,
                Name        = "Stop Task Button",
                ToolTipText = taskDetails.Options?.StopToolTip ?? "Cancel".Localize()
            };

            stopButton.Click += (s, e) =>
            {
                var stopAction = taskDetails.Options?.StopAction;
                if (stopAction == null)
                {
                    taskDetails.CancelTask();
                }
                else
                {
                    stopAction.Invoke();
                }
            };
            topRow.AddChild(stopButton);

            this.AddChild(detailsPanel);

            // Add rich progress controls
            if (taskDetails.Options?.RichProgressWidget?.Invoke() is GuiWidget guiWidget)
            {
                detailsPanel.AddChild(guiWidget);
            }

            if (taskDetails.Options?.ReadOnlyReporting == true)
            {
                stopButton.Visible   = false;
                pauseButton.Visible  = false;
                resumeButton.Visible = false;

                // Ensure the top row is as big as it would be with buttons
                topRow.MinimumSize = new Vector2(0, resumeButton.Height);
            }

            SetExpansionMode(theme, detailsPanel, taskDetails.IsExpanded);

            taskDetails.ProgressChanged += TaskDetails_ProgressChanged;
        }
Пример #14
0
        public RunningTaskRow(string title, RunningTaskDetails taskDetails, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.taskDetails = taskDetails;
            this.theme       = theme;

            this.MinimumSize = new Vector2(100 * GuiWidget.DeviceScale, 20 * GuiWidget.DeviceScale);

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

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

            this.AddChild(rowContainer);

            var topRow = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Padding = 0,
            };

            rowContainer.AddChild(topRow);

            progressBar = new ProgressBar()
            {
                HAnchor     = HAnchor.Stretch,
                Height      = 2 * GuiWidget.DeviceScale,
                VAnchor     = VAnchor.Absolute | VAnchor.Bottom,
                FillColor   = theme.PrimaryAccentColor,
                BorderColor = Color.Transparent,
                Margin      = new BorderDouble(32, 7, theme.ButtonHeight * 2 + 14, 0),
                Visible     = !taskDetails.IsExpanded
            };
            rowContainer.AddChild(progressBar);

            expandButton = new ExpandCheckboxButton(!string.IsNullOrWhiteSpace(title) ? title : taskDetails.Title, theme, 10)
            {
                VAnchor         = VAnchor.Center | VAnchor.Fit,
                HAnchor         = HAnchor.Stretch,
                Checked         = false,
                Padding         = 0,
                AlwaysShowArrow = true
            };
            expandButton.CheckedStateChanged += (s, e) =>
            {
                taskDetails.IsExpanded = expandButton.Checked;
                SetExpansionMode(theme, detailsPanel, expandButton.Checked);
            };
            topRow.AddChild(expandButton);

            GuiWidget resumeButton = null;

            GuiWidget pauseButton = CreateIconOrTextButton("fa-pause_12.png",
                                                           taskDetails.Options?.PauseText,
                                                           taskDetails.Options?.PauseAction,
                                                           taskDetails.Options?.PauseToolTip ?? "Pause".Localize(),
                                                           "",
                                                           theme,
                                                           0);

            if (taskDetails.Options?.IsPaused != null)
            {
                RunningInterval runningInterval = null;
                runningInterval = UiThread.SetInterval(() =>
                {
                    if (taskDetails.Options.IsPaused())
                    {
                        pauseButton.Visible  = false;
                        resumeButton.Visible = true;
                    }
                    else
                    {
                        pauseButton.Visible  = true;
                        resumeButton.Visible = false;
                    }
                    if (this.HasBeenClosed)
                    {
                        UiThread.ClearInterval(runningInterval);
                    }
                }, .2);
            }
            pauseButton.Click += (s, e) =>
            {
                taskDetails.Options?.PauseAction();
                pauseButton.Visible  = false;
                resumeButton.Visible = true;
            };
            topRow.AddChild(pauseButton);


            resumeButton = CreateIconOrTextButton("fa-play_12.png",
                                                  taskDetails.Options?.ResumeText,
                                                  taskDetails.Options?.ResumeAction,
                                                  taskDetails.Options?.ResumeToolTip ?? "Resume".Localize(),
                                                  "Resume Task Button",
                                                  theme,
                                                  0);
            // start with it hidden
            resumeButton.Visible = false;

            resumeButton.Click += (s, e) =>
            {
                taskDetails.Options?.ResumeAction();
                pauseButton.Visible  = true;
                resumeButton.Visible = false;
            };
            topRow.AddChild(resumeButton);

            var stopButton = CreateIconOrTextButton("fa-stop_12.png",
                                                    taskDetails.Options?.StopText,
                                                    taskDetails.Options?.StopAction,
                                                    taskDetails.Options?.StopToolTip ?? "Cancel".Localize(),
                                                    "Stop Task Button",
                                                    theme,
                                                    5);

            stopButton.Enabled = true;

            stopButton.Click += (s, e) =>
            {
                var stopAction = taskDetails.Options?.StopAction;
                if (stopAction == null)
                {
                    taskDetails.CancelTask();
                }
                else
                {
                    stopAction.Invoke(() =>
                    {
                        stopButton.Enabled = true;
                    });
                }

                stopButton.Enabled = false;
            };
            topRow.AddChild(stopButton);

            this.AddChild(detailsPanel);

            // Add rich progress controls
            if (taskDetails.Options?.RichProgressWidget?.Invoke() is GuiWidget guiWidget)
            {
                detailsPanel.AddChild(guiWidget);
            }
            else
            {
                expandButton.Expandable = false;
            }

            if (taskDetails.Options?.ReadOnlyReporting == true)
            {
                stopButton.Visible   = false;
                pauseButton.Visible  = false;
                resumeButton.Visible = false;

                // Ensure the top row is as big as it would be with buttons
                topRow.MinimumSize = new Vector2(0, resumeButton.Height);
            }

            SetExpansionMode(theme, detailsPanel, taskDetails.IsExpanded);

            taskDetails.ProgressChanged += TaskDetails_ProgressChanged;
        }
Пример #15
0
        private GuiWidget GetPopupContent(ThemeConfig menuTheme)
        {
            var widget = new IgnoredPopupWidget()
            {
                Width           = 300,
                HAnchor         = HAnchor.Absolute,
                VAnchor         = VAnchor.Fit,
                Padding         = new BorderDouble(12, 0),
                BackgroundColor = menuTheme.BackgroundColor
            };

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

            widget.AddChild(container);

            GuiWidget hotendRow;

            container.AddChild(hotendRow = new SettingsItem(
                                   "Heated Bed".Localize(),
                                   menuTheme,
                                   new SettingsItem.ToggleSwitchConfig()
            {
                Checked      = false,
                ToggleAction = (itemChecked) =>
                {
                    var goalTemp = itemChecked ? printer.Settings.GetValue <double>(SettingsKey.bed_temperature) : 0;

                    if (itemChecked)
                    {
                        SetTargetTemperature(goalTemp);
                    }
                    else
                    {
                        SetTargetTemperature(0);
                    }
                }
            },
                                   enforceGutter: false));

            var toggleWidget = hotendRow.Children.Where(o => o is ICheckbox).FirstOrDefault();

            toggleWidget.Name = "Toggle Heater";

            heatToggle = toggleWidget as ICheckbox;

            int tabIndex        = 0;
            var settingsContext = new SettingsContext(printer, null, NamedSettingsLayers.All);

            var settingsData   = PrinterSettings.SettingsData[SettingsKey.bed_temperature];
            var temperatureRow = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields);

            container.AddChild(temperatureRow);

            // Add the temperature row to the always enabled list ensuring the field can be set when disconnected
            alwaysEnabled.Add(temperatureRow);

            // add in the temp graph
            var graph = new DataViewGraph()
            {
                DynamicallyScaleRange = false,
                MinValue  = 0,
                ShowGoal  = true,
                GoalColor = menuTheme.PrimaryAccentColor,
                GoalValue = printer.Settings.GetValue <double>(SettingsKey.bed_temperature),
                MaxValue  = 150,             // could come from some profile value in the future
                Width     = widget.Width - 20,
                Height    = 35,              // this works better if it is a common multiple of the Width
                Margin    = new BorderDouble(0, 5, 0, 0),
            };

            runningInterval = UiThread.SetInterval(() =>
            {
                graph.AddData(this.ActualTemperature);
            }, 1);

            var settingsRow = temperatureRow.DescendantsAndSelf <SliceSettingsRow>().FirstOrDefault();

            void Printer_SettingChanged(object s, StringEventArgs stringEvent)
            {
                if (stringEvent != null)
                {
                    string settingsKey = stringEvent.Data;
                    if (this.allUiFields.TryGetValue(settingsKey, out UIField uifield))
                    {
                        string currentValue = settingsContext.GetValue(settingsKey);
                        if (uifield.Value != currentValue)
                        {
                            uifield.SetValue(
                                currentValue,
                                userInitiated: false);
                        }
                    }

                    if (stringEvent.Data == SettingsKey.bed_temperature)
                    {
                        var temp = printer.Settings.GetValue <double>(SettingsKey.bed_temperature);
                        graph.GoalValue = temp;

                        // TODO: Why is this only when enabled? How does it get set to
                        if (heatToggle.Checked)
                        {
                            // TODO: Why is a UI widget who is listening to model events driving this behavior? What when it's not loaded?
                            SetTargetTemperature(temp);
                        }

                        settingsRow.UpdateStyle();
                    }
                }
            }

            printer.Settings.SettingChanged += Printer_SettingChanged;
            printer.Disposed += (s, e) => printer.Settings.SettingChanged -= Printer_SettingChanged;

            container.AddChild(graph);

            return(widget);
        }
Пример #16
0
        public PartPreviewContent(ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.AnchorAll();

            var extensionArea = new LeftClipFlowLayoutWidget()
            {
                BackgroundColor = theme.TabBarBackground,
                VAnchor         = VAnchor.Stretch,
                Padding         = new BorderDouble(left: 8)
            };

            tabControl = new ChromeTabs(extensionArea, theme)
            {
                VAnchor         = VAnchor.Stretch,
                HAnchor         = HAnchor.Stretch,
                BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor,
                BorderColor     = theme.MinimalShade,
                Border          = new BorderDouble(left: 1),
                NewTabPage      = () =>
                {
                    return(new StartTabPage(this, theme));
                }
            };
            tabControl.ActiveTabChanged += (s, e) =>
            {
                if (this.tabControl.ActiveTab?.TabContent is PartTabPage tabPage)
                {
                    var dragDropData = ApplicationController.Instance.DragDropData;

                    // Set reference on tab change
                    dragDropData.View3DWidget = tabPage.view3DWidget;
                    dragDropData.SceneContext = tabPage.sceneContext;
                }
            };

            // Force the ActionArea to be as high as ButtonHeight
            tabControl.TabBar.ActionArea.MinimumSize = new Vector2(0, theme.ButtonHeight);
            tabControl.TabBar.BackgroundColor        = theme.TabBarBackground;
            tabControl.TabBar.BorderColor            = theme.ActiveTabColor;

            // Force common padding into top region
            tabControl.TabBar.Padding = theme.TabbarPadding.Clone(top: theme.TabbarPadding.Top * 2, bottom: 0);

            // add in a what's new button
            var seeWhatsNewButton = new LinkLabel("What's New...".Localize(), theme)
            {
                Name        = "What's New Link",
                ToolTipText = "See what's new in this version of MatterControl".Localize(),
                VAnchor     = VAnchor.Center,
                Margin      = new BorderDouble(10, 0),
                TextColor   = theme.Colors.PrimaryTextColor
            };

            seeWhatsNewButton.Click += (s, e) => UiThread.RunOnIdle(() =>
            {
                UserSettings.Instance.set(UserSettingsKey.LastReadWhatsNew, JsonConvert.SerializeObject(DateTime.Now));
                DialogWindow.Show(new HelpPage("What's New"));
            });

            tabControl.TabBar.ActionArea.AddChild(seeWhatsNewButton);

            // add in the update available button
            var updateAvailableButton = new LinkLabel("Update Available".Localize(), theme)
            {
                Visible = false,
            };

            // make the function inline so we don't have to create members for the buttons
            EventHandler SetLinkButtonsVisibility = (s, e) =>
            {
                if (UserSettings.Instance.HasLookedAtWhatsNew())
                {
                    // hide it
                    seeWhatsNewButton.Visible = false;
                }

                if (UpdateControlData.Instance.UpdateStatus == UpdateControlData.UpdateStatusStates.UpdateAvailable)
                {
                    updateAvailableButton.Visible = true;
                    // if we are going to show the update link hide the whats new link no matter what
                    seeWhatsNewButton.Visible = false;
                }
                else
                {
                    updateAvailableButton.Visible = false;
                }
            };

            UserSettings.Instance.Changed += SetLinkButtonsVisibility;
            Closed += (s, e) => UserSettings.Instance.Changed -= SetLinkButtonsVisibility;

            RunningInterval showUpdateInterval = null;

            updateAvailableButton.VisibleChanged += (s, e) =>
            {
                if (!updateAvailableButton.Visible)
                {
                    if (showUpdateInterval != null)
                    {
                        showUpdateInterval.Continue = false;
                        showUpdateInterval          = null;
                    }
                    return;
                }

                showUpdateInterval = UiThread.SetInterval(() =>
                {
                    double displayTime  = 1;
                    double pulseTime    = 1;
                    double totalSeconds = 0;
                    var textWidgets     = updateAvailableButton.Descendants <TextWidget>().Where((w) => w.Visible == true).ToArray();
                    Color startColor    = theme.Colors.PrimaryTextColor;
                    // Show a highlight on the button as the user did not click it
                    Animation flashBackground = null;
                    flashBackground           = new Animation()
                    {
                        DrawTarget      = updateAvailableButton,
                        FramesPerSecond = 10,
                        Update          = (s1, updateEvent) =>
                        {
                            totalSeconds += updateEvent.SecondsPassed;
                            if (totalSeconds < displayTime)
                            {
                                double blend = AttentionGetter.GetFadeInOutPulseRatio(totalSeconds, pulseTime);
                                var color    = new Color(startColor, (int)((1 - blend) * 255));
                                foreach (var textWidget in textWidgets)
                                {
                                    textWidget.TextColor = color;
                                }
                            }
                            else
                            {
                                foreach (var textWidget in textWidgets)
                                {
                                    textWidget.TextColor = startColor;
                                }
                                flashBackground.Stop();
                            }
                        }
                    };
                    flashBackground.Start();
                }, 120);
            };

            updateAvailableButton.Name = "Update Available Link";
            SetLinkButtonsVisibility(this, null);
            updateAvailableButton.ToolTipText = "There is a new update available for download".Localize();
            updateAvailableButton.VAnchor     = VAnchor.Center;
            updateAvailableButton.Margin      = new BorderDouble(10, 0);
            updateAvailableButton.Click      += (s, e) => UiThread.RunOnIdle(() =>
            {
                UiThread.RunOnIdle(() =>
                {
                    UpdateControlData.Instance.CheckForUpdate();
                    DialogWindow.Show <CheckForUpdatesPage>();
                });
            });

            tabControl.TabBar.ActionArea.AddChild(updateAvailableButton);

            UpdateControlData.Instance.UpdateStatusChanged.RegisterEvent(SetLinkButtonsVisibility, ref unregisterEvents);

            this.AddChild(tabControl);

            ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
            {
                if (e is StringEventArgs stringEvent &&
                    stringEvent.Data == SettingsKey.printer_name &&
                    printerTab != null)
                {
                    printerTab.Text = ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name);
                }
            }, ref unregisterEvents);

            ActiveSliceSettings.ActivePrinterChanged.RegisterEvent((s, e) =>
            {
                var activePrinter = ApplicationController.Instance.ActivePrinter;

                // If ActivePrinter has been nulled and a printer tab is open, close it
                var tab1 = tabControl.AllTabs.Skip(1).FirstOrDefault();
                if ((activePrinter == null || !activePrinter.Settings.PrinterSelected) &&
                    tab1?.TabContent is PrinterTabPage)
                {
                    tabControl.RemoveTab(tab1);
                }
                else
                {
                    this.CreatePrinterTab(activePrinter, theme);
                }
            }, ref unregisterEvents);

            ApplicationController.Instance.NotifyPrintersTabRightElement(extensionArea);

            // Show fixed start page
            tabControl.AddTab(
                new ChromeTab("Start".Localize(), tabControl, tabControl.NewTabPage(), theme, hasClose: false)
            {
                MinimumSize = new Vector2(0, theme.TabButtonHeight),
                Name        = "Start Tab",
                Padding     = new BorderDouble(15, 0)
            });

            // Add a tab for the current printer
            if (ActiveSliceSettings.Instance.PrinterSelected)
            {
                this.CreatePrinterTab(ApplicationController.Instance.ActivePrinter, theme);
            }

            // Restore active tabs
            foreach (var bed in ApplicationController.Instance.Workspaces)
            {
                this.CreatePartTab("New Part", bed, theme);
            }
        }
        public RunningMacroPage(PrinterConfig printer, MacroCommandData macroData, ThemeConfig theme)
            : base("Cancel")
        {
            this.printer     = printer;
            this.WindowTitle = "Running Macro".Localize();
            this.HeaderText  = macroData.title;

            if (macroData.showMaterialSelector)
            {
                contentRow.AddChild(new PresetSelectorWidget(printer, "Material".Localize(), Color.Transparent, NamedSettingsLayers.Material, theme)
                {
                    BackgroundColor = Color.Transparent,
                    Margin          = new BorderDouble(0, 0, 0, 15)
                });
            }

            printer.Connection.LineSent.RegisterEvent(LookForTempRequest, ref unregisterEvents);

            if (macroData.waitOk | macroData.expireTime > 0)
            {
                var okButton = theme.CreateDialogButton("Continue".Localize());
                okButton.Click += (s, e) =>
                {
                    printer.Connection.MacroContinue();
                };

                this.AddPageAction(okButton);
            }

            if (macroData.image != null)
            {
                var imageWidget = new ImageWidget(macroData.image)
                {
                    HAnchor = HAnchor.Center,
                    Margin  = new BorderDouble(5, 15),
                };

                contentRow.AddChild(imageWidget);
            }

            var holder = new FlowLayoutWidget();

            progressBar = new ProgressBar((int)(150 * GuiWidget.DeviceScale), (int)(15 * GuiWidget.DeviceScale))
            {
                FillColor       = ActiveTheme.Instance.PrimaryAccentColor,
                BorderColor     = ActiveTheme.Instance.PrimaryTextColor,
                BackgroundColor = Color.White,
                Margin          = new BorderDouble(3, 0, 0, 10),
            };
            progressBarText = new TextWidget("", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
            {
                AutoExpandBoundsToText = true,
                Margin = new BorderDouble(5, 0, 0, 0),
            };
            holder.AddChild(progressBar);
            holder.AddChild(progressBarText);
            contentRow.AddChild(holder);
            progressBar.Visible = false;

            if (macroData.countDown > 0)
            {
                timeToWaitMs    = (long)(macroData.countDown * 1000);
                startTimeMs     = UiThread.CurrentTimerMs;
                runningInterval = UiThread.SetInterval(CountDownTime, .2);
            }
        }
Пример #18
0
        public MainViewWidget(ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.AnchorAll();
            this.theme           = theme;
            this.Name            = "PartPreviewContent";
            this.BackgroundColor = theme.BackgroundColor;

            // Push TouchScreenMode into GuiWidget
            GuiWidget.TouchScreenMode = UserSettings.Instance.IsTouchScreen;

            var extensionArea = new LeftClipFlowLayoutWidget()
            {
                BackgroundColor = theme.TabBarBackground,
                VAnchor         = VAnchor.Stretch,
                Padding         = new BorderDouble(left: 8)
            };

            tabControl = new ChromeTabs(extensionArea, theme)
            {
                VAnchor         = VAnchor.Stretch,
                HAnchor         = HAnchor.Stretch,
                BackgroundColor = theme.BackgroundColor,
                BorderColor     = theme.MinimalShade,
                Border          = new BorderDouble(left: 1),
            };

            tabControl.PlusClicked += (s, e) =>
            {
                UiThread.RunOnIdle(() =>
                {
                    this.CreatePartTab().ConfigureAwait(false);
                });
            };

            tabControl.ActiveTabChanged += (s, e) =>
            {
                if (this.tabControl.ActiveTab?.TabContent is PartTabPage tabPage)
                {
                    var dragDropData = ApplicationController.Instance.DragDropData;

                    // Set reference on tab change
                    dragDropData.View3DWidget = tabPage.view3DWidget;
                    dragDropData.SceneContext = tabPage.sceneContext;

                    ApplicationController.Instance.PrinterTabSelected = true;
                }
                else
                {
                    ApplicationController.Instance.PrinterTabSelected = false;
                }

                ApplicationController.Instance.MainTabKey = tabControl.SelectedTabKey;
            };

            // Force the ActionArea to be as high as ButtonHeight
            tabControl.TabBar.ActionArea.MinimumSize = new Vector2(0, theme.ButtonHeight);
            tabControl.TabBar.BackgroundColor        = theme.TabBarBackground;
            tabControl.TabBar.BorderColor            = theme.BackgroundColor;

            // Force common padding into top region
            tabControl.TabBar.Padding = theme.TabbarPadding.Clone(top: theme.TabbarPadding.Top * 2, bottom: 0);

            // add in a what's new button
            seeWhatsNewButton = new LinkLabel("What's New...".Localize(), theme)
            {
                Name        = "What's New Link",
                ToolTipText = "See what's new in this version of MatterControl".Localize(),
                VAnchor     = VAnchor.Center,
                Margin      = new BorderDouble(10, 0),
                TextColor   = theme.TextColor
            };
            seeWhatsNewButton.Click += (s, e) => UiThread.RunOnIdle(() =>
            {
                UserSettings.Instance.set(UserSettingsKey.LastReadWhatsNew, JsonConvert.SerializeObject(DateTime.Now));
                DialogWindow.Show(new HelpPage("What's New"));
            });

            tabControl.TabBar.ActionArea.AddChild(seeWhatsNewButton);

            // add in the update available button
            updateAvailableButton = new LinkLabel("Update Available".Localize(), theme)
            {
                Visible     = false,
                Name        = "Update Available Link",
                ToolTipText = "There is a new update available for download".Localize(),
                VAnchor     = VAnchor.Center,
                Margin      = new BorderDouble(10, 0)
            };

            // Register listeners
            UserSettings.Instance.SettingChanged += SetLinkButtonsVisibility;

            RunningInterval showUpdateInterval = null;

            updateAvailableButton.VisibleChanged += (s, e) =>
            {
                if (!updateAvailableButton.Visible)
                {
                    if (showUpdateInterval != null)
                    {
                        UiThread.ClearInterval(showUpdateInterval);
                        showUpdateInterval = null;
                    }
                    return;
                }

                showUpdateInterval = UiThread.SetInterval(() =>
                {
                    double displayTime  = 1;
                    double pulseTime    = 1;
                    double totalSeconds = 0;
                    var textWidgets     = updateAvailableButton.Descendants <TextWidget>().Where((w) => w.Visible == true).ToArray();
                    Color startColor    = theme.TextColor;
                    // Show a highlight on the button as the user did not click it
                    Animation flashBackground = null;
                    flashBackground           = new Animation()
                    {
                        DrawTarget      = updateAvailableButton,
                        FramesPerSecond = 10,
                        Update          = (s1, updateEvent) =>
                        {
                            totalSeconds += updateEvent.SecondsPassed;
                            if (totalSeconds < displayTime)
                            {
                                double blend = AttentionGetter.GetFadeInOutPulseRatio(totalSeconds, pulseTime);
                                var color    = new Color(startColor, (int)((1 - blend) * 255));
                                foreach (var textWidget in textWidgets)
                                {
                                    textWidget.TextColor = color;
                                }
                            }
                            else
                            {
                                foreach (var textWidget in textWidgets)
                                {
                                    textWidget.TextColor = startColor;
                                }
                                flashBackground.Stop();
                            }
                        }
                    };
                    flashBackground.Start();
                }, 120);
            };

            SetLinkButtonsVisibility(this, null);
            updateAvailableButton.Click += (s, e) => UiThread.RunOnIdle(() =>
            {
                UpdateControlData.Instance.CheckForUpdate();
                DialogWindow.Show <CheckForUpdatesPage>();
            });

            tabControl.TabBar.ActionArea.AddChild(updateAvailableButton);

            this.AddChild(tabControl);

            ApplicationController.Instance.NotifyPrintersTabRightElement(extensionArea);

            // Store tab
            tabControl.AddTab(
                new ChromeTab("Store", "Store".Localize(), tabControl, new StoreTabPage(theme), theme, hasClose: false)
            {
                MinimumSize = new Vector2(0, theme.TabButtonHeight),
                Name        = "Store Tab",
                Padding     = new BorderDouble(15, 0),
            });

            // Library tab
            var libraryWidget = new LibraryWidget(this, theme)
            {
                BackgroundColor = theme.BackgroundColor
            };

            tabControl.AddTab(
                new ChromeTab("Library", "Library".Localize(), tabControl, libraryWidget, theme, hasClose: false)
            {
                MinimumSize = new Vector2(0, theme.TabButtonHeight),
                Name        = "Library Tab",
                Padding     = new BorderDouble(15, 0),
            });

            // Hardware tab
            tabControl.AddTab(
                new ChromeTab(
                    "Hardware",
                    "Hardware".Localize(),
                    tabControl,
                    new HardwareTabPage(theme)
            {
                BackgroundColor = theme.BackgroundColor
            },
                    theme,
                    hasClose: false)
            {
                MinimumSize = new Vector2(0, theme.TabButtonHeight),
                Name        = "Hardware Tab",
                Padding     = new BorderDouble(15, 0),
            });

            if (ApplicationController.Instance.Workspaces.Count == 0)
            {
                this.CreatePartTab().ConfigureAwait(false);
            }

            string tabKey = ApplicationController.Instance.MainTabKey;

            if (string.IsNullOrEmpty(tabKey))
            {
                tabKey = "Hardware";
            }

            // HACK: Restore to the first printer tab if PrinterTabSelected and tabKey not found. This allows sign in/out to remain on the printer tab across different users
            if (!tabControl.AllTabs.Any(t => t.Key == tabKey) &&
                ApplicationController.Instance.PrinterTabSelected)
            {
                var key = tabControl.AllTabs.Where(t => t.TabContent is PrinterTabPage).FirstOrDefault()?.Key;
                if (key != null)
                {
                    tabKey = key;
                }
            }

            var brandMenu = new BrandMenuButton(theme)
            {
                HAnchor         = HAnchor.Fit,
                VAnchor         = VAnchor.Fit,
                BackgroundColor = theme.TabBarBackground,
                Padding         = theme.TabbarPadding.Clone(right: theme.DefaultContainerPadding)
            };

            tabControl.TabBar.ActionArea.AddChild(brandMenu, 0);

            // Restore active tabs
            foreach (var workspace in ApplicationController.Instance.Workspaces)
            {
                this.CreatePartTab(workspace);
            }

            tabControl.SelectedTabKey = tabKey;

            statusBar = new Toolbar(theme)
            {
                HAnchor         = HAnchor.Stretch,
                VAnchor         = VAnchor.Absolute,
                Padding         = 1,
                Height          = 22,
                BackgroundColor = theme.BackgroundColor,
                Border          = new BorderDouble(top: 1),
                BorderColor     = theme.BorderColor20,
            };
            this.AddChild(statusBar);

            statusBar.ActionArea.VAnchor = VAnchor.Stretch;

            tasksContainer = new FlowLayoutWidget(FlowDirection.LeftToRight)
            {
                HAnchor         = HAnchor.Fit,
                VAnchor         = VAnchor.Stretch,
                BackgroundColor = theme.MinimalShade,
                Name            = "runningTasksPanel"
            };
            statusBar.AddChild(tasksContainer);

            var tasks = ApplicationController.Instance.Tasks;

            tasks.TasksChanged += (s, e) =>
            {
                RenderRunningTasks(theme, tasks);
            };

            stretchStatusPanel = new GuiWidget()
            {
                HAnchor         = HAnchor.Stretch,
                VAnchor         = VAnchor.Stretch,
                Padding         = new BorderDouble(right: 3),
                Margin          = new BorderDouble(right: 2, top: 1, bottom: 1),
                Border          = new BorderDouble(1),
                BackgroundColor = theme.MinimalShade.WithAlpha(10),
                BorderColor     = theme.SlightShade,
                Width           = 200
            };
            statusBar.AddChild(stretchStatusPanel);

            var panelBackgroundColor = theme.MinimalShade.WithAlpha(10);

            statusBar.AddChild(
                this.CreateThemeStatusPanel(theme, panelBackgroundColor));

            statusBar.AddChild(
                this.CreateNetworkStatusPanel(theme));

            this.RenderRunningTasks(theme, tasks);

            // Register listeners
            PrinterSettings.AnyPrinterSettingChanged           += Printer_SettingChanged;
            ApplicationController.Instance.OpenPrintersChanged += OpenPrinters_Changed;

            UpdateControlData.Instance.UpdateStatusChanged.RegisterEvent((s, e) =>
            {
                SetLinkButtonsVisibility(s, new StringEventArgs("Unknown"));
            }, ref unregisterEvents);

            ApplicationController.Instance.MainView = this;
        }
Пример #19
0
        public InlineEditControl(string defaultSizeString = "-0000.00")
        {
            theme        = AppContext.Theme;
            base.Visible = false;

            double pointSize = 10;

            this.Padding = new BorderDouble(3);

            numberDisplay = new TextWidget(defaultSizeString, 0, 0, pointSize, justification: Agg.Font.Justification.Center, textColor: theme.TextColor)
            {
                Visible = false,
                VAnchor = VAnchor.Bottom,
                HAnchor = HAnchor.Left,
                Text    = "0",
                AutoExpandBoundsToText = true,
            };

            this.BeforeDraw += (s, e) =>
            {
                if (s is GuiWidget widget)
                {
                    var test = true;
                    if (test)
                    {
                        // return;
                    }

                    var bounds = widget.LocalBounds;
                    e.Graphics2D.Render(new RoundedRect(bounds, 3 * GuiWidget.DeviceScale), theme.BackgroundColor.WithAlpha(200));
                }
            };

            AddChild(numberDisplay);

            numberEdit = new MHNumberEdit(0, theme, pixelWidth: numberDisplay.Width, allowNegatives: true, allowDecimals: true)
            {
                Visible          = false,
                VAnchor          = VAnchor.Bottom,
                HAnchor          = HAnchor.Left,
                SelectAllOnFocus = true,
            };
            numberEdit.ActuallNumberEdit.InternalNumberEdit.TextChanged += (s, e) =>
            {
                numberDisplay.Text = GetDisplayString == null ? "None" : GetDisplayString.Invoke(Value);
                this.OnTextChanged(e);
            };
            numberEdit.ActuallNumberEdit.InternalNumberEdit.MaxDecimalsPlaces = 2;

            numberEdit.ActuallNumberEdit.EditComplete += (s, e) =>
            {
                EditComplete?.Invoke(this, e);
                timeSinceMouseUp.Restart();
                numberEdit.Visible    = false;
                numberDisplay.Visible = true;
            };

            AddChild(numberEdit);

            VAnchor = VAnchor.Fit;
            HAnchor = HAnchor.Fit;

            runningInterval = UiThread.SetInterval(HideIfApplicable, .1);
        }