public static async Task <GuiWidget> Initialize(SystemWindow systemWindow, Action <double, string> reporter) { var loading = "Loading..."; #if DEBUG loading = null; #endif reporter?.Invoke(0.01, (loading != null) ? loading : "PlatformInit"); AppContext.Platform.PlatformInit((status) => { reporter?.Invoke(0.01, (loading != null) ? loading : status); }); // TODO: Appears to be unused and should be removed // set this at startup so that we can tell next time if it got set to true in close UserSettings.Instance.Fields.StartCount = UserSettings.Instance.Fields.StartCount + 1; reporter?.Invoke(0.05, (loading != null) ? loading : "ApplicationController"); var applicationController = ApplicationController.Instance; // Accessing any property on ProfileManager will run the static constructor and spin up the ProfileManager instance reporter?.Invoke(0.2, (loading != null) ? loading : "ProfileManager"); bool na2 = ProfileManager.Instance.IsGuestProfile; await ProfileManager.Instance.Initialize(); reporter?.Invoke(0.25, (loading != null) ? loading : "Initialize printer"); reporter?.Invoke(0.3, (loading != null) ? loading : "Plugins"); ApplicationController.Plugins.InitializePlugins(systemWindow); reporter?.Invoke(0.4, (loading != null) ? loading : "MainView"); applicationController.MainView = new MainViewWidget(applicationController.Theme); reporter?.Invoke(0.91, (loading != null) ? loading : "OnLoadActions"); applicationController.OnLoadActions(); // Wired up to MainView.Load with the intent to fire startup actions and tasks in order with reporting async void InitialWindowLoad(object s, EventArgs e) { try { PrinterSettings.SliceEngines["MatterSlice"] = new EngineMappingsMatterSlice(); // Initial load builds UI elements, then constructs workspace tabs as they're encountered in RestoreUserTabs() await applicationController.RestoreUserTabs(); // Batch startup actions await applicationController.Tasks.Execute( "Finishing Startup".Localize(), null, (progress, cancellationToken) => { var status = new ProgressStatus(); int itemCount = ApplicationController.StartupActions.Count; double i = 1; foreach (var action in ApplicationController.StartupActions.OrderByDescending(t => t.Priority)) { status.Status = action.Title; progress.Report(status); action.Action?.Invoke(); status.Progress0To1 = i++ / itemCount; progress.Report(status); } return(Task.CompletedTask); }); // Batch execute startup tasks foreach (var task in ApplicationController.StartupTasks.OrderByDescending(t => t.Priority)) { await applicationController.Tasks.Execute(task.Title, null, task.Action); } if (UserSettings.Instance.get(UserSettingsKey.ShownWelcomeMessage) != "false") { UiThread.RunOnIdle(() => { DialogWindow.Show <WelcomePage>(); }); } } catch { } // Unhook after execution applicationController.MainView.Load -= InitialWindowLoad; } // Hook after first draw applicationController.MainView.Load += InitialWindowLoad; return(applicationController.MainView); }
private void onPrinterStatusChanged(object sender, EventArgs e) { SetVisibleControls(); UiThread.RunOnIdle(this.Invalidate); }
public void ChangeToMacroList() { this.ActiveMacro = null; UiThread.RunOnIdle(DoChangeToMacroList); }
private void ExtendOverflowMenu(PopupMenu popupMenu) { popupMenu.CreateHorizontalLine(); PopupMenu.MenuItem menuItem; menuItem = popupMenu.CreateMenuItem("Import Presets".Localize()); menuItem.Click += (s, e) => UiThread.RunOnIdle(() => { AggContext.FileDialogs.OpenFileDialog( new OpenFileDialogParams("settings files|*.printer"), (dialogParams) => { if (!string.IsNullOrEmpty(dialogParams.FileName)) { DialogWindow.Show(new ImportSettingsPage(dialogParams.FileName, printer)); } }); }, .2); popupMenu.CreateHorizontalLine(); menuItem = popupMenu.CreateMenuItem("Restore Settings".Localize()); menuItem.Click += (s, e) => UiThread.RunOnIdle(() => { DialogWindow.Show <PrinterProfileHistoryPage>(); }, .2); menuItem.Enabled = !string.IsNullOrEmpty(AuthenticationData.Instance.ActiveSessionUsername); menuItem = popupMenu.CreateMenuItem("Reset to Defaults".Localize()); menuItem.Click += (s, e) => UiThread.RunOnIdle(() => { StyledMessageBox.ShowMessageBox( (revertSettings) => { if (revertSettings) { bool onlyReloadSliceSettings = true; if (printer.Settings.GetValue <bool>(SettingsKey.print_leveling_required_to_print) && printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled)) { onlyReloadSliceSettings = false; } printer.Settings.ClearUserOverrides(); printer.Settings.Save(); if (onlyReloadSliceSettings) { printer?.Bed.GCodeRenderer?.Clear3DGCode(); } else { ApplicationController.Instance.ReloadAll(); } } }, "Resetting to default values will remove your current overrides and restore your original printer settings.\nAre you sure you want to continue?".Localize(), "Revert Settings".Localize(), StyledMessageBox.MessageType.YES_NO); }, .2); menuItem = popupMenu.CreateMenuItem("Export".Localize()); menuItem.Click += (s, e) => UiThread.RunOnIdle(() => { ActiveSliceSettings.Instance.Helpers.ExportAsMatterControlConfig(); }, .2); }
private void Rebuild(UndoBuffer undoBuffer) { var rebuildLock = RebuildLock(); ResetMeshWrapperMeshes(Object3DPropertyFlags.All, CancellationToken.None); ApplicationController.Instance.Tasks.Execute("Intersection".Localize(), (reporter, cancellationToken) => { var progressStatus = new ProgressStatus(); var participants = this.DescendantsAndSelf().Where((obj) => obj.OwnerID == this.ID); if (participants.Count() > 1) { var first = participants.First(); var totalOperations = participants.Count() - 1; double amountPerOperation = 1.0 / totalOperations; double percentCompleted = 0; foreach (var remove in participants) { if (remove != first) { var transformedRemove = remove.Mesh.Copy(CancellationToken.None); transformedRemove.Transform(remove.WorldMatrix()); var transformedKeep = first.Mesh.Copy(CancellationToken.None); transformedKeep.Transform(first.WorldMatrix()); transformedKeep = PolygonMesh.Csg.CsgOperations.Intersect(transformedKeep, transformedRemove, (status, progress0To1) => { // Abort if flagged cancellationToken.ThrowIfCancellationRequested(); progressStatus.Status = status; progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1; reporter.Report(progressStatus); }, cancellationToken); var inverse = first.WorldMatrix(); inverse.Invert(); transformedKeep.Transform(inverse); using (first.RebuildLock()) { first.Mesh = transformedKeep; } remove.Visible = false; percentCompleted += amountPerOperation; progressStatus.Progress0To1 = percentCompleted; reporter.Report(progressStatus); } } } UiThread.RunOnIdle(() => { rebuildLock.Dispose(); base.Invalidate(new InvalidateArgs(this, InvalidateType.Content)); }); return(Task.CompletedTask); }); }
private void AddLibraryButtonElements() { textImageButtonFactory.normalTextColor = ActiveTheme.Instance.PrimaryTextColor; textImageButtonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor; textImageButtonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor; textImageButtonFactory.disabledTextColor = ActiveTheme.Instance.TabLabelUnselected; textImageButtonFactory.disabledFillColor = new RGBA_Bytes(); buttonPanel.RemoveAllChildren(); // the add button { addToLibraryButton = textImageButtonFactory.Generate(LocalizedString.Get("Add"), "icon_circle_plus.png"); addToLibraryButton.Enabled = false; // The library selector (the first library selected) is protected so we can't add to it. addToLibraryButton.ToolTipText = "Add an .stl, .amf, .gcode or .zip file to the Library".Localize(); addToLibraryButton.Name = "Library Add Button"; buttonPanel.AddChild(addToLibraryButton); addToLibraryButton.Margin = new BorderDouble(0, 0, 3, 0); addToLibraryButton.Click += (sender, e) => UiThread.RunOnIdle(importToLibraryloadFile_ClickOnIdle); } // the create folder button { createFolderButton = textImageButtonFactory.Generate(LocalizedString.Get("Create Folder")); createFolderButton.Enabled = false; // The library selector (the first library selected) is protected so we can't add to it. createFolderButton.Name = "Create Folder From Library Button"; buttonPanel.AddChild(createFolderButton); createFolderButton.Margin = new BorderDouble(0, 0, 3, 0); createFolderButton.Click += (sender, e) => { if (createFolderWindow == null) { createFolderWindow = new CreateFolderWindow((returnInfo) => { this.libraryDataView.CurrentLibraryProvider.AddCollectionToLibrary(returnInfo.newName); }); createFolderWindow.Closed += (sender2, e2) => { createFolderWindow = null; }; } else { createFolderWindow.BringToFront(); } }; } // add in the message widget { providerMessageWidget = new TextWidget("") { PointSize = 8, HAnchor = HAnchor.ParentRight, VAnchor = VAnchor.ParentBottom, TextColor = ActiveTheme.Instance.SecondaryTextColor, Margin = new BorderDouble(6), AutoExpandBoundsToText = true, }; providerMessageContainer = new GuiWidget() { VAnchor = VAnchor.FitToChildren | VAnchor.ParentTop, HAnchor = HAnchor.ParentLeftRight, Visible = false, }; providerMessageContainer.AddChild(providerMessageWidget); buttonPanel.AddChild(providerMessageContainer, -1); } }
private bool SetImageFast() { if (this.ItemWrapper == null) { this.thumbnailImage = new ImageBuffer(this.noThumbnailImage); this.Invalidate(); return(true); } if (this.ItemWrapper.FileLocation == QueueData.SdCardFileName) { switch (this.Size) { case ImageSizes.Size115x115: { StaticData.Instance.LoadIcon(Path.ChangeExtension("icon_sd_card_115x115", partExtension), this.thumbnailImage); } break; case ImageSizes.Size50x50: { StaticData.Instance.LoadIcon(Path.ChangeExtension("icon_sd_card_50x50", partExtension), this.thumbnailImage); } break; default: throw new NotImplementedException(); } this.thumbnailImage.SetRecieveBlender(new BlenderPreMultBGRA()); Graphics2D graphics = this.thumbnailImage.NewGraphics2D(); Ellipse outline = new Ellipse(new Vector2(Width / 2.0, Height / 2.0), Width / 2 - Width / 12); graphics.Render(new Stroke(outline, Width / 12), RGBA_Bytes.White); UiThread.RunOnIdle(this.EnsureImageUpdated); return(true); } else if (Path.GetExtension(this.ItemWrapper.FileLocation).ToUpper() == ".GCODE") { CreateImage(this, Width, Height); this.thumbnailImage.SetRecieveBlender(new BlenderPreMultBGRA()); Graphics2D graphics = this.thumbnailImage.NewGraphics2D(); Vector2 center = new Vector2(Width / 2.0, Height / 2.0); Ellipse outline = new Ellipse(center, Width / 2 - Width / 12); graphics.Render(new Stroke(outline, Width / 12), RGBA_Bytes.White); graphics.DrawString("GCode", center.x, center.y, 8 * Width / 50, Agg.Font.Justification.Center, Agg.Font.Baseline.BoundsCenter, color: RGBA_Bytes.White); UiThread.RunOnIdle(this.EnsureImageUpdated); return(true); } else if (!File.Exists(this.ItemWrapper.FileLocation)) { CreateImage(this, Width, Height); this.thumbnailImage.SetRecieveBlender(new BlenderPreMultBGRA()); Graphics2D graphics = this.thumbnailImage.NewGraphics2D(); Vector2 center = new Vector2(Width / 2.0, Height / 2.0); graphics.DrawString("Missing", center.x, center.y, 8 * Width / 50, Agg.Font.Justification.Center, Agg.Font.Baseline.BoundsCenter, color: RGBA_Bytes.White); UiThread.RunOnIdle(this.EnsureImageUpdated); return(true); } else if (MeshIsTooBigToLoad(this.ItemWrapper.FileLocation)) { CreateImage(this, Width, Height); this.thumbnailImage.SetRecieveBlender(new BlenderPreMultBGRA()); Graphics2D graphics = this.thumbnailImage.NewGraphics2D(); Vector2 center = new Vector2(Width / 2.0, Height / 2.0); double yOffset = 8 * Width / 50 * TextWidget.GlobalPointSizeScaleRatio * 1.5; graphics.DrawString("Too Big\nto\nRender", center.x, center.y + yOffset, 8 * Width / 50, Agg.Font.Justification.Center, Agg.Font.Baseline.BoundsCenter, color: RGBA_Bytes.White); UiThread.RunOnIdle(this.EnsureImageUpdated); return(true); } string stlHashCode = this.ItemWrapper.FileHashCode.ToString(); if (stlHashCode != "0") { ImageBuffer bigRender = LoadImageFromDisk(this, stlHashCode); if (bigRender == null) { this.thumbnailImage = new ImageBuffer(buildingThumbnailImage); return(false); } bigRender.SetRecieveBlender(new BlenderPreMultBGRA()); this.thumbnailImage = ImageBuffer.CreateScaledImage(bigRender, (int)Width, (int)Height); UiThread.RunOnIdle(this.EnsureImageUpdated); return(true); } return(false); }
public GuiWidget Create(IObject3D item, UndoBuffer undoBuffer, ThemeConfig theme) { var column = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.MaxFitOrStretch }; var imageObject = item as ImageObject3D; var activeImage = imageObject.Image; var imageSection = new SearchableSectionWidget("Image".Localize(), new FlowLayoutWidget(FlowDirection.TopToBottom), theme, emptyText: "Search Google".Localize()); imageSection.SearchInvoked += (s, e) => { string imageType = " silhouette"; if (item.Parent.GetType().Name.Contains("Lithophane")) { imageType = ""; } ApplicationController.LaunchBrowser($"http://www.google.com/search?q={e.Data}{imageType}&tbm=isch"); }; theme.ApplyBoxStyle(imageSection, margin: 0); column.AddChild(imageSection); ImageBuffer thumbnailImage = SetImage(theme, imageObject); ImageWidget thumbnailWidget; imageSection.ContentPanel.AddChild(thumbnailWidget = new ImageWidget(thumbnailImage) { Margin = new BorderDouble(bottom: 5), HAnchor = HAnchor.Center }); thumbnailWidget.Click += (s, e) => { if (e.Button == MouseButtons.Right) { var popupMenu = new PopupMenu(theme); var pasteMenu = popupMenu.CreateMenuItem("Paste".Localize()); pasteMenu.Click += (s2, e2) => { activeImage = Clipboard.Instance.GetImage(); thumbnailWidget.Image = activeImage; // Persist string filePath = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".png"); AggContext.ImageIO.SaveImageData( filePath, activeImage); imageObject.AssetPath = filePath; imageObject.Mesh = null; thumbnailWidget.Image = SetImage(theme, imageObject); column.Invalidate(); imageObject.Invalidate(InvalidateType.Image); }; pasteMenu.Enabled = Clipboard.Instance.ContainsImage; var copyMenu = popupMenu.CreateMenuItem("Copy".Localize()); copyMenu.Click += (s2, e2) => { Clipboard.Instance.SetImage(thumbnailWidget.Image); }; popupMenu.ShowMenu(thumbnailWidget, e); } }; // add in the invert checkbox and change image button var changeButton = new TextButton("Change".Localize(), theme) { BackgroundColor = theme.MinimalShade }; changeButton.Click += (sender, e) => { UiThread.RunOnIdle(() => { // we do this using to make sure that the stream is closed before we try and insert the Picture AggContext.FileDialogs.OpenFileDialog( new OpenFileDialogParams( "Select an image file|*.jpg;*.png;*.bmp;*.gif;*.pdf", multiSelect: false, title: "Add Image".Localize()), (openParams) => { if (!File.Exists(openParams.FileName)) { return; } imageObject.AssetPath = openParams.FileName; using (imageObject.RebuildLock()) { imageObject.Mesh = null; } thumbnailWidget.Image = SetImage(theme, imageObject); column.Invalidate(); imageObject.Invalidate(InvalidateType.Image); }); }); }; var row = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = new BorderDouble(8, 5) }; imageSection.ContentPanel.AddChild(row); // Invert checkbox var invertCheckbox = new CheckBox(new CheckBoxViewText("Invert".Localize(), textColor: theme.TextColor)) { Checked = imageObject.Invert, Margin = new BorderDouble(0), VAnchor = VAnchor.Center, }; invertCheckbox.CheckedStateChanged += (s, e) => { imageObject.Invert = invertCheckbox.Checked; }; row.AddChild(invertCheckbox); row.AddChild(new HorizontalSpacer()); row.AddChild(changeButton); imageObject.Invalidated += (s, e) => { if (e.InvalidateType.HasFlag(InvalidateType.Image) && activeImage != imageObject.Image) { thumbnailImage = SetImage(theme, imageObject); thumbnailWidget.Image = thumbnailImage; activeImage = imageObject.Image; } }; return(column); }
private void GeneratePrinterOverflowMenu(PopupMenu popupMenu, ThemeConfig theme) { var menuActions = new List <NamedAction>() { new NamedAction() { Icon = StaticData.Instance.LoadIcon("memory_16x16.png", 16, 16, theme.InvertIcons), Title = "Configure EEProm".Localize(), Action = configureEePromButton_Click, IsEnabled = () => printer.Connection.IsConnected }, new NamedBoolAction() { Title = "Show Printer".Localize(), Action = () => { }, GetIsActive = () => printer.ViewState.ConfigurePrinterVisible, SetIsActive = (value) => printer.ViewState.ConfigurePrinterVisible = value }, new ActionSeparator(), new NamedAction() { Title = "Import Presets".Localize(), Action = () => { AggContext.FileDialogs.OpenFileDialog( new OpenFileDialogParams("settings files|*.printer"), (dialogParams) => { if (!string.IsNullOrEmpty(dialogParams.FileName)) { DialogWindow.Show(new ImportSettingsPage(dialogParams.FileName, printer)); } }); } }, new NamedAction() { Title = "Export Printer".Localize(), Action = () => UiThread.RunOnIdle(() => { ApplicationController.Instance.ExportAsMatterControlConfig(printer); }), Icon = StaticData.Instance.LoadIcon("cube_export.png", 16, 16, theme.InvertIcons), }, new ActionSeparator(), new NamedAction() { Title = "Calibrate Printer".Localize(), Action = () => UiThread.RunOnIdle(() => { UiThread.RunOnIdle(() => { DialogWindow.Show(new PrinterCalibrationWizard(printer, theme)); }); }), Icon = StaticData.Instance.LoadIcon("compass.png", 16, 16, theme.InvertIcons) }, new ActionSeparator(), new NamedAction() { Title = "Update Settings...".Localize(), Action = () => { DialogWindow.Show(new UpdateSettingsPage(printer)); }, Icon = StaticData.Instance.LoadIcon("fa-refresh_14.png", 16, 16, theme.InvertIcons) }, new NamedAction() { Title = "Restore Settings...".Localize(), Action = () => { DialogWindow.Show(new PrinterProfileHistoryPage(printer)); } }, new NamedAction() { Title = "Reset to Defaults...".Localize(), Action = () => { StyledMessageBox.ShowMessageBox( (revertSettings) => { if (revertSettings) { printer.Settings.ClearUserOverrides(); printer.Settings.ResetSettingsForNewProfile(); // this is user driven printer.Settings.Save(); printer.Settings.Helpers.PrintLevelingData.SampledPositions.Clear(); ApplicationController.Instance.ReloadAll().ConfigureAwait(false); } }, "Resetting to default values will remove your current overrides and restore your original printer settings.\nAre you sure you want to continue?".Localize(), "Revert Settings".Localize(), StyledMessageBox.MessageType.YES_NO); } }, new ActionSeparator(), new NamedAction() { Title = "Delete Printer".Localize(), Action = () => { StyledMessageBox.ShowMessageBox( (doDelete) => { if (doDelete) { ProfileManager.Instance.DeletePrinter(printer.Settings.ID); } }, "Are you sure you want to delete printer '{0}'?".Localize().FormatWith(printer.Settings.GetValue(SettingsKey.printer_name)), "Delete Printer?".Localize(), StyledMessageBox.MessageType.YES_NO, "Delete Printer".Localize()); }, } }; var printerType = printer.Settings.Slicer.PrinterType; if (printerType == PrinterType.FFF) { menuActions.Add(new NamedBoolAction() { Title = "Show Controls".Localize(), Action = () => { }, GetIsActive = () => printer.ViewState.ControlsVisible, SetIsActive = (value) => printer.ViewState.ControlsVisible = value, }); menuActions.Add(new NamedBoolAction() { Title = "Show Terminal".Localize(), Action = () => { }, GetIsActive = () => printer.ViewState.TerminalVisible, SetIsActive = (value) => printer.ViewState.TerminalVisible = value, }); } theme.CreateMenuItems(popupMenu, menuActions); }
private void CreateMenuActions() { menuActions.Add(new PrintItemAction() { Icon = AggContext.StaticData.LoadIcon("cube.png", 16, 16, ApplicationController.Instance.MenuTheme.InvertIcons), Title = "Add".Localize(), ToolTipText = "Add an.stl, .obj, .amf, .gcode or.zip file to the Library".Localize(), Action = (selectedLibraryItems, listView) => { UiThread.RunOnIdle(() => { AggContext.FileDialogs.OpenFileDialog( new OpenFileDialogParams(ApplicationSettings.OpenPrintableFileParams, multiSelect: true), (openParams) => { if (openParams.FileNames != null) { var writableContainer = this.libraryView.ActiveContainer as ILibraryWritableContainer; if (writableContainer != null && openParams.FileNames.Length > 0) { writableContainer.Add(openParams.FileNames.Select(f => new FileSystemFileItem(f))); } } }); }); }, IsEnabled = (s, l) => this.libraryView.ActiveContainer is ILibraryWritableContainer }); menuActions.Add(new PrintItemAction() { Title = "Create Folder".Localize(), Icon = AggContext.StaticData.LoadIcon("fa-folder-new_16.png", 16, 16, ApplicationController.Instance.MenuTheme.InvertIcons), Action = (selectedLibraryItems, listView) => { DialogWindow.Show( new InputBoxPage( "Create Folder".Localize(), "Folder Name".Localize(), "", "Enter New Name Here".Localize(), "Create".Localize(), (newName) => { if (!string.IsNullOrEmpty(newName) && this.libraryView.ActiveContainer is ILibraryWritableContainer writableContainer) { writableContainer.Add(new[] { new CreateFolderItem() { Name = newName } }); } })); }, IsEnabled = (s, l) => { return(this.libraryView.ActiveContainer is ILibraryWritableContainer writableContainer && writableContainer?.AllowAction(ContainerActions.AddContainers) == true); } });
private CalibrationControls(PrinterConfig printer, ThemeConfig theme) : base(FlowDirection.TopToBottom) { this.printer = printer; // add in the controls for configuring auto leveling { SettingsRow settingsRow; this.AddChild(settingsRow = new SettingsRow( "Print Leveling Plane".Localize(), null, theme, AggContext.StaticData.LoadIcon("leveling_32x32.png", 16, 16, theme.InvertIcons))); // run leveling button var runWizardButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, ToolTipText = "Print Leveling Wizard - Can be re-calculated anytime there seems to be a problem with initial layer consistency".Localize() }; runWizardButton.Click += (s, e) => { UiThread.RunOnIdle(() => { LevelingWizard.ShowPrintLevelWizard(printer, theme); }); }; settingsRow.AddChild(runWizardButton); // only show the switch if leveling can be turned off (it can't if it is required). if (!printer.Settings.GetValue <bool>(SettingsKey.print_leveling_required_to_print)) { // put in the switch var printLevelingSwitch = new RoundedToggleSwitch(theme) { VAnchor = VAnchor.Center, Margin = new BorderDouble(left: 16), Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled) }; printLevelingSwitch.CheckedStateChanged += (sender, e) => { printer.Settings.Helpers.DoPrintLeveling(printLevelingSwitch.Checked); }; printer.Settings.PrintLevelingEnabledChanged.RegisterEvent((sender, e) => { printLevelingSwitch.Checked = printer.Settings.GetValue <bool>(SettingsKey.print_leveling_enabled); }, ref unregisterEvents); settingsRow.AddChild(printLevelingSwitch); } // add in the controls for configuring probe offset if (printer.Settings.GetValue <bool>(SettingsKey.has_z_probe) && printer.Settings.GetValue <bool>(SettingsKey.use_z_probe)) { this.AddChild(settingsRow = new SettingsRow( "Print Leveling Probe".Localize(), null, theme, AggContext.StaticData.LoadIcon("probing_32x32.png", 16, 16, theme.InvertIcons))); var runCalibrateProbeButton = new IconButton(AggContext.StaticData.LoadIcon("fa-cog_16.png", theme.InvertIcons), theme) { VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, ToolTipText = "Probe Calibration Wizard - needed for initial setup - normally should remain calibrated unless there are changes to hardware.".Localize() }; runCalibrateProbeButton.Click += (s, e) => { UiThread.RunOnIdle(() => { LevelingWizard.ShowProbeCalibrationWizard(printer, theme); }); }; settingsRow.BorderColor = Color.Transparent; settingsRow.AddChild(runCalibrateProbeButton); } } printer.Connection.CommunicationStateChanged.RegisterEvent(PrinterStatusChanged, ref unregisterEvents); printer.Connection.EnableChanged.RegisterEvent(PrinterStatusChanged, ref unregisterEvents); SetVisibleControls(); }
public static GuiWidget PrintProgressWidget(PrinterConfig printer, ThemeConfig theme) { var bodyRow = new GuiWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Top | VAnchor.Fit, //BackgroundColor = new Color(theme.Colors.PrimaryBackgroundColor, 128), MinimumSize = new Vector2(275, 140), }; // Progress section var expandingContainer = new HorizontalSpacer() { VAnchor = VAnchor.Fit | VAnchor.Center }; bodyRow.AddChild(expandingContainer); var progressContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) { VAnchor = VAnchor.Center | VAnchor.Fit, HAnchor = HAnchor.Stretch, }; expandingContainer.AddChild(progressContainer); var progressDial = new ProgressDial(theme) { HAnchor = HAnchor.Center, Height = 200 * DeviceScale, Width = 200 * DeviceScale }; progressContainer.AddChild(progressDial); var bottomRow = new GuiWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit }; progressContainer.AddChild(bottomRow); var timeContainer = new FlowLayoutWidget() { HAnchor = HAnchor.Center | HAnchor.Fit, Margin = 3 }; bottomRow.AddChild(timeContainer); // we can only reslice on 64 bit, because in 64 bit we always have the gcode loaded if (IntPtr.Size == 8) { var resliceButton = new TextButton("Re-Slice", theme) { HAnchor = HAnchor.Right, VAnchor = VAnchor.Center, Margin = new BorderDouble(0, 0, 7, 0), Name = "Re-Slice Button" }; bool activelySlicing = false; resliceButton.Click += (s, e) => { resliceButton.Enabled = false; UiThread.RunOnIdle(async() => { bool doSlicing = !activelySlicing && printer.Bed.EditContext.SourceItem != null; if (doSlicing) { var errors = printer.ValidateSettings(); if (errors.Any(err => err.ErrorLevel == ValidationErrorLevel.Error)) { doSlicing = false; ApplicationController.Instance.ShowValidationErrors("Slicing Error".Localize(), errors); } } if (doSlicing) { activelySlicing = true; if (bottomRow.Name == null) { bottomRow.Name = printer.Bed.EditContext.GCodeFilePath(printer); } await ApplicationController.Instance.Tasks.Execute("Saving".Localize(), printer, printer.Bed.SaveChanges); // start up a new slice on a background thread await ApplicationController.Instance.SliceItemLoadOutput( printer, printer.Bed.Scene, printer.Bed.EditContext.GCodeFilePath(printer)); // Switch to the 3D layer view if on Model view if (printer.ViewState.ViewMode == PartViewMode.Model) { printer.ViewState.ViewMode = PartViewMode.Layers3D; } // when it is done queue it to the change to gcode stream var message2 = "Would you like to switch to the new G-Code? Before you switch, check that your are seeing the changes you expect.".Localize(); var caption2 = "Switch to new G-Code?".Localize(); StyledMessageBox.ShowMessageBox(async(clickedOk2) => { if (clickedOk2) { if (printer.Connection != null && (printer.Connection.Printing || printer.Connection.Paused)) { printer.Connection.SwitchToGCode(printer.Bed.EditContext.GCodeFilePath(printer)); bottomRow.Name = printer.Bed.EditContext.GCodeFilePath(printer); } } else { await ApplicationController.Instance.SliceItemLoadOutput( printer, printer.Bed.Scene, bottomRow.Name); } activelySlicing = false; resliceButton.Enabled = true; }, message2, caption2, StyledMessageBox.MessageType.YES_NO, "Switch".Localize(), "Cancel".Localize()); } else { resliceButton.Enabled = true; } }); }; bottomRow.AddChild(resliceButton); } timeContainer.AddChild(new ImageWidget(AggContext.StaticData.LoadIcon("fa-clock_24.png", theme.InvertIcons)) { VAnchor = VAnchor.Center }); var timeWidget = new TextWidget("", pointSize: 22, textColor: theme.TextColor) { AutoExpandBoundsToText = true, Margin = new BorderDouble(10, 0, 0, 0), VAnchor = VAnchor.Center, }; timeContainer.AddChild(timeWidget); var runningInterval = UiThread.SetInterval( () => { int secondsPrinted = printer.Connection.SecondsPrinted; int hoursPrinted = (int)(secondsPrinted / (60 * 60)); int minutesPrinted = (secondsPrinted / 60 - hoursPrinted * 60); secondsPrinted = secondsPrinted % 60; // TODO: Consider if the consistency of a common time format would look and feel better than changing formats based on elapsed duration timeWidget.Text = (hoursPrinted <= 0) ? $"{minutesPrinted}:{secondsPrinted:00}" : $"{hoursPrinted}:{minutesPrinted:00}:{secondsPrinted:00}"; progressDial.LayerIndex = printer.Connection.CurrentlyPrintingLayer; progressDial.LayerCompletedRatio = printer.Connection.RatioIntoCurrentLayer; progressDial.CompletedRatio = printer.Connection.PercentComplete / 100; switch (printer.Connection.CommunicationState) { case CommunicationStates.PreparingToPrint: case CommunicationStates.Printing: case CommunicationStates.Paused: bodyRow.Visible = true; break; default: bodyRow.Visible = false; break; } }, 1); bodyRow.Closed += (s, e) => UiThread.ClearInterval(runningInterval); bodyRow.Visible = false; return(bodyRow); }
public ViewControls3D(PartWorkspace workspace, ThemeConfig theme, UndoBuffer undoBuffer, bool isPrinterType, bool showPrintButton) : base(theme) { this.theme = theme; this.undoBuffer = undoBuffer; this.ActionArea.Click += (s, e) => { view3DWidget.InteractionLayer.Focus(); }; this.OverflowButton.DynamicPopupContent = () => { var menuTheme = AppContext.MenuTheme; var popupMenu = new PopupMenu(theme); int i = 0; foreach (var widget in this.ActionArea.Children.Where(c => !c.Visible && !ignoredInMenuTypes.Contains(c.GetType()))) { if (operationButtons.TryGetValue(widget, out SceneSelectionOperation operation)) { if (operation is OperationGroup operationGroup) { popupMenu.CreateSubMenu( operationGroup.Title, menuTheme, (subMenu) => { foreach (var childOperation in operationGroup.Operations) { var menuItem = subMenu.CreateMenuItem(childOperation.Title, childOperation.Icon(menuTheme.InvertIcons)); menuItem.Click += (s, e) => UiThread.RunOnIdle(() => { childOperation.Action?.Invoke(sceneContext); }); } }); } else { popupMenu.CreateMenuItem(operation.Title, operation.Icon(menuTheme.InvertIcons)); } } } return(popupMenu); }; this.IsPrinterMode = isPrinterType; this.sceneContext = workspace.SceneContext; this.workspace = workspace; string iconPath; this.AddChild(CreateAddButton(sceneContext, theme)); this.AddChild(new ToolbarSeparator(theme)); bedMenuButton = new PopupMenuButton(AggContext.StaticData.LoadIcon("bed.png", 16, 16, theme.InvertIcons), theme) { Name = "Bed Options Menu", ToolTipText = "Bed", Enabled = true, Margin = theme.ButtonSpacing, VAnchor = VAnchor.Center, DrawArrow = true }; this.AddChild(bedMenuButton); this.AddChild(new ToolbarSeparator(theme)); this.AddChild(CreateOpenButton(theme)); this.AddChild(CreateSaveButton(theme)); this.AddChild(new ToolbarSeparator(theme)); undoButton = new IconButton(AggContext.StaticData.LoadIcon("Undo_grey_16x.png", 16, 16, theme.InvertIcons), theme) { Name = "3D View Undo", ToolTipText = "Undo".Localize(), Enabled = false, Margin = theme.ButtonSpacing, VAnchor = VAnchor.Center }; undoButton.Click += (sender, e) => { sceneContext.Scene.Undo(); view3DWidget.InteractionLayer.Focus(); }; this.AddChild(undoButton); redoButton = new IconButton(AggContext.StaticData.LoadIcon("Redo_grey_16x.png", 16, 16, theme.InvertIcons), theme) { Name = "3D View Redo", Margin = theme.ButtonSpacing, ToolTipText = "Redo".Localize(), Enabled = false, VAnchor = VAnchor.Center }; redoButton.Click += (sender, e) => { sceneContext.Scene.Redo(); view3DWidget.InteractionLayer.Focus(); }; this.AddChild(redoButton); if (showPrintButton) { var printButton = new TextButton("Print", theme) { Name = "Print Button", BackgroundColor = theme.AccentMimimalOverlay }; printButton.Click += (s, e) => { view3DWidget.PushToPrinterAndPrint(); }; this.AddChild(printButton); } this.AddChild(new ToolbarSeparator(theme)); undoButton.Enabled = undoBuffer.UndoCount > 0; redoButton.Enabled = undoBuffer.RedoCount > 0; var buttonGroupA = new ObservableCollection <GuiWidget>(); if (UserSettings.Instance.IsTouchScreen) { iconPath = Path.Combine("ViewTransformControls", "rotate.png"); rotateButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 32, 32, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupA, ToolTipText = "Rotate (Alt + Left Mouse)".Localize(), Margin = theme.ButtonSpacing }; rotateButton.Click += (s, e) => this.ActiveButton = ViewControls3DButtons.Rotate; buttonGroupA.Add(rotateButton); AddChild(rotateButton); iconPath = Path.Combine("ViewTransformControls", "translate.png"); translateButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 32, 32, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupA, ToolTipText = "Move (Shift + Left Mouse)".Localize(), Margin = theme.ButtonSpacing }; translateButton.Click += (s, e) => this.ActiveButton = ViewControls3DButtons.Translate; buttonGroupA.Add(translateButton); AddChild(translateButton); iconPath = Path.Combine("ViewTransformControls", "scale.png"); scaleButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 32, 32, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupA, ToolTipText = "Zoom (Ctrl + Left Mouse)".Localize(), Margin = theme.ButtonSpacing }; scaleButton.Click += (s, e) => this.ActiveButton = ViewControls3DButtons.Scale; buttonGroupA.Add(scaleButton); AddChild(scaleButton); rotateButton.Checked = true; // Add vertical separator this.AddChild(new ToolbarSeparator(theme)); iconPath = Path.Combine("ViewTransformControls", "partSelect.png"); partSelectButton = new RadioIconButton(AggContext.StaticData.LoadIcon(iconPath, 32, 32, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupA, ToolTipText = "Select Part".Localize(), Margin = theme.ButtonSpacing }; partSelectButton.Click += (s, e) => this.ActiveButton = ViewControls3DButtons.PartSelect; buttonGroupA.Add(partSelectButton); AddChild(partSelectButton); } operationButtons = new Dictionary <GuiWidget, SceneSelectionOperation>(); // Add Selected IObject3D -> Operations to toolbar foreach (var namedAction in ApplicationController.Instance.RegisteredSceneOperations) { if (namedAction is SceneSelectionSeparator) { this.AddChild(new ToolbarSeparator(theme)); continue; } // add the create support before the align if (namedAction is OperationGroup group && group.GroupName == "Align") { this.AddChild(CreateWipeTowerButton(theme)); this.AddChild(CreateSupportButton(theme)); this.AddChild(new ToolbarSeparator(theme)); } GuiWidget button = null; if (namedAction is OperationGroup operationGroup) { if (operationGroup.Collapse) { var defaultOperation = operationGroup.GetDefaultOperation(); PopupMenuButton groupButton = null; groupButton = theme.CreateSplitButton( new SplitButtonParams() { Icon = defaultOperation.Icon(theme.InvertIcons), DefaultAction = (menuButton) => { defaultOperation.Action.Invoke(sceneContext); }, DefaultActionTooltip = defaultOperation.HelpText ?? defaultOperation.Title, ButtonName = defaultOperation.Title, ExtendPopupMenu = (PopupMenu popupMenu) => { foreach (var operation in operationGroup.Operations) { var operationMenu = popupMenu.CreateMenuItem(operation.Title, operation.Icon?.Invoke(theme.InvertIcons)); operationMenu.ToolTipText = operation.HelpText; operationMenu.Enabled = operation.IsEnabled(sceneContext); operationMenu.Click += (s, e) => UiThread.RunOnIdle(() => { if (operationGroup.StickySelection && defaultOperation != operation) { // Update button var iconButton = groupButton.Children.OfType <IconButton>().First(); iconButton.SetIcon(operation.Icon(theme.InvertIcons)); iconButton.ToolTipText = operation.HelpText ?? operation.Title; UserSettings.Instance.set(operationGroup.GroupRecordId, operationGroup.Operations.IndexOf(operation).ToString()); defaultOperation = operation; iconButton.Invalidate(); } operation.Action?.Invoke(sceneContext); }); } } }, operationGroup); button = groupButton; } else { if (!(this.ActionArea.Children.LastOrDefault() is ToolbarSeparator)) { this.AddChild(new ToolbarSeparator(theme)); } foreach (var operation in operationGroup.Operations) { var operationButton = new OperationIconButton(operation, sceneContext, theme); operationButtons.Add(operationButton, operation); this.AddChild(operationButton); } this.AddChild(new ToolbarSeparator(theme)); } } else if (namedAction.Icon != null) { button = new IconButton(namedAction.Icon(theme.InvertIcons), theme) { Name = namedAction.Title + " Button", ToolTipText = namedAction.Title, Margin = theme.ButtonSpacing, BackgroundColor = theme.ToolbarButtonBackground, HoverColor = theme.ToolbarButtonHover, MouseDownColor = theme.ToolbarButtonDown, }; } else { button = new TextButton(namedAction.Title, theme) { Name = namedAction.Title + " Button", Margin = theme.ButtonSpacing, BackgroundColor = theme.ToolbarButtonBackground, HoverColor = theme.ToolbarButtonHover, MouseDownColor = theme.ToolbarButtonDown, }; } if (button != null) { operationButtons.Add(button, namedAction); // Only bind Click event if not a SplitButton if (!(button is PopupMenuButton)) { button.Click += (s, e) => UiThread.RunOnIdle(() => { namedAction.Action.Invoke(sceneContext); var partTab = button.Parents <PartTabPage>().FirstOrDefault(); var view3D = partTab.Descendants <View3DWidget>().FirstOrDefault(); view3D.InteractionLayer.Focus(); }); } this.AddChild(button); } } // Register listeners undoBuffer.Changed += UndoBuffer_Changed; sceneContext.Scene.SelectionChanged += UpdateToolbarButtons; sceneContext.Scene.ItemsModified += UpdateToolbarButtons; // Run on load UpdateToolbarButtons(null, null); }
public static SystemWindow LoadRootWindow(int width, int height) { timer = Stopwatch.StartNew(); if (false) { // set the default font AggContext.DefaultFont = ApplicationController.GetTypeFace(NamedTypeFace.Nunito_Regular); AggContext.DefaultFontBold = ApplicationController.GetTypeFace(NamedTypeFace.Nunito_Bold); AggContext.DefaultFontItalic = ApplicationController.GetTypeFace(NamedTypeFace.Nunito_Italic); AggContext.DefaultFontBoldItalic = ApplicationController.GetTypeFace(NamedTypeFace.Nunito_Bold_Italic); } var systemWindow = new RootSystemWindow(width, height); var overlay = new GuiWidget() { BackgroundColor = AppContext.Theme.BackgroundColor, }; overlay.AnchorAll(); systemWindow.AddChild(overlay); var mutedAccentColor = AppContext.Theme.SplashAccentColor; var spinner = new LogoSpinner(overlay, rotateX: -0.05) { MeshColor = mutedAccentColor }; progressPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Position = new Vector2(0, height * .25), HAnchor = HAnchor.Center | HAnchor.Fit, VAnchor = VAnchor.Fit, MinimumSize = new Vector2(400, 100), Margin = new BorderDouble(0, 0, 0, 200) }; overlay.AddChild(progressPanel); progressPanel.AddChild(statusText = new TextWidget("", textColor: AppContext.Theme.TextColor) { MinimumSize = new Vector2(200, 30), HAnchor = HAnchor.Center, AutoExpandBoundsToText = true }); progressPanel.AddChild(progressBar = new ProgressBar() { FillColor = mutedAccentColor, BorderColor = Color.Gray, // theme.BorderColor75, Height = 11 * GuiWidget.DeviceScale, Width = 230 * GuiWidget.DeviceScale, HAnchor = HAnchor.Center, VAnchor = VAnchor.Absolute }); AppContext.RootSystemWindow = systemWindow; // hook up a keyboard watcher to rout keys when not handled by children systemWindow.KeyPressed += SystemWindow_KeyPressed; systemWindow.KeyDown += (s, keyEvent) => { var view3D = systemWindow.Descendants <View3DWidget>().Where((v) => v.ActuallyVisibleOnScreen()).FirstOrDefault(); var printerTabPage = systemWindow.Descendants <PrinterTabPage>().Where((v) => v.ActuallyVisibleOnScreen()).FirstOrDefault(); var offsetDist = 50; var arrowKeyOperation = keyEvent.Shift ? TrackBallTransformType.Translation : TrackBallTransformType.Rotation; var gcode2D = systemWindow.Descendants <GCode2DWidget>().Where((v) => v.ActuallyVisibleOnScreen()).FirstOrDefault(); if (keyEvent.KeyCode == Keys.F1) { ApplicationController.Instance.ActivateHelpTab("Docs"); } if (EnableF5Collect && keyEvent.KeyCode == Keys.F5) { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); systemWindow.Invalidate(); } if (!keyEvent.Handled && gcode2D != null) { switch (keyEvent.KeyCode) { case Keys.Oemplus: case Keys.Add: if (keyEvent.Control) { // Zoom out gcode2D.Zoom(1.2); keyEvent.Handled = true; } break; case Keys.OemMinus: case Keys.Subtract: if (keyEvent.Control) { // Zoom in gcode2D.Zoom(.8); keyEvent.Handled = true; } break; } } if (!keyEvent.Handled && view3D != null) { switch (keyEvent.KeyCode) { case Keys.C: if (keyEvent.Control) { view3D.Scene.Copy(); keyEvent.Handled = true; } break; case Keys.P: if (keyEvent.Control) { view3D.PushToPrinterAndPrint(); } break; case Keys.X: if (keyEvent.Control) { view3D.Scene.Cut(); keyEvent.Handled = true; } break; case Keys.Y: if (keyEvent.Control) { view3D.Scene.UndoBuffer.Redo(); keyEvent.Handled = true; } break; case Keys.A: if (keyEvent.Control) { view3D.SelectAll(); keyEvent.Handled = true; } break; case Keys.S: if (keyEvent.Control) { view3D.Save(); keyEvent.Handled = true; } break; case Keys.V: if (keyEvent.Control) { view3D.sceneContext.Paste(); keyEvent.Handled = true; } break; case Keys.Oemplus: case Keys.Add: if (keyEvent.Control) { // Zoom out Offset3DView(view3D, new Vector2(0, offsetDist), TrackBallTransformType.Scale); keyEvent.Handled = true; } break; case Keys.OemMinus: case Keys.Subtract: if (keyEvent.Control) { // Zoom in Offset3DView(view3D, new Vector2(0, -offsetDist), TrackBallTransformType.Scale); keyEvent.Handled = true; } break; case Keys.Z: if (keyEvent.Control) { if (keyEvent.Shift) { view3D.Scene.Redo(); } else { // undo last operation view3D.Scene.Undo(); } keyEvent.Handled = true; } break; case Keys.Insert: if (keyEvent.Shift) { view3D.sceneContext.Paste(); keyEvent.Handled = true; } break; case Keys.Delete: case Keys.Back: view3D.Scene.DeleteSelection(); keyEvent.Handled = true; keyEvent.SuppressKeyPress = true; break; case Keys.Escape: if (view3D.CurrentSelectInfo.DownOnPart) { view3D.CurrentSelectInfo.DownOnPart = false; view3D.Scene.SelectedItem.Matrix = view3D.TransformOnMouseDown; keyEvent.Handled = true; keyEvent.SuppressKeyPress = true; } foreach (var object3DControls in view3D.Object3DControlLayer.Object3DControls) { object3DControls.CancelOperation(); } break; case Keys.Left: if (keyEvent.Control && printerTabPage != null && !printerTabPage.sceneContext.ViewState.ModelView) { // Decrement slider printerTabPage.LayerFeaturesIndex -= 1; } else { if (view3D.sceneContext.Scene.SelectedItem is IObject3D object3D) { NudgeItem(view3D, object3D, ArrowDirection.Left, keyEvent); } else { // move or rotate view left Offset3DView(view3D, new Vector2(-offsetDist, 0), arrowKeyOperation); } } keyEvent.Handled = true; keyEvent.SuppressKeyPress = true; break; case Keys.Right: if (keyEvent.Control && printerTabPage != null && !printerTabPage.sceneContext.ViewState.ModelView) { // Increment slider printerTabPage.LayerFeaturesIndex += 1; } else { if (view3D.sceneContext.Scene.SelectedItem is IObject3D object3D) { NudgeItem(view3D, object3D, ArrowDirection.Right, keyEvent); } else { // move or rotate view right Offset3DView(view3D, new Vector2(offsetDist, 0), arrowKeyOperation); } } keyEvent.Handled = true; keyEvent.SuppressKeyPress = true; break; case Keys.Up: if (view3D.Printer != null && printerTabPage != null && view3D.Printer.ViewState.ViewMode != PartViewMode.Model) { printerTabPage.LayerScrollbar.Value += 1; } else { if (view3D.sceneContext.Scene.SelectedItem is IObject3D object3D) { NudgeItem(view3D, object3D, ArrowDirection.Up, keyEvent); } else { Offset3DView(view3D, new Vector2(0, offsetDist), arrowKeyOperation); } } keyEvent.Handled = true; keyEvent.SuppressKeyPress = true; break; case Keys.Down: if (view3D.Printer != null && printerTabPage != null && view3D.Printer.ViewState.ViewMode != PartViewMode.Model) { printerTabPage.LayerScrollbar.Value -= 1; } else { if (view3D.sceneContext.Scene.SelectedItem is IObject3D object3D) { NudgeItem(view3D, object3D, ArrowDirection.Down, keyEvent); } else { Offset3DView(view3D, new Vector2(0, -offsetDist), arrowKeyOperation); } } keyEvent.Handled = true; keyEvent.SuppressKeyPress = true; break; } } }; // Hook SystemWindow load and spin up MatterControl once we've hit first draw systemWindow.Load += (s, e) => { // Show the End User License Agreement if it has not been shown (on windows it is shown in the installer) if (AggContext.OperatingSystem != OSType.Windows && UserSettings.Instance.get(UserSettingsKey.SoftwareLicenseAccepted) != "true") { var eula = new LicenseAgreementPage(LoadMC) { Margin = new BorderDouble(5) }; systemWindow.AddChild(eula); } else { LoadMC(); } }; void LoadMC() { ReportStartupProgress(0.02, "First draw->RunOnIdle"); // UiThread.RunOnIdle(() => Task.Run(async() => { try { ReportStartupProgress(0.15, "MatterControlApplication.Initialize"); ApplicationController.LoadTranslationMap(); var mainView = await Initialize(systemWindow, (progress0To1, status) => { ReportStartupProgress(0.2 + progress0To1 * 0.7, status); }); ReportStartupProgress(0.9, "AddChild->MainView"); systemWindow.AddChild(mainView, 0); ReportStartupProgress(1, ""); systemWindow.BackgroundColor = Color.Transparent; overlay.Close(); } catch (Exception ex) { UiThread.RunOnIdle(() => { statusText.Visible = false; var errorTextColor = Color.White; progressPanel.Margin = 0; progressPanel.VAnchor = VAnchor.Center | VAnchor.Fit; progressPanel.BackgroundColor = Color.DarkGray; progressPanel.Padding = 20; progressPanel.Border = 1; progressPanel.BorderColor = Color.Red; var theme = new ThemeConfig(); progressPanel.AddChild( new TextWidget("Startup Failure".Localize() + ":", pointSize: theme.DefaultFontSize, textColor: errorTextColor)); progressPanel.AddChild( new TextWidget(ex.Message, pointSize: theme.FontSize9, textColor: errorTextColor)); var closeButton = new TextButton("Close", theme) { BackgroundColor = theme.SlightShade, HAnchor = HAnchor.Right, VAnchor = VAnchor.Absolute }; closeButton.Click += (s1, e1) => { systemWindow.Close(); }; spinner.SpinLogo = false; progressBar.Visible = false; progressPanel.AddChild(closeButton); }); } AppContext.IsLoading = false; }); } ReportStartupProgress(0, "ShowAsSystemWindow"); AddTextWidgetRightClickMenu(); return(systemWindow); }
private void addToQueueButton_Click(object sender, EventArgs mouseEvent) { UiThread.RunOnIdle(AddItemsToQueue); }
public PrinterActionsBar(PrinterConfig printer, PrinterTabPage printerTabPage, ThemeConfig theme) : base(theme) { this.printer = printer; this.printerTabPage = printerTabPage; this.HAnchor = HAnchor.Stretch; this.VAnchor = VAnchor.Fit; var defaultMargin = theme.ButtonSpacing; var printerType = printer.Settings.Slicer.PrinterType; if (printerType == PrinterType.FFF) { // add the reset button first (if there is one) if (printer.Settings.GetValue <bool>(SettingsKey.show_reset_connection)) { var resetConnectionButton = new TextIconButton( "Reset".Localize(), StaticData.Instance.LoadIcon("e_stop.png", 14, 14, theme.InvertIcons), theme) { ToolTipText = "Reboots the firmware on the controller".Localize(), Margin = defaultMargin }; resetConnectionButton.Click += (s, e) => { UiThread.RunOnIdle(printer.Connection.RebootBoard); }; this.AddChild(resetConnectionButton); } this.AddChild(new PrinterConnectButton(printer, theme)); // add the start print button GuiWidget startPrintButton; this.AddChild(startPrintButton = new PrintPopupMenu(printer, theme) { Margin = theme.ButtonSpacing }); void SetPrintButtonStyle(object s, EventArgs e) { switch (printer.Connection.CommunicationState) { case CommunicationStates.FinishedPrint: case CommunicationStates.Connected: theme.ApplyPrimaryActionStyle(startPrintButton); break; default: theme.RemovePrimaryActionStyle(startPrintButton); break; } } // make sure the buttons state is set correctly printer.Connection.CommunicationStateChanged += SetPrintButtonStyle; startPrintButton.Closed += (s, e) => printer.Connection.CommunicationStateChanged -= SetPrintButtonStyle; // and set the style right now SetPrintButtonStyle(this, null); } else { var exportButton = new ExportSlaPopupMenu(printer, theme) { Margin = theme.ButtonSpacing }; // add the SLA export button this.AddChild(exportButton); theme.ApplyPrimaryActionStyle(exportButton); } this.AddChild(new SliceButton(printer, printerTabPage, theme) { Name = "Generate Gcode Button", Margin = theme.ButtonSpacing, }); // Add vertical separator this.AddChild(new ToolbarSeparator(theme.GetBorderColor(50), theme.SeparatorMargin) { VAnchor = VAnchor.Absolute, Height = theme.ButtonHeight, }); var buttonGroupB = new ObservableCollection <GuiWidget>(); var iconPath = Path.Combine("ViewTransformControls", "model.png"); modelViewButton = new RadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupB, Name = "Model View Button", Checked = printer?.ViewState.ViewMode == PartViewMode.Model || printer == null, ToolTipText = "Model View".Localize(), Margin = theme.ButtonSpacing }; modelViewButton.Click += SwitchModes_Click; buttonGroupB.Add(modelViewButton); AddChild(modelViewButton); viewModes.Add(PartViewMode.Model, modelViewButton); iconPath = Path.Combine("ViewTransformControls", "gcode_3d.png"); layers3DButton = new RadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupB, Name = "Layers3D Button", Checked = printer?.ViewState.ViewMode == PartViewMode.Layers3D, ToolTipText = "3D Layer View".Localize(), Margin = theme.ButtonSpacing }; layers3DButton.Click += SwitchModes_Click; buttonGroupB.Add(layers3DButton); viewModes.Add(PartViewMode.Layers3D, layers3DButton); if (!UserSettings.Instance.IsTouchScreen) { this.AddChild(layers3DButton); } iconPath = Path.Combine("ViewTransformControls", "gcode_2d.png"); layers2DButton = new RadioIconButton(StaticData.Instance.LoadIcon(iconPath, 16, 16, theme.InvertIcons), theme) { SiblingRadioButtonList = buttonGroupB, Name = "Layers2D Button", Checked = printer?.ViewState.ViewMode == PartViewMode.Layers2D, ToolTipText = "2D Layer View".Localize(), Margin = theme.ButtonSpacing, }; layers2DButton.Click += SwitchModes_Click; buttonGroupB.Add(layers2DButton); this.AddChild(layers2DButton); viewModes.Add(PartViewMode.Layers2D, layers2DButton); this.AddChild(new HorizontalSpacer()); if (printerType == PrinterType.FFF) { int hotendCount = printer.Settings.Helpers.HotendCount(); for (int extruderIndex = 0; extruderIndex < hotendCount; extruderIndex++) { this.AddChild(new TemperatureWidgetHotend(printer, extruderIndex, theme, hotendCount) { Margin = new BorderDouble(right: 10) }); } if (printer.Settings.GetValue <bool>(SettingsKey.has_heated_bed)) { this.AddChild(new TemperatureWidgetBed(printer, theme)); } // Register listeners printer.Connection.ConnectionSucceeded += CheckForPrintRecovery; // if we are already connected than check if there is a print recovery right now if (printer.Connection.CommunicationState == CommunicationStates.Connected) { CheckForPrintRecovery(null, null); } } this.OverflowButton.Name = "Printer Overflow Menu"; this.OverflowButton.ToolTipText = "Printer Options".Localize(); this.ExtendOverflowMenu = (popupMenu) => { this.GeneratePrinterOverflowMenu(popupMenu, ApplicationController.Instance.MenuTheme); }; printer.ViewState.ViewModeChanged += (s, e) => { if (viewModes[e.ViewMode] is RadioIconButton activeButton && viewModes[e.PreviousMode] is RadioIconButton previousButton && !buttonIsBeingClicked) { // Show slide to animation from previous to current, on completion update view to current by setting active.Checked previousButton.SlideToNewState( activeButton, this, () => { activeButton.Checked = true; }, theme); } }; }
private void save_Click(object sender, EventArgs mouseEvent) { UiThread.RunOnIdle(save_OnIdle); }
public AboutPage() : base("Close".Localize()) { this.WindowTitle = "About".Localize() + " " + ApplicationController.Instance.ProductName; this.MinimumSize = new Vector2(480 * GuiWidget.DeviceScale, 520 * GuiWidget.DeviceScale); this.WindowSize = new Vector2(500 * GuiWidget.DeviceScale, 550 * GuiWidget.DeviceScale); contentRow.BackgroundColor = Color.Transparent; headerRow.Visible = false; var altHeadingRow = new GuiWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Absolute, Height = 100, }; contentRow.AddChild(altHeadingRow); var productInfo = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.Center | HAnchor.Fit, VAnchor = VAnchor.Center | VAnchor.Fit }; var productTitle = new FlowLayoutWidget() { HAnchor = HAnchor.Center | HAnchor.Fit }; productTitle.AddChild(new TextWidget("MatterControl".Localize(), textColor: theme.TextColor, pointSize: 20) { Margin = new BorderDouble(right: 3) }); productTitle.AddChild(new TextWidget("TM".Localize(), textColor: theme.TextColor, pointSize: 7) { VAnchor = VAnchor.Top }); altHeadingRow.AddChild(productInfo); productInfo.AddChild(productTitle); var spinnerPanel = new GuiWidget() { HAnchor = HAnchor.Absolute | HAnchor.Left, VAnchor = VAnchor.Absolute, Height = 100, Width = 100, }; altHeadingRow.AddChild(spinnerPanel); var accentColor = theme.PrimaryAccentColor; var spinner = new LogoSpinner(spinnerPanel, 4, 0.2, 0, rotateX: 0) { /* * MeshColor = new Color(175, 175, 175, 255), * AmbientColor = new float[] * { * accentColor.Red0To1, * accentColor.Green0To1, * accentColor.Blue0To1, * 0 * }*/ }; productInfo.AddChild( new TextWidget("Version".Localize() + " " + VersionInfo.Instance.BuildVersion, textColor: theme.TextColor, pointSize: theme.DefaultFontSize) { HAnchor = HAnchor.Center }); productInfo.AddChild( new TextWidget("Developed By".Localize() + ": " + "MatterHackers", textColor: theme.TextColor, pointSize: theme.DefaultFontSize) { HAnchor = HAnchor.Center }); contentRow.AddChild( new WrappedTextWidget( "MatterControl is made possible by the team at MatterHackers and other open source software".Localize() + ":", pointSize: theme.DefaultFontSize, textColor: theme.TextColor) { HAnchor = HAnchor.Stretch, Margin = new BorderDouble(0, 15) }); var licensePanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = new BorderDouble(bottom: 15) }; var data = JsonConvert.DeserializeObject <List <LibraryLicense> >(AggContext.StaticData.ReadAllText(Path.Combine("License", "license.json"))); var linkIcon = AggContext.StaticData.LoadIcon("fa-link_16.png", 16, 16, theme.InvertIcons); SectionWidget section = null; foreach (var item in data.OrderBy(i => i.Name)) { var linkButton = new IconButton(linkIcon, theme); linkButton.Click += (s, e) => UiThread.RunOnIdle(() => { ApplicationController.Instance.LaunchBrowser(item.Url); }); section = new SectionWidget(item.Title ?? item.Name, new LazyLicenseText(item.Name, theme), theme, linkButton, expanded: false) { HAnchor = HAnchor.Stretch }; licensePanel.AddChild(section); } // Apply a bottom border to the last time for balance if (section != null) { section.Border = section.Border.Clone(bottom: 1); } var scrollable = new ScrollableWidget(autoScroll: true) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Stretch, Margin = new BorderDouble(bottom: 10), }; scrollable.ScrollArea.HAnchor = HAnchor.Stretch; scrollable.AddChild(licensePanel); contentRow.AddChild(scrollable); var feedbackButton = new TextButton("Send Feedback", theme) { BackgroundColor = theme.MinimalShade, HAnchor = HAnchor.Absolute, }; feedbackButton.Click += (s, e) => UiThread.RunOnIdle(() => { this.DialogWindow.ChangeToPage <ContactFormPage>(); }); this.AddPageAction(feedbackButton, highlightFirstAction: false); contentRow.AddChild( new TextWidget("Copyright © 2018 MatterHackers, Inc.", textColor: theme.TextColor, pointSize: theme.DefaultFontSize) { HAnchor = HAnchor.Center, }); var siteLink = new LinkLabel("www.matterhackers.com", theme) { HAnchor = HAnchor.Center, TextColor = theme.TextColor }; siteLink.Click += (s, e) => UiThread.RunOnIdle(() => { ApplicationController.Instance.LaunchBrowser("http://www.matterhackers.com"); }); contentRow.AddChild(siteLink); }
private void CreateThumbnail() { string stlHashCode = this.ItemWrapper.FileHashCode.ToString(); ImageBuffer bigRender = new ImageBuffer(); if (!File.Exists(this.ItemWrapper.FileLocation)) { return; } List <MeshGroup> loadedMeshGroups = MeshFileIo.Load(this.ItemWrapper.FileLocation); RenderType renderType = GetRenderType(this.ItemWrapper.FileLocation); switch (renderType) { case RenderType.RAY_TRACE: { ThumbnailTracer tracer = new ThumbnailTracer(loadedMeshGroups, BigRenderSize.x, BigRenderSize.y); tracer.DoTrace(); bigRender = tracer.destImage; } break; case RenderType.PERSPECTIVE: { ThumbnailTracer tracer = new ThumbnailTracer(loadedMeshGroups, BigRenderSize.x, BigRenderSize.y); this.thumbnailImage = new ImageBuffer(this.buildingThumbnailImage); this.thumbnailImage.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0)); bigRender = new ImageBuffer(BigRenderSize.x, BigRenderSize.y, 32, new BlenderBGRA()); foreach (MeshGroup meshGroup in loadedMeshGroups) { double minZ = double.MaxValue; double maxZ = double.MinValue; foreach (Mesh loadedMesh in meshGroup.Meshes) { tracer.GetMinMaxZ(loadedMesh, ref minZ, ref maxZ); } foreach (Mesh loadedMesh in meshGroup.Meshes) { tracer.DrawTo(bigRender.NewGraphics2D(), loadedMesh, RGBA_Bytes.White, minZ, maxZ); } } if (bigRender == null) { bigRender = new ImageBuffer(this.noThumbnailImage); } } break; case RenderType.NONE: case RenderType.ORTHOGROPHIC: this.thumbnailImage = new ImageBuffer(this.buildingThumbnailImage); this.thumbnailImage.NewGraphics2D().Clear(new RGBA_Bytes(255, 255, 255, 0)); bigRender = BuildImageFromMeshGroups(loadedMeshGroups, stlHashCode, BigRenderSize); if (bigRender == null) { bigRender = new ImageBuffer(this.noThumbnailImage); } break; } // and save it to disk string imageFileName = GetImageFileName(stlHashCode); if (partExtension == ".png") { ImageIO.SaveImageData(imageFileName, bigRender); } else { ImageTgaIO.SaveImageData(imageFileName, bigRender); } bigRender.SetRecieveBlender(new BlenderPreMultBGRA()); this.thumbnailImage = ImageBuffer.CreateScaledImage(bigRender, (int)Width, (int)Height); UiThread.RunOnIdle(this.EnsureImageUpdated); OnDoneRendering(); }
private void buttonSave_Click(object sender, EventArgs e) { UiThread.RunOnIdle(DoButtonSave_Click); }
protected void Initialize() { UiThread.RunOnIdle(OnIdle); this.Margin = new BorderDouble(6, 3, 6, 6); }
private static void CreateSlicedPartsThread() { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; while (!haltSlicingThread) { if (listOfSlicingItems.Count > 0) { PrintItemWrapper itemToSlice = listOfSlicingItems[0]; bool doMergeInSlicer = false; string mergeRules = ""; doMergeInSlicer = ActivePrinterProfile.Instance.ActiveSliceEngineType == ActivePrinterProfile.SlicingEngineTypes.MatterSlice; string[] stlFileLocations = GetStlFileLocations(itemToSlice.FileLocation, doMergeInSlicer, ref mergeRules); string fileToSlice = stlFileLocations[0]; // check that the STL file is currently on disk if (File.Exists(fileToSlice)) { itemToSlice.CurrentlySlicing = true; string currentConfigurationFileAndPath = Path.Combine(ApplicationDataStorage.Instance.GCodeOutputPath, "config_" + ActiveSliceSettings.Instance.GetHashCode().ToString() + ".ini"); ActiveSliceSettings.Instance.GenerateConfigFile(currentConfigurationFileAndPath); string gcodePathAndFileName = itemToSlice.GetGCodePathAndFileName(); bool gcodeFileIsComplete = itemToSlice.IsGCodeFileComplete(gcodePathAndFileName); if (!File.Exists(gcodePathAndFileName) || !gcodeFileIsComplete) { string commandArgs = ""; switch (ActivePrinterProfile.Instance.ActiveSliceEngineType) { case ActivePrinterProfile.SlicingEngineTypes.Slic3r: commandArgs = "--load \"" + currentConfigurationFileAndPath + "\" --output \"" + gcodePathAndFileName + "\" \"" + fileToSlice + "\""; break; case ActivePrinterProfile.SlicingEngineTypes.CuraEngine: commandArgs = "-v -o \"" + gcodePathAndFileName + "\" " + EngineMappingCura.GetCuraCommandLineSettings() + " \"" + fileToSlice + "\""; break; case ActivePrinterProfile.SlicingEngineTypes.MatterSlice: { EngineMappingsMatterSlice.WriteMatterSliceSettingsFile(currentConfigurationFileAndPath); if (mergeRules == "") { commandArgs = "-v -o \"" + gcodePathAndFileName + "\" -c \"" + currentConfigurationFileAndPath + "\""; } else { commandArgs = "-b {0} -v -o \"".FormatWith(mergeRules) + gcodePathAndFileName + "\" -c \"" + currentConfigurationFileAndPath + "\""; } foreach (string filename in stlFileLocations) { commandArgs = commandArgs + " \"" + filename + "\""; } } break; } #if false Mesh loadedMesh = StlProcessing.Load(fileToSlice); SliceLayers layers = new SliceLayers(); layers.GetPerimetersForAllLayers(loadedMesh, .2, .2); layers.DumpSegmentsToGcode("test.gcode"); #endif if (OsInformation.OperatingSystem == OSType.Android || ((OsInformation.OperatingSystem == OSType.Mac || runInProcess) && ActivePrinterProfile.Instance.ActiveSliceEngineType == ActivePrinterProfile.SlicingEngineTypes.MatterSlice)) { itemCurrentlySlicing = itemToSlice; MatterHackers.MatterSlice.LogOutput.GetLogWrites += SendProgressToItem; MatterSlice.MatterSlice.ProcessArgs(commandArgs); MatterHackers.MatterSlice.LogOutput.GetLogWrites -= SendProgressToItem; itemCurrentlySlicing = null; } else { slicerProcess = new Process(); slicerProcess.StartInfo.Arguments = commandArgs; string slicerFullPath = getSlicerFullPath(); slicerProcess.StartInfo.CreateNoWindow = true; slicerProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; slicerProcess.StartInfo.RedirectStandardError = true; slicerProcess.StartInfo.RedirectStandardOutput = true; slicerProcess.StartInfo.FileName = slicerFullPath; slicerProcess.StartInfo.UseShellExecute = false; slicerProcess.OutputDataReceived += (sender, args) => { if (args.Data != null) { string message = args.Data; message = message.Replace("=>", "").Trim(); if (message.Contains(".gcode")) { message = "Saving intermediate file"; } message += "..."; UiThread.RunOnIdle(() => { itemToSlice.OnSlicingOutputMessage(new StringEventArgs(message)); }); } }; slicerProcess.Start(); slicerProcess.BeginOutputReadLine(); string stdError = slicerProcess.StandardError.ReadToEnd(); slicerProcess.WaitForExit(); lock (slicerProcess) { slicerProcess = null; } } } try { if (File.Exists(gcodePathAndFileName) && File.Exists(currentConfigurationFileAndPath)) { // make sure we have not already written the settings onto this file bool fileHaseSettings = false; int bufferSize = 32000; using (Stream fileStream = File.OpenRead(gcodePathAndFileName)) { byte[] buffer = new byte[bufferSize]; fileStream.Seek(Math.Max(0, fileStream.Length - bufferSize), SeekOrigin.Begin); int numBytesRead = fileStream.Read(buffer, 0, bufferSize); string fileEnd = System.Text.Encoding.UTF8.GetString(buffer); if (fileEnd.Contains("GCode settings used")) { fileHaseSettings = true; } } if (!fileHaseSettings) { using (StreamWriter gcodeWirter = File.AppendText(gcodePathAndFileName)) { string oemName = "MatterControl"; if (OemSettings.Instance.WindowTitleExtra != null && OemSettings.Instance.WindowTitleExtra.Trim().Length > 0) { oemName = oemName + " - {0}".FormatWith(OemSettings.Instance.WindowTitleExtra); } gcodeWirter.WriteLine("; {0} Version {1} Build {2} : GCode settings used".FormatWith(oemName, VersionInfo.Instance.ReleaseVersion, VersionInfo.Instance.BuildVersion)); gcodeWirter.WriteLine("; Date {0} Time {1}:{2:00}".FormatWith(DateTime.Now.Date, DateTime.Now.Hour, DateTime.Now.Minute)); foreach (string line in File.ReadLines(currentConfigurationFileAndPath)) { gcodeWirter.WriteLine("; {0}".FormatWith(line)); } } } } } catch (Exception) { } } UiThread.RunOnIdle(() => { itemToSlice.CurrentlySlicing = false; itemToSlice.DoneSlicing = true; }); lock (listOfSlicingItems) { listOfSlicingItems.RemoveAt(0); } } Thread.Sleep(100); } }
void CloseWindow(object o, EventArgs e) { //Stop listening for connection events (if set) and close window UiThread.RunOnIdle(CloseOnIdle); }
private void AddAdvancedPannel(GuiWidget settingsColumn) { var advancedPanel = new FlowLayoutWidget(FlowDirection.TopToBottom); var advancedSection = new SectionWidget("Advanced".Localize(), advancedPanel, theme, serializationKey: "ApplicationSettings-Advanced", expanded: false) { Name = "Advanced Section", HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = 0 }; settingsColumn.AddChild(advancedSection); theme.ApplyBoxStyle(advancedSection); // Touch Screen Mode this.AddSettingsRow( new SettingsItem( "Touch Screen Mode".Localize(), theme, new SettingsItem.ToggleSwitchConfig() { Checked = UserSettings.Instance.get(UserSettingsKey.ApplicationDisplayMode) == "touchscreen", ToggleAction = (itemChecked) => { string displayMode = itemChecked ? "touchscreen" : "responsive"; if (displayMode != UserSettings.Instance.get(UserSettingsKey.ApplicationDisplayMode)) { UserSettings.Instance.set(UserSettingsKey.ApplicationDisplayMode, displayMode); UiThread.RunOnIdle(() => ApplicationController.Instance.ReloadAll().ConfigureAwait(false)); } } }), advancedPanel); AddUserBoolToggle(advancedPanel, "Utilize High Res Monitors".Localize(), UserSettingsKey.ApplicationUseHeigResDisplays, true, false); AddUserBoolToggle(advancedPanel, "Enable Socketeer Client".Localize(), UserSettingsKey.ApplicationUseSocketeer, true, false); var openCacheButton = new IconButton(AggContext.StaticData.LoadIcon("fa-link_16.png", 16, 16, theme.InvertIcons), theme) { ToolTipText = "Open Folder".Localize(), }; openCacheButton.Click += (s, e) => UiThread.RunOnIdle(() => { Process.Start(ApplicationDataStorage.ApplicationUserDataPath); }); this.AddSettingsRow( new SettingsItem( "Application Storage".Localize(), openCacheButton, theme), advancedPanel); var clearCacheButton = new HoverIconButton(AggContext.StaticData.LoadIcon("remove.png", 16, 16, theme.InvertIcons), theme) { ToolTipText = "Clear Cache".Localize(), }; clearCacheButton.Click += (s, e) => UiThread.RunOnIdle(() => { CacheDirectory.DeleteCacheData(); }); this.AddSettingsRow( new SettingsItem( "Application Cache".Localize(), clearCacheButton, theme), advancedPanel); #if DEBUG var configureIcon = AggContext.StaticData.LoadIcon("fa-cog_16.png", 16, 16, theme.InvertIcons); var configurePluginsButton = new IconButton(configureIcon, theme) { ToolTipText = "Configure Plugins".Localize(), Margin = 0 }; configurePluginsButton.Click += (s, e) => { UiThread.RunOnIdle(() => { DialogWindow.Show <PluginsPage>(); }); }; this.AddSettingsRow( new SettingsItem( "Plugins".Localize(), configurePluginsButton, theme), advancedPanel); #endif advancedPanel.Children <SettingsItem>().First().Border = new BorderDouble(0, 1); }
public override void RemoveCollection(int collectionIndexToRemove) { libraryCreators.RemoveAt(collectionIndexToRemove); UiThread.RunOnIdle(() => OnDataReloaded(null)); }
private void AddGeneralPannel(GuiWidget settingsColumn) { var generalPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, }; var configureIcon = AggContext.StaticData.LoadIcon("fa-cog_16.png", 16, 16, theme.InvertIcons); var generalSection = new SectionWidget("General".Localize(), generalPanel, theme, expandingContent: false) { Name = "General Section", HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, }; settingsColumn.AddChild(generalSection); theme.ApplyBoxStyle(generalSection); #if __ANDROID__ // Camera Monitoring bool hasCamera = true || ApplicationSettings.Instance.get(ApplicationSettingsKey.HardwareHasCamera) == "true"; var previewButton = new IconButton(configureIcon, theme) { ToolTipText = "Preview".Localize() }; previewButton.Click += (s, e) => { AppContext.Platform.OpenCameraPreview(); }; var printer = ApplicationController.Instance.ActivePrinters.FirstOrDefault(); // TODO: Sort out how handle this better on Android and in a multi-printer setup if (printer != null) { this.AddSettingsRow( new SettingsItem( "Camera Monitoring".Localize(), theme, new SettingsItem.ToggleSwitchConfig() { Checked = printer.Settings.GetValue <bool>(SettingsKey.publish_bed_image), ToggleAction = (itemChecked) => { printer.Settings.SetValue(SettingsKey.publish_bed_image, itemChecked ? "1" : "0"); } }, previewButton, AggContext.StaticData.LoadIcon("camera-24x24.png", 24, 24)) { Enabled = printer.Settings.PrinterSelected }, generalPanel ); } #endif // Print Notifications var configureNotificationsButton = new IconButton(configureIcon, theme) { Name = "Configure Notification Settings Button", ToolTipText = "Configure Notifications".Localize(), Margin = new BorderDouble(left: 6), VAnchor = VAnchor.Center }; configureNotificationsButton.Click += (s, e) => { if (ApplicationController.ChangeToPrintNotification != null) { UiThread.RunOnIdle(() => { ApplicationController.ChangeToPrintNotification(this.DialogWindow); }); } }; this.AddSettingsRow( new SettingsItem( "Notifications".Localize(), theme, new SettingsItem.ToggleSwitchConfig() { Checked = UserSettings.Instance.get(UserSettingsKey.PrintNotificationsEnabled) == "true", ToggleAction = (itemChecked) => { UserSettings.Instance.set(UserSettingsKey.PrintNotificationsEnabled, itemChecked ? "true" : "false"); } }, configureNotificationsButton, AggContext.StaticData.LoadIcon("notify-24x24.png", 16, 16, theme.InvertIcons)), generalPanel); // LanguageControl var languageSelector = new LanguageSelector(theme); languageSelector.SelectionChanged += (s, e) => { UiThread.RunOnIdle(() => { string languageCode = languageSelector.SelectedValue; if (languageCode != UserSettings.Instance.get(UserSettingsKey.Language)) { UserSettings.Instance.set(UserSettingsKey.Language, languageCode); if (languageCode == "L10N") { #if DEBUG AppContext.Platform.GenerateLocalizationValidationFile(); #endif } ApplicationController.Instance.ResetTranslationMap(); ApplicationController.Instance.ReloadAll().ConfigureAwait(false); } }); }; this.AddSettingsRow(new SettingsItem("Language".Localize(), languageSelector, theme), generalPanel); #if !__ANDROID__ // ThumbnailRendering var thumbnailsModeDropList = new MHDropDownList("", theme, maxHeight: 200); thumbnailsModeDropList.AddItem("Flat".Localize(), "orthographic"); thumbnailsModeDropList.AddItem("3D".Localize(), "raytraced"); thumbnailsModeDropList.SelectedValue = UserSettings.Instance.ThumbnailRenderingMode; thumbnailsModeDropList.SelectionChanged += (s, e) => { string thumbnailRenderingMode = thumbnailsModeDropList.SelectedValue; if (thumbnailRenderingMode != UserSettings.Instance.ThumbnailRenderingMode) { UserSettings.Instance.ThumbnailRenderingMode = thumbnailRenderingMode; UiThread.RunOnIdle(() => { // Ask if the user they would like to rebuild their thumbnails StyledMessageBox.ShowMessageBox( (bool rebuildThumbnails) => { if (rebuildThumbnails) { string[] thumbnails = new string[] { ApplicationController.CacheablePath( Path.Combine("Thumbnails", "Content"), ""), ApplicationController.CacheablePath( Path.Combine("Thumbnails", "Library"), "") }; foreach (var directoryToRemove in thumbnails) { try { if (Directory.Exists(directoryToRemove)) { Directory.Delete(directoryToRemove, true); } } catch (Exception) { GuiWidget.BreakInDebugger(); } Directory.CreateDirectory(directoryToRemove); } ApplicationController.Instance.Library.NotifyContainerChanged(); } }, "You are switching to a different thumbnail rendering mode. If you want, your current thumbnails can be removed and recreated in the new style. You can switch back and forth at any time. There will be some processing overhead while the new thumbnails are created.\n\nDo you want to rebuild your existing thumbnails now?".Localize(), "Rebuild Thumbnails Now".Localize(), StyledMessageBox.MessageType.YES_NO, "Rebuild".Localize()); }); } }; this.AddSettingsRow( new SettingsItem( "Thumbnails".Localize(), thumbnailsModeDropList, theme), generalPanel); #endif // TextSize if (!double.TryParse(UserSettings.Instance.get(UserSettingsKey.ApplicationTextSize), out double currentTextSize)) { currentTextSize = 1.0; } double sliderThumbWidth = 10 * GuiWidget.DeviceScale; double sliderWidth = 100 * GuiWidget.DeviceScale; var textSizeSlider = new SolidSlider(default(Vector2), sliderThumbWidth, theme, .7, 2.5) { Name = "Text Size Slider", Margin = new BorderDouble(5, 0), Value = currentTextSize, HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Center, TotalWidthInPixels = sliderWidth, }; theme.ApplySliderStyle(textSizeSlider); var optionalContainer = new FlowLayoutWidget() { VAnchor = VAnchor.Center | VAnchor.Fit, HAnchor = HAnchor.Fit }; TextWidget sectionLabel = null; var textSizeApplyButton = new TextButton("Apply".Localize(), theme) { VAnchor = VAnchor.Center, BackgroundColor = theme.SlightShade, Visible = false, Margin = new BorderDouble(right: 6) }; textSizeApplyButton.Click += (s, e) => UiThread.RunOnIdle(() => { GuiWidget.DeviceScale = textSizeSlider.Value; ApplicationController.Instance.ReloadAll().ConfigureAwait(false); }); optionalContainer.AddChild(textSizeApplyButton); textSizeSlider.ValueChanged += (s, e) => { double textSizeNew = textSizeSlider.Value; UserSettings.Instance.set(UserSettingsKey.ApplicationTextSize, textSizeNew.ToString("0.0")); sectionLabel.Text = "Text Size".Localize() + $" : {textSizeNew:0.0}"; textSizeApplyButton.Visible = textSizeNew != currentTextSize; }; var textSizeRow = new SettingsItem( "Text Size".Localize() + $" : {currentTextSize:0.0}", textSizeSlider, theme, optionalContainer); sectionLabel = textSizeRow.Children <TextWidget>().FirstOrDefault(); this.AddSettingsRow(textSizeRow, generalPanel); var themeSection = CreateThemePanel(theme); settingsColumn.AddChild(themeSection); theme.ApplyBoxStyle(themeSection); }
public MacroListWidget(EditMacrosWindow windowController) { this.windowController = windowController; linkButtonFactory.fontSize = 10; FlowLayoutWidget topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom); topToBottom.AnchorAll(); topToBottom.Padding = new BorderDouble(3, 0, 3, 5); FlowLayoutWidget headerRow = new FlowLayoutWidget(FlowDirection.LeftToRight); headerRow.HAnchor = HAnchor.ParentLeftRight; headerRow.Margin = new BorderDouble(0, 3, 0, 0); headerRow.Padding = new BorderDouble(0, 3, 0, 3); { string macroPresetsLabel = LocalizedString.Get("Macro Presets"); string macroPresetsLabelFull = string.Format("{0}:", macroPresetsLabel); TextWidget elementHeader = new TextWidget(macroPresetsLabelFull, pointSize: 14); elementHeader.TextColor = ActiveTheme.Instance.PrimaryTextColor; elementHeader.HAnchor = HAnchor.ParentLeftRight; elementHeader.VAnchor = Agg.UI.VAnchor.ParentBottom; headerRow.AddChild(elementHeader); } topToBottom.AddChild(headerRow); FlowLayoutWidget presetsFormContainer = new FlowLayoutWidget(FlowDirection.TopToBottom); { presetsFormContainer.HAnchor = HAnchor.ParentLeftRight; presetsFormContainer.VAnchor = VAnchor.ParentBottomTop; presetsFormContainer.Padding = new BorderDouble(3); presetsFormContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor; } topToBottom.AddChild(presetsFormContainer); IEnumerable <DataStorage.CustomCommands> macroList = GetMacros(); foreach (DataStorage.CustomCommands currentCommand in macroList) { FlowLayoutWidget macroRow = new FlowLayoutWidget(); macroRow.Margin = new BorderDouble(3, 0, 3, 3); macroRow.HAnchor = Agg.UI.HAnchor.ParentLeftRight; macroRow.Padding = new BorderDouble(3); macroRow.BackgroundColor = RGBA_Bytes.White; TextWidget buttonLabel = new TextWidget(currentCommand.Name); macroRow.AddChild(buttonLabel); FlowLayoutWidget hSpacer = new FlowLayoutWidget(); hSpacer.HAnchor = Agg.UI.HAnchor.ParentLeftRight; macroRow.AddChild(hSpacer); Button editLink = linkButtonFactory.Generate(LocalizedString.Get("edit")); editLink.Margin = new BorderDouble(right: 5); // You can't pass a foreach variable into a link function or it wall always be the last item. // So we make a local variable copy of it and pass that. This will get the right one. DataStorage.CustomCommands currentCommandForLinkFunction = currentCommand; editLink.Click += (sender, e) => { windowController.ChangeToMacroDetail(currentCommandForLinkFunction); }; macroRow.AddChild(editLink); Button removeLink = linkButtonFactory.Generate(LocalizedString.Get("remove")); removeLink.Click += (sender, e) => { currentCommandForLinkFunction.Delete(); windowController.functionToCallOnSave(this, null); windowController.ChangeToMacroList(); }; macroRow.AddChild(removeLink); presetsFormContainer.AddChild(macroRow); } Button addMacroButton = textImageButtonFactory.Generate(LocalizedString.Get("Add"), "icon_circle_plus.png"); addMacroButton.Click += new EventHandler(addMacro_Click); Button cancelPresetsButton = textImageButtonFactory.Generate(LocalizedString.Get("Close")); cancelPresetsButton.Click += (sender, e) => { UiThread.RunOnIdle((state) => { this.windowController.Close(); }); }; FlowLayoutWidget buttonRow = new FlowLayoutWidget(); buttonRow.HAnchor = HAnchor.ParentLeftRight; buttonRow.Padding = new BorderDouble(0, 3); GuiWidget hButtonSpacer = new GuiWidget(); hButtonSpacer.HAnchor = HAnchor.ParentLeftRight; buttonRow.AddChild(addMacroButton); buttonRow.AddChild(hButtonSpacer); buttonRow.AddChild(cancelPresetsButton); topToBottom.AddChild(buttonRow); AddChild(topToBottom); this.AnchorAll(); }
public void CreateCopyInQueue() { // Guard for single item selection if (this.queueDataView.SelectedItems.Count != 1) { return; } var queueRowItem = this.queueDataView.SelectedItems[0]; var printItemWrapper = queueRowItem.PrintItemWrapper; int thisIndexInQueue = QueueData.Instance.GetIndex(printItemWrapper); if (thisIndexInQueue != -1 && File.Exists(printItemWrapper.FileLocation)) { string libraryDataPath = ApplicationDataStorage.Instance.ApplicationLibraryDataPath; if (!Directory.Exists(libraryDataPath)) { Directory.CreateDirectory(libraryDataPath); } string newCopyFilename; int infiniteBlocker = 0; do { newCopyFilename = Path.Combine(libraryDataPath, Path.ChangeExtension(Path.GetRandomFileName(), Path.GetExtension(printItemWrapper.FileLocation))); newCopyFilename = Path.GetFullPath(newCopyFilename); infiniteBlocker++; } while (File.Exists(newCopyFilename) && infiniteBlocker < 100); File.Copy(printItemWrapper.FileLocation, newCopyFilename); string newName = printItemWrapper.Name; if (!newName.Contains(" - copy")) { newName += " - copy"; } else { int index = newName.LastIndexOf(" - copy"); newName = newName.Substring(0, index) + " - copy"; } int copyNumber = 2; string testName = newName; string[] itemNames = QueueData.Instance.GetItemNames(); // figure out if we have a copy already and increment the number if we do while (true) { if (itemNames.Contains(testName)) { testName = "{0} {1}".FormatWith(newName, copyNumber); copyNumber++; } else { break; } } newName = testName; PrintItem newPrintItem = new PrintItem(); newPrintItem.Name = newName; newPrintItem.FileLocation = newCopyFilename; newPrintItem.ReadOnly = printItemWrapper.PrintItem.ReadOnly; newPrintItem.Protected = printItemWrapper.PrintItem.Protected; UiThread.RunOnIdle(AddPartCopyToQueue, new PartToAddToQueue() { PrintItem = newPrintItem, InsertAfterIndex = thisIndexInQueue + 1 }); } }
public void ChangeToMacroDetail(CustomCommands macro = null) { this.ActiveMacro = macro; UiThread.RunOnIdle(DoChangeToMacroDetail); }
public ExportPrintItemPage(IEnumerable <ILibraryItem> libraryItems) { this.WindowTitle = "Export File".Localize(); this.HeaderText = "Export selection to".Localize() + ":"; this.libraryItems = libraryItems; this.Name = "Export Item Window"; var commonMargin = new BorderDouble(4, 2); bool isFirstItem = true; // TODO: Someday export operations need to resolve printer context interactively var printer = ApplicationController.Instance.ActivePrinter; // GCode export exportPluginButtons = new Dictionary <RadioButton, IExportPlugin>(); foreach (IExportPlugin plugin in PluginFinder.CreateInstancesOf <IExportPlugin>().OrderBy(p => p.ButtonText)) { plugin.Initialize(printer); // Skip plugins which are invalid for the current printer if (!plugin.Enabled) { continue; } // Create export button for each plugin var pluginButton = new RadioButton(new RadioImageWidget(plugin.ButtonText, theme.Colors.PrimaryTextColor, plugin.Icon)) { HAnchor = HAnchor.Left, Margin = commonMargin, Cursor = Cursors.Hand, Name = plugin.ButtonText + " Button" }; contentRow.AddChild(pluginButton); if (isFirstItem) { pluginButton.Checked = true; isFirstItem = false; } if (plugin is IExportWithOptions pluginWithOptions) { var optionPanel = pluginWithOptions.GetOptionsPanel(); if (optionPanel != null) { optionPanel.HAnchor = HAnchor.Stretch; optionPanel.VAnchor = VAnchor.Fit; contentRow.AddChild(optionPanel); } } exportPluginButtons.Add(pluginButton, plugin); } contentRow.AddChild(new VerticalSpacer()); // TODO: make this work on the mac and then delete this if if (AggContext.OperatingSystem == OSType.Windows || AggContext.OperatingSystem == OSType.X11) { showInFolderAfterSave = new CheckBox("Show file in folder after save".Localize(), ActiveTheme.Instance.PrimaryTextColor, 10) { HAnchor = HAnchor.Left, Cursor = Cursors.Hand }; contentRow.AddChild(showInFolderAfterSave); } var exportButton = theme.CreateDialogButton("Export".Localize()); exportButton.Name = "Export Button"; exportButton.Click += (s, e) => { string fileTypeFilter = ""; string targetExtension = ""; IExportPlugin activePlugin = null; // Loop over all plugin buttons, break on the first checked item found foreach (var button in this.exportPluginButtons.Keys) { if (button.Checked) { activePlugin = exportPluginButtons[button]; break; } } // Early exit if no plugin radio button is selected if (activePlugin == null) { return; } fileTypeFilter = activePlugin.ExtensionFilter; targetExtension = activePlugin.FileExtension; this.Parent.CloseOnIdle(); if (activePlugin is FolderExport) { UiThread.RunOnIdle(() => { AggContext.FileDialogs.SelectFolderDialog( new SelectFolderDialogParams("Select Location To Export Files") { ActionButtonLabel = "Export".Localize(), Title = ApplicationController.Instance.ProductName + " - " + "Select A Folder".Localize() }, async(openParams) => { string path = openParams.FolderPath; if (!string.IsNullOrEmpty(path)) { await activePlugin.Generate(libraryItems, path); } }); }); return; } UiThread.RunOnIdle(() => { string title = ApplicationController.Instance.ProductName + " - " + "Export File".Localize(); string workspaceName = "Workspace " + DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss"); AggContext.FileDialogs.SaveFileDialog( new SaveFileDialogParams(fileTypeFilter) { Title = title, ActionButtonLabel = "Export".Localize(), FileName = Path.GetFileNameWithoutExtension(libraryItems.FirstOrDefault()?.Name ?? workspaceName) }, (saveParams) => { string savePath = saveParams.FileName; if (!string.IsNullOrEmpty(savePath)) { Task.Run(async() => { string extension = Path.GetExtension(savePath); if (extension != targetExtension) { savePath += targetExtension; } bool succeeded = false; if (activePlugin != null) { succeeded = await activePlugin.Generate(libraryItems, savePath); } if (succeeded) { ShowFileIfRequested(savePath); } else { UiThread.RunOnIdle(() => { StyledMessageBox.ShowMessageBox("Export failed".Localize(), title); }); } }); } }); }); }; this.AddPageAction(exportButton); }