Exemple #1
0
        protected static SolidSlider InsertUiForSlider(FlowLayoutWidget wordOptionContainer, string header, double min = 0, double max = .5)
        {
            double scrollBarWidth = 10;

            if (ActiveTheme.Instance.DisplayMode == ActiveTheme.ApplicationDisplayType.Touchscreen)
            {
                scrollBarWidth = 20;
            }

            TextWidget spacingText = new TextWidget(header, textColor: ActiveTheme.Instance.PrimaryTextColor);

            spacingText.Margin  = new BorderDouble(10, 3, 3, 5);
            spacingText.HAnchor = HAnchor.ParentLeft;
            wordOptionContainer.AddChild(spacingText);
            SolidSlider namedSlider = new SolidSlider(new Vector2(), scrollBarWidth, 0, 1);

            namedSlider.TotalWidthInPixels   = DefaultScrollBarWidth;
            namedSlider.Minimum              = min;
            namedSlider.Maximum              = max;
            namedSlider.Margin               = new BorderDouble(3, 5, 3, 3);
            namedSlider.HAnchor              = HAnchor.ParentCenter;
            namedSlider.View.BackgroundColor = new RGBA_Bytes();
            wordOptionContainer.AddChild(namedSlider);

            return(namedSlider);
        }
Exemple #2
0
        public SliceLayerSelector(PrinterConfig printer, BedConfig sceneContext)
        {
            var theme = ApplicationController.Instance.Theme;

            this.sceneContext = sceneContext;

            this.AddChild(layerScrollbar = new LayerScrollbar(printer, sceneContext)
            {
                VAnchor = VAnchor.Stretch,
                HAnchor = HAnchor.Right
            });

            layerSlider = layerScrollbar.layerSlider;

            var tagContainer = new HorizontalTag()
            {
                HAnchor  = HAnchor.Fit | HAnchor.Right,
                VAnchor  = VAnchor.Fit,
                Padding  = new BorderDouble(6, 4, 10, 4),
                Margin   = new BorderDouble(right: layerScrollbar.Width + layerScrollbar.Margin.Width),
                TagColor = (theme.Colors.IsDarkTheme) ? theme.Shade : theme.SlightShade
            };

            currentLayerInfo = new InlineEditControl("1000")
            {
                Name             = "currentLayerInfo",
                TextColor        = theme.Colors.PrimaryTextColor,
                GetDisplayString = (value) => $"{value}",
                HAnchor          = HAnchor.Right | HAnchor.Fit,
                VAnchor          = VAnchor.Absolute | VAnchor.Fit,
            };
            currentLayerInfo.EditComplete += (s, e) =>
            {
                layerScrollbar.Value = currentLayerInfo.Value - 1;
            };

            tagContainer.AddChild(currentLayerInfo);
            this.AddChild(tagContainer);

            currentLayerInfo.Visible = true;
            layerInfoHalfHeight      = currentLayerInfo.Height / 2;
            currentLayerInfo.Visible = false;

            layerSlider.ValueChanged += (s, e) =>
            {
                currentLayerInfo.StopEditing();
                currentLayerInfo.Position = new Vector2(0, (double)(layerSlider.Position.Y + layerSlider.PositionPixelsFromFirstValue - layerInfoHalfHeight));
            };

            // Set initial position
            currentLayerInfo.Position = new Vector2(0, (double)(layerSlider.Position.Y + layerSlider.PositionPixelsFromFirstValue - layerInfoHalfHeight));

            sceneContext.ActiveLayerChanged += SetPositionAndValue;
            layerScrollbar.MouseEnter       += SetPositionAndValue;
        }
        void DoneLoadingGCode(object sender, EventArgs e)
        {
            SetProcessingMessage("");
            if (gcodeViewWidget != null &&
                gcodeViewWidget.LoadedGCode != null &&
                gcodeViewWidget.LoadedGCode.Count > 0)
            {
                CreateOptionsContent();
                buttonRightPanel.Visible   = true;
                viewControlsToggle.Visible = true;

                CloseIfNotNull(setLayerWidget);
                setLayerWidget         = new SetLayerWidget(gcodeViewWidget);
                setLayerWidget.VAnchor = Agg.UI.VAnchor.ParentTop;
                layerSelectionButtonsPanel.AddChild(setLayerWidget);

                CloseIfNotNull(navigationWidget);
                navigationWidget        = new LayerNavigationWidget(gcodeViewWidget);
                navigationWidget.Margin = new BorderDouble(0, 0, 20, 0);
                layerSelectionButtonsPanel.AddChild(navigationWidget);

                CloseIfNotNull(selectLayerSlider);
                selectLayerSlider = new SolidSlider(new Vector2(), sliderWidth, 0, gcodeViewWidget.LoadedGCode.NumChangesInZ - 1, Orientation.Vertical);
                selectLayerSlider.ValueChanged     += new EventHandler(selectLayerSlider_ValueChanged);
                gcodeViewWidget.ActiveLayerChanged += new EventHandler(gcodeViewWidget_ActiveLayerChanged);
                AddChild(selectLayerSlider);

                CloseIfNotNull(layerRenderRatioSlider);
                layerRenderRatioSlider                     = new DoubleSolidSlider(new Vector2(), sliderWidth);
                layerRenderRatioSlider.FirstValue          = 0;
                layerRenderRatioSlider.FirstValueChanged  += new EventHandler(layerStartRenderRatioSlider_ValueChanged);
                layerRenderRatioSlider.SecondValue         = 1;
                layerRenderRatioSlider.SecondValueChanged += new EventHandler(layerEndRenderRatioSlider_ValueChanged);
                AddChild(layerRenderRatioSlider);

                SetSliderSizes();

                // let's change the active layer so that it is set to the first layer with data
                gcodeViewWidget.ActiveLayerIndex = gcodeViewWidget.ActiveLayerIndex + 1;
                gcodeViewWidget.ActiveLayerIndex = gcodeViewWidget.ActiveLayerIndex - 1;

                BoundsChanged += new EventHandler(PartPreviewGCode_BoundsChanged);

                meshViewerWidget.partProcessingInfo.Visible = false;
            }
        }
		private void DoneLoadingGCode(object sender, EventArgs e)
		{
			SetProcessingMessage("");
			if (gcodeViewWidget != null
				&& gcodeViewWidget.LoadedGCode == null)
			{
				// If we have finished loading the gcode and the source file exists but we don't have any loaded gcode it is because the loader decided to not load it.
				if (File.Exists(printItem.FileLocation))
				{
					SetProcessingMessage(string.Format(fileTooBigToLoad, printItem.Name));
				}
				else
				{
					SetProcessingMessage(string.Format("{0}\n'{1}'", fileNotFoundMessage, Path.GetFileName(printItem.FileLocation)));
				}
			}

			if (gcodeViewWidget != null
				&& gcodeViewWidget.LoadedGCode != null
				&& gcodeViewWidget.LoadedGCode.LineCount > 0)
			{
				CloseIfNotNull(gradientWidget);
				gradientWidget = new ColorGradientWidget(gcodeViewWidget.LoadedGCode);
				AddChild(gradientWidget);
				gradientWidget.Visible = false;

				CreateOptionsContent();
				setGradientVisibility();
				buttonRightPanel.Visible = true;
				viewControlsToggle.Visible = true;

				CloseIfNotNull(setLayerWidget);
				setLayerWidget = new SetLayerWidget(gcodeViewWidget);
				setLayerWidget.VAnchor = Agg.UI.VAnchor.ParentTop;
				layerSelectionButtonsPanel.AddChild(setLayerWidget);

				CloseIfNotNull(navigationWidget);
				navigationWidget = new LayerNavigationWidget(gcodeViewWidget);
				navigationWidget.Margin = new BorderDouble(0, 0, 20, 0);
				layerSelectionButtonsPanel.AddChild(navigationWidget);

				CloseIfNotNull(selectLayerSlider);
				selectLayerSlider = new SolidSlider(new Vector2(), sliderWidth, 0, gcodeViewWidget.LoadedGCode.NumChangesInZ - 1, Orientation.Vertical);
				selectLayerSlider.ValueChanged += new EventHandler(selectLayerSlider_ValueChanged);
				gcodeViewWidget.ActiveLayerChanged += new EventHandler(gcodeViewWidget_ActiveLayerChanged);
				AddChild(selectLayerSlider);

				CloseIfNotNull(layerRenderRatioSlider);
				layerRenderRatioSlider = new DoubleSolidSlider(new Vector2(), sliderWidth);
				layerRenderRatioSlider.FirstValue = 0;
				layerRenderRatioSlider.FirstValueChanged += new EventHandler(layerStartRenderRatioSlider_ValueChanged);
				layerRenderRatioSlider.SecondValue = 1;
				layerRenderRatioSlider.SecondValueChanged += new EventHandler(layerEndRenderRatioSlider_ValueChanged);
				AddChild(layerRenderRatioSlider);

				SetSliderSizes();

				// let's change the active layer so that it is set to the first layer with data
				gcodeViewWidget.ActiveLayerIndex = gcodeViewWidget.ActiveLayerIndex + 1;
				gcodeViewWidget.ActiveLayerIndex = gcodeViewWidget.ActiveLayerIndex - 1;

				BoundsChanged += new EventHandler(PartPreviewGCode_BoundsChanged);

				meshViewerWidget.partProcessingInfo.Visible = false;
			}
		}
        private FlowLayoutWidget CreateRightButtonPanel(double buildHeight)
        {
            FlowLayoutWidget buttonRightPanel = new FlowLayoutWidget(FlowDirection.TopToBottom);

            buttonRightPanel.Width = 200;
            {
                BorderDouble buttonMargin = new BorderDouble(top: 3);

                // put in the word editing menu
                {
                    CheckBox expandWordOptions = expandMenuOptionFactory.GenerateCheckBoxButton("Word Edit".Localize(), "icon_arrow_right_no_border_32x32.png", "icon_arrow_down_no_border_32x32.png");
                    expandWordOptions.Margin = new BorderDouble(bottom: 2);
                    buttonRightPanel.AddChild(expandWordOptions);

                    FlowLayoutWidget wordOptionContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
                    wordOptionContainer.HAnchor = HAnchor.ParentLeftRight;
                    wordOptionContainer.Visible = false;
                    buttonRightPanel.AddChild(wordOptionContainer);

                    spacingScrollBar = InsertUiForSlider(wordOptionContainer, "Spacing:".Localize(), .5, 1);
                    {
                        spacingScrollBar.ValueChanged += (sender, e) =>
                        {
                            SetWordSpacing(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
                            RebuildUnderlineIfRequired();
                        };
                    }

                    sizeScrollBar = InsertUiForSlider(wordOptionContainer, "Size:".Localize(), .3, 2);
                    {
                        sizeScrollBar.ValueChanged += (sender, e) =>
                        {
                            SetWordSize(MeshGroups, MeshGroupTransforms);

                            //SetWordSpacing(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
                            RebuildUnderlineIfRequired();
                        };
                    }

                    heightScrollBar = InsertUiForSlider(wordOptionContainer, "Height:".Localize(), .05, 1);
                    {
                        heightScrollBar.ValueChanged += (sender, e) =>
                        {
                            SetWordHeight(MeshGroups, MeshGroupTransforms);
                            RebuildUnderlineIfRequired();
                        };
                    }

                    createUnderline         = new CheckBox(new CheckBoxViewText("Underline".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor));
                    createUnderline.Checked = true;
                    createUnderline.Margin  = new BorderDouble(10, 5);
                    createUnderline.HAnchor = HAnchor.ParentLeft;
                    wordOptionContainer.AddChild(createUnderline);
                    createUnderline.CheckedStateChanged += (sender, e) =>
                    {
                        int oldIndex = SelectedMeshGroupIndex;
                        if (!createUnderline.Checked)
                        {
                            // we need to remove the underline
                            if (MeshGroups.Count > 1)
                            {
                                SelectedMeshGroupIndex = MeshGroups.Count - 1;
                                DeleteSelectedMesh();
                            }
                        }
                        else if (MeshGroups.Count > 0)
                        {
                            // we need to add the underline
                            CreateUnderline(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
                        }
                        SelectedMeshGroupIndex = Math.Min(oldIndex, MeshGroups.Count - 1);
                    };

                    expandWordOptions.CheckedStateChanged += (sender, e) =>
                    {
                        wordOptionContainer.Visible = expandWordOptions.Checked;
                    };

                    expandWordOptions.Checked = true;
                }

                // put in the letter editing menu
                {
                    CheckBox expandLetterOptions = expandMenuOptionFactory.GenerateCheckBoxButton("Letter", "icon_arrow_right_no_border_32x32.png", "icon_arrow_down_no_border_32x32.png");
                    expandLetterOptions.Margin = new BorderDouble(bottom: 2);
                    //buttonRightPanel.AddChild(expandLetterOptions);

                    FlowLayoutWidget letterOptionContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
                    letterOptionContainer.HAnchor = HAnchor.ParentLeftRight;
                    letterOptionContainer.Visible = false;
                    buttonRightPanel.AddChild(letterOptionContainer);

                    SolidSlider sizeScrollBar     = InsertUiForSlider(letterOptionContainer, "Size:".Localize());
                    SolidSlider heightScrollBar   = InsertUiForSlider(letterOptionContainer, "Height:".Localize());
                    SolidSlider rotationScrollBar = InsertUiForSlider(letterOptionContainer, "Rotation:".Localize());

                    expandLetterOptions.CheckedStateChanged += (sender, e) =>
                    {
                        letterOptionContainer.Visible = expandLetterOptions.Checked;
                    };
                }

                GuiWidget verticalSpacer = new GuiWidget();
                verticalSpacer.VAnchor = VAnchor.ParentBottomTop;
                buttonRightPanel.AddChild(verticalSpacer);

                saveButton         = whiteButtonFactory.Generate("Save".Localize(), centerText: true);
                saveButton.Visible = false;
                saveButton.Cursor  = Cursors.Hand;

                saveAndExitButton         = whiteButtonFactory.Generate("Save & Exit".Localize(), centerText: true);
                saveAndExitButton.Visible = false;
                saveAndExitButton.Cursor  = Cursors.Hand;

                //buttonRightPanel.AddChild(saveButton);
                buttonRightPanel.AddChild(saveAndExitButton);
            }

            buttonRightPanel.Padding         = new BorderDouble(6, 6);
            buttonRightPanel.Margin          = new BorderDouble(0, 1);
            buttonRightPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
            buttonRightPanel.VAnchor         = VAnchor.ParentBottomTop;

            return(buttonRightPanel);
        }
Exemple #6
0
        private AdjustmentControls(PrinterConfig printer, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            double sliderWidth      = 300 * GuiWidget.DeviceScale;
            double sliderThumbWidth = 10 * GuiWidget.DeviceScale;

            this.printer = printer;

            SettingsRow settingsRow;

            {
                this.AddChild(settingsRow = new SettingsRow(
                                  "Speed Multiplier".Localize(),
                                  null,
                                  theme));

                // Remove the HorizontalSpacer
                settingsRow.Children.Last().Close();

                feedRateRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, theme, minFeedRateRatio, maxFeedRateRatio)
                {
                    Name               = "Feed Rate Slider",
                    Margin             = new BorderDouble(5, 0),
                    Value              = FeedRateMultiplyerStream.FeedRateRatio,
                    HAnchor            = HAnchor.Stretch,
                    VAnchor            = VAnchor.Center,
                    TotalWidthInPixels = sliderWidth,
                };
                theme.ApplySliderStyle(feedRateRatioSlider);
                feedRateRatioSlider.ValueChanged += (sender, e) =>
                {
                    feedRateValue.ActuallNumberEdit.Value = Math.Round(feedRateRatioSlider.Value, 2);
                };
                feedRateRatioSlider.SliderReleased += (s, e) =>
                {
                    // Update state for runtime use
                    FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.feedrate_ratio,
                        FeedRateMultiplyerStream.FeedRateRatio.ToString());
                };
                settingsRow.AddChild(feedRateRatioSlider);

                feedRateValue = new MHNumberEdit(Math.Round(FeedRateMultiplyerStream.FeedRateRatio, 2), theme, allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale)
                {
                    Name             = "Feed Rate NumberEdit",
                    SelectAllOnFocus = true,
                    Margin           = new BorderDouble(0, 0, 5, 0),
                    VAnchor          = VAnchor.Center | VAnchor.Fit,
                    Padding          = 0
                };
                feedRateValue.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    feedRateRatioSlider.Value = feedRateValue.ActuallNumberEdit.Value;

                    // Update state for runtime use
                    FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.feedrate_ratio,
                        FeedRateMultiplyerStream.FeedRateRatio.ToString());
                };
                settingsRow.AddChild(feedRateValue);
            }

            {
                this.AddChild(settingsRow = new SettingsRow(
                                  "Extrusion Multiplier".Localize(),
                                  null,
                                  theme));

                // Remove the HorizontalSpacer
                settingsRow.Children.Last().Close();

                extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, theme, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal)
                {
                    Name = "Extrusion Multiplier Slider",
                    TotalWidthInPixels = sliderWidth,
                    HAnchor            = HAnchor.Stretch,
                    VAnchor            = VAnchor.Center,
                    Margin             = new BorderDouble(5, 0),
                    Value = ExtrusionMultiplyerStream.ExtrusionRatio
                };
                theme.ApplySliderStyle(extrusionRatioSlider);
                extrusionRatioSlider.ValueChanged += (sender, e) =>
                {
                    extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatioSlider.Value, 2);
                };
                extrusionRatioSlider.SliderReleased += (s, e) =>
                {
                    // Update state for runtime use
                    ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.extrusion_ratio,
                        ExtrusionMultiplyerStream.ExtrusionRatio.ToString());
                };
                settingsRow.AddChild(extrusionRatioSlider);

                extrusionValue = new MHNumberEdit(Math.Round(ExtrusionMultiplyerStream.ExtrusionRatio, 2), theme, allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale)
                {
                    Name             = "Extrusion Multiplier NumberEdit",
                    SelectAllOnFocus = true,
                    Margin           = new BorderDouble(0, 0, 5, 0),
                    VAnchor          = VAnchor.Center | VAnchor.Fit,
                    Padding          = 0
                };
                extrusionValue.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    extrusionRatioSlider.Value = extrusionValue.ActuallNumberEdit.Value;

                    // Update state for runtime use
                    ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.extrusion_ratio,
                        ExtrusionMultiplyerStream.ExtrusionRatio.ToString());
                };
                settingsRow.AddChild(extrusionValue);
            }

            // Register listeners
            printer.Settings.SettingChanged += Printer_SettingChanged;
        }
        protected override void AddChildElements()
        {
            AltGroupBox adjustmentControlsGroupBox = new AltGroupBox(new TextWidget("Tuning Adjustment".Localize(), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor));

            adjustmentControlsGroupBox.Margin      = new BorderDouble(0);
            adjustmentControlsGroupBox.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
            adjustmentControlsGroupBox.HAnchor     = Agg.UI.HAnchor.ParentLeftRight;

            {
                FlowLayoutWidget tuningRatiosLayout = new FlowLayoutWidget(FlowDirection.TopToBottom);
                tuningRatiosLayout.Margin  = new BorderDouble(0, 0, 0, 0) * TextWidget.GlobalPointSizeScaleRatio;
                tuningRatiosLayout.HAnchor = HAnchor.ParentLeftRight;
                tuningRatiosLayout.Padding = new BorderDouble(3, 0, 3, 0) * TextWidget.GlobalPointSizeScaleRatio;

                double sliderWidth      = 300;
                double sliderThumbWidth = 10;
                if (ActiveTheme.Instance.DisplayMode == ActiveTheme.ApplicationDisplayType.Touchscreen)
                {
                    sliderWidth      = 280;
                    sliderThumbWidth = 20;
                }

                TextWidget subheader = new TextWidget("Fine-tune adjustment while actively printing", pointSize: 8, textColor: ActiveTheme.Instance.PrimaryTextColor);
                subheader.Margin = new BorderDouble(bottom: 6);
                tuningRatiosLayout.AddChild(subheader);
                TextWidget feedRateDescription;
                {
                    FlowLayoutWidget feedRateLeftToRight;
                    {
                        feedRateValue       = new NumberEdit(0, allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * TextWidget.GlobalPointSizeScaleRatio);
                        feedRateValue.Value = ((int)(PrinterConnectionAndCommunication.Instance.FeedRateRatio * 100 + .5)) / 100.0;

                        feedRateLeftToRight         = new FlowLayoutWidget();
                        feedRateLeftToRight.HAnchor = HAnchor.ParentLeftRight;

                        feedRateDescription             = new TextWidget(LocalizedString.Get("Speed Multiplier"));
                        feedRateDescription.MinimumSize = new Vector2(140, 0) * TextWidget.GlobalPointSizeScaleRatio;
                        feedRateDescription.TextColor   = ActiveTheme.Instance.PrimaryTextColor;
                        feedRateDescription.VAnchor     = VAnchor.ParentCenter;
                        feedRateLeftToRight.AddChild(feedRateDescription);
                        feedRateRatioSlider                      = new SolidSlider(new Vector2(), sliderThumbWidth, minFeedRateRatio, maxFeedRateRatio);
                        feedRateRatioSlider.Margin               = new BorderDouble(5, 0);
                        feedRateRatioSlider.Value                = PrinterConnectionAndCommunication.Instance.FeedRateRatio;
                        feedRateRatioSlider.TotalWidthInPixels   = sliderWidth;
                        feedRateRatioSlider.View.BackgroundColor = new RGBA_Bytes();
                        feedRateRatioSlider.ValueChanged        += (sender, e) =>
                        {
                            PrinterConnectionAndCommunication.Instance.FeedRateRatio = feedRateRatioSlider.Value;
                        };
                        PrinterConnectionAndCommunication.Instance.FeedRateRatioChanged.RegisterEvent(FeedRateRatioChanged_Event, ref unregisterEvents);
                        feedRateValue.EditComplete += (sender, e) =>
                        {
                            feedRateRatioSlider.Value = feedRateValue.Value;
                        };
                        feedRateLeftToRight.AddChild(feedRateRatioSlider);
                        tuningRatiosLayout.AddChild(feedRateLeftToRight);

                        feedRateLeftToRight.AddChild(feedRateValue);
                        feedRateValue.Margin  = new BorderDouble(0, 0, 5, 0);
                        feedRateValue.VAnchor = VAnchor.ParentCenter;
                        textImageButtonFactory.FixedHeight       = (int)feedRateValue.Height + 1;
                        textImageButtonFactory.borderWidth       = 1;
                        textImageButtonFactory.normalBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);
                        textImageButtonFactory.hoverBorderColor  = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);

                        Button setFeedRateButton = textImageButtonFactory.Generate(LocalizedString.Get("Set"));
                        setFeedRateButton.VAnchor = VAnchor.ParentCenter;

                        feedRateLeftToRight.AddChild(setFeedRateButton);
                    }

                    TextWidget extrusionDescription;
                    {
                        extrusionValue       = new NumberEdit(0, allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * TextWidget.GlobalPointSizeScaleRatio);
                        extrusionValue.Value = ((int)(PrinterConnectionAndCommunication.Instance.ExtrusionRatio * 100 + .5)) / 100.0;

                        FlowLayoutWidget leftToRight = new FlowLayoutWidget();
                        leftToRight.HAnchor = HAnchor.ParentLeftRight;
                        leftToRight.Margin  = new BorderDouble(top: 10) * TextWidget.GlobalPointSizeScaleRatio;

                        extrusionDescription             = new TextWidget(LocalizedString.Get("Extrusion Multiplier"));
                        extrusionDescription.MinimumSize = new Vector2(140, 0) * TextWidget.GlobalPointSizeScaleRatio;
                        extrusionDescription.TextColor   = ActiveTheme.Instance.PrimaryTextColor;
                        extrusionDescription.VAnchor     = VAnchor.ParentCenter;
                        leftToRight.AddChild(extrusionDescription);
                        extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal);
                        extrusionRatioSlider.TotalWidthInPixels = sliderWidth;
                        extrusionRatioSlider.Margin             = new BorderDouble(5, 0);
                        extrusionRatioSlider.Value = PrinterConnectionAndCommunication.Instance.ExtrusionRatio;
                        extrusionRatioSlider.View.BackgroundColor = new RGBA_Bytes();
                        extrusionRatioSlider.ValueChanged        += (sender, e) =>
                        {
                            PrinterConnectionAndCommunication.Instance.ExtrusionRatio = extrusionRatioSlider.Value;
                        };
                        PrinterConnectionAndCommunication.Instance.ExtrusionRatioChanged.RegisterEvent(ExtrusionRatioChanged_Event, ref unregisterEvents);
                        extrusionValue.EditComplete += (sender, e) =>
                        {
                            extrusionRatioSlider.Value = extrusionValue.Value;
                        };
                        leftToRight.AddChild(extrusionRatioSlider);
                        tuningRatiosLayout.AddChild(leftToRight);
                        leftToRight.AddChild(extrusionValue);
                        extrusionValue.Margin              = new BorderDouble(0, 0, 5, 0);
                        extrusionValue.VAnchor             = VAnchor.ParentCenter;
                        textImageButtonFactory.FixedHeight = (int)extrusionValue.Height + 1;
                        Button setExtrusionButton = textImageButtonFactory.Generate(LocalizedString.Get("Set"));
                        setExtrusionButton.VAnchor = VAnchor.ParentCenter;
                        leftToRight.AddChild(setExtrusionButton);
                    }
                    feedRateLeftToRight.VAnchor = VAnchor.FitToChildren;
                }

                adjustmentControlsGroupBox.AddChild(tuningRatiosLayout);

                if (false)
                {
                    HorizontalLine line = new HorizontalLine();
                    line.Margin = new BorderDouble(0, 10);
                    tuningRatiosLayout.AddChild(line);
                    TextWidget subheader2 = new TextWidget("Fine-tune z-height, while actively printing", pointSize: 8, textColor: ActiveTheme.Instance.PrimaryTextColor);
                    subheader2.Margin = new BorderDouble(bottom: 6);
                    tuningRatiosLayout.AddChild(subheader2);

                    ImageBuffer togetherBig;
                    ImageBuffer appartBig;

                    CreateButtonImages(out togetherBig, out appartBig);

                    textImageButtonFactory.FixedHeight = 0;
                    Button togetherALot = textImageButtonFactory.GenerateFromImages("", togetherBig);
                    Button appartALot   = textImageButtonFactory.GenerateFromImages("", appartBig);

                    FlowLayoutWidget leftToRigth = new FlowLayoutWidget();
                    leftToRigth.AddChild(togetherALot);
                    leftToRigth.AddChild(appartALot);

                    tuningRatiosLayout.AddChild(leftToRigth);
                }
            }

            this.AddChild(adjustmentControlsGroupBox);
        }
		protected override void AddChildElements()
		{
			AltGroupBox adjustmentControlsGroupBox = new AltGroupBox(new TextWidget("Tuning Adjustment".Localize(), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor));
			adjustmentControlsGroupBox.Margin = new BorderDouble(0);
			adjustmentControlsGroupBox.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
			adjustmentControlsGroupBox.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

			{
				FlowLayoutWidget tuningRatiosLayout = new FlowLayoutWidget(FlowDirection.TopToBottom);
				tuningRatiosLayout.Margin = new BorderDouble(0, 0, 0, 0);
				tuningRatiosLayout.HAnchor = HAnchor.ParentLeftRight;
				tuningRatiosLayout.Padding = new BorderDouble(3, 0, 3, 0);

				double sliderWidth = 300 * GuiWidget.DeviceScale;
				double sliderThumbWidth = 10 * GuiWidget.DeviceScale;
				if (UserSettings.Instance.DisplayMode == ApplicationDisplayType.Touchscreen)
				{
					sliderThumbWidth = 15 * GuiWidget.DeviceScale;
				}

				TextWidget subheader = new TextWidget("", pointSize: 4, textColor: ActiveTheme.Instance.PrimaryTextColor);
				subheader.Margin = new BorderDouble(bottom: 6);
				tuningRatiosLayout.AddChild(subheader);
				TextWidget feedRateDescription;
				{
					FlowLayoutWidget feedRateLeftToRight;
					{
						feedRateValue = new NumberEdit(0, allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale);
						feedRateValue.Value = ((int)(PrinterConnectionAndCommunication.Instance.FeedRateRatio * 100 + .5)) / 100.0;

						feedRateLeftToRight = new FlowLayoutWidget();
						feedRateLeftToRight.HAnchor = HAnchor.ParentLeftRight;

						feedRateDescription = new TextWidget(LocalizedString.Get("Speed Multiplier"));
						feedRateDescription.MinimumSize = new Vector2(140, 0) * GuiWidget.DeviceScale;
						feedRateDescription.TextColor = ActiveTheme.Instance.PrimaryTextColor;
						feedRateDescription.VAnchor = VAnchor.ParentCenter;
						feedRateLeftToRight.AddChild(feedRateDescription);
						feedRateRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minFeedRateRatio, maxFeedRateRatio);
						feedRateRatioSlider.Margin = new BorderDouble(5, 0);
						feedRateRatioSlider.Value = PrinterConnectionAndCommunication.Instance.FeedRateRatio;
						feedRateRatioSlider.TotalWidthInPixels = sliderWidth;
						feedRateRatioSlider.View.BackgroundColor = new RGBA_Bytes();
						feedRateRatioSlider.ValueChanged += (sender, e) =>
						{
							PrinterConnectionAndCommunication.Instance.FeedRateRatio = feedRateRatioSlider.Value;
						};
						PrinterConnectionAndCommunication.Instance.FeedRateRatioChanged.RegisterEvent(FeedRateRatioChanged_Event, ref unregisterEvents);
						feedRateValue.EditComplete += (sender, e) =>
						{
							feedRateRatioSlider.Value = feedRateValue.Value;
						};
						feedRateLeftToRight.AddChild(feedRateRatioSlider);
						tuningRatiosLayout.AddChild(feedRateLeftToRight);

						feedRateLeftToRight.AddChild(feedRateValue);
						feedRateValue.Margin = new BorderDouble(0, 0, 5, 0);
						feedRateValue.VAnchor = VAnchor.ParentCenter;
						textImageButtonFactory.FixedHeight = (int)feedRateValue.Height + 1;
						textImageButtonFactory.borderWidth = 1;
						textImageButtonFactory.normalBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);
						textImageButtonFactory.hoverBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);

						Button setFeedRateButton = textImageButtonFactory.Generate(LocalizedString.Get("Set"));
						setFeedRateButton.VAnchor = VAnchor.ParentCenter;

						feedRateLeftToRight.AddChild(setFeedRateButton);
					}

					TextWidget extrusionDescription;
					{
						extrusionValue = new NumberEdit(0, allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale);
						extrusionValue.Value = ((int)(PrinterConnectionAndCommunication.Instance.ExtrusionRatio * 100 + .5)) / 100.0;

						FlowLayoutWidget leftToRight = new FlowLayoutWidget();
						leftToRight.HAnchor = HAnchor.ParentLeftRight;
						leftToRight.Margin = new BorderDouble(top: 10);

						extrusionDescription = new TextWidget(LocalizedString.Get("Extrusion Multiplier"));
						extrusionDescription.MinimumSize = new Vector2(140, 0) * GuiWidget.DeviceScale;
						extrusionDescription.TextColor = ActiveTheme.Instance.PrimaryTextColor;
						extrusionDescription.VAnchor = VAnchor.ParentCenter;
						leftToRight.AddChild(extrusionDescription);
						extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal);
						extrusionRatioSlider.TotalWidthInPixels = sliderWidth;
						extrusionRatioSlider.Margin = new BorderDouble(5, 0);
						extrusionRatioSlider.Value = PrinterConnectionAndCommunication.Instance.ExtrusionRatio;
						extrusionRatioSlider.View.BackgroundColor = new RGBA_Bytes();
						extrusionRatioSlider.ValueChanged += (sender, e) =>
						{
							PrinterConnectionAndCommunication.Instance.ExtrusionRatio = extrusionRatioSlider.Value;
						};
						PrinterConnectionAndCommunication.Instance.ExtrusionRatioChanged.RegisterEvent(ExtrusionRatioChanged_Event, ref unregisterEvents);
						extrusionValue.EditComplete += (sender, e) =>
						{
							extrusionRatioSlider.Value = extrusionValue.Value;
						};
						leftToRight.AddChild(extrusionRatioSlider);
						tuningRatiosLayout.AddChild(leftToRight);
						leftToRight.AddChild(extrusionValue);
						extrusionValue.Margin = new BorderDouble(0, 0, 5, 0);
						extrusionValue.VAnchor = VAnchor.ParentCenter;
						textImageButtonFactory.FixedHeight = (int)extrusionValue.Height + 1;
						Button setExtrusionButton = textImageButtonFactory.Generate(LocalizedString.Get("Set"));
						setExtrusionButton.VAnchor = VAnchor.ParentCenter;
						leftToRight.AddChild(setExtrusionButton);
					}
					feedRateLeftToRight.VAnchor = VAnchor.FitToChildren;
				}

				adjustmentControlsGroupBox.AddChild(tuningRatiosLayout);
			}

			this.AddChild(adjustmentControlsGroupBox);
		}
        private FlowLayoutWidget CreateRightButtonPanel(double buildHeight)
        {
            FlowLayoutWidget buttonRightPanel = new FlowLayoutWidget(FlowDirection.TopToBottom);

            buttonRightPanel.Width = 200;
            {
                BorderDouble buttonMargin = new BorderDouble(top: 3);

                // put in the word editing menu
                {
                    CheckBox expandWordOptions = expandMenuOptionFactory.GenerateCheckBoxButton("Word Edit".Localize(), "icon_arrow_right_no_border_32x32.png", "icon_arrow_down_no_border_32x32.png");
                    expandWordOptions.Margin = new BorderDouble(bottom: 2);
                    buttonRightPanel.AddChild(expandWordOptions);

                    FlowLayoutWidget wordOptionContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
                    wordOptionContainer.HAnchor = HAnchor.ParentLeftRight;
                    wordOptionContainer.Visible = false;
                    buttonRightPanel.AddChild(wordOptionContainer);

                    sizeScrollBar = InsertUiForSlider(wordOptionContainer, "Size:".Localize(), .3, 2);
                    {
                        sizeScrollBar.ValueChanged += (sender, e) =>
                        {
                            SetWordSize(MeshGroups, MeshGroupTransforms);

                            //SetWordSpacing(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
                            RebuildBase();
                        };
                    }

                    heightScrollBar = InsertUiForSlider(wordOptionContainer, "Height:".Localize(), .05, 1);
                    {
                        heightScrollBar.ValueChanged += (sender, e) =>
                        {
                            SetWordHeight(MeshGroups, MeshGroupTransforms);
                            RebuildBase();
                        };
                    }

                    // put in the user alpha checkbox
                    {
                        includeText             = new CheckBox(new CheckBoxViewText("Include Text".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor));
                        includeText.ToolTipText = "Show normal text under the braille".Localize();
                        includeText.Checked     = false;
                        includeText.Margin      = new BorderDouble(10, 5);
                        includeText.HAnchor     = HAnchor.ParentLeft;
                        wordOptionContainer.AddChild(includeText);
                        includeText.CheckedStateChanged += (sender, e) =>
                        {
                            InsertTextNow(this.word);
                        };
                    }

                    // put in the user alpha checkbox
                    {
                        useGrade2             = new CheckBox(new CheckBoxViewText("Use Grade 2".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor));
                        useGrade2.ToolTipText = "Experimental support for Braille grade 2 (contractions)".Localize();
                        useGrade2.Checked     = false;
                        useGrade2.Margin      = new BorderDouble(10, 5);
                        useGrade2.HAnchor     = HAnchor.ParentLeft;
                        wordOptionContainer.AddChild(useGrade2);
                        useGrade2.CheckedStateChanged += (sender, e) =>
                        {
                            InsertTextNow(this.word);
                        };
                    }

                    // put in a link to the wikipedia article
                    {
                        LinkButtonFactory linkButtonFactory = new LinkButtonFactory();
                        linkButtonFactory.fontSize  = 10;
                        linkButtonFactory.textColor = ActiveTheme.Instance.PrimaryTextColor;

                        Button moreAboutBrailleLink = linkButtonFactory.Generate("About Braille".Localize());
                        moreAboutBrailleLink.Margin  = new BorderDouble(10, 5);
                        moreAboutBrailleLink.HAnchor = HAnchor.ParentLeft;
                        moreAboutBrailleLink.Click  += (sender, e) =>
                        {
                            UiThread.RunOnIdle(() =>
                            {
                                MatterControlApplication.Instance.LaunchBrowser("https://en.wikipedia.org/wiki/Braille");
                            });
                        };

                        wordOptionContainer.AddChild(moreAboutBrailleLink);
                    }

                    expandWordOptions.CheckedStateChanged += (sender, e) =>
                    {
                        wordOptionContainer.Visible = expandWordOptions.Checked;
                    };

                    expandWordOptions.Checked = true;
                }

                GuiWidget verticalSpacer = new GuiWidget();
                verticalSpacer.VAnchor = VAnchor.ParentBottomTop;
                buttonRightPanel.AddChild(verticalSpacer);

                saveButton         = whiteButtonFactory.Generate("Save".Localize(), centerText: true);
                saveButton.Visible = false;
                saveButton.Cursor  = Cursors.Hand;

                saveAndExitButton         = whiteButtonFactory.Generate("Save & Exit".Localize(), centerText: true);
                saveAndExitButton.Visible = false;
                saveAndExitButton.Cursor  = Cursors.Hand;

                //buttonRightPanel.AddChild(saveButton);
                buttonRightPanel.AddChild(saveAndExitButton);
            }

            buttonRightPanel.Padding         = new BorderDouble(6, 6);
            buttonRightPanel.Margin          = new BorderDouble(0, 1);
            buttonRightPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
            buttonRightPanel.VAnchor         = VAnchor.ParentBottomTop;

            return(buttonRightPanel);
        }
		protected static SolidSlider InsertUiForSlider(FlowLayoutWidget wordOptionContainer, string header, double min = 0, double max = .5)
		{
			double scrollBarWidth = 10;
			if (UserSettings.Instance.DisplayMode == ApplicationDisplayType.Touchscreen)
			{
				scrollBarWidth = 20;
			}

			TextWidget spacingText = new TextWidget(header, textColor: ActiveTheme.Instance.PrimaryTextColor);
			spacingText.Margin = new BorderDouble(10, 3, 3, 5);
			spacingText.HAnchor = HAnchor.ParentLeft;
			wordOptionContainer.AddChild(spacingText);
			SolidSlider namedSlider = new SolidSlider(new Vector2(), scrollBarWidth, 0, 1);
			namedSlider.TotalWidthInPixels = DefaultScrollBarWidth;
			namedSlider.Minimum = min;
			namedSlider.Maximum = max;
			namedSlider.Margin = new BorderDouble(3, 5, 3, 3);
			namedSlider.HAnchor = HAnchor.ParentCenter;
			namedSlider.View.BackgroundColor = new RGBA_Bytes();
			wordOptionContainer.AddChild(namedSlider);

			return namedSlider;
		}
		private FlowLayoutWidget CreateRightButtonPanel(double buildHeight)
		{
			FlowLayoutWidget buttonRightPanel = new FlowLayoutWidget(FlowDirection.TopToBottom);
			buttonRightPanel.Width = 200;
			{
				BorderDouble buttonMargin = new BorderDouble(top: 3);

				// put in the word editing menu
				{
					CheckBox expandWordOptions = expandMenuOptionFactory.GenerateCheckBoxButton("Word Edit".Localize(), "icon_arrow_right_no_border_32x32.png", "icon_arrow_down_no_border_32x32.png");
					expandWordOptions.Margin = new BorderDouble(bottom: 2);
					buttonRightPanel.AddChild(expandWordOptions);

					FlowLayoutWidget wordOptionContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
					wordOptionContainer.HAnchor = HAnchor.ParentLeftRight;
					wordOptionContainer.Visible = false;
					buttonRightPanel.AddChild(wordOptionContainer);

					spacingScrollBar = InsertUiForSlider(wordOptionContainer, "Spacing:".Localize(), .5, 1);
					{
						spacingScrollBar.ValueChanged += (sender, e) =>
						{
							SetWordSpacing(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
							RebuildUnderlineIfRequired();
						};
					}

					sizeScrollBar = InsertUiForSlider(wordOptionContainer, "Size:".Localize(), .3, 2);
					{
						sizeScrollBar.ValueChanged += (sender, e) =>
						{
							SetWordSize(MeshGroups, MeshGroupTransforms);

							SetWordSpacing(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
							RebuildUnderlineIfRequired();
						};
					}

					heightScrollBar = InsertUiForSlider(wordOptionContainer, "Height:".Localize(), .05, 1);
					{
						heightScrollBar.ValueChanged += (sender, e) =>
						{
							SetWordHeight(MeshGroups, MeshGroupTransforms);
							RebuildUnderlineIfRequired();
						};
					}

					createUnderline = new CheckBox(new CheckBoxViewText("Underline".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor));
					createUnderline.Checked = true;
					createUnderline.Margin = new BorderDouble(10, 5);
					createUnderline.HAnchor = HAnchor.ParentLeft;
					wordOptionContainer.AddChild(createUnderline);
					createUnderline.CheckedStateChanged += (sender, e) =>
					{
						int oldIndex = SelectedMeshGroupIndex;
						if (!createUnderline.Checked)
						{
							// we need to remove the underline
							if (MeshGroups.Count > 1)
							{
								SelectedMeshGroupIndex = MeshGroups.Count - 1;
								DeleteSelectedMesh();
							}
						}
						else if (MeshGroups.Count > 0)
						{
							// we need to add the underline
							CreateUnderline(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
						}
						SelectedMeshGroupIndex = Math.Min(oldIndex, MeshGroups.Count - 1);
					};

					expandWordOptions.CheckedStateChanged += (sender, e) =>
					{
						wordOptionContainer.Visible = expandWordOptions.Checked;
					};

					expandWordOptions.Checked = true;
				}

				// put in the letter editing menu
				{
					CheckBox expandLetterOptions = expandMenuOptionFactory.GenerateCheckBoxButton("Letter", "icon_arrow_right_no_border_32x32.png", "icon_arrow_down_no_border_32x32.png");
					expandLetterOptions.Margin = new BorderDouble(bottom: 2);
					//buttonRightPanel.AddChild(expandLetterOptions);

					FlowLayoutWidget letterOptionContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
					letterOptionContainer.HAnchor = HAnchor.ParentLeftRight;
					letterOptionContainer.Visible = false;
					buttonRightPanel.AddChild(letterOptionContainer);

					SolidSlider sizeScrollBar = InsertUiForSlider(letterOptionContainer, "Size:".Localize());
					SolidSlider heightScrollBar = InsertUiForSlider(letterOptionContainer, "Height:".Localize());
					SolidSlider rotationScrollBar = InsertUiForSlider(letterOptionContainer, "Rotation:".Localize());

					expandLetterOptions.CheckedStateChanged += (sender, e) =>
					{
						letterOptionContainer.Visible = expandLetterOptions.Checked;
					};
				}

				GuiWidget verticalSpacer = new GuiWidget();
				verticalSpacer.VAnchor = VAnchor.ParentBottomTop;
				buttonRightPanel.AddChild(verticalSpacer);

				saveButton = whiteButtonFactory.Generate("Save".Localize(), centerText: true);
				saveButton.Visible = false;
				saveButton.Cursor = Cursors.Hand;

				saveAndExitButton = whiteButtonFactory.Generate("Save & Exit".Localize(), centerText: true);
				saveAndExitButton.Visible = false;
				saveAndExitButton.Cursor = Cursors.Hand;

				//buttonRightPanel.AddChild(saveButton);
				buttonRightPanel.AddChild(saveAndExitButton);
			}

			buttonRightPanel.Padding = new BorderDouble(6, 6);
			buttonRightPanel.Margin = new BorderDouble(0, 1);
			buttonRightPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
			buttonRightPanel.VAnchor = VAnchor.ParentBottomTop;

			return buttonRightPanel;
		}
        public AdjustmentControls()
        {
            var adjustmentControlsGroupBox = new AltGroupBox(new TextWidget("Tuning Adjustment".Localize(), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor))
            {
                Margin      = 0,
                BorderColor = ActiveTheme.Instance.PrimaryTextColor,
                HAnchor     = HAnchor.ParentLeftRight
            };

            var topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                Margin  = new BorderDouble(0, 0, 0, 0),
                HAnchor = HAnchor.ParentLeftRight,
                Padding = new BorderDouble(3, 0, 3, 0)
            };

            double sliderWidth      = 300 * GuiWidget.DeviceScale;
            double sliderThumbWidth = 10 * GuiWidget.DeviceScale;

            if (UserSettings.Instance.IsTouchScreen)
            {
                sliderThumbWidth = 15 * GuiWidget.DeviceScale;
            }

            var subheader = new TextWidget("", pointSize: 4, textColor: ActiveTheme.Instance.PrimaryTextColor);

            subheader.Margin = new BorderDouble(bottom: 6);
            topToBottom.AddChild(subheader);

            {
                var row = new FlowLayoutWidget()
                {
                    HAnchor = HAnchor.ParentLeftRight,
                    Margin  = 0,
                    VAnchor = VAnchor.FitToChildren
                };

                var feedRateDescription = new TextWidget("Speed Multiplier".Localize())
                {
                    MinimumSize = new Vector2(140, 0) * GuiWidget.DeviceScale,
                    TextColor   = ActiveTheme.Instance.PrimaryTextColor,
                    VAnchor     = VAnchor.ParentCenter,
                };
                row.AddChild(feedRateDescription);

                feedRateRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minFeedRateRatio, maxFeedRateRatio)
                {
                    Name               = "Feed Rate Slider",
                    Margin             = new BorderDouble(5, 0),
                    Value              = FeedRateMultiplyerStream.FeedRateRatio,
                    HAnchor            = HAnchor.ParentLeftRight,
                    TotalWidthInPixels = sliderWidth,
                };
                feedRateRatioSlider.View.BackgroundColor = new RGBA_Bytes();
                feedRateRatioSlider.ValueChanged        += (sender, e) =>
                {
                    feedRateValue.ActuallNumberEdit.Value = Math.Round(feedRateRatioSlider.Value, 2);
                };
                feedRateRatioSlider.SliderReleased += (s, e) =>
                {
                    // Update state for runtime use
                    FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2);

                    // Persist data for future use
                    ActiveSliceSettings.Instance.SetValue(
                        SettingsKey.feedrate_ratio,
                        FeedRateMultiplyerStream.FeedRateRatio.ToString());
                };
                row.AddChild(feedRateRatioSlider);

                feedRateValue = new MHNumberEdit(Math.Round(FeedRateMultiplyerStream.FeedRateRatio, 2), allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale)
                {
                    Name             = "Feed Rate NumberEdit",
                    SelectAllOnFocus = true,
                    Margin           = new BorderDouble(0, 0, 5, 0),
                    VAnchor          = VAnchor.ParentCenter | VAnchor.FitToChildren,
                    Padding          = 0
                };
                feedRateValue.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    feedRateRatioSlider.Value = feedRateValue.ActuallNumberEdit.Value;

                    // Update state for runtime use
                    FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2);

                    // Persist data for future use
                    ActiveSliceSettings.Instance.SetValue(
                        SettingsKey.feedrate_ratio,
                        FeedRateMultiplyerStream.FeedRateRatio.ToString());
                };
                row.AddChild(feedRateValue);

                topToBottom.AddChild(row);

                textImageButtonFactory.FixedHeight       = (int)feedRateValue.Height + 1;
                textImageButtonFactory.borderWidth       = 1;
                textImageButtonFactory.normalBorderColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);
                textImageButtonFactory.hoverBorderColor  = new RGBA_Bytes(ActiveTheme.Instance.PrimaryTextColor, 200);

                Button setButton = textImageButtonFactory.Generate("Set".Localize());
                setButton.VAnchor = VAnchor.ParentCenter;
                row.AddChild(setButton);
            }

            {
                var row = new FlowLayoutWidget()
                {
                    HAnchor = HAnchor.ParentLeftRight,
                    Margin  = new BorderDouble(top: 10),
                    VAnchor = VAnchor.FitToChildren
                };

                var extrusionDescription = new TextWidget("Extrusion Multiplier".Localize())
                {
                    MinimumSize = new Vector2(140, 0) * GuiWidget.DeviceScale,
                    TextColor   = ActiveTheme.Instance.PrimaryTextColor,
                    VAnchor     = VAnchor.ParentCenter
                };
                row.AddChild(extrusionDescription);

                extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal)
                {
                    Name = "Extrusion Multiplier Slider",
                    TotalWidthInPixels = sliderWidth,
                    HAnchor            = HAnchor.ParentLeftRight,
                    Margin             = new BorderDouble(5, 0),
                    Value = ExtrusionMultiplyerStream.ExtrusionRatio
                };
                extrusionRatioSlider.View.BackgroundColor = new RGBA_Bytes();
                extrusionRatioSlider.ValueChanged        += (sender, e) =>
                {
                    extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatioSlider.Value, 2);
                };
                extrusionRatioSlider.SliderReleased += (s, e) =>
                {
                    // Update state for runtime use
                    ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2);

                    // Persist data for future use
                    ActiveSliceSettings.Instance.SetValue(
                        SettingsKey.extrusion_ratio,
                        ExtrusionMultiplyerStream.ExtrusionRatio.ToString());
                };

                extrusionValue = new MHNumberEdit(Math.Round(ExtrusionMultiplyerStream.ExtrusionRatio, 2), allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale)
                {
                    Name             = "Extrusion Multiplier NumberEdit",
                    SelectAllOnFocus = true,
                    Margin           = new BorderDouble(0, 0, 5, 0),
                    VAnchor          = VAnchor.ParentCenter | VAnchor.FitToChildren,
                    Padding          = 0
                };
                extrusionValue.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    extrusionRatioSlider.Value = extrusionValue.ActuallNumberEdit.Value;

                    // Update state for runtime use
                    ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2);

                    // Persist data for future use
                    ActiveSliceSettings.Instance.SetValue(
                        SettingsKey.extrusion_ratio,
                        ExtrusionMultiplyerStream.ExtrusionRatio.ToString());
                };
                row.AddChild(extrusionRatioSlider);
                row.AddChild(extrusionValue);

                topToBottom.AddChild(row);

                textImageButtonFactory.FixedHeight = (int)extrusionValue.Height + 1;

                Button setButton = textImageButtonFactory.Generate("Set".Localize());
                setButton.VAnchor = VAnchor.ParentCenter;
                row.AddChild(setButton);
            }

            adjustmentControlsGroupBox.AddChild(topToBottom);

            this.AddChild(adjustmentControlsGroupBox);

            ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
            {
                var eventArgs = e as StringEventArgs;
                if (eventArgs?.Data == SettingsKey.extrusion_ratio)
                {
                    double extrusionRatio                  = ActiveSliceSettings.Instance.GetValue <double>(SettingsKey.extrusion_ratio);
                    extrusionRatioSlider.Value             = extrusionRatio;
                    extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatio, 2);
                }
                else if (eventArgs?.Data == SettingsKey.feedrate_ratio)
                {
                    double feedrateRatio                  = ActiveSliceSettings.Instance.GetValue <double>(SettingsKey.feedrate_ratio);
                    feedRateRatioSlider.Value             = feedrateRatio;
                    feedRateValue.ActuallNumberEdit.Value = Math.Round(feedrateRatio, 2);
                }
            }, ref unregisterEvents);
        }
		private FlowLayoutWidget CreateRightButtonPanel(double buildHeight)
		{
			FlowLayoutWidget buttonRightPanel = new FlowLayoutWidget(FlowDirection.TopToBottom);
			buttonRightPanel.Width = 200;
			{
				BorderDouble buttonMargin = new BorderDouble(top: 3);

				// put in the word editing menu
				{
					CheckBox expandWordOptions = ExpandMenuOptionFactory.GenerateCheckBoxButton("Word Edit".Localize(),
					View3DWidget.ArrowRight,
					View3DWidget.ArrowDown);
					expandWordOptions.Margin = new BorderDouble(bottom: 2);
					buttonRightPanel.AddChild(expandWordOptions);

					FlowLayoutWidget wordOptionContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
					wordOptionContainer.HAnchor = HAnchor.ParentLeftRight;
					wordOptionContainer.Visible = false;
					buttonRightPanel.AddChild(wordOptionContainer);

					sizeScrollBar = InsertUiForSlider(wordOptionContainer, "Size:".Localize(), .3, 2);
					{
						sizeScrollBar.ValueChanged += (sender, e) =>
						{
							SetWordSize(MeshGroups, MeshGroupTransforms);

							//SetWordSpacing(MeshGroups, MeshGroupTransforms, MeshGroupExtraData);
							RebuildBase();
						};
					}

					heightScrollBar = InsertUiForSlider(wordOptionContainer, "Height:".Localize(), .05, 1);
					{
						heightScrollBar.ValueChanged += (sender, e) =>
						{
							SetWordHeight(MeshGroups, MeshGroupTransforms);
							RebuildBase();
						};
					}

					// put in the user alpha check box
					{
						includeText = new CheckBox(new CheckBoxViewText("Include Text".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor));
						includeText.ToolTipText = "Show normal text above the braille".Localize();
						includeText.Checked = false;
						includeText.Margin = new BorderDouble(10, 5);
						includeText.HAnchor = HAnchor.ParentLeft;
						wordOptionContainer.AddChild(includeText);
						includeText.CheckedStateChanged += (sender, e) =>
						{
							InsertTextNow(this.word);
						};
					}

					// put in the user alpha check box
					{
						useGrade2 = new CheckBox(new CheckBoxViewText("Use Grade 2".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor));
						useGrade2.ToolTipText = "Experimental support for Braille grade 2 (contractions)".Localize();
						useGrade2.Checked = false;
						useGrade2.Margin = new BorderDouble(10, 5);
						useGrade2.HAnchor = HAnchor.ParentLeft;
						wordOptionContainer.AddChild(useGrade2);
						useGrade2.CheckedStateChanged += (sender, e) =>
						{
							InsertTextNow(this.word);
						};
					}

					// put in a link to the wikipedia article
					{
						LinkButtonFactory linkButtonFactory = new LinkButtonFactory();
						linkButtonFactory.fontSize = 10;
						linkButtonFactory.textColor = ActiveTheme.Instance.PrimaryTextColor;

						Button moreAboutBrailleLink = linkButtonFactory.Generate("About Braille".Localize());
						moreAboutBrailleLink.Margin = new BorderDouble(10, 5);
						moreAboutBrailleLink.HAnchor = HAnchor.ParentLeft;
						moreAboutBrailleLink.Click += (sender, e) =>
						{
							UiThread.RunOnIdle(() =>
							{
								MatterControlApplication.Instance.LaunchBrowser("https://en.wikipedia.org/wiki/Braille");
							});
						};

						wordOptionContainer.AddChild(moreAboutBrailleLink);
					}

					expandWordOptions.CheckedStateChanged += (sender, e) =>
					{
						wordOptionContainer.Visible = expandWordOptions.Checked;
					};

					expandWordOptions.Checked = true;
				}

				GuiWidget verticalSpacer = new GuiWidget();
				verticalSpacer.VAnchor = VAnchor.ParentBottomTop;
				buttonRightPanel.AddChild(verticalSpacer);

				saveButton = WhiteButtonFactory.Generate("Save".Localize(), centerText: true);
				saveButton.Visible = false;
				saveButton.Cursor = Cursors.Hand;

				saveAndExitButton = WhiteButtonFactory.Generate("Save & Exit".Localize(), centerText: true);
				saveAndExitButton.Visible = false;
				saveAndExitButton.Cursor = Cursors.Hand;

				//buttonRightPanel.AddChild(saveButton);
				buttonRightPanel.AddChild(saveAndExitButton);
			}

			buttonRightPanel.Padding = new BorderDouble(6, 6);
			buttonRightPanel.Margin = new BorderDouble(0, 1);
			buttonRightPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
			buttonRightPanel.VAnchor = VAnchor.ParentBottomTop;

			return buttonRightPanel;
		}
        private AdjustmentControls(PrinterConfig printer, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            double sliderWidth      = 300 * GuiWidget.DeviceScale;
            double sliderThumbWidth = 10 * GuiWidget.DeviceScale;

            Color sliderTrackColor = theme.Colors.IsDarkTheme ? new Color(theme.Shade, 65) : theme.SlightShade;

            SettingsRow settingsRow;

            {
                this.AddChild(settingsRow = new SettingsRow(
                                  "Speed Multiplier".Localize(),
                                  null,
                                  theme));

                // Remove the HorizontalSpacer
                settingsRow.Children.Last().Close();

                feedRateRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minFeedRateRatio, maxFeedRateRatio)
                {
                    Name               = "Feed Rate Slider",
                    Margin             = new BorderDouble(5, 0),
                    Value              = FeedRateMultiplyerStream.FeedRateRatio,
                    HAnchor            = HAnchor.Stretch,
                    VAnchor            = VAnchor.Center,
                    TotalWidthInPixels = sliderWidth,
                };
                feedRateRatioSlider.View.TrackColor  = sliderTrackColor;
                feedRateRatioSlider.View.TrackRadius = 4;
                feedRateRatioSlider.ValueChanged    += (sender, e) =>
                {
                    feedRateValue.ActuallNumberEdit.Value = Math.Round(feedRateRatioSlider.Value, 2);
                };
                feedRateRatioSlider.SliderReleased += (s, e) =>
                {
                    // Update state for runtime use
                    FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.feedrate_ratio,
                        FeedRateMultiplyerStream.FeedRateRatio.ToString());
                };
                settingsRow.AddChild(feedRateRatioSlider);

                feedRateValue = new MHNumberEdit(Math.Round(FeedRateMultiplyerStream.FeedRateRatio, 2), allowDecimals: true, minValue: minFeedRateRatio, maxValue: maxFeedRateRatio, pixelWidth: 40 * GuiWidget.DeviceScale)
                {
                    Name             = "Feed Rate NumberEdit",
                    SelectAllOnFocus = true,
                    Margin           = new BorderDouble(0, 0, 5, 0),
                    VAnchor          = VAnchor.Center | VAnchor.Fit,
                    Padding          = 0
                };
                feedRateValue.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    feedRateRatioSlider.Value = feedRateValue.ActuallNumberEdit.Value;

                    // Update state for runtime use
                    FeedRateMultiplyerStream.FeedRateRatio = Math.Round(feedRateRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.feedrate_ratio,
                        FeedRateMultiplyerStream.FeedRateRatio.ToString());
                };
                settingsRow.AddChild(feedRateValue);
            }

            {
                this.AddChild(settingsRow = new SettingsRow(
                                  "Extrusion Multiplier".Localize(),
                                  null,
                                  theme));

                // Remove the HorizontalSpacer
                settingsRow.Children.Last().Close();

                extrusionRatioSlider = new SolidSlider(new Vector2(), sliderThumbWidth, minExtrutionRatio, maxExtrusionRatio, Orientation.Horizontal)
                {
                    Name = "Extrusion Multiplier Slider",
                    TotalWidthInPixels = sliderWidth,
                    HAnchor            = HAnchor.Stretch,
                    VAnchor            = VAnchor.Center,
                    Margin             = new BorderDouble(5, 0),
                    Value = ExtrusionMultiplyerStream.ExtrusionRatio
                };
                extrusionRatioSlider.View.TrackColor  = sliderTrackColor;
                extrusionRatioSlider.View.TrackRadius = 4;
                extrusionRatioSlider.ValueChanged    += (sender, e) =>
                {
                    extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatioSlider.Value, 2);
                };
                extrusionRatioSlider.SliderReleased += (s, e) =>
                {
                    // Update state for runtime use
                    ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.extrusion_ratio,
                        ExtrusionMultiplyerStream.ExtrusionRatio.ToString());
                };
                settingsRow.AddChild(extrusionRatioSlider);

                extrusionValue = new MHNumberEdit(Math.Round(ExtrusionMultiplyerStream.ExtrusionRatio, 2), allowDecimals: true, minValue: minExtrutionRatio, maxValue: maxExtrusionRatio, pixelWidth: 40 * GuiWidget.DeviceScale)
                {
                    Name             = "Extrusion Multiplier NumberEdit",
                    SelectAllOnFocus = true,
                    Margin           = new BorderDouble(0, 0, 5, 0),
                    VAnchor          = VAnchor.Center | VAnchor.Fit,
                    Padding          = 0
                };
                extrusionValue.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    extrusionRatioSlider.Value = extrusionValue.ActuallNumberEdit.Value;

                    // Update state for runtime use
                    ExtrusionMultiplyerStream.ExtrusionRatio = Math.Round(extrusionRatioSlider.Value, 2);

                    // Persist data for future use
                    printer.Settings.SetValue(
                        SettingsKey.extrusion_ratio,
                        ExtrusionMultiplyerStream.ExtrusionRatio.ToString());
                };
                settingsRow.AddChild(extrusionValue);
            }

            ActiveSliceSettings.SettingChanged.RegisterEvent((s, e) =>
            {
                var eventArgs = e as StringEventArgs;
                if (eventArgs?.Data == SettingsKey.extrusion_ratio)
                {
                    double extrusionRatio                  = printer.Settings.GetValue <double>(SettingsKey.extrusion_ratio);
                    extrusionRatioSlider.Value             = extrusionRatio;
                    extrusionValue.ActuallNumberEdit.Value = Math.Round(extrusionRatio, 2);
                }
                else if (eventArgs?.Data == SettingsKey.feedrate_ratio)
                {
                    double feedrateRatio                  = printer.Settings.GetValue <double>(SettingsKey.feedrate_ratio);
                    feedRateRatioSlider.Value             = feedrateRatio;
                    feedRateValue.ActuallNumberEdit.Value = Math.Round(feedrateRatio, 2);
                }
            }, ref unregisterEvents);
        }
        public ApplicationSettingsWidget(ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.HAnchor         = HAnchor.Stretch;
            this.VAnchor         = VAnchor.Fit;
            this.BackgroundColor = theme.Colors.PrimaryBackgroundColor;
            this.theme           = theme;

            var configureIcon = AggContext.StaticData.LoadIcon("fa-cog_16.png", 16, 16, theme.InvertIcons);

#if __ANDROID__
            // Camera Monitoring
            bool hasCamera = true || ApplicationSettings.Instance.get(ApplicationSettingsKey.HardwareHasCamera) == "true";

            var previewButton = new IconButton(configureIcon, theme)
            {
                ToolTipText = "Configure Camera View".Localize()
            };
            previewButton.Click += (s, e) =>
            {
                AppContext.Platform.OpenCameraPreview();
            };

            this.AddSettingsRow(
                new SettingsItem(
                    "Camera Monitoring".Localize(),
                    theme,
                    new SettingsItem.ToggleSwitchConfig()
            {
                Checked      = ActiveSliceSettings.Instance.GetValue <bool>(SettingsKey.publish_bed_image),
                ToggleAction = (itemChecked) =>
                {
                    ActiveSliceSettings.Instance.SetValue(SettingsKey.publish_bed_image, itemChecked ? "1" : "0");
                }
            },
                    previewButton,
                    AggContext.StaticData.LoadIcon("camera-24x24.png", 24, 24))
                );
#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 (OpenPrintNotification != null)
                {
                    UiThread.RunOnIdle(OpenPrintNotification);
                }
            };

            AddMenuItem("Help".Localize(), () =>
            {
                UiThread.RunOnIdle(() =>
                {
                    DialogWindow.Show(new HelpPage("AllGuides"));
                });
            });

            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")));

            // 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);
                        ApplicationController.Instance.ReloadAll();
                    }
                }
            }));

            // 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")
                        {
                            GenerateLocalizationValidationFile();
                        }

                        ApplicationController.Instance.ResetTranslationMap();
                        ApplicationController.Instance.ReloadAll();
                    }
                });
            };

            this.AddSettingsRow(new SettingsItem("Language".Localize(), languageSelector, theme));

#if !__ANDROID__
            {
                // ThumbnailRendering
                var thumbnailsModeDropList = new DropDownList("", theme.Colors.PrimaryTextColor, maxHeight: 200, pointSize: theme.DefaultFontSize)
                {
                    BorderColor = theme.GetBorderColor(75)
                };
                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 directoryToRemove = ApplicationController.CacheablePath("ItemThumbnails", "");
                                    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));

                // TextSize
                if (!double.TryParse(UserSettings.Instance.get(UserSettingsKey.ApplicationTextSize), out double currentTexSize))
                {
                    currentTexSize = 1.0;
                }

                double sliderThumbWidth = 10 * GuiWidget.DeviceScale;
                double sliderWidth      = 100 * GuiWidget.DeviceScale;
                var    textSizeSlider   = new SolidSlider(new Vector2(), sliderThumbWidth, .7, 1.4)
                {
                    Name               = "Text Size Slider",
                    Margin             = new BorderDouble(5, 0),
                    Value              = currentTexSize,
                    HAnchor            = HAnchor.Stretch,
                    VAnchor            = VAnchor.Center,
                    TotalWidthInPixels = sliderWidth,
                };

                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) =>
                {
                    GuiWidget.DeviceScale = textSizeSlider.Value;
                    ApplicationController.Instance.ReloadAll();
                };
                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 != currentTexSize;
                };

                var section = new SettingsItem(
                    "Text Size".Localize() + $" : {currentTexSize:0.0}",
                    textSizeSlider,
                    theme,
                    optionalContainer);

                sectionLabel = section.Children <TextWidget>().FirstOrDefault();

                this.AddSettingsRow(section);
            }
#endif

            AddMenuItem("Forums".Localize(), () => ApplicationController.Instance.LaunchBrowser("https://forums.matterhackers.com/category/20/mattercontrol"));
            AddMenuItem("Wiki".Localize(), () => ApplicationController.Instance.LaunchBrowser("http://wiki.mattercontrol.com"));
            AddMenuItem("Guides and Articles".Localize(), () => ApplicationController.Instance.LaunchBrowser("http://www.matterhackers.com/topic/mattercontrol"));
            AddMenuItem("Release Notes".Localize(), () => ApplicationController.Instance.LaunchBrowser("http://wiki.mattercontrol.com/Release_Notes"));
            AddMenuItem("Report a Bug".Localize(), () => ApplicationController.Instance.LaunchBrowser("https://github.com/MatterHackers/MatterControl/issues"));

            var updateMatterControl = new SettingsItem("Check For Update".Localize(), theme);
            updateMatterControl.Click += (s, e) =>
            {
                UiThread.RunOnIdle(() =>
                {
                    UpdateControlData.Instance.CheckForUpdate();
                    DialogWindow.Show <CheckForUpdatesPage>();
                });
            };
            this.AddSettingsRow(updateMatterControl);

            this.AddChild(new SettingsItem("Theme".Localize(), new GuiWidget(), theme));
            this.AddChild(this.GetThemeControl(theme));

            var aboutMatterControl = new SettingsItem("About".Localize() + " " + ApplicationController.Instance.ProductName, theme);
            if (IntPtr.Size == 8)
            {
                // Push right
                aboutMatterControl.AddChild(new HorizontalSpacer());

                // Add x64 adornment
                var blueBox = new FlowLayoutWidget()
                {
                    Margin      = new BorderDouble(10, 0),
                    Padding     = new BorderDouble(2),
                    Border      = new BorderDouble(1),
                    BorderColor = theme.Colors.PrimaryAccentColor,
                    VAnchor     = VAnchor.Center | VAnchor.Fit,
                };
                blueBox.AddChild(new TextWidget("64", pointSize: 8, textColor: theme.Colors.PrimaryAccentColor));

                aboutMatterControl.AddChild(blueBox);
            }
            aboutMatterControl.Click += (s, e) =>
            {
                UiThread.RunOnIdle(() => DialogWindow.Show <AboutPage>());
            };
            this.AddSettingsRow(aboutMatterControl);
        }