private void AddLetterControls(FlowLayoutWidget buttonPanel)
        {
            textImageButtonFactory.FixedWidth = 44 * TextWidget.GlobalPointSizeScaleRatio;

            FlowLayoutWidget degreesContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);

            degreesContainer.HAnchor = HAnchor.ParentLeftRight;
            degreesContainer.Padding = new BorderDouble(5);

            GuiWidget horizontalSpacer = new GuiWidget();

            horizontalSpacer.HAnchor = HAnchor.ParentLeftRight;

            TextWidget degreesLabel = new TextWidget("Degrees:".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor);

            degreesContainer.AddChild(degreesLabel);
            degreesContainer.AddChild(horizontalSpacer);

            MHNumberEdit degreesControl = new MHNumberEdit(45, pixelWidth: 40, allowNegatives: true, increment: 5, minValue: -360, maxValue: 360);

            degreesControl.VAnchor = Agg.UI.VAnchor.ParentTop;
            degreesContainer.AddChild(degreesControl);

            buttonPanel.AddChild(degreesContainer);

            FlowLayoutWidget rotateButtonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);

            rotateButtonContainer.HAnchor = HAnchor.ParentLeftRight;

            buttonPanel.AddChild(rotateButtonContainer);

            buttonPanel.AddChild(generateHorizontalRule());
            textImageButtonFactory.FixedWidth = 0;
        }
 private GuiWidget CreateMHNumEdit(ref MHNumberEdit numberEditToCreate)
 {
     numberEditToCreate         = new MHNumberEdit(0, pixelWidth: 80, allowNegatives: true, allowDecimals: true);
     numberEditToCreate.VAnchor = Agg.UI.VAnchor.ParentCenter;
     numberEditToCreate.Margin  = new BorderDouble(3, 0);
     return(numberEditToCreate);
 }
Example #3
0
        public override void Initialize(int tabIndex)
        {
            var container = new FlowLayoutWidget();

            string[] xyValueStrings = this.Value?.Split(',');
            if (xyValueStrings == null ||
                xyValueStrings.Length != 2)
            {
                xyValueStrings = new string[] { "0", "0" };
            }

            double.TryParse(xyValueStrings[0], out double currentXValue);

            xEditWidget = new MHNumberEdit(currentXValue, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex)
            {
                ToolTipText      = this.HelpText,
                TabIndex         = tabIndex,
                SelectAllOnFocus = true
            };
            xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
            {
                this.SetValue(
                    string.Format("{0},{1}", xEditWidget.ActuallNumberEdit.Value.ToString(), yEditWidget.ActuallNumberEdit.Value.ToString()),
                    userInitiated: true);
            };

            container.AddChild(new TextWidget("X:", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
            {
                VAnchor = VAnchor.Center,
                Margin  = new BorderDouble(5, 0),
            });
            container.AddChild(xEditWidget);

            double.TryParse(xyValueStrings[1], out double currentYValue);

            yEditWidget = new MHNumberEdit(currentYValue, allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex)
            {
                ToolTipText      = this.HelpText,
                TabIndex         = tabIndex + 1,
                SelectAllOnFocus = true,
            };
            yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
            {
                this.SetValue(
                    string.Format("{0},{1}", xEditWidget.ActuallNumberEdit.Value.ToString(), yEditWidget.ActuallNumberEdit.Value.ToString()),
                    userInitiated: true);
            };

            container.AddChild(new TextWidget("Y:", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
            {
                VAnchor = VAnchor.Center,
                Margin  = new BorderDouble(15, 0, 5, 0),
            });
            container.AddChild(yEditWidget);

            this.Content = container;
        }
        private GuiWidget CreateField(string label, ref MHNumberEdit field1)
        {
            MHNumberEdit none = null;

            return(Create4FieldSet(label,
                                   "", ref field1,
                                   null, ref none,
                                   null, ref none,
                                   null, ref none));
        }
        private GuiWidget Create4FieldSet(string label,
                                          string field1Label, ref MHNumberEdit field1,
                                          string field2Label, ref MHNumberEdit field2,
                                          string field3Label, ref MHNumberEdit field3,
                                          string field4Label, ref MHNumberEdit field4)
        {
            FlowLayoutWidget row = new FlowLayoutWidget();

            row.Margin  = new BorderDouble(3);
            row.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

            TextWidget labelWidget = new TextWidget(label, textColor: ActiveTheme.Instance.PrimaryTextColor);

            labelWidget.VAnchor = VAnchor.ParentCenter;
            maxWidthOfLeftStuff = Math.Max(maxWidthOfLeftStuff, labelWidget.Width);
            GuiWidget holder = new GuiWidget(labelWidget.Width, labelWidget.Height);

            holder.Margin = new BorderDouble(3, 0);
            holder.AddChild(labelWidget);
            leftStuffToSize.Add(holder);
            row.AddChild(holder);

            {
                row.AddChild(CreateTextField(field1Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field1);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            if (field2Label != null)
            {
                row.AddChild(CreateTextField(field2Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field2);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            if (field3Label != null)
            {
                row.AddChild(CreateTextField(field3Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field3);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            if (field4Label != null)
            {
                row.AddChild(CreateTextField(field4Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field4);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            return(row);
        }
Example #6
0
        private GuiWidget CreateMHNumEdit(ref MHNumberEdit numberEditToCreate)
        {
            numberEditToCreate = new MHNumberEdit(0, pixelWidth: 80, allowNegatives: true, allowDecimals: true)
            {
                SelectAllOnFocus = true,
                VAnchor          = VAnchor.Center,
                Margin           = new BorderDouble(3, 0),
                TabIndex         = GetNextTabIndex()
            };

            return(numberEditToCreate);
        }
        private GuiWidget Create3FieldSet(string label,
                                          string field1Label, ref MHNumberEdit field1,
                                          string field2Label, ref MHNumberEdit field2,
                                          string field3Label, ref MHNumberEdit field3)
        {
            MHNumberEdit none = null;

            return(Create4FieldSet(label,
                                   field1Label, ref field1,
                                   field2Label, ref field2,
                                   field3Label, ref field3,
                                   null, ref none));
        }
        private void RebuildUi()
        {
            var tempList = new List <EePromRepetierParameter>();

            lock (currentEePromSettings.eePromSettingsList)
            {
                foreach (var keyValue in currentEePromSettings.eePromSettingsList)
                {
                    tempList.Add(keyValue.Value);
                }
            }

            settingsColumn.CloseAllChildren();

            foreach (EePromRepetierParameter newSetting in tempList)
            {
                if (newSetting != null)
                {
                    var row = new FlowLayoutWidget
                    {
                        HAnchor = HAnchor.MaxFitOrStretch,
                        Padding = new BorderDouble(5, 0)
                    };
                    row.AddChild(AddDescription(newSetting.Description));

                    if ((settingsColumn.Children.Count % 2) == 1)
                    {
                        row.BackgroundColor = new Color(0, 0, 0, 30);
                    }

                    CreateSpacer(row);

                    double.TryParse(newSetting.Value, out double currentValue);
                    var valueEdit = new MHNumberEdit(currentValue, theme, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true)
                    {
                        SelectAllOnFocus = true,
                        TabIndex         = currentTabIndex++,
                        VAnchor          = VAnchor.Center
                    };
                    valueEdit.ActuallNumberEdit.EditComplete += (s, e) =>
                    {
                        newSetting.Value = valueEdit.ActuallNumberEdit.Value.ToString();
                    };
                    row.AddChild(valueEdit);

                    settingsColumn.AddChild(row);
                }
            }
            waitingForUiUpdate = false;
        }
Example #9
0
        private GuiWidget Create4FieldSet(string label,
                                          string field1Label, ref MHNumberEdit field1,
                                          string field2Label, ref MHNumberEdit field2,
                                          string field3Label, ref MHNumberEdit field3,
                                          string field4Label, ref MHNumberEdit field4)
        {
            var row = new FlowLayoutWidget
            {
                Margin  = 3,
                HAnchor = HAnchor.Stretch
            };

            var labelWidget = new TextWidget(label, pointSize: theme.FontSize10, textColor: ActiveTheme.Instance.PrimaryTextColor);

            maxWidthOfLeftStuff = Math.Max(maxWidthOfLeftStuff, labelWidget.Width);

            var holder = new GuiWidget(labelWidget.Width, labelWidget.Height)
            {
                Margin  = new BorderDouble(3, 0),
                VAnchor = VAnchor.Fit | VAnchor.Center
            };

            holder.AddChild(labelWidget);
            leftStuffToSize.Add(holder);
            row.AddChild(holder);

            row.AddChild(CreateTextField(field1Label));
            row.AddChild(CreateMHNumEdit(ref field1));

            if (field2Label != null)
            {
                row.AddChild(CreateTextField(field2Label));
                row.AddChild(CreateMHNumEdit(ref field2));
            }

            if (field3Label != null)
            {
                row.AddChild(CreateTextField(field3Label));
                row.AddChild(CreateMHNumEdit(ref field3));
            }

            if (field4Label != null)
            {
                row.AddChild(CreateTextField(field4Label));
                row.AddChild(CreateMHNumEdit(ref field4));
            }

            return(row);
        }
Example #10
0
        public override void Initialize(int tabIndex)
        {
            var container = new FlowLayoutWidget();

            string[] xyValueStrings = this.Value?.Split(',');
            if (xyValueStrings == null ||
                xyValueStrings.Length != 2)
            {
                xyValueStrings = new string[] { "0", "0" };
            }

            double.TryParse(xyValueStrings[0], out double currentXValue);

            xEditWidget = new MHNumberEdit(currentXValue, theme, singleCharLabel: 'X', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex)
            {
                ToolTipText      = this.HelpText,
                TabIndex         = tabIndex,
                SelectAllOnFocus = true,
                Margin           = theme.ButtonSpacing
            };
            xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
            {
                this.SetValue(
                    string.Format("{0},{1}", xEditWidget.ActuallNumberEdit.Value.ToString(), yEditWidget.ActuallNumberEdit.Value.ToString()),
                    userInitiated: true);
            };

            container.AddChild(xEditWidget);

            double.TryParse(xyValueStrings[1], out double currentYValue);

            yEditWidget = new MHNumberEdit(currentYValue, theme, 'Y', allowNegatives: true, allowDecimals: true, pixelWidth: VectorXYEditWidth, tabIndex: tabIndex)
            {
                ToolTipText      = this.HelpText,
                TabIndex         = tabIndex + 1,
                SelectAllOnFocus = true,
            };
            yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
            {
                this.SetValue(
                    string.Format("{0},{1}", xEditWidget.ActuallNumberEdit.Value.ToString(), yEditWidget.ActuallNumberEdit.Value.ToString()),
                    userInitiated: true);
            };

            container.AddChild(yEditWidget);

            this.Content = container;
        }
Example #11
0
        private void RebuildUi()
        {
            List <EePromRepetierParameter> tempList = new List <EePromRepetierParameter>();

            lock (currentEePromSettings.eePromSettingsList)
            {
                foreach (KeyValuePair <int, EePromRepetierParameter> keyValue in currentEePromSettings.eePromSettingsList)
                {
                    tempList.Add(keyValue.Value);
                }
            }

            settingsColmun.CloseAllChildren();

            foreach (EePromRepetierParameter newSetting in tempList)
            {
                if (newSetting != null)
                {
                    FlowLayoutWidget row = new FlowLayoutWidget();
                    row.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
                    row.AddChild(AddDescription(newSetting.Description));
                    row.Padding = new BorderDouble(5, 0);
                    if ((settingsColmun.Children.Count % 2) == 1)
                    {
                        row.BackgroundColor = new RGBA_Bytes(0, 0, 0, 30);
                    }

                    CreateSpacer(row);

                    double currentValue;
                    double.TryParse(newSetting.Value, out currentValue);
                    MHNumberEdit valueEdit = new MHNumberEdit(currentValue, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true);
                    valueEdit.SelectAllOnFocus = true;
                    valueEdit.TabIndex         = currentTabIndex++;
                    valueEdit.VAnchor          = Agg.UI.VAnchor.ParentCenter;
                    valueEdit.ActuallNumberEdit.EditComplete += (sender, e) =>
                    {
                        newSetting.Value = valueEdit.ActuallNumberEdit.Value.ToString();
                    };
                    row.AddChild(valueEdit);

                    settingsColmun.AddChild(row);
                }
            }
            waitingForUiUpdate = false;
        }
Example #12
0
        public InlineEditControl(string defaultSizeString = "-0000.00", Agg.Font.Justification justification = Agg.Font.Justification.Left)
        {
            theme        = AppContext.Theme;
            base.Visible = false;

            double pointSize = 12;

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

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

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

            AddChild(numberEdit);

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

            runningInterval = UiThread.SetInterval(HideIfApplicable, .1);
        }
Example #13
0
        public override void Initialize(int tabIndex)
        {
            numberEdit = new MHNumberEdit(0, pixelWidth: ControlWidth, allowDecimals: this.AllowDecimals, allowNegatives: this.AllowNegatives, tabIndex: tabIndex)
            {
                ToolTipText      = this.HelpText,
                SelectAllOnFocus = true,
                Name             = this.Name,
            };
            numberEdit.ActuallNumberEdit.EditComplete += (s, e) =>
            {
                if (this.Value != numberEdit.Value.ToString())
                {
                    this.SetValue(
                        numberEdit.Value.ToString(),
                        userInitiated: true);
                }
            };

            this.Content = numberEdit;
        }
        private void AddItemToUi(object state)
        {
            EePromRepetierParameter newSetting = state as EePromRepetierParameter;

            if (newSetting != null)
            {
                FlowLayoutWidget row = new FlowLayoutWidget();
                row.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
                row.AddChild(AddDescription(newSetting.Description));
                row.Padding = new BorderDouble(5, 0);
                if ((settingsColmun.Children.Count % 2) == 1)
                {
                    row.BackgroundColor = new RGBA_Bytes(0, 0, 0, 50);
                }

                CreateSpacer(row);

                double currentValue;
                double.TryParse(newSetting.Value, out currentValue);
                MHNumberEdit valueEdit = new MHNumberEdit(currentValue, pixelWidth: 80, allowNegatives: true, allowDecimals: true);
                valueEdit.SelectAllOnFocus = true;
                valueEdit.TabIndex         = currentTabIndex++;
                valueEdit.VAnchor          = Agg.UI.VAnchor.ParentCenter;
                valueEdit.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    newSetting.Value = valueEdit.ActuallNumberEdit.Value.ToString();
                };
                row.AddChild(valueEdit);

                settingsColmun.AddChild(row);
            }

            // TODO: fix the flow layout so we don't need this.
            // This is correcting a bug in flow layout widgets not setting sizes correctly.
            double oldWidth = Width;

            Width = Width + 1;
            Width = oldWidth;
        }
        private GuiWidget CreateField(string label, ref MHNumberEdit field1)
        {
            MHNumberEdit none = null;

            return Create4FieldSet(label,
            "", ref field1,
            null, ref none,
            null, ref none,
            null, ref none);
        }
		private void RebuildUi()
		{
			List<EePromRepetierParameter> tempList = new List<EePromRepetierParameter>();
			lock (currentEePromSettings.eePromSettingsList)
			{
				foreach (KeyValuePair<int, EePromRepetierParameter> keyValue in currentEePromSettings.eePromSettingsList)
				{
					tempList.Add(keyValue.Value);
				}
			}

			settingsColmun.CloseAllChildren();

			foreach (EePromRepetierParameter newSetting in tempList)
			{
				if (newSetting != null)
				{
					FlowLayoutWidget row = new FlowLayoutWidget();
					row.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
					row.AddChild(AddDescription(newSetting.Description));
					row.Padding = new BorderDouble(5, 0);
					if ((settingsColmun.Children.Count % 2) == 1)
					{
						row.BackgroundColor = new RGBA_Bytes(0, 0, 0, 30);
					}

					CreateSpacer(row);

					double currentValue;
					double.TryParse(newSetting.Value, out currentValue);
					MHNumberEdit valueEdit = new MHNumberEdit(currentValue, pixelWidth: 80 * GuiWidget.DeviceScale, allowNegatives: true, allowDecimals: true);
					valueEdit.SelectAllOnFocus = true;
					valueEdit.TabIndex = currentTabIndex++;
					valueEdit.VAnchor = Agg.UI.VAnchor.ParentCenter;
					valueEdit.ActuallNumberEdit.EditComplete += (sender, e) =>
					{
						newSetting.Value = valueEdit.ActuallNumberEdit.Value.ToString();
					};
					row.AddChild(valueEdit);

					settingsColmun.AddChild(row);
				}
			}
			waitingForUiUpdate = false;
		}
        private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth)
        {
            FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget();
            if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
            {
                int intEditWidth = 60;
                int doubleEditWidth = 60;
                int vectorXYEditWidth = 60;
                int multiLineEditHeight = 60;

                string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
                leftToRightLayout.Margin = new BorderDouble(0, 5);
                leftToRightLayout.HAnchor |= Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;

                if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT)
                {
                    string convertedNewLines = settingData.PresentationName.Replace("\\n ", "\n");
                    convertedNewLines = convertedNewLines.Replace("\\n", "\n");
					convertedNewLines = new LocalizedString (convertedNewLines).Translated;
                    TextWidget settingName = new TextWidget(convertedNewLines);
                    settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                    settingName.Width = minSettingNameWidth;
                    //settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                    leftToRightLayout.AddChild(settingName);
                }
                
                switch (settingData.DataEditType)
                {
                    case OrganizerSettingsData.DataEditTypes.INT:
                        {
                            int currentValue = 0;
                            int.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
                            intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                            leftToRightLayout.AddChild(intEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.DOUBLE:
                        {
                            double currentValue = 0;
                            double.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                            doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                            leftToRightLayout.AddChild(doubleEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.POSITVE_DOUBLE:
                        {
                            double currentValue = 0;
                            double.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                            doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                            leftToRightLayout.AddChild(doubleEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.OFFSET:
                        {
                            double currentValue = 0;
                            double.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                            doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                            leftToRightLayout.AddChild(doubleEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
                        {
                            MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++);
                            stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                            {
                                TextEditWidget textEditWidget = (TextEditWidget)sender;
                                string text = textEditWidget.Text;
                                text = text.Trim();
                                bool isPercent = text.Contains("%");
                                if(isPercent)
                                {
                                    text = text.Substring(0, text.IndexOf("%"));
                                }
                                double result;
                                double.TryParse(text, out result);
                                text = result.ToString();
                                if (isPercent)
                                {
                                    text += "%";
                                }
                                textEditWidget.Text = text;
                                SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
                            };

                            leftToRightLayout.AddChild(stringEdit);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
                        {
                            CheckBox checkBoxWidget = new CheckBox("");
                            checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
                            checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                            checkBoxWidget.Checked = (sliceSettingValue == "1");
                            checkBoxWidget.CheckedStateChanged += (sender, e) =>
                            {
                                if (((CheckBox)sender).Checked)
                                {
                                    SaveSetting(settingData.SlicerConfigName, "1");
                                }
                                else
                                {
                                    SaveSetting(settingData.SlicerConfigName, "0");
                                }
                            };
                            leftToRightLayout.AddChild(checkBoxWidget);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.STRING:
                        {
                            MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
                            stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); };
                            leftToRightLayout.AddChild(stringEdit);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
                        {
                            string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
                            MHTextEditWidget stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
                            stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); };
                            leftToRightLayout.AddChild(stringEdit);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.LIST:
                        {
                            StyledDropDownList selectableOptions = new StyledDropDownList("None", Direction.Up);
                            selectableOptions.Margin = new BorderDouble();
                            
                            string[] listItems = settingData.ExtraSettings.Split(',');
                            foreach (string listItem in listItems)
                            {
                                MenuItem newItem = selectableOptions.AddItem(listItem);
                                if (newItem.Text == sliceSettingValue)
                                {
                                    selectableOptions.SelectedValue = sliceSettingValue;
                                }

                                newItem.Selected += (sender, e) =>
                                {
                                    MenuItem menuItem = ((MenuItem)sender);
                                    SaveSetting(settingData.SlicerConfigName, menuItem.Text);
                                };
                            }
                            leftToRightLayout.AddChild(selectableOptions);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.VECTOR2:
                        {
                            string[] xyValueStrings = sliceSettingValue.Split(',');
                            if (xyValueStrings.Length != 2)
                            {
                                xyValueStrings = new string[] { "0", "0" };
                            }
                                double currentXValue = 0;
                                double.TryParse(xyValueStrings[0], out currentXValue);
                                MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                                double currentYValue = 0;
                                double.TryParse(xyValueStrings[1], out currentYValue);
                                MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                            {
                                xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                                leftToRightLayout.AddChild(xEditWidget);
                                TextWidget xText = new TextWidget("x");
                                xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                                xText.Margin = new BorderDouble(5, 0);
                                leftToRightLayout.AddChild(xText);
                            }
                            {
                                yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                                leftToRightLayout.AddChild(yEditWidget);
                                TextWidget yText = new TextWidget("y");
                                yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                                yText.Margin = new BorderDouble(5, 0);
                                leftToRightLayout.AddChild(yText);
                            }
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.OFFSET2:
                        {
                            string[] xyValueStrings = sliceSettingValue.Split('x');
                            if (xyValueStrings.Length != 2)
                            {
                                xyValueStrings = new string[] { "0", "0" };
                            }
                            double currentXValue = 0;
                            double.TryParse(xyValueStrings[0], out currentXValue);
                            MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                            double currentYValue = 0;
                            double.TryParse(xyValueStrings[1], out currentYValue);
                            MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                            {
                                xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                                leftToRightLayout.AddChild(xEditWidget);
                                TextWidget xText = new TextWidget("x");
                                xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                                xText.Margin = new BorderDouble(5, 0);
                                leftToRightLayout.AddChild(xText);
                            }
                            {
                                yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                                leftToRightLayout.AddChild(yEditWidget);
                                TextWidget yText = new TextWidget("y");
                                yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                                yText.Margin = new BorderDouble(5, 0);
                                leftToRightLayout.AddChild(yText);
                            }
                        }
                        break;

                    default:
                        TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
                        missingSetting.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        missingSetting.BackgroundColor = RGBA_Bytes.Red;
                        leftToRightLayout.AddChild(missingSetting);
                        break;
                }
            }
            else // the setting we think we are adding is not in the config.ini it may have been depricated
            {
                TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
                settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                leftToRightLayout.AddChild(settingName);
                leftToRightLayout.BackgroundColor = RGBA_Bytes.Red;
            }

            return leftToRightLayout;
        }
		private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth, int extruderIndex)
		{
			GuiWidget container = new GuiWidget();
			this.HAnchor = HAnchor.ParentLeftRight;

			string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);

			var settingsRow = new SettingsRow()
			{
				SettingsKey = settingData.SlicerConfigName,
				SettingsValue = sliceSettingValue
			};

			if (!ActiveSliceSettings.Instance.InBaseConfig(settingData.SlicerConfigName))
			{
				// the setting we think we are adding is not in the config.ini it may have been deprecated
				TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
				settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
				settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
				settingsRow.AddChild(settingName);
				settingsRow.BackgroundColor = RGBA_Bytes.Red;
			}
			else
			{
				int intEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
				int doubleEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
				if (settingData.QuickMenuSettings.Count > 0)
				{
					doubleEditWidth = (int)(35 * TextWidget.GlobalPointSizeScaleRatio + .5);
				}
				int vectorXYEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
				int multiLineEditHeight = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);


				if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT)
				{
					var nameHolder = new GuiWidget(HAnchor.AbsolutePosition, VAnchor.FitToChildren | VAnchor.ParentCenter)
					{
						Width = minSettingNameWidth,
						Padding = new BorderDouble(0, 0, 5, 0),
					};

					nameHolder.AddChild(new WrappedTextWidget(
						settingData.PresentationName.Localize(), 
						minSettingNameWidth, 
						pointSize: 10, 
						textColor: ActiveTheme.Instance.PrimaryTextColor));

					settingsRow.AddChild(nameHolder);
				}

				switch (settingData.DataEditType)
				{
					case OrganizerSettingsData.DataEditTypes.INT:
						{
							int currentValue;
							int.TryParse(sliceSettingValue, out currentValue);

							var intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};
							intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							settingsRow.AddChild(intEditWidget);
							settingsRow.AddChild(GetExtraSettingsWidget(settingData));

							settingsRow.ValueChanged = (text) => intEditWidget.Text = text;
						}
						break;

					case OrganizerSettingsData.DataEditTypes.DOUBLE:
						{
							double currentValue;
							double.TryParse(sliceSettingValue, out currentValue);

							var doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							settingsRow.AddChild(doubleEditWidget);
							settingsRow.AddChild(GetExtraSettingsWidget(settingData));

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2 = 0;
								double.TryParse(text, out currentValue2);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue2;
							};
						}
						break;

					case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
						{
							const string multiValuesAreDiffernt = "-";
							FlowLayoutWidget content = new FlowLayoutWidget();

							var doubleEditWidget = new MHNumberEdit(0, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								Name = settingData.PresentationName + " Textbox",
								SelectAllOnFocus = true
							};

							double currentValue;
							bool ChangesMultipleOtherSettings = settingData.SetSettingsOnChange.Count > 0;
							if (ChangesMultipleOtherSettings)
							{
								bool allTheSame = true;
								string setting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[0]);
								for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++)
								{
									string nextSetting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[i]);
									if (setting != nextSetting)
									{
										allTheSame = false;
										break;
									}
								}

								if (allTheSame && setting.EndsWith("mm"))
								{
									double.TryParse(setting.Substring(0, setting.Length - 2), out currentValue);
									doubleEditWidget.ActuallNumberEdit.Value = currentValue;
								}
								else
								{
									doubleEditWidget.ActuallNumberEdit.InternalNumberEdit.Text = multiValuesAreDiffernt;
								}
							}
							else // just set the setting normally
							{
								double.TryParse(sliceSettingValue, out currentValue);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue;
							}
							doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget.MarkAsStartingState();
							
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								NumberEdit numberEdit = (NumberEdit)sender;
								// If this setting sets other settings, then do that.
								if (ChangesMultipleOtherSettings
									&& numberEdit.Text != multiValuesAreDiffernt)
								{
									foreach (string setting in settingData.SetSettingsOnChange)
									{
										SaveSetting(setting, numberEdit.Value.ToString() + "mm");
									}
								}

								// also always save to the local setting
								SaveSetting(settingData.SlicerConfigName, numberEdit.Value.ToString());
								settingsRow.UpdateStyle();
								OnSettingsChanged(settingData);
							};
							content.AddChild(doubleEditWidget);
							content.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								settingsRow.AddChild(CreateQuickMenu(settingData, content, doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget));
							}
							else
							{
								settingsRow.AddChild(content);
							}

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2 = 0;
								double.TryParse(text, out currentValue2);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue2;
							};
						}
						break;

					case OrganizerSettingsData.DataEditTypes.OFFSET:
						{
							double currentValue;
							double.TryParse(sliceSettingValue, out currentValue);
							var doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true

							};
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
								settingsRow.UpdateStyle();
								OnSettingsChanged(settingData);
							};
							settingsRow.AddChild(doubleEditWidget);
							settingsRow.AddChild(GetExtraSettingsWidget(settingData));

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2;
								double.TryParse(text, out currentValue2);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue2;
							};
						}
						break;

					case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								var textEditWidget = (TextEditWidget)sender;
								string text = textEditWidget.Text.Trim();

								bool isPercent = text.Contains("%");
								if (isPercent)
								{
									text = text.Substring(0, text.IndexOf("%"));
								}
								double result;
								double.TryParse(text, out result);
								text = result.ToString();
								if (isPercent)
								{
									text += "%";
								}
								textEditWidget.Text = text;
								SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select everything up to the % (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int percentIndex = textEditWidget.Text.IndexOf("%");
								if (percentIndex != -1)
								{
									textEditWidget.SetSelection(0, percentIndex - 1);
								}
							};

							content.AddChild(stringEdit);
							content.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								settingsRow.AddChild(CreateQuickMenu(settingData, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget));
							}
							else
							{
								settingsRow.AddChild(content);
							}

							settingsRow.ValueChanged = (text) => stringEdit.Text = text;
						}
						break;

					case OrganizerSettingsData.DataEditTypes.INT_OR_MM:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};

							string startingText = stringEdit.Text;
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								TextEditWidget textEditWidget = (TextEditWidget)sender;
								// only validate when we lose focus
								if (!textEditWidget.ContainsFocus)
								{
									string text = textEditWidget.Text;
									text = text.Trim();
									bool isMm = text.Contains("mm");
									if (isMm)
									{
										text = text.Substring(0, text.IndexOf("mm"));
									}
									double result;
									double.TryParse(text, out result);
									text = result.ToString();
									if (isMm)
									{
										text += "mm";
									}
									else
									{
										result = (int)result;
										text = result.ToString();
									}
									textEditWidget.Text = text;
									startingText = stringEdit.Text;
								}
								SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);

								OnSettingsChanged(settingData);

								// make sure we are still looking for the final validation before saving.
								if (textEditWidget.ContainsFocus)
								{
									UiThread.RunOnIdle(() =>
									{
										string currentText = textEditWidget.Text;
										int cursorIndex = textEditWidget.InternalTextEditWidget.CharIndexToInsertBefore;
										textEditWidget.Text = startingText;
										textEditWidget.InternalTextEditWidget.MarkAsStartingState();
										textEditWidget.Text = currentText;
										textEditWidget.InternalTextEditWidget.CharIndexToInsertBefore = cursorIndex;
									});
								}
							};

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select everything up to the mm (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int mMIndex = textEditWidget.Text.IndexOf("mm");
								if (mMIndex != -1)
								{
									textEditWidget.SetSelection(0, mMIndex - 1);
								}
							};

							content.AddChild(stringEdit);
							content.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								settingsRow.AddChild(CreateQuickMenu(settingData, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget));
							}
							else
							{
								settingsRow.AddChild(content);
							}

							settingsRow.ValueChanged = (text) => stringEdit.Text = text;
						}
						break;

					case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
						{
							var checkBoxWidget = new CheckBox("")
							{
								Name = settingData.PresentationName + " Checkbox",
								ToolTipText = settingData.HelpText,
								VAnchor = Agg.UI.VAnchor.ParentBottom,
								TextColor = ActiveTheme.Instance.PrimaryTextColor,
								Checked = sliceSettingValue == "1"
							};
							checkBoxWidget.CheckedStateChanged += (sender, e) =>
							{
								bool isChecked = ((CheckBox)sender).Checked;
								SaveSetting(settingData.SlicerConfigName, isChecked ? "1" : "0");
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							settingsRow.AddChild(checkBoxWidget);

							settingsRow.ValueChanged = (text) => checkBoxWidget.Checked = text == "1";
						}
						break;

					case OrganizerSettingsData.DataEditTypes.STRING:
						{
							var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
							stringEdit.ToolTipText = settingData.HelpText;
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							settingsRow.AddChild(stringEdit);

							settingsRow.ValueChanged = (text) => stringEdit.Text = text;
						}
						break;

					case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
						{
							string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
							var stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
							
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n"));
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							settingsRow.AddChild(stringEdit);

							settingsRow.ValueChanged = (text) => stringEdit.Text = text.Replace("\\n", "\n");
						}
						break;

					case OrganizerSettingsData.DataEditTypes.LIST:
						{
							var selectableOptions = new StyledDropDownList("None", maxHeight: 200)
							{
								ToolTipText = settingData.HelpText,
								Margin = new BorderDouble()
							};

							foreach (string listItem in settingData.ExtraSettings.Split(','))
							{
								MenuItem newItem = selectableOptions.AddItem(listItem);
								if (newItem.Text == sliceSettingValue)
								{
									selectableOptions.SelectedLabel = sliceSettingValue;
								}

								newItem.Selected += (sender, e) =>
								{
									MenuItem menuItem = ((MenuItem)sender);
									SaveSetting(settingData.SlicerConfigName, menuItem.Text);

									settingsRow.UpdateStyle();

									OnSettingsChanged(settingData);
								};
							}

							settingsRow.AddChild(selectableOptions);

							settingsRow.ValueChanged = (text) => selectableOptions.SelectedLabel = text;
						}
						break;

					case OrganizerSettingsData.DataEditTypes.HARDWARE_PRESENT:
						{
							var checkBoxWidget = new CheckBox("")
							{
								Name = settingData.PresentationName + " Checkbox",
								ToolTipText = settingData.HelpText,
								VAnchor = Agg.UI.VAnchor.ParentBottom,
								TextColor = ActiveTheme.Instance.PrimaryTextColor,
								Checked = sliceSettingValue == "1"
							};

							checkBoxWidget.CheckedStateChanged += (sender, e) =>
							{
								bool isChecked = ((CheckBox)sender).Checked;
								SaveSetting(settingData.SlicerConfigName, isChecked ? "1" : "0");

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							settingsRow.AddChild(checkBoxWidget);

							settingsRow.ValueChanged = (text) => checkBoxWidget.Checked = text == "1";
						}
						break;

					case OrganizerSettingsData.DataEditTypes.VECTOR2:
						{
							string[] xyValueStrings = sliceSettingValue.Split(',');
							if (xyValueStrings.Length != 2)
							{
								xyValueStrings = new string[] { "0", "0" };
							}

							double currentXValue;
							double.TryParse(xyValueStrings[0], out currentXValue);

							var xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								Margin = new BorderDouble(0, 0, 30 * TextWidget.GlobalPointSizeScaleRatio, 0),
								SelectAllOnFocus = true
							};

							double currentYValue;
							double.TryParse(xyValueStrings[1], out currentYValue);

							var yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};

							xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString());

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							settingsRow.AddChild(xEditWidget);

							yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString());

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							settingsRow.AddChild(yEditWidget);

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2;
								string[] xyValueStrings2 = text.Split(',');
								if (xyValueStrings2.Length != 2)
								{
									xyValueStrings2 = new string[] { "0", "0" };
								}

								double.TryParse(xyValueStrings2[0], out currentValue2);
								xEditWidget.ActuallNumberEdit.Value = currentValue2;

								double.TryParse(xyValueStrings2[1], out currentValue2);
								yEditWidget.ActuallNumberEdit.Value = currentValue2;
							};

						}
						break;

					case OrganizerSettingsData.DataEditTypes.OFFSET2:
						{
							Vector2 offset = ActiveSliceSettings.Instance.GetOffset(extruderIndex);

							var xEditWidget = new MHNumberEdit(offset.x, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true,
								Margin = new BorderDouble(0, 0, 30 * TextWidget.GlobalPointSizeScaleRatio, 0)
							};

							var yEditWidget = new MHNumberEdit(offset.y, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};

							xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								int extruderIndexLocal = extruderIndex;
								SaveCommaSeparatedIndexSetting(extruderIndexLocal, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString());

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							settingsRow.AddChild(xEditWidget);


							yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								int extruderIndexLocal = extruderIndex;
								SaveCommaSeparatedIndexSetting(extruderIndexLocal, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString());

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							settingsRow.AddChild(yEditWidget);

							settingsRow.ValueChanged = (text) =>
							{
								Vector2 offset2 = ActiveSliceSettings.Instance.GetOffset(extruderIndex);
								xEditWidget.ActuallNumberEdit.Value = offset2.x;
								yEditWidget.ActuallNumberEdit.Value = offset2.y;
							};

						}
						break;

					default:
						var missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()))
						{
							TextColor = ActiveTheme.Instance.PrimaryTextColor,
							BackgroundColor = RGBA_Bytes.Red
						};
						settingsRow.AddChild(missingSetting);
						break;
				}
			}

			container.HAnchor = HAnchor.ParentLeftRight;
			container.VAnchor = VAnchor.FitToChildren;

			var restoreButton = new Button(new ButtonViewStates(new ImageWidget(restoreNormal), new ImageWidget(restoreHover), new ImageWidget(restorePressed), new ImageWidget(restoreNormal)))
			{
				Name = "Restore " + settingData.SlicerConfigName,
				VAnchor = VAnchor.ParentCenter,
				Margin = new BorderDouble(0, 0, 5, 0),
				ToolTipText = "Restore Default".Localize()
			};

			restoreButton.Click += (sender, e) =>
			{
				// Revert the user override 
				if (persistenceLayer == null)
				{
					ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName);
				}
				else
				{
					ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName, persistenceLayer);
				}

				settingsRow.RefreshValue();
			};

			settingsRow.AddChild(new GuiWidget(HAnchor.ParentLeftRight));
			settingsRow.AddChild(restoreButton);

			container.AddChild(settingsRow);

			// Define the UpdateStyle implementation
			settingsRow.UpdateStyle = () =>
			{
				if (persistenceLayer.ContainsKey(settingData.SlicerConfigName))
				{
					switch (this.viewFilter)
					{
						case NamedSettingsLayers.All:
							settingsRow.BackgroundColor = userSettingBackgroundColor;
							break;
						case NamedSettingsLayers.Material:
							settingsRow.BackgroundColor = materialSettingBackgroundColor;
							break;
						case NamedSettingsLayers.Quality:
							settingsRow.BackgroundColor = qualitySettingBackgroundColor;
							break;
					}

					restoreButton.Visible = true;
				}
				else if (layerFilters == null)
				{
					if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Material))
					{
						settingsRow.BackgroundColor = materialSettingBackgroundColor;
					}
					else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Quality))
					{
						settingsRow.BackgroundColor = qualitySettingBackgroundColor;
					}
					else
					{
						settingsRow.BackgroundColor = RGBA_Bytes.Transparent;
					}

					restoreButton.Visible = false;
				}
				else
				{
					restoreButton.Visible = false;
					settingsRow.BackgroundColor = RGBA_Bytes.Transparent;
				}
			};

			// Invoke the UpdateStyle implementation
			settingsRow.UpdateStyle();

			return container;
		}
        void AddItemToUi(object state)
        {
            EePromRepetierParameter newSetting = state as EePromRepetierParameter;
            if (newSetting != null)
            {
                FlowLayoutWidget row = new FlowLayoutWidget();
                row.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
                row.AddChild(AddDescription(newSetting.Description));
                row.Padding = new BorderDouble(5, 0);
                if ((settingsColmun.Children.Count % 2) == 1)
                {
                    row.BackgroundColor = new RGBA_Bytes(0, 0, 0, 50);
                }

                CreateSpacer(row);

                double currentValue;
                double.TryParse(newSetting.Value, out currentValue);
                MHNumberEdit valueEdit = new MHNumberEdit(currentValue, pixelWidth: 80, allowNegatives: true, allowDecimals: true);
                valueEdit.TabIndex = currentTabIndex++;
                valueEdit.VAnchor = Agg.UI.VAnchor.ParentCenter;
                valueEdit.ActuallNumberEdit.EditComplete += (sender, e) =>
                {
                    newSetting.Value = valueEdit.ActuallNumberEdit.Value.ToString();
                };
                row.AddChild(valueEdit);

                settingsColmun.AddChild(row);
            }

            // TODO: fix the flow layout so we don't need this.
            // This is correcting a bug in flow layout widgets not setting sizes correctly.
            double oldWidth = Width;
            Width = Width + 1;
            Width = oldWidth;
        }
		private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth, int extruderIndex)
		{
			GuiWidget container = new GuiWidget();
			FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget();

			bool addQualityOverlay = false;
			bool addMaterialOverlay = false;

			RGBA_Bytes qualityOverlayColor = new RGBA_Bytes(255, 255, 0, 40);
			RGBA_Bytes materialOverlayColor = new RGBA_Bytes(255, 127, 0, 40);

			if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
			{
				int intEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
				int doubleEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
				if (settingData.QuickMenuSettings.Count > 0)
				{
					doubleEditWidth = (int)(35 * TextWidget.GlobalPointSizeScaleRatio + .5);
				}
				int vectorXYEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
				int multiLineEditHeight = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);

				string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
				leftToRightLayout.Margin = new BorderDouble(0, 2);
				leftToRightLayout.Padding = new BorderDouble(3);
				leftToRightLayout.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

				if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT)
				{
					string convertedNewLines = settingData.PresentationName.Replace("\\n ", "\n");
					convertedNewLines = convertedNewLines.Replace("\\n", "\n");
					convertedNewLines = LocalizedString.Get(convertedNewLines);
					TextWidget settingName = new TextWidget(convertedNewLines, pointSize: 10);
					settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
					settingName.VAnchor = Agg.UI.VAnchor.ParentCenter;

#if DO_IN_PLACE_EDIT
                    if (SettingsIndexBeingEdited != 0)
                    {
                        if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, SettingsIndexBeingEdited))
                        {
                            CheckBox removeFromSettingCheckBox = new CheckBox("");
                            removeFromSettingCheckBox.Checked = true;
                            removeFromSettingCheckBox.VAnchor = VAnchor.ParentCenter;
                            leftToRightLayout.AddChild(removeFromSettingCheckBox);
                        }
                        else
                        {
                            CheckBox addToSettingCheckBox = new CheckBox("");
                            addToSettingCheckBox.VAnchor = VAnchor.ParentCenter;
                            leftToRightLayout.AddChild(addToSettingCheckBox);
                        }
                    }
#endif
					settingName.Width = minSettingNameWidth;
					//settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
					leftToRightLayout.AddChild(settingName);
				}

				if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 3))
				{
					addMaterialOverlay = true;
				}
				else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2))
				{
					addQualityOverlay = true;
				}

				switch (settingData.DataEditType)
				{
					case OrganizerSettingsData.DataEditTypes.INT:
						{
							int currentValue = 0;
							int.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
							intEditWidget.ToolTipText = settingData.HelpText;
							intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
								CallEventsOnSettingsChange(settingData);
							};
							intEditWidget.SelectAllOnFocus = true;

							leftToRightLayout.AddChild(intEditWidget);
							leftToRightLayout.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.DOUBLE:
						{
							double currentValue = 0;
							double.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
							doubleEditWidget.ToolTipText = settingData.HelpText;
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
								CallEventsOnSettingsChange(settingData);
							};
							doubleEditWidget.SelectAllOnFocus = true;
							leftToRightLayout.AddChild(doubleEditWidget);
							leftToRightLayout.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
						{
							const string multiValuesAreDiffernt = "-";
							FlowLayoutWidget content = new FlowLayoutWidget();

							MHNumberEdit doubleEditWidget = new MHNumberEdit(0, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
							doubleEditWidget.ToolTipText = settingData.HelpText;

							double currentValue = 0;
							bool ChangesMultipleOtherSettings = settingData.SetSettingsOnChange.Count > 0;
							if (ChangesMultipleOtherSettings)
							{
								bool allTheSame = true;
								string setting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[0]);								
								for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++)
								{
									string nextSetting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[i]);
									if (setting != nextSetting)
									{
										allTheSame = false;
										break;
									}
								}

								if (allTheSame && setting.EndsWith("mm"))
								{
									double.TryParse(setting.Substring(0, setting.Length-2), out currentValue);
									doubleEditWidget.ActuallNumberEdit.Value = currentValue;
								}
								else
								{
									doubleEditWidget.ActuallNumberEdit.InternalNumberEdit.Text = multiValuesAreDiffernt;
								}
							}
							else // just set the setting nomrmaly
							{
								double.TryParse(sliceSettingValue, out currentValue);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue;
							}
							doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget.MarkAsStartingState();

							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								NumberEdit numberEdit = (NumberEdit)sender;
								// If this setting sets other settings, then do that.
								if (ChangesMultipleOtherSettings
									&& numberEdit.Text != multiValuesAreDiffernt)
								{
									foreach (string setting in settingData.SetSettingsOnChange)
									{
										SaveSetting(setting, numberEdit.Value.ToString() + "mm");
									}
								}

								// also always save to the local setting
								SaveSetting(settingData.SlicerConfigName, numberEdit.Value.ToString());
								CallEventsOnSettingsChange(settingData);
							};
							doubleEditWidget.SelectAllOnFocus = true;

							content.AddChild(doubleEditWidget);
							content.AddChild(getSettingInfoData(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								leftToRightLayout.AddChild(CreateQuickMenu(settingData, content, doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget));
							}
							else
							{
								leftToRightLayout.AddChild(content);
							}
						}
						break;

					case OrganizerSettingsData.DataEditTypes.OFFSET:
						{
							double currentValue = 0;
							double.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
							doubleEditWidget.ToolTipText = settingData.HelpText;
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
								CallEventsOnSettingsChange(settingData);
							};
							doubleEditWidget.SelectAllOnFocus = true;
							leftToRightLayout.AddChild(doubleEditWidget);
							leftToRightLayout.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++);
							stringEdit.ToolTipText = settingData.HelpText;
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								TextEditWidget textEditWidget = (TextEditWidget)sender;
								string text = textEditWidget.Text;
								text = text.Trim();
								bool isPercent = text.Contains("%");
								if (isPercent)
								{
									text = text.Substring(0, text.IndexOf("%"));
								}
								double result;
								double.TryParse(text, out result);
								text = result.ToString();
								if (isPercent)
								{
									text += "%";
								}
								textEditWidget.Text = text;
								SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
								CallEventsOnSettingsChange(settingData);
							};
							stringEdit.SelectAllOnFocus = true;

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select evrything up to the % (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int percentIndex = textEditWidget.Text.IndexOf("%");
								if (percentIndex != -1)
								{
									textEditWidget.SetSelection(0, percentIndex-1);
								}
							};

							content.AddChild(stringEdit);
							content.AddChild(getSettingInfoData(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								leftToRightLayout.AddChild(CreateQuickMenu(settingData, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget));
							}
							else
							{
								leftToRightLayout.AddChild(content);
							}
						}
						break;

					case OrganizerSettingsData.DataEditTypes.INT_OR_MM:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++);
							stringEdit.ToolTipText = settingData.HelpText;
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								TextEditWidget textEditWidget = (TextEditWidget)sender;
								string text = textEditWidget.Text;
								text = text.Trim();
								bool isMm = text.Contains("mm");
								if (isMm)
								{
									text = text.Substring(0, text.IndexOf("mm"));
								}
								double result;
								double.TryParse(text, out result);
								text = result.ToString();
								if (isMm)
								{
									text += "mm";
								}
								else
								{
									result = (int)result;
									text = result.ToString();
								}
								textEditWidget.Text = text;
								SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
								CallEventsOnSettingsChange(settingData);
							};
							stringEdit.SelectAllOnFocus = true;

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select evrything up to the mm (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int mMIndex = textEditWidget.Text.IndexOf("mm");
								if (mMIndex != -1)
								{
									textEditWidget.SetSelection(0, mMIndex-1);
								}
							};

							content.AddChild(stringEdit);
							content.AddChild(getSettingInfoData(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								leftToRightLayout.AddChild(CreateQuickMenu(settingData, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget));
							}
							else
							{
								leftToRightLayout.AddChild(content);
							}
						}
						break;

					case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
						{
							CheckBox checkBoxWidget = new CheckBox("");
							checkBoxWidget.ToolTipText = settingData.HelpText;
							checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
							checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
							checkBoxWidget.Checked = (sliceSettingValue == "1");
							checkBoxWidget.CheckedStateChanged += (sender, e) =>
							{
								if (((CheckBox)sender).Checked)
								{
									SaveSetting(settingData.SlicerConfigName, "1");
								}
								else
								{
									SaveSetting(settingData.SlicerConfigName, "0");
								}
								CallEventsOnSettingsChange(settingData);
							};
							leftToRightLayout.AddChild(checkBoxWidget);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.STRING:
						{
							MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
							stringEdit.ToolTipText = settingData.HelpText;
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text);
								CallEventsOnSettingsChange(settingData);
							};
							leftToRightLayout.AddChild(stringEdit);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
						{
							string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
							MHTextEditWidget stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n"));
								CallEventsOnSettingsChange(settingData);
							};
							leftToRightLayout.AddChild(stringEdit);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.LIST:
						{
							StyledDropDownList selectableOptions = new StyledDropDownList("None", maxHeight: 200);
							selectableOptions.ToolTipText = settingData.HelpText;
							selectableOptions.Margin = new BorderDouble();

							string[] listItems = settingData.ExtraSettings.Split(',');

							foreach (string listItem in listItems)
							{
								MenuItem newItem = selectableOptions.AddItem(listItem);
								if (newItem.Text == sliceSettingValue)
								{
									selectableOptions.SelectedLabel = sliceSettingValue;
								}

								newItem.Selected += (sender, e) =>
								{
									MenuItem menuItem = ((MenuItem)sender);
									SaveSetting(settingData.SlicerConfigName, menuItem.Text);
									CallEventsOnSettingsChange(settingData);
								};
							}
							leftToRightLayout.AddChild(selectableOptions);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.HARDWARE_PRESENT:
						{
							CheckBox checkBoxWidget = new CheckBox("");
							checkBoxWidget.ToolTipText = settingData.HelpText;
							checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
							checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
							checkBoxWidget.Checked = (sliceSettingValue == "1");
							checkBoxWidget.CheckedStateChanged += (sender, e) =>
							{
								if (((CheckBox)sender).Checked)
								{
									SaveSetting(settingData.SlicerConfigName, "1");
									// Now show all of the settings that this control is associated with.
								}
								else
								{
									SaveSetting(settingData.SlicerConfigName, "0");
									// Now hide all of the settings that this control is associated with.
								}
								CallEventsOnSettingsChange(settingData);
							};
							leftToRightLayout.AddChild(checkBoxWidget);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.VECTOR2:
						{
							string[] xyValueStrings = sliceSettingValue.Split(',');
							if (xyValueStrings.Length != 2)
							{
								xyValueStrings = new string[] { "0", "0" };
							}
							double currentXValue = 0;
							double.TryParse(xyValueStrings[0], out currentXValue);
							MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
							xEditWidget.ToolTipText = settingData.HelpText;

							double currentYValue = 0;
							double.TryParse(xyValueStrings[1], out currentYValue);
							MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
							yEditWidget.ToolTipText = settingData.HelpText;

							xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString());
								CallEventsOnSettingsChange(settingData);
							};
							xEditWidget.SelectAllOnFocus = true;

							leftToRightLayout.AddChild(xEditWidget);
							leftToRightLayout.AddChild(new HorizontalSpacer());

							yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString());
								CallEventsOnSettingsChange(settingData);
							};
							yEditWidget.SelectAllOnFocus = true;
							leftToRightLayout.AddChild(yEditWidget);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.OFFSET2:
						{
							Vector2 offset = ActiveSliceSettings.Instance.GetOffset(extruderIndex);
							MHNumberEdit xEditWidget = new MHNumberEdit(offset.x, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
							xEditWidget.ToolTipText = settingData.HelpText;
							MHNumberEdit yEditWidget = new MHNumberEdit(offset.y, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
							yEditWidget.ToolTipText = settingData.HelpText;
							{
								xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
								{
									int extruderIndexLocal = extruderIndex;
									SaveCommaSeparatedIndexSetting(extruderIndexLocal, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString());
									CallEventsOnSettingsChange(settingData);
								};
								xEditWidget.SelectAllOnFocus = true;
								leftToRightLayout.AddChild(xEditWidget);
								leftToRightLayout.AddChild(new HorizontalSpacer());
							}
							{
								yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
								{
									int extruderIndexLocal = extruderIndex;
									SaveCommaSeparatedIndexSetting(extruderIndexLocal, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString());
									CallEventsOnSettingsChange(settingData);
								};
								yEditWidget.SelectAllOnFocus = true;
								leftToRightLayout.AddChild(yEditWidget);
							}
						}
						break;

					default:
						TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
						missingSetting.TextColor = ActiveTheme.Instance.PrimaryTextColor;
						missingSetting.BackgroundColor = RGBA_Bytes.Red;
						leftToRightLayout.AddChild(missingSetting);
						break;
				}
			}
			else // the setting we think we are adding is not in the config.ini it may have been depricated
			{
				TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
				settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
				settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
				leftToRightLayout.AddChild(settingName);
				leftToRightLayout.BackgroundColor = RGBA_Bytes.Red;
			}

			container.HAnchor = HAnchor.ParentLeftRight;
			container.VAnchor = VAnchor.FitToChildren;

			container.AddChild(leftToRightLayout);

			if (addQualityOverlay || addMaterialOverlay)
			{
				SettingPresetOverlay overlay = new SettingPresetOverlay();
				overlay.HAnchor = HAnchor.ParentLeftRight;
				overlay.VAnchor = Agg.UI.VAnchor.ParentBottomTop;

				SettingPresetClick clickToEdit = new SettingPresetClick();
				clickToEdit.HAnchor = HAnchor.ParentLeftRight;
				clickToEdit.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
				clickToEdit.Visible = false;

				Button editButton = buttonFactory.Generate("Edit Preset".Localize().ToUpper());
				editButton.HAnchor = Agg.UI.HAnchor.ParentCenter;
				editButton.VAnchor = Agg.UI.VAnchor.ParentCenter;

				clickToEdit.AddChild(editButton);

				if (addQualityOverlay)
				{
					overlay.OverlayColor = qualityOverlayColor;
					clickToEdit.OverlayColor = qualityOverlayColor;
					editButton.Click += (sender, e) =>
					{
						if (ApplicationController.Instance.EditQualityPresetsWindow == null)
						{
							ApplicationController.Instance.EditQualityPresetsWindow = new SlicePresetsWindow(ReloadOptions, "Quality", "quality", false, ActivePrinterProfile.Instance.ActiveQualitySettingsID);
							ApplicationController.Instance.EditQualityPresetsWindow.Closed += (popupWindowSender, popupWindowSenderE) => { ApplicationController.Instance.EditQualityPresetsWindow = null; };
						}
						else
						{
							ApplicationController.Instance.EditQualityPresetsWindow.ChangeToSlicePresetFromID(ActivePrinterProfile.Instance.ActiveQualitySettingsID);
							ApplicationController.Instance.EditQualityPresetsWindow.BringToFront();
						}
					};
				}
				else if (addMaterialOverlay)
				{
					overlay.OverlayColor = materialOverlayColor;
					clickToEdit.OverlayColor = materialOverlayColor;
					editButton.Click += (sender, e) =>
					{
						if (ApplicationController.Instance.EditMaterialPresetsWindow == null)
						{
							ApplicationController.Instance.EditMaterialPresetsWindow = new SlicePresetsWindow(ReloadOptions, "Material", "material", false, ActivePrinterProfile.Instance.GetMaterialSetting(1));
							ApplicationController.Instance.EditMaterialPresetsWindow.Closed += (popupWindowSender, popupWindowSenderE) => { ApplicationController.Instance.EditMaterialPresetsWindow = null; };
						}
						else
						{
							ApplicationController.Instance.EditMaterialPresetsWindow.ChangeToSlicePresetFromID(ActivePrinterProfile.Instance.GetMaterialSetting(1));
							ApplicationController.Instance.EditMaterialPresetsWindow.BringToFront();
						}
					};
				}

				container.MouseEnterBounds += (sender, e) =>
				{
					UiThread.RunOnIdle(() =>
					{
						overlay.Visible = false;
						clickToEdit.Visible = true;
					});
				};

				container.MouseLeaveBounds += (sender, e) =>
				{
					UiThread.RunOnIdle(() =>
					{
						overlay.Visible = true;
						clickToEdit.Visible = false;
					});
				};

				container.AddChild(overlay);
				container.AddChild(clickToEdit);
			}

			return container;
		}
		private void AddLetterControls(FlowLayoutWidget buttonPanel)
		{
			textImageButtonFactory.FixedWidth = 44 * TextWidget.GlobalPointSizeScaleRatio;

			FlowLayoutWidget degreesContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
			degreesContainer.HAnchor = HAnchor.ParentLeftRight;
			degreesContainer.Padding = new BorderDouble(5);

			GuiWidget horizontalSpacer = new GuiWidget();
			horizontalSpacer.HAnchor = HAnchor.ParentLeftRight;

			TextWidget degreesLabel = new TextWidget("Degrees:".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor);
			degreesContainer.AddChild(degreesLabel);
			degreesContainer.AddChild(horizontalSpacer);

			MHNumberEdit degreesControl = new MHNumberEdit(45, pixelWidth: 40, allowNegatives: true, increment: 5, minValue: -360, maxValue: 360);
			degreesControl.VAnchor = Agg.UI.VAnchor.ParentTop;
			degreesContainer.AddChild(degreesControl);

			buttonPanel.AddChild(degreesContainer);

			FlowLayoutWidget rotateButtonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
			rotateButtonContainer.HAnchor = HAnchor.ParentLeftRight;

			buttonPanel.AddChild(rotateButtonContainer);

			buttonPanel.AddChild(generateHorizontalRule());
			textImageButtonFactory.FixedWidth = 0;
		}
        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 GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth)
        {
            GuiWidget        container         = new GuiWidget();
            FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget();

            bool addQualityOverlay  = false;
            bool addMaterialOverlay = false;

            RGBA_Bytes qualityOverlayColor  = new RGBA_Bytes(255, 255, 0, 40);
            RGBA_Bytes materialOverlayColor = new RGBA_Bytes(255, 127, 0, 40);

            if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
            {
                int intEditWidth        = 60;
                int doubleEditWidth     = 60;
                int vectorXYEditWidth   = 60;
                int multiLineEditHeight = 60;



                string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
                leftToRightLayout.Margin  = new BorderDouble(0, 2);
                leftToRightLayout.Padding = new BorderDouble(3);
                leftToRightLayout.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

                if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT)
                {
                    string convertedNewLines = settingData.PresentationName.Replace("\\n ", "\n");
                    convertedNewLines = convertedNewLines.Replace("\\n", "\n");
                    convertedNewLines = LocalizedString.Get(convertedNewLines);
                    TextWidget settingName = new TextWidget(convertedNewLines);
                    settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;

                    if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 3))
                    {
                        addMaterialOverlay = true;
                    }
                    else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2))
                    {
                        addQualityOverlay = true;
                    }

                    settingName.Width = minSettingNameWidth;
                    //settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                    leftToRightLayout.AddChild(settingName);
                }

                switch (settingData.DataEditType)
                {
                case OrganizerSettingsData.DataEditTypes.INT:
                {
                    int currentValue = 0;
                    int.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
                    intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(intEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.DOUBLE:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(doubleEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(doubleEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.OFFSET:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(doubleEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
                {
                    MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                    {
                        TextEditWidget textEditWidget = (TextEditWidget)sender;
                        string         text           = textEditWidget.Text;
                        text = text.Trim();
                        bool isPercent = text.Contains("%");
                        if (isPercent)
                        {
                            text = text.Substring(0, text.IndexOf("%"));
                        }
                        double result;
                        double.TryParse(text, out result);
                        text = result.ToString();
                        if (isPercent)
                        {
                            text += "%";
                        }
                        textEditWidget.Text = text;
                        SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
                    };

                    leftToRightLayout.AddChild(stringEdit);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
                {
                    CheckBox checkBoxWidget = new CheckBox("");
                    checkBoxWidget.VAnchor              = Agg.UI.VAnchor.ParentBottom;
                    checkBoxWidget.TextColor            = ActiveTheme.Instance.PrimaryTextColor;
                    checkBoxWidget.Checked              = (sliceSettingValue == "1");
                    checkBoxWidget.CheckedStateChanged += (sender, e) =>
                    {
                        if (((CheckBox)sender).Checked)
                        {
                            SaveSetting(settingData.SlicerConfigName, "1");
                        }
                        else
                        {
                            SaveSetting(settingData.SlicerConfigName, "0");
                        }
                    };
                    leftToRightLayout.AddChild(checkBoxWidget);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.STRING:
                {
                    MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); };
                    leftToRightLayout.AddChild(stringEdit);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
                {
                    string           convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
                    MHTextEditWidget stringEdit        = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); };
                    leftToRightLayout.AddChild(stringEdit);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.LIST:
                {
                    StyledDropDownList selectableOptions = new StyledDropDownList("None", maxHeight: 200);
                    selectableOptions.Margin = new BorderDouble();

                    string[] listItems = settingData.ExtraSettings.Split(',');
                    foreach (string listItem in listItems)
                    {
                        MenuItem newItem = selectableOptions.AddItem(listItem);
                        if (newItem.Text == sliceSettingValue)
                        {
                            selectableOptions.SelectedLabel = sliceSettingValue;
                        }

                        newItem.Selected += (sender, e) =>
                        {
                            MenuItem menuItem = ((MenuItem)sender);
                            SaveSetting(settingData.SlicerConfigName, menuItem.Text);
                        };
                    }
                    leftToRightLayout.AddChild(selectableOptions);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.VECTOR2:
                {
                    string[] xyValueStrings = sliceSettingValue.Split(',');
                    if (xyValueStrings.Length != 2)
                    {
                        xyValueStrings = new string[] { "0", "0" };
                    }
                    double currentXValue = 0;
                    double.TryParse(xyValueStrings[0], out currentXValue);
                    MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                    double currentYValue = 0;
                    double.TryParse(xyValueStrings[1], out currentYValue);
                    MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                    {
                        xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(xEditWidget);
                        TextWidget xText = new TextWidget("x");
                        xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        xText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(xText);
                    }
                    {
                        yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(yEditWidget);
                        TextWidget yText = new TextWidget("y");
                        yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        yText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(yText);
                    }
                }
                break;

                case OrganizerSettingsData.DataEditTypes.OFFSET2:
                {
                    string[] xyValueStrings = sliceSettingValue.Split('x');
                    if (xyValueStrings.Length != 2)
                    {
                        xyValueStrings = new string[] { "0", "0" };
                    }
                    double currentXValue = 0;
                    double.TryParse(xyValueStrings[0], out currentXValue);
                    MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                    double currentYValue = 0;
                    double.TryParse(xyValueStrings[1], out currentYValue);
                    MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                    {
                        xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(xEditWidget);
                        TextWidget xText = new TextWidget("x");
                        xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        xText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(xText);
                    }
                    {
                        yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(yEditWidget);
                        TextWidget yText = new TextWidget("y");
                        yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        yText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(yText);
                    }
                }
                break;

                default:
                    TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
                    missingSetting.TextColor       = ActiveTheme.Instance.PrimaryTextColor;
                    missingSetting.BackgroundColor = RGBA_Bytes.Red;
                    leftToRightLayout.AddChild(missingSetting);
                    break;
                }
            }
            else // the setting we think we are adding is not in the config.ini it may have been depricated
            {
                TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
                settingName.TextColor   = ActiveTheme.Instance.PrimaryTextColor;
                settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                leftToRightLayout.AddChild(settingName);
                leftToRightLayout.BackgroundColor = RGBA_Bytes.Red;
            }

            container.HAnchor = HAnchor.ParentLeftRight;
            container.VAnchor = VAnchor.FitToChildren;

            container.AddChild(leftToRightLayout);

            if (addQualityOverlay || addMaterialOverlay)
            {
                SettingPresetOverlay overlay = new SettingPresetOverlay();
                overlay.HAnchor = HAnchor.ParentLeftRight;
                overlay.VAnchor = Agg.UI.VAnchor.ParentBottomTop;

                SettingPresetClick clickToEdit = new SettingPresetClick();
                clickToEdit.HAnchor = HAnchor.ParentLeftRight;
                clickToEdit.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
                clickToEdit.Visible = false;

                Button editButton = buttonFactory.Generate("Edit Preset".Localize().ToUpper());
                editButton.HAnchor = Agg.UI.HAnchor.ParentCenter;
                editButton.VAnchor = Agg.UI.VAnchor.ParentCenter;

                clickToEdit.AddChild(editButton);

                if (addQualityOverlay)
                {
                    overlay.OverlayColor     = qualityOverlayColor;
                    clickToEdit.OverlayColor = qualityOverlayColor;
                    editButton.Click        += (sender, e) =>
                    {
                        if (ApplicationWidget.Instance.EditSlicePresetsWindow == null)
                        {
                            ApplicationWidget.Instance.EditSlicePresetsWindow         = new SlicePresetsWindow(ReloadOptions, "Quality", "quality", false, ActivePrinterProfile.Instance.ActiveQualitySettingsID);
                            ApplicationWidget.Instance.EditSlicePresetsWindow.Closed += (popupWindowSender, popupWindowSenderE) => { ApplicationWidget.Instance.EditSlicePresetsWindow = null; };
                        }
                        else
                        {
                            ApplicationWidget.Instance.EditSlicePresetsWindow.ChangeToSlicePresetFromID(ActivePrinterProfile.Instance.ActiveQualitySettingsID);
                            ApplicationWidget.Instance.EditSlicePresetsWindow.BringToFront();
                        }
                    };
                }
                else if (addMaterialOverlay)
                {
                    overlay.OverlayColor     = materialOverlayColor;
                    clickToEdit.OverlayColor = materialOverlayColor;
                    editButton.Click        += (sender, e) =>
                    {
                        if (ApplicationWidget.Instance.EditSlicePresetsWindow == null)
                        {
                            ApplicationWidget.Instance.EditSlicePresetsWindow         = new SlicePresetsWindow(ReloadOptions, "Material", "material", false, ActivePrinterProfile.Instance.GetMaterialSetting(1));
                            ApplicationWidget.Instance.EditSlicePresetsWindow.Closed += (popupWindowSender, popupWindowSenderE) => { ApplicationWidget.Instance.EditSlicePresetsWindow = null; };
                        }
                        else
                        {
                            ApplicationWidget.Instance.EditSlicePresetsWindow.ChangeToSlicePresetFromID(ActivePrinterProfile.Instance.GetMaterialSetting(1));
                            ApplicationWidget.Instance.EditSlicePresetsWindow.BringToFront();
                        }
                    };
                }

                container.MouseEnterBounds += (sender, e) =>
                {
                    UiThread.RunOnIdle((state) =>
                    {
                        overlay.Visible     = false;
                        clickToEdit.Visible = true;
                    });
                };

                container.MouseLeaveBounds += (sender, e) =>
                {
                    UiThread.RunOnIdle((state) =>
                    {
                        overlay.Visible     = true;
                        clickToEdit.Visible = false;
                    });
                };

                container.AddChild(overlay);
                container.AddChild(clickToEdit);
            }



            return(container);
        }
        private GuiWidget Create3FieldSet(string label,
            string field1Label, ref MHNumberEdit field1,
            string field2Label, ref MHNumberEdit field2,
            string field3Label, ref MHNumberEdit field3)
        {
            MHNumberEdit none = null;

            return Create4FieldSet(label,
            field1Label, ref field1,
            field2Label, ref field2,
            field3Label, ref field3,
            null, ref none);
        }
        private GuiWidget Create4FieldSet(string label,
            string field1Label, ref MHNumberEdit field1,
            string field2Label, ref MHNumberEdit field2,
            string field3Label, ref MHNumberEdit field3,
            string field4Label, ref MHNumberEdit field4)
        {
            FlowLayoutWidget row = new FlowLayoutWidget();
            row.Margin = new BorderDouble(3);
            row.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

            TextWidget labelWidget = new TextWidget(LocalizedString.Get(label), textColor: ActiveTheme.Instance.PrimaryTextColor);
            labelWidget.VAnchor = VAnchor.ParentCenter;
            maxWidthOfLeftStuff = Math.Max(maxWidthOfLeftStuff, labelWidget.Width);
            GuiWidget holder = new GuiWidget(labelWidget.Width, labelWidget.Height);
            holder.Margin = new BorderDouble(3, 0);
            holder.AddChild(labelWidget);
            leftStuffToSize.Add(holder);
            row.AddChild(holder);

            {
                row.AddChild(CreateTextField(field1Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field1);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            if (field2Label != null)
            {
                row.AddChild(CreateTextField(field2Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field2);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            if (field3Label != null)
            {
                row.AddChild(CreateTextField(field3Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field3);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            if (field4Label != null)
            {
                row.AddChild(CreateTextField(field4Label));
                GuiWidget nextTabIndex = CreateMHNumEdit(ref field4);
                nextTabIndex.TabIndex = GetNextTabIndex();
                row.AddChild(nextTabIndex);
            }

            return row;
        }
		private FlowLayoutWidget GetSettingsRow(OrganizerSettingsData settingData, string sliceSettingValue = null)
		{
			FlowLayoutWidget container = new FlowLayoutWidget();
			container.HAnchor = HAnchor.ParentLeftRight;

			double minSettingNameWidth = 400;

			if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
			{
				int intEditWidth = 60;
				int doubleEditWidth = 60;
				int vectorXYEditWidth = 60;
				int multiLineEditHeight = 60;

				//Get the current value as a default value
				if (sliceSettingValue == null)
				{
					sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
				}

				//Get the presentation name from the SettingNameLookup
				TextWidget settingName = new TextWidget(SettingNameLookup[settingData.SlicerConfigName], pointSize: 10);
				settingName.AutoExpandBoundsToText = false;
				settingName.EllipsisIfClipped = true;
				settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
				settingName.VAnchor = Agg.UI.VAnchor.ParentCenter;
				settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.Height);
				settingName.Width = minSettingNameWidth;

				container.AddChild(settingName);

				switch (settingData.DataEditType)
				{
					case OrganizerSettingsData.DataEditTypes.INT:
						{
							int currentValue = 0;
							int.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
							intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
							container.AddChild(intEditWidget);
							container.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.DOUBLE:
						{
							double currentValue = 0;
							double.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
							container.AddChild(doubleEditWidget);
							container.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
						{
							double currentValue = 0;
							double.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
							container.AddChild(doubleEditWidget);
							container.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.OFFSET:
						{
							double currentValue = 0;
							double.TryParse(sliceSettingValue, out currentValue);
							MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
							container.AddChild(doubleEditWidget);
							container.AddChild(getSettingInfoData(settingData));
						}
						break;

					case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++);
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								TextEditWidget textEditWidget = (TextEditWidget)sender;
								string text = textEditWidget.Text;
								text = text.Trim();
								bool isPercent = text.Contains("%");
								if (isPercent)
								{
									text = text.Substring(0, text.IndexOf("%"));
								}
								double result;
								double.TryParse(text, out result);
								text = result.ToString();
								if (isPercent)
								{
									text += "%";
								}
								textEditWidget.Text = text;
								SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
							};
							stringEdit.SelectAllOnFocus = true;

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select evrything up to the % (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int percentIndex = textEditWidget.Text.IndexOf("%");
								if (percentIndex != -1)
								{
									textEditWidget.SetSelection(0, percentIndex - 1);
								}
							};

							content.AddChild(stringEdit);
							content.AddChild(getSettingInfoData(settingData));

							container.AddChild(content);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.INT_OR_MM:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++);
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								TextEditWidget textEditWidget = (TextEditWidget)sender;
								string text = textEditWidget.Text;
								text = text.Trim();
								bool isMm = text.Contains("mm");
								if (isMm)
								{
									text = text.Substring(0, text.IndexOf("mm"));
								}
								double result;
								double.TryParse(text, out result);
								text = result.ToString();
								if (isMm)
								{
									text += "mm";
								}
								else
								{
									result = (int)result;
									text = result.ToString();
								}
								textEditWidget.Text = text;
								SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
							};
							stringEdit.SelectAllOnFocus = true;

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select evrything up to the mm (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int mMIndex = textEditWidget.Text.IndexOf("mm");
								if (mMIndex != -1)
								{
									textEditWidget.SetSelection(0, mMIndex - 1);
								}
							};

							content.AddChild(stringEdit);
							content.AddChild(getSettingInfoData(settingData));

							container.AddChild(content);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
						{
							CheckBox checkBoxWidget = new CheckBox("");
							checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
							checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
							checkBoxWidget.Checked = (sliceSettingValue == "1");
							checkBoxWidget.CheckedStateChanged += (sender, e) =>
							{
								if (((CheckBox)sender).Checked)
								{
									SaveSetting(settingData.SlicerConfigName, "1");
								}
								else
								{
									SaveSetting(settingData.SlicerConfigName, "0");
								}
							};
							container.AddChild(checkBoxWidget);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.STRING:
						{
							MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); };
							container.AddChild(stringEdit);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
						{
							string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
							MHTextEditWidget stringEdit = new MHTextEditWidget(convertedNewLines, pointSize: 10, pixelWidth: 280, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); };
							container.AddChild(stringEdit);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.LIST:
						{
							StyledDropDownList selectableOptions = new StyledDropDownList("None", Direction.Down);
							selectableOptions.Margin = new BorderDouble();

							string[] listItems = settingData.ExtraSettings.Split(',');
							foreach (string listItem in listItems)
							{
								MenuItem newItem = selectableOptions.AddItem(listItem);
								if (newItem.Text == sliceSettingValue)
								{
									selectableOptions.SelectedLabel = sliceSettingValue;
								}

								newItem.Selected += (sender, e) =>
								{
									MenuItem menuItem = ((MenuItem)sender);
									SaveSetting(settingData.SlicerConfigName, menuItem.Text);
								};
							}
							container.AddChild(selectableOptions);
						}
						break;

					case OrganizerSettingsData.DataEditTypes.HARDWARE_PRESENT:
						// this is not editable for a detail setting (quality or material)
						break;

					case OrganizerSettingsData.DataEditTypes.VECTOR2:
						{
							string[] xyValueStrings = sliceSettingValue.Split(',');
							if (xyValueStrings.Length != 2)
							{
								xyValueStrings = new string[] { "0", "0" };
							}
							double currentXValue = 0;
							double.TryParse(xyValueStrings[0], out currentXValue);
							MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

							double currentYValue = 0;
							double.TryParse(xyValueStrings[1], out currentYValue);
							MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
							{
								xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
								container.AddChild(xEditWidget);
								TextWidget xText = new TextWidget("x");
								xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
								xText.Margin = new BorderDouble(5, 0);
								container.AddChild(xText);
							}
							{
								yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
								container.AddChild(yEditWidget);
								TextWidget yText = new TextWidget("y");
								yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
								yText.Margin = new BorderDouble(5, 0);
								container.AddChild(yText);
							}
						}
						break;

					case OrganizerSettingsData.DataEditTypes.OFFSET2:
						{
							string[] xyValueStrings = sliceSettingValue.Split('x');
							if (xyValueStrings.Length != 2)
							{
								xyValueStrings = new string[] { "0", "0" };
							}
							double currentXValue = 0;
							double.TryParse(xyValueStrings[0], out currentXValue);
							MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

							double currentYValue = 0;
							double.TryParse(xyValueStrings[1], out currentYValue);
							MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
							{
								xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
								container.AddChild(xEditWidget);
								TextWidget xText = new TextWidget("x");
								xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
								xText.Margin = new BorderDouble(5, 0);
								container.AddChild(xText);
							}
							{
								yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
								container.AddChild(yEditWidget);
								TextWidget yText = new TextWidget("y");
								yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
								yText.Margin = new BorderDouble(5, 0);
								container.AddChild(yText);
							}
						}
						break;

					default:
						TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
						missingSetting.TextColor = ActiveTheme.Instance.PrimaryTextColor;
						missingSetting.BackgroundColor = RGBA_Bytes.Red;
						container.AddChild(missingSetting);
						break;
				}
			}
			else // the setting we think we are adding is not in the config.ini it may have been depricated
			{
				TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
				settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
				settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
				container.AddChild(settingName);
				container.BackgroundColor = RGBA_Bytes.Red;
			}
			container.AddChild(new HorizontalSpacer());
			Button removeLink = linkButtonFactory.Generate("remove");
			removeLink.Click += (sender, e) =>
			{
				RemoveSetting(settingData.SlicerConfigName);
			};
			removeLink.VAnchor = Agg.UI.VAnchor.ParentCenter;
			container.AddChild(removeLink);

			return container;
		}
Example #27
0
		private void AddScaleControls(FlowLayoutWidget buttonPanel)
		{
			List<GuiWidget> scaleControls = new List<GuiWidget>();
			transformControls.Add("Scale", scaleControls);

			// Put in the scale ratio edit field
			{
				FlowLayoutWidget scaleRatioContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
				scaleRatioContainer.HAnchor = HAnchor.ParentLeftRight;
				scaleRatioContainer.Padding = new BorderDouble(5);

				string scaleRatioLabelText = "Ratio".Localize();
				string scaleRatioLabelTextFull = "{0}:".FormatWith(scaleRatioLabelText);
				TextWidget scaleRatioLabel = new TextWidget(scaleRatioLabelTextFull, textColor: ActiveTheme.Instance.PrimaryTextColor);
				scaleRatioLabel.Margin = new BorderDouble(0, 0, 3, 0);
				scaleRatioLabel.VAnchor = VAnchor.ParentCenter;
				scaleRatioContainer.AddChild(scaleRatioLabel);

				scaleRatioContainer.AddChild(new HorizontalSpacer());

				scaleRatioControl = new MHNumberEdit(1, pixelWidth: 50 * TextWidget.GlobalPointSizeScaleRatio, allowDecimals: true, increment: .05);
				scaleRatioControl.SelectAllOnFocus = true;
				scaleRatioControl.VAnchor = VAnchor.ParentCenter;
				scaleRatioContainer.AddChild(scaleRatioControl);
				scaleRatioControl.ActuallNumberEdit.KeyPressed += (sender, e) =>
				{
					SetApplyScaleVisability(this, null);
				};

				scaleRatioControl.ActuallNumberEdit.KeyDown += (sender, e) =>
				{
					SetApplyScaleVisability(this, null);
				};

				scaleRatioControl.ActuallNumberEdit.EnterPressed += (object sender, KeyEventArgs keyEvent) =>
				{
					ApplyScaleFromEditField();
				};

				scaleRatioContainer.AddChild(CreateScaleDropDownMenu());

				buttonPanel.AddChild(scaleRatioContainer);

				scaleControls.Add(scaleRatioControl);
			}

			applyScaleButton = whiteButtonFactory.Generate("Apply Scale".Localize(), centerText: true);
			applyScaleButton.Visible = false;
			applyScaleButton.Cursor = Cursors.Hand;
			buttonPanel.AddChild(applyScaleButton);

			scaleControls.Add(applyScaleButton);
			applyScaleButton.Click += (object sender, EventArgs mouseEvent) =>
			{
				ApplyScaleFromEditField();
			};

			// add in the dimensions
			{
				buttonPanel.AddChild(createAxisScalingControl("x", 0));
				buttonPanel.AddChild(createAxisScalingControl("y", 1));
				buttonPanel.AddChild(createAxisScalingControl("z", 2));

				uniformScale = new CheckBox("Lock Ratio".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor);
				uniformScale.Checked = true;

				FlowLayoutWidget leftToRight = new FlowLayoutWidget();
				leftToRight.Padding = new BorderDouble(5, 3);

				leftToRight.AddChild(uniformScale);
				buttonPanel.AddChild(leftToRight);
			}

			buttonPanel.AddChild(generateHorizontalRule());
		}
        private FlowLayoutWidget GetSettingsRow(OrganizerSettingsData settingData, string sliceSettingValue = null)
        {
            FlowLayoutWidget container = new FlowLayoutWidget();

            container.HAnchor = HAnchor.ParentLeftRight;

            double minSettingNameWidth = 400;

            if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
            {
                int intEditWidth        = 60;
                int doubleEditWidth     = 60;
                int vectorXYEditWidth   = 60;
                int multiLineEditHeight = 60;

                //Get the current value as a default value
                if (sliceSettingValue == null)
                {
                    sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
                }

                //Get the presentation name from the SettingNameLookup
                TextWidget settingName = new TextWidget(SettingNameLookup[settingData.SlicerConfigName], pointSize: 10);
                settingName.AutoExpandBoundsToText = false;
                settingName.EllipsisIfClipped      = true;
                settingName.TextColor   = ActiveTheme.Instance.PrimaryTextColor;
                settingName.VAnchor     = Agg.UI.VAnchor.ParentCenter;
                settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.Height);
                settingName.Width       = minSettingNameWidth;

                container.AddChild(settingName);


                switch (settingData.DataEditType)
                {
                case OrganizerSettingsData.DataEditTypes.INT:
                {
                    int currentValue = 0;
                    int.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
                    intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    container.AddChild(intEditWidget);
                    container.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.DOUBLE:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    container.AddChild(doubleEditWidget);
                    container.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    container.AddChild(doubleEditWidget);
                    container.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.OFFSET:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    container.AddChild(doubleEditWidget);
                    container.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
                {
                    MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                    {
                        TextEditWidget textEditWidget = (TextEditWidget)sender;
                        string         text           = textEditWidget.Text;
                        text = text.Trim();
                        bool isPercent = text.Contains("%");
                        if (isPercent)
                        {
                            text = text.Substring(0, text.IndexOf("%"));
                        }
                        double result;
                        double.TryParse(text, out result);
                        text = result.ToString();
                        if (isPercent)
                        {
                            text += "%";
                        }
                        textEditWidget.Text = text;
                        SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
                    };

                    container.AddChild(stringEdit);
                    container.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
                {
                    CheckBox checkBoxWidget = new CheckBox("");
                    checkBoxWidget.VAnchor              = Agg.UI.VAnchor.ParentBottom;
                    checkBoxWidget.TextColor            = ActiveTheme.Instance.PrimaryTextColor;
                    checkBoxWidget.Checked              = (sliceSettingValue == "1");
                    checkBoxWidget.CheckedStateChanged += (sender, e) =>
                    {
                        if (((CheckBox)sender).Checked)
                        {
                            SaveSetting(settingData.SlicerConfigName, "1");
                        }
                        else
                        {
                            SaveSetting(settingData.SlicerConfigName, "0");
                        }
                    };
                    container.AddChild(checkBoxWidget);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.STRING:
                {
                    MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); };
                    container.AddChild(stringEdit);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
                {
                    string           convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
                    MHTextEditWidget stringEdit        = new MHTextEditWidget(convertedNewLines, pointSize: 10, pixelWidth: 280, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); };
                    container.AddChild(stringEdit);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.LIST:
                {
                    StyledDropDownList selectableOptions = new StyledDropDownList("None", Direction.Down);
                    selectableOptions.Margin = new BorderDouble();

                    string[] listItems = settingData.ExtraSettings.Split(',');
                    foreach (string listItem in listItems)
                    {
                        MenuItem newItem = selectableOptions.AddItem(listItem);
                        if (newItem.Text == sliceSettingValue)
                        {
                            selectableOptions.SelectedLabel = sliceSettingValue;
                        }

                        newItem.Selected += (sender, e) =>
                        {
                            MenuItem menuItem = ((MenuItem)sender);
                            SaveSetting(settingData.SlicerConfigName, menuItem.Text);
                        };
                    }
                    container.AddChild(selectableOptions);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.VECTOR2:
                {
                    string[] xyValueStrings = sliceSettingValue.Split(',');
                    if (xyValueStrings.Length != 2)
                    {
                        xyValueStrings = new string[] { "0", "0" };
                    }
                    double currentXValue = 0;
                    double.TryParse(xyValueStrings[0], out currentXValue);
                    MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                    double currentYValue = 0;
                    double.TryParse(xyValueStrings[1], out currentYValue);
                    MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                    {
                        xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        container.AddChild(xEditWidget);
                        TextWidget xText = new TextWidget("x");
                        xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        xText.Margin    = new BorderDouble(5, 0);
                        container.AddChild(xText);
                    }
                    {
                        yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        container.AddChild(yEditWidget);
                        TextWidget yText = new TextWidget("y");
                        yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        yText.Margin    = new BorderDouble(5, 0);
                        container.AddChild(yText);
                    }
                }
                break;

                case OrganizerSettingsData.DataEditTypes.OFFSET2:
                {
                    string[] xyValueStrings = sliceSettingValue.Split('x');
                    if (xyValueStrings.Length != 2)
                    {
                        xyValueStrings = new string[] { "0", "0" };
                    }
                    double currentXValue = 0;
                    double.TryParse(xyValueStrings[0], out currentXValue);
                    MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                    double currentYValue = 0;
                    double.TryParse(xyValueStrings[1], out currentYValue);
                    MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                    {
                        xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        container.AddChild(xEditWidget);
                        TextWidget xText = new TextWidget("x");
                        xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        xText.Margin    = new BorderDouble(5, 0);
                        container.AddChild(xText);
                    }
                    {
                        yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        container.AddChild(yEditWidget);
                        TextWidget yText = new TextWidget("y");
                        yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        yText.Margin    = new BorderDouble(5, 0);
                        container.AddChild(yText);
                    }
                }
                break;

                default:
                    TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
                    missingSetting.TextColor       = ActiveTheme.Instance.PrimaryTextColor;
                    missingSetting.BackgroundColor = RGBA_Bytes.Red;
                    container.AddChild(missingSetting);
                    break;
                }
            }
            else // the setting we think we are adding is not in the config.ini it may have been depricated
            {
                TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
                settingName.TextColor   = ActiveTheme.Instance.PrimaryTextColor;
                settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                container.AddChild(settingName);
                container.BackgroundColor = RGBA_Bytes.Red;
            }
            container.AddChild(new HorizontalSpacer());
            Button removeLink = linkButtonFactory.Generate("remove");

            removeLink.Click += (sender, e) => {
                RemoveSetting(settingData.SlicerConfigName);
            };
            removeLink.VAnchor = Agg.UI.VAnchor.ParentCenter;
            container.AddChild(removeLink);

            return(container);
        }
Example #29
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;
        }
Example #30
0
        public InlineEditControl(string defaultSizeString = "-0000.00")
        {
            theme        = AppContext.Theme;
            base.Visible = false;

            double pointSize = 10;

            this.Padding = new BorderDouble(3);

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

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

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

            AddChild(numberDisplay);

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

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

            AddChild(numberEdit);

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

            runningInterval = UiThread.SetInterval(HideIfApplicable, .1);
        }
Example #31
0
        public FanControlsRow(int fanIndex, string fanName, PrinterConfig printer, ThemeConfig theme)
            : base(fanName, null, theme)
        {
            this.printer = printer;

            this.fanIndex = fanIndex;

            var timeSinceLastManualSend = new Stopwatch();

            var container = new FlowLayoutWidget();

            this.AddChild(container);
            this.BorderColor = Color.Transparent;

            fanSpeedDisplay = new MHNumberEdit(0, theme, minValue: 0, maxValue: 100, pixelWidth: 30 * GuiWidget.DeviceScale)
            {
                Value   = printer.Connection.GetFanSpeed0To255(fanIndex) * 100 / 255,
                VAnchor = VAnchor.Center | VAnchor.Fit,
                Margin  = new BorderDouble(right: 2),
            };
            fanSpeedDisplay.ActuallNumberEdit.EditComplete += (sender, e) =>
            {
                // limit the rate we can send this message to 2 per second so we don't get in a crazy toggle state.
                if (!timeSinceLastManualSend.IsRunning ||
                    timeSinceLastManualSend.ElapsedMilliseconds > 500)
                {
                    timeSinceLastManualSend.Restart();
                    printer.Connection.SetFanSpeed0To255(fanIndex, (int)(fanSpeedDisplay.Value * 255 / 100 + .5));
                }
            };
            container.AddChild(fanSpeedDisplay);

            container.Selectable = true;

            // put in %
            container.AddChild(new TextWidget("%", pointSize: 10, textColor: theme.TextColor)
            {
                VAnchor = VAnchor.Center
            });

            toggleSwitch = new RoundedToggleSwitch(theme)
            {
                Margin  = new BorderDouble(5, 0),
                VAnchor = VAnchor.Center
            };
            toggleSwitch.CheckedStateChanged += (s, e) =>
            {
                if (!timeSinceLastManualSend.IsRunning ||
                    timeSinceLastManualSend.ElapsedMilliseconds > 500)
                {
                    timeSinceLastManualSend.Restart();
                    if (toggleSwitch.Checked)
                    {
                        printer.Connection.SetFanSpeed0To255(fanIndex, 255);
                    }
                    else
                    {
                        printer.Connection.SetFanSpeed0To255(fanIndex, 0);
                    }
                }
            };
            container.AddChild(toggleSwitch);
            this.ActionWidget = toggleSwitch;

            // Register listeners
            printer.Connection.FanSpeedSet += Connection_FanSpeedSet;
        }
        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);
        }
        private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth)
        {
            FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget();

            if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
            {
                int intEditWidth        = 60;
                int doubleEditWidth     = 60;
                int vectorXYEditWidth   = 60;
                int multiLineEditHeight = 60;

                string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
                leftToRightLayout.Margin   = new BorderDouble(0, 5);
                leftToRightLayout.HAnchor |= Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;

                if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT)
                {
                    string convertedNewLines = settingData.PresentationName.Replace("\\n ", "\n");
                    convertedNewLines = convertedNewLines.Replace("\\n", "\n");
                    convertedNewLines = new LocalizedString(convertedNewLines).Translated;
                    TextWidget settingName = new TextWidget(convertedNewLines);
                    settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                    settingName.Width     = minSettingNameWidth;
                    //settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                    leftToRightLayout.AddChild(settingName);
                }

                switch (settingData.DataEditType)
                {
                case OrganizerSettingsData.DataEditTypes.INT:
                {
                    int currentValue = 0;
                    int.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
                    intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(intEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.DOUBLE:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(doubleEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.POSITVE_DOUBLE:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(doubleEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.OFFSET:
                {
                    double currentValue = 0;
                    double.TryParse(sliceSettingValue, out currentValue);
                    MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                    doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
                    leftToRightLayout.AddChild(doubleEditWidget);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
                {
                    MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                    {
                        TextEditWidget textEditWidget = (TextEditWidget)sender;
                        string         text           = textEditWidget.Text;
                        text = text.Trim();
                        bool isPercent = text.Contains("%");
                        if (isPercent)
                        {
                            text = text.Substring(0, text.IndexOf("%"));
                        }
                        double result;
                        double.TryParse(text, out result);
                        text = result.ToString();
                        if (isPercent)
                        {
                            text += "%";
                        }
                        textEditWidget.Text = text;
                        SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
                    };

                    leftToRightLayout.AddChild(stringEdit);
                    leftToRightLayout.AddChild(getSettingInfoData(settingData));
                }
                break;

                case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
                {
                    CheckBox checkBoxWidget = new CheckBox("");
                    checkBoxWidget.VAnchor              = Agg.UI.VAnchor.ParentBottom;
                    checkBoxWidget.TextColor            = ActiveTheme.Instance.PrimaryTextColor;
                    checkBoxWidget.Checked              = (sliceSettingValue == "1");
                    checkBoxWidget.CheckedStateChanged += (sender, e) =>
                    {
                        if (((CheckBox)sender).Checked)
                        {
                            SaveSetting(settingData.SlicerConfigName, "1");
                        }
                        else
                        {
                            SaveSetting(settingData.SlicerConfigName, "0");
                        }
                    };
                    leftToRightLayout.AddChild(checkBoxWidget);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.STRING:
                {
                    MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); };
                    leftToRightLayout.AddChild(stringEdit);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
                {
                    string           convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
                    MHTextEditWidget stringEdit        = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
                    stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); };
                    leftToRightLayout.AddChild(stringEdit);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.LIST:
                {
                    StyledDropDownList selectableOptions = new StyledDropDownList("None", Direction.Up);
                    selectableOptions.Margin = new BorderDouble();

                    string[] listItems = settingData.ExtraSettings.Split(',');
                    foreach (string listItem in listItems)
                    {
                        MenuItem newItem = selectableOptions.AddItem(listItem);
                        if (newItem.Text == sliceSettingValue)
                        {
                            selectableOptions.SelectedValue = sliceSettingValue;
                        }

                        newItem.Selected += (sender, e) =>
                        {
                            MenuItem menuItem = ((MenuItem)sender);
                            SaveSetting(settingData.SlicerConfigName, menuItem.Text);
                        };
                    }
                    leftToRightLayout.AddChild(selectableOptions);
                }
                break;

                case OrganizerSettingsData.DataEditTypes.VECTOR2:
                {
                    string[] xyValueStrings = sliceSettingValue.Split(',');
                    if (xyValueStrings.Length != 2)
                    {
                        xyValueStrings = new string[] { "0", "0" };
                    }
                    double currentXValue = 0;
                    double.TryParse(xyValueStrings[0], out currentXValue);
                    MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                    double currentYValue = 0;
                    double.TryParse(xyValueStrings[1], out currentYValue);
                    MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                    {
                        xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(xEditWidget);
                        TextWidget xText = new TextWidget("x");
                        xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        xText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(xText);
                    }
                    {
                        yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(yEditWidget);
                        TextWidget yText = new TextWidget("y");
                        yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        yText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(yText);
                    }
                }
                break;

                case OrganizerSettingsData.DataEditTypes.OFFSET2:
                {
                    string[] xyValueStrings = sliceSettingValue.Split('x');
                    if (xyValueStrings.Length != 2)
                    {
                        xyValueStrings = new string[] { "0", "0" };
                    }
                    double currentXValue = 0;
                    double.TryParse(xyValueStrings[0], out currentXValue);
                    MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                    double currentYValue = 0;
                    double.TryParse(xyValueStrings[1], out currentYValue);
                    MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                    {
                        xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(xEditWidget);
                        TextWidget xText = new TextWidget("x");
                        xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        xText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(xText);
                    }
                    {
                        yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
                        leftToRightLayout.AddChild(yEditWidget);
                        TextWidget yText = new TextWidget("y");
                        yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        yText.Margin    = new BorderDouble(5, 0);
                        leftToRightLayout.AddChild(yText);
                    }
                }
                break;

                default:
                    TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
                    missingSetting.TextColor       = ActiveTheme.Instance.PrimaryTextColor;
                    missingSetting.BackgroundColor = RGBA_Bytes.Red;
                    leftToRightLayout.AddChild(missingSetting);
                    break;
                }
            }
            else // the setting we think we are adding is not in the config.ini it may have been depricated
            {
                TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
                settingName.TextColor   = ActiveTheme.Instance.PrimaryTextColor;
                settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                leftToRightLayout.AddChild(settingName);
                leftToRightLayout.BackgroundColor = RGBA_Bytes.Red;
            }

            return(leftToRightLayout);
        }
 private GuiWidget CreateMHNumEdit(ref MHNumberEdit numberEditToCreate)
 {
     numberEditToCreate = new MHNumberEdit(0, pixelWidth: 80, allowNegatives: true, allowDecimals: true);
     numberEditToCreate.VAnchor = Agg.UI.VAnchor.ParentCenter;
     numberEditToCreate.Margin = new BorderDouble(3, 0);
     return numberEditToCreate;
 }
Example #35
0
        private void BuildGeneratorUI(ThemeConfig theme, FlowLayoutWidget mainContainer, string assetPath, string assetInfoPath)
        {
            // TODO: When an OpenSCAD script is added to the scene, we need to load the script and extract
            // the hard-coded variable values into the .Variables property for their default values or the
            // meta info file would need to include this hard-coded info

            // Load the OpenSCAD script

            // Load the script meta info

            // Walk the UI elements exposed by the meta info, constructing widgets bound to replacement data

            // When the build button is clicked, perform the replacements defined by the meta info and widgets.
            //  - Walk the meta info
            //  - Grab the values from the linked widgets
            //  - Load the script text
            //  - Perform the regex replaces against the script source
            //  - Execute the script, writing the results to a target file
            //  - Use the mesh loader to load the mesh
            //  - Replace the mesh in the scene with the newly generated content

            string   scriptText = File.ReadAllText(assetPath);
            MetaInfo info       = null;

            string json = File.ReadAllText(assetInfoPath);

            info = JsonConvert.DeserializeObject <MetaInfo>(json);

            if (info != null)
            {
                FlowLayoutWidget rowContainer;
                foreach (var field in info.Fields)
                {
                    string key = field.Key;

                    string latest;
                    this.item.Variables.TryGetValue(field.Key, out latest);

                    rowContainer = CreateSettingsRow(field.Title, theme);

                    if (field.Type == "text")
                    {
                        double val;
                        double.TryParse(latest, out val);

                        var editor = new MHNumberEdit(val, theme, pixelWidth: 50 * GuiWidget.DeviceScale, allowDecimals: true, increment: .05)
                        {
                            SelectAllOnFocus = true,
                            VAnchor          = VAnchor.Center
                        };
                        editor.ActuallNumberEdit.KeyPressed += (s, e) =>
                        {
                            var editWidget = s as NumberEdit;
                            this.item.Variables[key] = editWidget.Text;
                        };
                        rowContainer.AddChild(editor);
                    }
                    else if (field.Type == "bool")
                    {
                        var checkbox = new CheckBox("")
                        {
                            Checked = latest == "true"
                        };
                        checkbox.Click += (sender, e) =>
                        {
                            this.item.Variables[key] = ((CheckBox)sender).Checked.ToString().ToLower();
                        };
                        rowContainer.AddChild(checkbox);
                    }

                    mainContainer.AddChild(rowContainer);
                }
            }
            else
            {
                // TODO: some fallback ui?
            }
        }
		private static GuiWidget CreateSettingInfoUIControls(SliceSettingData settingData, List<PrinterSettingsLayer> layerCascade, PrinterSettingsLayer persistenceLayer,
			NamedSettingsLayers viewFilter,
			int extruderIndex, out bool addControl, ref int tabIndexForItem)
		{
			addControl = true;
			GuiWidget container = new GuiWidget();

			string sliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade);

			GuiWidget nameArea = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter);
			var dataArea = new FlowLayoutWidget();
			GuiWidget unitsArea = new GuiWidget(HAnchor.AbsolutePosition, VAnchor.FitToChildren | VAnchor.ParentCenter)
			{
				Width = settingData.ShowAsOverride ? 50 * GuiWidget.DeviceScale : 5,
			};
			GuiWidget restoreArea = new GuiWidget(HAnchor.AbsolutePosition, VAnchor.FitToChildren | VAnchor.ParentCenter)
			{
				Width = settingData.ShowAsOverride ? 30 * GuiWidget.DeviceScale : 0,
			};

			var settingsRow = new SettingsRow(layerCascade)
			{
				SettingsKey = settingData.SlicerConfigName,
				SettingsValue = sliceSettingValue,
			};
			settingsRow.AddChild(nameArea);
			settingsRow.AddChild(dataArea);
			settingsRow.AddChild(unitsArea);
			settingsRow.AddChild(restoreArea);
			settingsRow.Name = settingData.SlicerConfigName + " Edit Field";

			if (!PrinterSettings.KnownSettings.Contains(settingData.SlicerConfigName))
			{
				// the setting we think we are adding is not in the known settings it may have been deprecated
				TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in known settings", settingData.SlicerConfigName));
				settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
				//settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
				nameArea.AddChild(settingName);
				nameArea.BackgroundColor = RGBA_Bytes.Red;
			}
			else
			{
				int intEditWidth = (int)(60 * GuiWidget.DeviceScale + .5);
				int doubleEditWidth = (int)(60 * GuiWidget.DeviceScale + .5);
				int vectorXYEditWidth = (int)(60 * GuiWidget.DeviceScale + .5);
				int multiLineEditHeight = (int)(120 * GuiWidget.DeviceScale + .5);

				if (settingData.DataEditType != SliceSettingData.DataEditTypes.MULTI_LINE_TEXT)
				{
					var nameHolder = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter)
					{
						Padding = new BorderDouble(0, 0, 5, 0),
						HAnchor = HAnchor.ParentLeftRight,
					};

					nameHolder.AddChild(new WrappedTextWidget(settingData.PresentationName.Localize(), pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor));

					nameArea.AddChild(nameHolder);
				}

				switch (settingData.DataEditType)
				{
					case SliceSettingData.DataEditTypes.INT:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();
							int currentValue;
							int.TryParse(sliceSettingValue, out currentValue);

							var intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true,
								Name = settingData.PresentationName + " Edit",
							};
							intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString(), persistenceLayer);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							content.AddChild(intEditWidget);
							unitsArea.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, intEditWidget.ActuallNumberEdit.InternalTextEditWidget, layerCascade));
							}
							else
							{
								dataArea.AddChild(content);
							}

							settingsRow.ValueChanged = (text) =>
							{
								intEditWidget.Text = text;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.DOUBLE:
						{
							double currentValue;
							double.TryParse(sliceSettingValue, out currentValue);

							var doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString(), persistenceLayer);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							dataArea.AddChild(doubleEditWidget);
							unitsArea.AddChild(GetExtraSettingsWidget(settingData));

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2 = 0;
								double.TryParse(text, out currentValue2);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue2;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.POSITIVE_DOUBLE:
						{
							const string multiValuesAreDiffernt = "-";
							FlowLayoutWidget content = new FlowLayoutWidget();

							var doubleEditWidget = new MHNumberEdit(0, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								Name = settingData.PresentationName + " Textbox",
								SelectAllOnFocus = true
							};

							double currentValue;
							bool ChangesMultipleOtherSettings = settingData.SetSettingsOnChange.Count > 0;
							if (ChangesMultipleOtherSettings)
							{
								bool allTheSame = true;
								string setting = GetActiveValue(settingData.SetSettingsOnChange[0], layerCascade);
								for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++)
								{
									string nextSetting = GetActiveValue(settingData.SetSettingsOnChange[i], layerCascade);
									if (setting != nextSetting)
									{
										allTheSame = false;
										break;
									}
								}

								if (allTheSame && setting.EndsWith("mm"))
								{
									double.TryParse(setting.Substring(0, setting.Length - 2), out currentValue);
									doubleEditWidget.ActuallNumberEdit.Value = currentValue;
								}
								else
								{
									doubleEditWidget.ActuallNumberEdit.InternalNumberEdit.Text = multiValuesAreDiffernt;
								}
							}
							else // just set the setting normally
							{
								double.TryParse(sliceSettingValue, out currentValue);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue;
							}
							doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget.MarkAsStartingState();
							
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								NumberEdit numberEdit = (NumberEdit)sender;
								// If this setting sets other settings, then do that.
								if (ChangesMultipleOtherSettings
									&& numberEdit.Text != multiValuesAreDiffernt)
								{
									foreach (string setting in settingData.SetSettingsOnChange)
									{
										ActiveSliceSettings.Instance.SetValue(setting, numberEdit.Value.ToString() + "mm", persistenceLayer);
									}
								}

								// also always save to the local setting
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, numberEdit.Value.ToString(), persistenceLayer);
								settingsRow.UpdateStyle();
								OnSettingsChanged(settingData);
							};
							content.AddChild(doubleEditWidget);
							unitsArea.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget, layerCascade));
							}
							else
							{
								dataArea.AddChild(content);
							}

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2 = 0;
								double.TryParse(text, out currentValue2);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue2;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.OFFSET:
						{
							double currentValue;
							double.TryParse(sliceSettingValue, out currentValue);
							var doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true

							};
							doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString(), persistenceLayer);
								settingsRow.UpdateStyle();
								OnSettingsChanged(settingData);
							};
							dataArea.AddChild(doubleEditWidget);
							unitsArea.AddChild(GetExtraSettingsWidget(settingData));

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2;
								double.TryParse(text, out currentValue2);
								doubleEditWidget.ActuallNumberEdit.Value = currentValue2;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.DOUBLE_OR_PERCENT:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								var textEditWidget = (TextEditWidget)sender;
								string text = textEditWidget.Text.Trim();

								bool isPercent = text.Contains("%");
								if (isPercent)
								{
									text = text.Substring(0, text.IndexOf("%"));
								}
								double result;
								double.TryParse(text, out result);
								text = result.ToString();
								if (isPercent)
								{
									text += "%";
								}
								textEditWidget.Text = text;
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, textEditWidget.Text, persistenceLayer);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select everything up to the % (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int percentIndex = textEditWidget.Text.IndexOf("%");
								if (percentIndex != -1)
								{
									textEditWidget.SetSelection(0, percentIndex - 1);
								}
							};

							content.AddChild(stringEdit);
							unitsArea.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget, layerCascade));
							}
							else
							{
								dataArea.AddChild(content);
							}

							settingsRow.ValueChanged = (text) =>
							{
								stringEdit.Text = text;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.INT_OR_MM:
						{
							FlowLayoutWidget content = new FlowLayoutWidget();

							var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: doubleEditWidth - 2, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};

							string startingText = stringEdit.Text;
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								TextEditWidget textEditWidget = (TextEditWidget)sender;
								// only validate when we lose focus
								if (!textEditWidget.ContainsFocus)
								{
									string text = textEditWidget.Text;
									text = text.Trim();
									bool isMm = text.Contains("mm");
									if (isMm)
									{
										text = text.Substring(0, text.IndexOf("mm"));
									}
									double result;
									double.TryParse(text, out result);
									text = result.ToString();
									if (isMm)
									{
										text += "mm";
									}
									else
									{
										result = (int)result;
										text = result.ToString();
									}
									textEditWidget.Text = text;
									startingText = stringEdit.Text;
								}
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, textEditWidget.Text, persistenceLayer);
								settingsRow.UpdateStyle();
								OnSettingsChanged(settingData);

								// make sure we are still looking for the final validation before saving.
								if (textEditWidget.ContainsFocus)
								{
									UiThread.RunOnIdle(() =>
									{
										string currentText = textEditWidget.Text;
										int cursorIndex = textEditWidget.InternalTextEditWidget.CharIndexToInsertBefore;
										textEditWidget.Text = startingText;
										textEditWidget.InternalTextEditWidget.MarkAsStartingState();
										textEditWidget.Text = currentText;
										textEditWidget.InternalTextEditWidget.CharIndexToInsertBefore = cursorIndex;
									});
								}
							};

							stringEdit.ActualTextEditWidget.InternalTextEditWidget.AllSelected += (sender, e) =>
							{
								// select everything up to the mm (if present)
								InternalTextEditWidget textEditWidget = (InternalTextEditWidget)sender;
								int mMIndex = textEditWidget.Text.IndexOf("mm");
								if (mMIndex != -1)
								{
									textEditWidget.SetSelection(0, mMIndex - 1);
								}
							};

							content.AddChild(stringEdit);
							unitsArea.AddChild(GetExtraSettingsWidget(settingData));

							if (settingData.QuickMenuSettings.Count > 0)
							{
								dataArea.AddChild(CreateQuickMenu(settingData, persistenceLayer, content, stringEdit.ActualTextEditWidget.InternalTextEditWidget, layerCascade));
							}
							else
							{
								dataArea.AddChild(content);
							}

							settingsRow.ValueChanged = (text) =>
							{
								stringEdit.Text = text;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.CHECK_BOX:
						{
							var checkBoxWidget = new CheckBox("")
							{
								Name = settingData.PresentationName + " Checkbox",
								ToolTipText = settingData.HelpText,
								VAnchor = Agg.UI.VAnchor.ParentBottom,
								TextColor = ActiveTheme.Instance.PrimaryTextColor,
								Checked = sliceSettingValue == "1"
							};
							checkBoxWidget.Click += (sender, e) =>
							{
								bool isChecked = ((CheckBox)sender).Checked;
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, isChecked ? "1" : "0", persistenceLayer);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							dataArea.AddChild(checkBoxWidget);

							settingsRow.ValueChanged = (text) =>
							{
								checkBoxWidget.Checked = text == "1";
							};
						}
						break;

					case SliceSettingData.DataEditTypes.STRING:
						{
							var stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: settingData.ShowAsOverride ? 120 : 200, tabIndex: tabIndexForItem++)
							{
								Name = settingData.PresentationName + " Edit",
							};
							stringEdit.ToolTipText = settingData.HelpText;
							
							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((TextEditWidget)sender).Text, persistenceLayer);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							dataArea.AddChild(stringEdit);

							settingsRow.ValueChanged = (text) =>
							{
								stringEdit.Text = text;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.MULTI_LINE_TEXT:
						{
							string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
							var stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++, typeFace: ApplicationController.MonoSpacedTypeFace)
							{
								HAnchor = HAnchor.ParentLeftRight,
							};

							stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n"), persistenceLayer);
								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							nameArea.HAnchor = HAnchor.AbsolutePosition;
							nameArea.Width = 0;
							dataArea.AddChild(stringEdit);
							dataArea.HAnchor = HAnchor.ParentLeftRight;

							settingsRow.ValueChanged = (text) =>
							{
								stringEdit.Text = text.Replace("\\n", "\n");
							};
						}
						break;

					case SliceSettingData.DataEditTypes.COM_PORT:
						{
#if __ANDROID__
							addControl = false;
#endif
							// The COM_PORT control is unique in its approach to the SlicerConfigName. It uses "com_port" settings name to
							// bind to a context that will place it in the SliceSetting view but it binds its values to a machine
							// specific dictionary key that is not exposed in the UI. At runtime we lookup and store to '<machinename>_com_port'
							// ensuring that a single printer can be shared across different devices and we'll select the correct com port in each case
							var selectableOptions = new DropDownList("None", maxHeight: 200)
							{
								ToolTipText = settingData.HelpText,
								Margin = new BorderDouble(),
								Name = "Com Port Dropdown"
							};

							selectableOptions.Click += (s, e) =>
							{
								AddComMenuItems(settingData, persistenceLayer, settingsRow, selectableOptions);
							};

							AddComMenuItems(settingData, persistenceLayer, settingsRow, selectableOptions);

							dataArea.AddChild(selectableOptions);

							settingsRow.ValueChanged = (text) =>
							{
								// Lookup the machine specific comport value rather than the passed in text value
								selectableOptions.SelectedLabel = ActiveSliceSettings.Instance.Helpers.ComPort();
							};
						}
						break;

					case SliceSettingData.DataEditTypes.LIST:
						{
							var selectableOptions = new DropDownList("None", maxHeight: 200)
							{
								ToolTipText = settingData.HelpText,
								Margin = new BorderDouble()
							};

							foreach (string listItem in settingData.ExtraSettings.Split(','))
							{
								MenuItem newItem = selectableOptions.AddItem(listItem);
								if (newItem.Text == sliceSettingValue)
								{
									selectableOptions.SelectedLabel = sliceSettingValue;
								}

								newItem.Selected += (sender, e) =>
								{
									MenuItem menuItem = ((MenuItem)sender);
									ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, menuItem.Text, persistenceLayer);

									settingsRow.UpdateStyle();

									OnSettingsChanged(settingData);
								};
							}

							dataArea.AddChild(selectableOptions);

							settingsRow.ValueChanged = (text) =>
							{
								selectableOptions.SelectedLabel = text;
							};
						}
						break;

					case SliceSettingData.DataEditTypes.HARDWARE_PRESENT:
						{
							var checkBoxWidget = new CheckBox("")
							{
								Name = settingData.PresentationName + " Checkbox",
								ToolTipText = settingData.HelpText,
								VAnchor = Agg.UI.VAnchor.ParentBottom,
								TextColor = ActiveTheme.Instance.PrimaryTextColor,
								Checked = sliceSettingValue == "1"
							};

							checkBoxWidget.Click += (sender, e) =>
							{
								bool isChecked = ((CheckBox)sender).Checked;
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, isChecked ? "1" : "0", persistenceLayer);

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};

							dataArea.AddChild(checkBoxWidget);

							settingsRow.ValueChanged = (text) =>
							{
								checkBoxWidget.Checked = text == "1";
							};
						}
						break;

					case SliceSettingData.DataEditTypes.VECTOR2:
						{
							string[] xyValueStrings = sliceSettingValue.Split(',');
							if (xyValueStrings.Length != 2)
							{
								xyValueStrings = new string[] { "0", "0" };
							}

							double currentXValue;
							double.TryParse(xyValueStrings[0], out currentXValue);

							var xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true
							};

							double currentYValue;
							double.TryParse(xyValueStrings[1], out currentYValue);

							var yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true,
								Margin = new BorderDouble(20, 0, 0, 0),
							};

							xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer);

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							dataArea.AddChild(xEditWidget);
							dataArea.AddChild(new TextWidget("X", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
							{
								VAnchor = VAnchor.ParentCenter,
								Margin = new BorderDouble(5, 0),
							});

							yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer);

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							dataArea.AddChild(yEditWidget);
							var yLabel = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter)
							{
								Padding = new BorderDouble(5, 0),
								HAnchor = HAnchor.ParentLeftRight,
							};
							yLabel.AddChild(new WrappedTextWidget("Y", pointSize: 9, textColor: ActiveTheme.Instance.PrimaryTextColor));
							unitsArea.AddChild(yLabel);

							settingsRow.ValueChanged = (text) =>
							{
								double currentValue2;
								string[] xyValueStrings2 = text.Split(',');
								if (xyValueStrings2.Length != 2)
								{
									xyValueStrings2 = new string[] { "0", "0" };
								}

								double.TryParse(xyValueStrings2[0], out currentValue2);
								xEditWidget.ActuallNumberEdit.Value = currentValue2;

								double.TryParse(xyValueStrings2[1], out currentValue2);
								yEditWidget.ActuallNumberEdit.Value = currentValue2;
							};

						}
						break;

					case SliceSettingData.DataEditTypes.OFFSET2:
						{
							Vector2 offset = ActiveSliceSettings.Instance.Helpers.ExtruderOffset(extruderIndex);

							var xEditWidget = new MHNumberEdit(offset.x, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true,
							};

							var yEditWidget = new MHNumberEdit(offset.y, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++)
							{
								ToolTipText = settingData.HelpText,
								SelectAllOnFocus = true,
								Margin = new BorderDouble(20, 0, 0, 0),
							};

							xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								int extruderIndexLocal = extruderIndex;
								SaveCommaSeparatedIndexSetting(extruderIndexLocal, layerCascade, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer);

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							dataArea.AddChild(xEditWidget);
							dataArea.AddChild(new TextWidget("X", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor)
							{
								VAnchor = VAnchor.ParentCenter,
								Margin = new BorderDouble(5, 0),
							});

							yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
							{
								int extruderIndexLocal = extruderIndex;
								SaveCommaSeparatedIndexSetting(extruderIndexLocal, layerCascade, settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString(), persistenceLayer);

								settingsRow.UpdateStyle();

								OnSettingsChanged(settingData);
							};
							dataArea.AddChild(yEditWidget);
							var yLabel = new GuiWidget(HAnchor.ParentLeftRight, VAnchor.FitToChildren | VAnchor.ParentCenter)
							{
								Padding = new BorderDouble(5, 0),
								HAnchor = HAnchor.ParentLeftRight,
							};
							yLabel.AddChild(new WrappedTextWidget("Y", pointSize: 9, textColor: ActiveTheme.Instance.PrimaryTextColor));
							unitsArea.AddChild(yLabel);

							settingsRow.ValueChanged = (text) =>
							{
								Vector2 offset2 = ActiveSliceSettings.Instance.Helpers.ExtruderOffset(extruderIndex);
								xEditWidget.ActuallNumberEdit.Value = offset2.x;
								yEditWidget.ActuallNumberEdit.Value = offset2.y;
							};
						}
						break;

					default:
						var missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()))
						{
							TextColor = ActiveTheme.Instance.PrimaryTextColor,
							BackgroundColor = RGBA_Bytes.Red
						};
						dataArea.AddChild(missingSetting);
						break;
				}
			}

			container.HAnchor = HAnchor.ParentLeftRight;
			container.VAnchor = VAnchor.FitToChildren;

			Button restoreButton = null;
			if (settingData.ShowAsOverride)
			{
				restoreButton = new Button(new ButtonViewStates(new ImageWidget(restoreNormal), new ImageWidget(restoreHover), new ImageWidget(restorePressed), new ImageWidget(restoreNormal)))
				{
					Name = "Restore " + settingData.SlicerConfigName,
					VAnchor = VAnchor.ParentCenter,
					Margin = new BorderDouble(0, 0, 5, 0),
					ToolTipText = "Restore Default".Localize()
				};

				restoreButton.Click += (sender, e) =>
				{
					// Revert the user override 
					if (persistenceLayer == null)
					{
						ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName);
					}
					else
					{
						ActiveSliceSettings.Instance.ClearValue(settingData.SlicerConfigName, persistenceLayer);
					}

					settingsRow.RefreshValue(layerCascade);
					OnSettingsChanged(settingData);
				};

				restoreArea.AddChild(restoreButton);
			}

			container.AddChild(settingsRow);

			// Define the UpdateStyle implementation
			settingsRow.UpdateStyle = () =>
			{
				if (persistenceLayer.ContainsKey(settingData.SlicerConfigName))
				{
					switch (viewFilter)
					{
						case NamedSettingsLayers.All:
							if (settingData.ShowAsOverride)
							{
								settingsRow.BackgroundColor = userSettingBackgroundColor;
							}
							break;
						case NamedSettingsLayers.Material:
							settingsRow.BackgroundColor = materialSettingBackgroundColor;
							break;
						case NamedSettingsLayers.Quality:
							settingsRow.BackgroundColor = qualitySettingBackgroundColor;
							break;
					}

					if(restoreButton != null) restoreButton.Visible = true;
				}
				else if (layerCascade == null)
				{
					if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Material))
					{
						settingsRow.BackgroundColor = materialSettingBackgroundColor;
					}
					else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, NamedSettingsLayers.Quality))
					{
						settingsRow.BackgroundColor = qualitySettingBackgroundColor;
					}
					else
					{
						settingsRow.BackgroundColor = RGBA_Bytes.Transparent;
					}

					if (restoreButton != null) restoreButton.Visible = false;
				}
				else
				{
					if (restoreButton != null) restoreButton.Visible = false;
					settingsRow.BackgroundColor = RGBA_Bytes.Transparent;
				}
			};

			// Invoke the UpdateStyle implementation
			settingsRow.UpdateStyle();

			return container;
		}
Example #37
0
		private void AddRotateControls(FlowLayoutWidget buttonPanel)
		{
			List<GuiWidget> rotateControls = new List<GuiWidget>();
			transformControls.Add("Rotate".Localize(), rotateControls);

			textImageButtonFactory.FixedWidth = EditButtonHeight;

			FlowLayoutWidget degreesContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
			degreesContainer.HAnchor = HAnchor.ParentLeftRight;
			degreesContainer.Padding = new BorderDouble(5);

			string degreesLabelText = "Degrees".Localize();
			string degreesLabelTextFull = "{0}:".FormatWith(degreesLabelText);
			TextWidget degreesLabel = new TextWidget(degreesLabelText, textColor: ActiveTheme.Instance.PrimaryTextColor);
			degreesContainer.AddChild(degreesLabel);
			degreesContainer.AddChild(new HorizontalSpacer());

			MHNumberEdit degreesControl = new MHNumberEdit(45, pixelWidth: 40, allowNegatives: true, allowDecimals: true, increment: 5, minValue: -360, maxValue: 360);
			degreesControl.VAnchor = Agg.UI.VAnchor.ParentTop;
			degreesContainer.AddChild(degreesControl);
			rotateControls.Add(degreesControl);

			buttonPanel.AddChild(degreesContainer);

			FlowLayoutWidget rotateButtonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
			rotateButtonContainer.HAnchor = HAnchor.ParentLeftRight;

			Button rotateXButton = textImageButtonFactory.Generate("", "icon_rotate_32x32.png");
			TextWidget centeredX = new TextWidget("X", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor); centeredX.Margin = new BorderDouble(3, 0, 0, 0); centeredX.AnchorCenter(); rotateXButton.AddChild(centeredX);
			rotateButtonContainer.AddChild(rotateXButton);
			rotateControls.Add(rotateXButton);
			rotateXButton.Click += (object sender, EventArgs mouseEvent) =>
			{
				if (SelectedMeshGroupIndex != -1)
				{
					double radians = MathHelper.DegreesToRadians(degreesControl.ActuallNumberEdit.Value);
					// rotate it
					ScaleRotateTranslate rotated = SelectedMeshGroupTransform;
					rotated.rotation *= Matrix4X4.CreateRotationX(radians);
					SelectedMeshGroupTransform = rotated;

					PlatingHelper.PlaceMeshGroupOnBed(MeshGroups, MeshGroupTransforms, SelectedMeshGroupIndex);
					PartHasBeenChanged();
					Invalidate();
				}
			};

			Button rotateYButton = textImageButtonFactory.Generate("", "icon_rotate_32x32.png");
			TextWidget centeredY = new TextWidget("Y", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor); centeredY.Margin = new BorderDouble(3, 0, 0, 0); centeredY.AnchorCenter(); rotateYButton.AddChild(centeredY);
			rotateButtonContainer.AddChild(rotateYButton);
			rotateControls.Add(rotateYButton);
			rotateYButton.Click += (object sender, EventArgs mouseEvent) =>
			{
				if (SelectedMeshGroupIndex != -1)
				{
					double radians = MathHelper.DegreesToRadians(degreesControl.ActuallNumberEdit.Value);
					// rotate it
					ScaleRotateTranslate rotated = SelectedMeshGroupTransform;
					rotated.rotation *= Matrix4X4.CreateRotationY(radians);
					SelectedMeshGroupTransform = rotated;
					PlatingHelper.PlaceMeshGroupOnBed(MeshGroups, MeshGroupTransforms, SelectedMeshGroupIndex);
					saveButtons.Visible = true;
					Invalidate();
				}
			};

			Button rotateZButton = textImageButtonFactory.Generate("", "icon_rotate_32x32.png");
			TextWidget centeredZ = new TextWidget("Z", pointSize: 10, textColor: ActiveTheme.Instance.PrimaryTextColor); centeredZ.Margin = new BorderDouble(3, 0, 0, 0); centeredZ.AnchorCenter(); rotateZButton.AddChild(centeredZ);
			rotateButtonContainer.AddChild(rotateZButton);
			rotateControls.Add(rotateZButton);
			rotateZButton.Click += (object sender, EventArgs mouseEvent) =>
			{
				if (SelectedMeshGroupIndex != -1)
				{
					double radians = MathHelper.DegreesToRadians(degreesControl.ActuallNumberEdit.Value);
					// rotate it
					ScaleRotateTranslate rotated = SelectedMeshGroupTransform;
					rotated.rotation *= Matrix4X4.CreateRotationZ(radians);
					SelectedMeshGroupTransform = rotated;

					PlatingHelper.PlaceMeshGroupOnBed(MeshGroups, MeshGroupTransforms, SelectedMeshGroupIndex);
					PartHasBeenChanged();
					Invalidate();
				}
			};

			buttonPanel.AddChild(rotateButtonContainer);

			Button layFlatButton = whiteButtonFactory.Generate("Align to Bed".Localize(), centerText: true);
			layFlatButton.Cursor = Cursors.Hand;
			buttonPanel.AddChild(layFlatButton);

			layFlatButton.Click += (object sender, EventArgs mouseEvent) =>
			{
				if (SelectedMeshGroupIndex != -1)
				{
					MakeLowestFaceFlat(SelectedMeshGroupIndex);

					PartHasBeenChanged();
					Invalidate();
				}
			};

			buttonPanel.AddChild(generateHorizontalRule());
			textImageButtonFactory.FixedWidth = 0;
		}
Example #38
0
        private void AddScaleControls(FlowLayoutWidget buttonPanel)
        {
            List <GuiWidget> scaleControls = new List <GuiWidget>();

            // Put in the scale ratio edit field
            {
                FlowLayoutWidget scaleRatioContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
                scaleRatioContainer.HAnchor = HAnchor.ParentLeftRight;
                scaleRatioContainer.Padding = new BorderDouble(5);

                string     scaleRatioLabelText     = "Ratio".Localize();
                string     scaleRatioLabelTextFull = "{0}:".FormatWith(scaleRatioLabelText);
                TextWidget scaleRatioLabel         = new TextWidget(scaleRatioLabelTextFull, textColor: ActiveTheme.Instance.PrimaryTextColor);
                scaleRatioLabel.Margin  = new BorderDouble(0, 0, 3, 0);
                scaleRatioLabel.VAnchor = VAnchor.ParentCenter;
                scaleRatioContainer.AddChild(scaleRatioLabel);

                scaleRatioContainer.AddChild(new HorizontalSpacer());

                scaleRatioControl = new MHNumberEdit(1, pixelWidth: 50 * GuiWidget.DeviceScale, allowDecimals: true, increment: .05);
                scaleRatioControl.SelectAllOnFocus = true;
                scaleRatioControl.VAnchor          = VAnchor.ParentCenter;
                scaleRatioContainer.AddChild(scaleRatioControl);
                scaleRatioControl.ActuallNumberEdit.KeyPressed += (sender, e) =>
                {
                    OnSelectedTransformChanged(this, null);
                };

                scaleRatioControl.ActuallNumberEdit.KeyDown += (sender, e) =>
                {
                    OnSelectedTransformChanged(this, null);
                };

                scaleRatioControl.ActuallNumberEdit.EnterPressed += (object sender, KeyEventArgs keyEvent) =>
                {
                    ApplyScaleFromEditField();
                };

                scaleRatioContainer.AddChild(CreateScaleDropDownMenu());

                buttonPanel.AddChild(scaleRatioContainer);

                scaleControls.Add(scaleRatioControl);
            }

            applyScaleButton        = view3DWidget.WhiteButtonFactory.Generate("Apply Scale".Localize(), centerText: true);
            applyScaleButton.Cursor = Cursors.Hand;
            buttonPanel.AddChild(applyScaleButton);

            scaleControls.Add(applyScaleButton);
            applyScaleButton.Click += (object sender, EventArgs mouseEvent) =>
            {
                ApplyScaleFromEditField();
            };

            // add in the dimensions
            {
                buttonPanel.AddChild(CreateAxisScalingControl("x".ToUpper(), 0));
                buttonPanel.AddChild(CreateAxisScalingControl("y".ToUpper(), 1));
                buttonPanel.AddChild(CreateAxisScalingControl("z".ToUpper(), 2));

                uniformScale         = new CheckBox("Lock Ratio".Localize(), textColor: ActiveTheme.Instance.PrimaryTextColor);
                uniformScale.Checked = true;

                FlowLayoutWidget leftToRight = new FlowLayoutWidget();
                leftToRight.Padding = new BorderDouble(5, 3);

                leftToRight.AddChild(uniformScale);
                buttonPanel.AddChild(leftToRight);
            }

            buttonPanel.AddChild(view3DWidget.GenerateHorizontalRule());
        }
        public async Task DualExtrusionShowsCorrectHotendData()
        {
            await MatterControlUtilities.RunTest((testRunner) =>
            {
                using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
                {
                    testRunner.ClickByName("Features Tab");

                    // only 1 hotend and 1 extruder
                    Assert.IsTrue(testRunner.NameExists("Hotend 0"));
                    Assert.IsTrue(testRunner.NameExists("Bed TemperatureWidget"));
                    Assert.IsFalse(testRunner.NameExists("Hotend 1", .1));

                    testRunner.ClickByName("Hotend 0");

                    // assert the temp is set when we first open (it comes from the material)
                    MHNumberEdit tempWidget = testRunner.GetWidgetByName("Temperature Input", out _) as MHNumberEdit;
                    Assert.AreEqual(240, (int)tempWidget.Value);

                    // change material
                    var dropDownLists = testRunner.GetWidgetsByName("Hotend Preset Selector");
                    Assert.AreEqual(1, dropDownLists.Count, "There is one. The slice settings and the pop out.");
                    DropDownList materialSelector = dropDownLists[0].Widget as DropDownList;
                    Assert.AreEqual("", materialSelector.SelectedValue);

                    testRunner.ClickByName("Hotend Preset Selector");
                    testRunner.ClickByName("HIPS Menu");

                    // check the extruder count
                    var extrudeButtons = testRunner.GetWidgetsByName("Extrude Button");
                    Assert.AreEqual(1, extrudeButtons.Count, "There should be just one.");

                    int hipsGoalTemp = 220;

                    // assert the temp changed to a new temp
                    Assert.AreEqual(hipsGoalTemp, (int)tempWidget.Value, "The goal temp should match the material temp");
                    // and the printer heat is off
                    Assert.AreEqual(0, (int)emulator.CurrentExtruder.TargetTemperature, "The printer should report the heaters are off");

                    // turn on the heater
                    testRunner.ClickByName("Toggle Heater");
                    testRunner.Delay(1);

                    // assert the printer is heating
                    Assert.AreEqual(hipsGoalTemp, (int)emulator.CurrentExtruder.TargetTemperature, "The printer should report the expected goal temp");

                    // turn off the heater
                    testRunner.ClickByName("Toggle Heater");
                    testRunner.Delay(1);

                    // assert the printer is off
                    Assert.AreEqual(0, (int)emulator.CurrentExtruder.TargetTemperature, "The printer should report the heaters are off");

                    // type in a temp when the heating is off
                    testRunner.ClickByName("Temperature Input");
                    testRunner.Type("110");
                    testRunner.Type("{Enter}");
                    testRunner.Delay();

                    // assert the printer is off
                    Assert.AreEqual(0, (int)emulator.CurrentExtruder.TargetTemperature);

                    // and the heat toggle is showing on
                    ICheckbox heatToggle = testRunner.GetWidgetByName("Toggle Heater", out _) as ICheckbox;
                    Assert.IsFalse(heatToggle.Checked);

                    // turn it on
                    testRunner.ClickByName("Toggle Heater");
                    Assert.AreEqual(110, (int)emulator.CurrentExtruder.TargetTemperature);

                    // adjust when on
                    testRunner.ClickByName("Temperature Input");
                    testRunner.Type("104");
                    testRunner.Type("{Enter}");
                    testRunner.Delay();
                    Assert.AreEqual(104, (int)emulator.CurrentExtruder.TargetTemperature);

                    // type in 0 and have the heater turn off
                    testRunner.ClickByName("Temperature Input");
                    testRunner.Type("^a");
                    testRunner.Type("0");
                    testRunner.Type("{Enter}");
                    testRunner.Delay();

                    // assert the printer is not heating
                    Assert.AreEqual(0, (int)emulator.CurrentExtruder.TargetTemperature);
                    // and the on toggle is showing off
                    Assert.IsFalse(heatToggle.Checked);

                    // test that the load filament button works and closes correctly
                    testRunner.ClickByName("Temperature Input");
                    testRunner.Type("^a");
                    testRunner.Type("104");
                    testRunner.Type("{Enter}");
                    testRunner.Delay();
                    testRunner.ClickByName("Load Filament Button");
                    testRunner.ClickByName("Continue Button");
                    Assert.AreEqual(104, (int)emulator.CurrentExtruder.TargetTemperature);
                    testRunner.ClickByName("Cancel Wizard Button");
                    testRunner.Delay();
                    Assert.AreEqual(0, (int)emulator.CurrentExtruder.TargetTemperature);

                    testRunner.ClickByName("Hotend 0");
                    testRunner.ClickByName("Load Filament Button");
                    testRunner.ClickByName("Continue Button");
                    testRunner.Delay();
                    Assert.AreEqual(104, (int)emulator.CurrentExtruder.TargetTemperature);
                    var systemWindow = testRunner.GetWidgetByName("Cancel Wizard Button", out SystemWindow containingWindow);
                    // close the window through windows (alt-f4)
                    testRunner.Type("%{F4}");
                    Assert.AreEqual(0, (int)emulator.CurrentExtruder.TargetTemperature);

                    // Switch back to the general tab
                    testRunner.ClickByName("General Tab");

                    testRunner.SelectSliceSettingsField("Printer", SettingsKey.extruder_count);
                    testRunner.Type("2");
                    testRunner.Type("{Enter}");

                    // there are now 2 hotends and 2 extruders
                    Assert.IsTrue(testRunner.NameExists("Hotend 0"));
                    Assert.IsTrue(testRunner.NameExists("Hotend 1"));

                    SetCheckBoxSetting(testRunner, SettingsKey.extruders_share_temperature, true, true);

                    // there is one hotend and 2 extruders
                    Assert.IsTrue(testRunner.NameExists("Hotend 0"));
                    Assert.IsFalse(testRunner.NameExists("Hotend 1", .1));

                    testRunner.ClickByName("Hotend 0");

                    extrudeButtons = testRunner.GetWidgetsByName("Extrude Button");
                    Assert.AreEqual(2, extrudeButtons.Count, "Now there should be two.");
                }

                return(Task.CompletedTask);
            });
        }
        private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth)
        {
            GuiWidget container = new GuiWidget();
            FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget();

            bool addQualityOverlay = false;
            bool addMaterialOverlay = false;

            RGBA_Bytes qualityOverlayColor = new RGBA_Bytes(255, 255, 0, 40);
            RGBA_Bytes materialOverlayColor = new RGBA_Bytes(255, 127, 0, 40);


            if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
            {
                int intEditWidth = 60;
                int doubleEditWidth = 60;
                int vectorXYEditWidth = 60;
                int multiLineEditHeight = 60;

                string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
                leftToRightLayout.Margin = new BorderDouble(0, 2);
                leftToRightLayout.Padding = new BorderDouble(3);
                leftToRightLayout.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

                if (settingData.DataEditType != OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT)
                {
                    string convertedNewLines = settingData.PresentationName.Replace("\\n ", "\n");
                    convertedNewLines = convertedNewLines.Replace("\\n", "\n");
                    convertedNewLines = LocalizedString.Get(convertedNewLines);
                    TextWidget settingName = new TextWidget(convertedNewLines);
                    settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;

                    if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 3))
                    {
                        addMaterialOverlay = true;
                    }
                    else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2))
                    {
                        addQualityOverlay = true;
                    }

                    settingName.Width = minSettingNameWidth;
                    //settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                    leftToRightLayout.AddChild(settingName);
                }

                switch (settingData.DataEditType)
                {
                    case OrganizerSettingsData.DataEditTypes.INT:
                        {
                            int currentValue = 0;
                            int.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
                            intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                            {
                                SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(intEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.DOUBLE:
                        {
                            double currentValue = 0;
                            double.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                            doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                            {
                                SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(doubleEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
                        {
                            double currentValue = 0;
                            double.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                            doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                                {
                                    SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
                                    CallEventsOnSettingsChange(settingData);
                                };
                            leftToRightLayout.AddChild(doubleEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.OFFSET:
                        {
                            double currentValue = 0;
                            double.TryParse(sliceSettingValue, out currentValue);
                            MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
                            doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                            {
                                SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(doubleEditWidget);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
                        {
                            MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++);
                            stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                            {
                                TextEditWidget textEditWidget = (TextEditWidget)sender;
                                string text = textEditWidget.Text;
                                text = text.Trim();
                                bool isPercent = text.Contains("%");
                                if (isPercent)
                                {
                                    text = text.Substring(0, text.IndexOf("%"));
                                }
                                double result;
                                double.TryParse(text, out result);
                                text = result.ToString();
                                if (isPercent)
                                {
                                    text += "%";
                                }
                                textEditWidget.Text = text;
                                SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
                                CallEventsOnSettingsChange(settingData);
                            };

                            leftToRightLayout.AddChild(stringEdit);
                            leftToRightLayout.AddChild(getSettingInfoData(settingData));
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
                        {
                            CheckBox checkBoxWidget = new CheckBox("");
                            checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
                            checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                            checkBoxWidget.Checked = (sliceSettingValue == "1");
                            checkBoxWidget.CheckedStateChanged += (sender, e) =>
                            {
                                if (((CheckBox)sender).Checked)
                                {
                                    SaveSetting(settingData.SlicerConfigName, "1");
                                }
                                else
                                {
                                    SaveSetting(settingData.SlicerConfigName, "0");
                                }
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(checkBoxWidget);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.STRING:
                        {
                            MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
                            stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                            {
                                SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text);
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(stringEdit);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
                        {
                            string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
                            MHTextEditWidget stringEdit = new MHTextEditWidget(convertedNewLines, pixelWidth: 320, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
                            stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
                            {
                                SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n"));
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(stringEdit);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.LIST:
                        {
                            StyledDropDownList selectableOptions = new StyledDropDownList("None", maxHeight: 200);
                            selectableOptions.Margin = new BorderDouble();

                            string[] listItems = settingData.ExtraSettings.Split(',');

                            foreach (string listItem in listItems)
                            {
                                MenuItem newItem = selectableOptions.AddItem(listItem);
                                if (newItem.Text == sliceSettingValue)
                                {
                                    selectableOptions.SelectedLabel = sliceSettingValue;
                                }

                                newItem.Selected += (sender, e) =>
                                {
                                    MenuItem menuItem = ((MenuItem)sender);
                                    SaveSetting(settingData.SlicerConfigName, menuItem.Text);
                                    CallEventsOnSettingsChange(settingData);
                                };
                            }
                            leftToRightLayout.AddChild(selectableOptions);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.HARDWARE_PRESENT:
                        {
                            CheckBox checkBoxWidget = new CheckBox("");
                            checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
                            checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                            checkBoxWidget.Checked = (sliceSettingValue == "1");
                            checkBoxWidget.CheckedStateChanged += (sender, e) =>
                            {
                                if (((CheckBox)sender).Checked)
                                {
                                    SaveSetting(settingData.SlicerConfigName, "1");
                                    // Now show all of the settings that this control is associated with.
                                }
                                else
                                {
                                    SaveSetting(settingData.SlicerConfigName, "0");
                                    // Now hide all of the settings that this control is associated with.
                                }
                                CallEventsOnSettingsChange(settingData);
                            };
                            leftToRightLayout.AddChild(checkBoxWidget);
                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.VECTOR2:
                        {
                            string[] xyValueStrings = sliceSettingValue.Split(',');
                            if (xyValueStrings.Length != 2)
                            {
                                xyValueStrings = new string[] { "0", "0" };
                            }
                            double currentXValue = 0;
                            double.TryParse(xyValueStrings[0], out currentXValue);
                            MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                            double currentYValue = 0;
                            double.TryParse(xyValueStrings[1], out currentYValue);
                            MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                            xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                            {
                                SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString());
                                CallEventsOnSettingsChange(settingData);
                            };

                            leftToRightLayout.AddChild(xEditWidget);
                            TextWidget xText = new TextWidget("x");
                            xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                            xText.Margin = new BorderDouble(5, 0);
                            leftToRightLayout.AddChild(xText);

                            yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                                {
                                    SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString());
                                    CallEventsOnSettingsChange(settingData);
                                };
                            leftToRightLayout.AddChild(yEditWidget);
                            TextWidget yText = new TextWidget("y");
                            yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                            yText.Margin = new BorderDouble(5, 0);
                            leftToRightLayout.AddChild(yText);

                        }
                        break;

                    case OrganizerSettingsData.DataEditTypes.OFFSET2:
                        {
                            string[] xyValueStrings = sliceSettingValue.Split('x');
                            if (xyValueStrings.Length != 2)
                            {
                                xyValueStrings = new string[] { "0", "0" };
                            }
                            double currentXValue = 0;
                            double.TryParse(xyValueStrings[0], out currentXValue);
                            MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);

                            double currentYValue = 0;
                            double.TryParse(xyValueStrings[1], out currentYValue);
                            MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
                            {
                                xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                                {
                                    SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString());
                                    CallEventsOnSettingsChange(settingData);
                                };
                                leftToRightLayout.AddChild(xEditWidget);
                                TextWidget xText = new TextWidget("x");
                                xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                                xText.Margin = new BorderDouble(5, 0);
                                leftToRightLayout.AddChild(xText);
                            }
                            {
                                yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) =>
                                {
                                    SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString());
                                    CallEventsOnSettingsChange(settingData);
                                };
                                leftToRightLayout.AddChild(yEditWidget);
                                TextWidget yText = new TextWidget("y");
                                yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                                yText.Margin = new BorderDouble(5, 0);
                                leftToRightLayout.AddChild(yText);
                            }
                        }
                        break;

                    default:
                        TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
                        missingSetting.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                        missingSetting.BackgroundColor = RGBA_Bytes.Red;
                        leftToRightLayout.AddChild(missingSetting);
                        break;
                }
            }
            else // the setting we think we are adding is not in the config.ini it may have been depricated
            {
                TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
                settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
                leftToRightLayout.AddChild(settingName);
                leftToRightLayout.BackgroundColor = RGBA_Bytes.Red;
            }

            container.HAnchor = HAnchor.ParentLeftRight;
            container.VAnchor = VAnchor.FitToChildren;

            container.AddChild(leftToRightLayout);

            if (addQualityOverlay || addMaterialOverlay)
            {
                SettingPresetOverlay overlay = new SettingPresetOverlay();
                overlay.HAnchor = HAnchor.ParentLeftRight;
                overlay.VAnchor = Agg.UI.VAnchor.ParentBottomTop;

                SettingPresetClick clickToEdit = new SettingPresetClick();
                clickToEdit.HAnchor = HAnchor.ParentLeftRight;
                clickToEdit.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
                clickToEdit.Visible = false;

                Button editButton = buttonFactory.Generate("Edit Preset".Localize().ToUpper());
                editButton.HAnchor = Agg.UI.HAnchor.ParentCenter;
                editButton.VAnchor = Agg.UI.VAnchor.ParentCenter;

                clickToEdit.AddChild(editButton);

                if (addQualityOverlay)
                {
                    overlay.OverlayColor = qualityOverlayColor;
                    clickToEdit.OverlayColor = qualityOverlayColor;
                    editButton.Click += (sender, e) =>
                    {
                        if (ApplicationWidget.Instance.EditQualityPresetsWindow == null)
                        {
                            ApplicationWidget.Instance.EditQualityPresetsWindow = new SlicePresetsWindow(ReloadOptions, "Quality", "quality", false, ActivePrinterProfile.Instance.ActiveQualitySettingsID);
                            ApplicationWidget.Instance.EditQualityPresetsWindow.Closed += (popupWindowSender, popupWindowSenderE) => { ApplicationWidget.Instance.EditQualityPresetsWindow = null; };
                        }
                        else
                        {
                            ApplicationWidget.Instance.EditQualityPresetsWindow.ChangeToSlicePresetFromID(ActivePrinterProfile.Instance.ActiveQualitySettingsID);
                            ApplicationWidget.Instance.EditQualityPresetsWindow.BringToFront();
                        }
                    };
                }
                else if (addMaterialOverlay)
                {
                    overlay.OverlayColor = materialOverlayColor;
                    clickToEdit.OverlayColor = materialOverlayColor;
                    editButton.Click += (sender, e) =>
                    {
                        if (ApplicationWidget.Instance.EditMaterialPresetsWindow == null)
                        {
                            ApplicationWidget.Instance.EditMaterialPresetsWindow = new SlicePresetsWindow(ReloadOptions, "Material", "material", false, ActivePrinterProfile.Instance.GetMaterialSetting(1));
                            ApplicationWidget.Instance.EditMaterialPresetsWindow.Closed += (popupWindowSender, popupWindowSenderE) => { ApplicationWidget.Instance.EditMaterialPresetsWindow = null; };
                        }
                        else
                        {
                            ApplicationWidget.Instance.EditMaterialPresetsWindow.ChangeToSlicePresetFromID(ActivePrinterProfile.Instance.GetMaterialSetting(1));
                            ApplicationWidget.Instance.EditMaterialPresetsWindow.BringToFront();
                        }
                    };
                }

                container.MouseEnterBounds += (sender, e) =>
                {
                    UiThread.RunOnIdle((state) =>
                    {
                        overlay.Visible = false;
                        clickToEdit.Visible = true;
                    });
                };

                container.MouseLeaveBounds += (sender, e) =>
                {
                    UiThread.RunOnIdle((state) =>
                    {
                        overlay.Visible = true;
                        clickToEdit.Visible = false;
                    });
                };

                container.AddChild(overlay);
                container.AddChild(clickToEdit);
            }



            return container;
        }