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); }
private void WaitToRefresh() { if (UiThread.CurrentTimerMs > lastTimeContentsChanged + 500 && waitingForRefresh != null) { UiThread.ClearInterval(waitingForRefresh); waitingForRefresh = null; this.ReloadContent(); } }
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); } }
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)); }
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); } }
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); }
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); }
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)); }
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)); }
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; }
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; }
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); }
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); } }
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; }
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); }