Example #1
0
		public MenuPage()
			: base("Menu Controls")
		{
			//GuiWidget.DebugBoundsUnderMouse = true;
			BackgroundColor = RGBA_Bytes.Green;
			lastAction = new TextWidget("Last Menu Action");
			lastAction.OriginRelativeParent = new Vector2(100, 250);
			AddChild(lastAction);

			Menu dropListMenu = new Menu(new TextWidget("gAction v"));
			dropListMenu.Name = "ListMenu Down";
			AddMenu(dropListMenu, "Walk");
			AddMenu(dropListMenu, "Jog");
			AddMenu(dropListMenu, "Run");
			dropListMenu.OriginRelativeParent = new Vector2(100, 200);
			AddChild(dropListMenu);

			Menu longMenue = new Menu(new TextWidget("very long"), maxHeight: 50);
			longMenue.Name = "ListMenu Down";
			for (int i = 0; i < 30; i++)
			{
				AddMenu(longMenue, "menu {0}".FormatWith(i));
			}
			longMenue.OriginRelativeParent = new Vector2(100, 300);
			AddChild(longMenue);

			Menu raiseListMenu = new Menu(new TextWidget("jAction ^"), Direction.Up);
			raiseListMenu.Name = "ListMenu Up";
			AddMenu(raiseListMenu, "Walk");
			AddMenu(raiseListMenu, "Jog");
			AddMenu(raiseListMenu, "Run");
			raiseListMenu.OriginRelativeParent = new Vector2(200, 200);
			AddChild(raiseListMenu);

			MenuBar mainMenu = new MenuBar();
			mainMenu.VAnchor = UI.VAnchor.ParentTop;

			PopupMenu popupMenu = new PopupMenu(new TextWidget("Simple Menu"));
			popupMenu.OriginRelativeParent = new Vector2(100, 100);
			//AddChild(popupMenu);

			DropDownList dropDownList = new DropDownList("- Select Something -", RGBA_Bytes.Black, RGBA_Bytes.Gray);

			dropDownList.BackgroundColor = RGBA_Bytes.Black;
			dropDownList.TextColor = RGBA_Bytes.White;

			dropDownList.MenuItemsPadding = new BorderDouble(13);
			dropDownList.MenuItemsBorderWidth = 3;
			dropDownList.MenuItemsBorderColor = RGBA_Bytes.Red;
			dropDownList.MenuItemsBackgroundColor = RGBA_Bytes.Blue;
			dropDownList.MenuItemsTextColor = RGBA_Bytes.White;
			dropDownList.MenuItemsTextHoverColor = RGBA_Bytes.Yellow;

			dropDownList.Name = "Drop Down List";
			dropDownList.AddItem("Item 1", "value1");
			dropDownList.AddItem("Item 2 long name");
			dropDownList.AddItem("Item 3 realy long name");
			dropDownList.OriginRelativeParent = new Vector2(300, 200);
			AddChild(dropDownList);
		}
		private void AddGridSnapSettings(GuiWidget widgetToAddTo)
		{
			FlowLayoutWidget container = new FlowLayoutWidget()
			{
				Margin = new BorderDouble(5, 0),
			};

			TextWidget snapGridLabel = new TextWidget("Snap Grid".Localize())
			{
				TextColor = ActiveTheme.Instance.PrimaryTextColor,
				VAnchor = VAnchor.ParentCenter,
				Margin = new BorderDouble(3, 0, 0, 0),
			};

			container.AddChild(snapGridLabel);

			DropDownList selectableOptions = new DropDownList("Custom", Direction.Up)
			{
				VAnchor = VAnchor.ParentCenter | VAnchor.FitToChildren,
			};

			Dictionary<double, string> snapSettings = new Dictionary<double, string>()
			{
				{ 0, "Off" },
				{ .1, "0.1" },
				{ .25, "0.25" },
				{ .5, "0.5" },
				{ 1, "1" },
				{ 2, "2" },
				{ 5, "5" },
			};

			foreach (KeyValuePair<double, string> snapSetting in snapSettings)
			{
				double valueLocal = snapSetting.Key;

				MenuItem newItem = selectableOptions.AddItem(snapSetting.Value);
				if (meshViewerWidget.SnapGridDistance == valueLocal)
				{
					selectableOptions.SelectedLabel = snapSetting.Value;
				}

				newItem.Selected += (sender, e) =>
				{
					meshViewerWidget.SnapGridDistance = snapSetting.Key;
				};
			}

			container.AddChild(selectableOptions);

			widgetToAddTo.AddChild(container);
		}
		private FlowLayoutWidget GetThumbnailRenderingControl()
		{
			FlowLayoutWidget buttonRow = new FlowLayoutWidget();
			buttonRow.HAnchor = HAnchor.ParentLeftRight;
			buttonRow.Margin = new BorderDouble(top: 4);

			TextWidget settingsLabel = new TextWidget("Thumbnail Rendering".Localize());
			settingsLabel.AutoExpandBoundsToText = true;
			settingsLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			settingsLabel.VAnchor = VAnchor.ParentTop;

			FlowLayoutWidget optionsContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
			optionsContainer.Margin = new BorderDouble(bottom: 6);

			DropDownList interfaceOptionsDropList = new DropDownList("Development", maxHeight: 200);
			interfaceOptionsDropList.HAnchor = HAnchor.ParentLeftRight;

			optionsContainer.AddChild(interfaceOptionsDropList);
			optionsContainer.Width = 200;

			interfaceOptionsDropList.AddItem("Flat".Localize(), "orthographic");
			interfaceOptionsDropList.AddItem("3D".Localize(), "raytraced");

			List<string> acceptableUpdateFeedTypeValues = new List<string>() { "orthographic", "raytraced" };
			string currentThumbnailRenderingMode = UserSettings.Instance.get(UserSettingsKey.ThumbnailRenderingMode);

			if (acceptableUpdateFeedTypeValues.IndexOf(currentThumbnailRenderingMode) == -1)
			{
#if __ANDROID__
					UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, "orthographic");
#else
					UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, "raytraced");
#endif
			}

			interfaceOptionsDropList.SelectedValue = UserSettings.Instance.get(UserSettingsKey.ThumbnailRenderingMode);
			interfaceOptionsDropList.SelectionChanged += (sender, e) =>
			{
				string thumbnailRenderingMode = ((DropDownList)sender).SelectedValue;
				if (thumbnailRenderingMode != UserSettings.Instance.get(UserSettingsKey.ThumbnailRenderingMode))
				{
					UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, thumbnailRenderingMode);

					// Ask if the user would like to rebuild all their thumbnails
					Action<bool> removeThumbnails = (bool shouldRebuildThumbnails) =>
					{
						if (shouldRebuildThumbnails)
						{
							string directoryToRemove = PartThumbnailWidget.ThumbnailPath();
							try
							{
								if (Directory.Exists(directoryToRemove))
								{
									Directory.Delete(directoryToRemove, true);
								}
							}
							catch (Exception)
							{
								GuiWidget.BreakInDebugger();
							}
						}

						ApplicationController.Instance.ReloadAll(null, null);
					};

					UiThread.RunOnIdle(() =>
					{
						StyledMessageBox.ShowMessageBox(removeThumbnails, rebuildThumbnailsMessage, rebuildThumbnailsTitle, StyledMessageBox.MessageType.YES_NO, "Rebuild".Localize());
					});
				}
			};

			buttonRow.AddChild(settingsLabel);
			buttonRow.AddChild(new HorizontalSpacer());
			buttonRow.AddChild(optionsContainer);
			return buttonRow;
		}
		private FlowLayoutWidget GetUpdateControl()
		{
			FlowLayoutWidget buttonRow = new FlowLayoutWidget();
			buttonRow.HAnchor = HAnchor.ParentLeftRight;
			buttonRow.Margin = new BorderDouble(top: 4);

			configureUpdateFeedButton = textImageButtonFactory.Generate("Configure".Localize().ToUpper());
			configureUpdateFeedButton.Margin = new BorderDouble(left: 6);
			configureUpdateFeedButton.VAnchor = VAnchor.ParentCenter;

			TextWidget settingsLabel = new TextWidget("Update Notification Feed".Localize());
			settingsLabel.AutoExpandBoundsToText = true;
			settingsLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			settingsLabel.VAnchor = VAnchor.ParentTop;

			FlowLayoutWidget optionsContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
			optionsContainer.Margin = new BorderDouble(bottom: 6);

			releaseOptionsDropList = new DropDownList("Development", maxHeight: 200);
			releaseOptionsDropList.HAnchor = HAnchor.ParentLeftRight;

			optionsContainer.AddChild(releaseOptionsDropList);
			optionsContainer.Width = 200;

			MenuItem releaseOptionsDropDownItem = releaseOptionsDropList.AddItem("Stable".Localize(), "release");
			releaseOptionsDropDownItem.Selected += new EventHandler(FixTabDot);

			MenuItem preReleaseDropDownItem = releaseOptionsDropList.AddItem("Beta".Localize(), "pre-release");
			preReleaseDropDownItem.Selected += new EventHandler(FixTabDot);

			MenuItem developmentDropDownItem = releaseOptionsDropList.AddItem("Alpha".Localize(), "development");
			developmentDropDownItem.Selected += new EventHandler(FixTabDot);

			List<string> acceptableUpdateFeedTypeValues = new List<string>() { "release", "pre-release", "development" };
			string currentUpdateFeedType = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);

			if (acceptableUpdateFeedTypeValues.IndexOf(currentUpdateFeedType) == -1)
			{
				UserSettings.Instance.set(UserSettingsKey.UpdateFeedType, "release");
			}

			releaseOptionsDropList.SelectedValue = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);
			releaseOptionsDropList.SelectionChanged += new EventHandler(ReleaseOptionsDropList_SelectionChanged);

			buttonRow.AddChild(settingsLabel);
			buttonRow.AddChild(new HorizontalSpacer());
			buttonRow.AddChild(optionsContainer);
			return buttonRow;
		}
		private FlowLayoutWidget GetModeControl()
		{
			FlowLayoutWidget buttonRow = new FlowLayoutWidget();
			buttonRow.HAnchor = HAnchor.ParentLeftRight;
			buttonRow.Margin = new BorderDouble(top: 4);

			TextWidget settingsLabel = new TextWidget("Interface Mode".Localize());
			settingsLabel.AutoExpandBoundsToText = true;
			settingsLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			settingsLabel.VAnchor = VAnchor.ParentTop;

			FlowLayoutWidget optionsContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
			optionsContainer.Margin = new BorderDouble(bottom: 6);

			DropDownList interfaceModeDropList = new DropDownList("Standard", maxHeight: 200);
			interfaceModeDropList.HAnchor = HAnchor.ParentLeftRight;

			optionsContainer.AddChild(interfaceModeDropList);
			optionsContainer.Width = 200;

			MenuItem standardModeDropDownItem = interfaceModeDropList.AddItem("Standard".Localize(), "True");
			MenuItem advancedModeDropDownItem = interfaceModeDropList.AddItem("Advanced".Localize(), "False");

			interfaceModeDropList.SelectedValue = UserSettings.Instance.Fields.IsSimpleMode.ToString();
			interfaceModeDropList.SelectionChanged += new EventHandler(InterfaceModeDropList_SelectionChanged);

			buttonRow.AddChild(settingsLabel);
			buttonRow.AddChild(new HorizontalSpacer());
			buttonRow.AddChild(optionsContainer);
			return buttonRow;
		}
		private FlowLayoutWidget GetDisplayControl()
		{
			FlowLayoutWidget buttonRow = new FlowLayoutWidget();
			buttonRow.HAnchor = HAnchor.ParentLeftRight;
			buttonRow.Margin = new BorderDouble(top: 4);

			TextWidget settingsLabel = new TextWidget("Display Mode".Localize());
			settingsLabel.AutoExpandBoundsToText = true;
			settingsLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			settingsLabel.VAnchor = VAnchor.ParentTop;

			Button displayControlRestartButton = textImageButtonFactory.Generate("Restart");
			displayControlRestartButton.VAnchor = Agg.UI.VAnchor.ParentCenter;
			displayControlRestartButton.Visible = false;
			displayControlRestartButton.Margin = new BorderDouble(right: 6);
			displayControlRestartButton.Click += (sender, e) =>
			{
				if (PrinterConnectionAndCommunication.Instance.PrinterIsPrinting)
				{
					StyledMessageBox.ShowMessageBox(null, cannotRestartWhilePrintIsActiveMessage, cannotRestartWhileActive);
				}
				else
				{
					RestartApplication();
				}
			};

			FlowLayoutWidget optionsContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
			optionsContainer.Margin = new BorderDouble(bottom: 6);

			DropDownList interfaceOptionsDropList = new DropDownList("Development", maxHeight: 200);
			interfaceOptionsDropList.HAnchor = HAnchor.ParentLeftRight;

			optionsContainer.AddChild(interfaceOptionsDropList);
			optionsContainer.Width = 200;

			MenuItem responsizeOptionsDropDownItem = interfaceOptionsDropList.AddItem("Normal".Localize(), "responsive");
			MenuItem touchscreenOptionsDropDownItem = interfaceOptionsDropList.AddItem("Touchscreen".Localize(), "touchscreen");

			List<string> acceptableUpdateFeedTypeValues = new List<string>() { "responsive", "touchscreen" };
			string currentDisplayModeType = UserSettings.Instance.get(UserSettingsKey.ApplicationDisplayMode);

			if (acceptableUpdateFeedTypeValues.IndexOf(currentDisplayModeType) == -1)
			{
				UserSettings.Instance.set(UserSettingsKey.ApplicationDisplayMode, "responsive");
			}

			interfaceOptionsDropList.SelectedValue = UserSettings.Instance.get(UserSettingsKey.ApplicationDisplayMode);
			interfaceOptionsDropList.SelectionChanged += (sender, e) =>
			{
				string releaseCode = ((DropDownList)sender).SelectedValue;
				if (releaseCode != UserSettings.Instance.get(UserSettingsKey.ApplicationDisplayMode))
				{
					UserSettings.Instance.set(UserSettingsKey.ApplicationDisplayMode, releaseCode);
					displayControlRestartButton.Visible = true;
				}
			};

			buttonRow.AddChild(settingsLabel);
			buttonRow.AddChild(new HorizontalSpacer());
			buttonRow.AddChild(displayControlRestartButton);
			buttonRow.AddChild(optionsContainer);
			return buttonRow;
		}
        public CheckForUpdateWindow()
            : base (540, 350)
        {
            linkButtonFactory.fontSize = 10;
            linkButtonFactory.textColor = ActiveTheme.Instance.SecondaryAccentColor;

            FlowLayoutWidget topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);
            topToBottom.AnchorAll();
            topToBottom.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            Padding = new BorderDouble(left: 5, right: 5);

            FlowLayoutWidget mainLabelContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
            mainLabelContainer.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
            mainLabelContainer.VAnchor = VAnchor.FitToChildren;
            mainLabelContainer.HAnchor = HAnchor.ParentLeftRight;
            
            FlowLayoutWidget currentFeedAndDropDownContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
            currentFeedAndDropDownContainer.VAnchor = VAnchor.FitToChildren;
            currentFeedAndDropDownContainer.HAnchor = HAnchor.ParentLeftRight;
            currentFeedAndDropDownContainer.Margin = new BorderDouble(0,5,0,0);
            currentFeedAndDropDownContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;

			TextWidget checkUpdateLabel = new TextWidget("Check for Update".Localize(), pointSize: 20);
			if (UpdateControlData.Instance.UpdateRequired)
			{
				checkUpdateLabel = new TextWidget("Update Required".Localize(), pointSize: 20);
			}

			checkUpdateLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
            checkUpdateLabel.Margin = new BorderDouble(2, 10, 10, 5);
            
            UpdateControlView updateStatusWidget = new UpdateControlView();
            
            String fullCurrentFeedLabel = "Update Channel".Localize();
            TextWidget feedLabel = new TextWidget(fullCurrentFeedLabel, pointSize: 12);
            feedLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
            feedLabel.VAnchor = VAnchor.ParentCenter;
            feedLabel.Margin = new BorderDouble(left: 5);

            releaseOptionsDropList = new DropDownList("Development", maxHeight: 200);
            releaseOptionsDropList.HAnchor = HAnchor.ParentLeftRight;

            MenuItem releaseOptionsDropDownItem = releaseOptionsDropList.AddItem("Stable".Localize(), "release");
            releaseOptionsDropDownItem.Selected += new EventHandler(FixTabDot);

            MenuItem preReleaseDropDownItem = releaseOptionsDropList.AddItem("Beta".Localize(), "pre-release");
            preReleaseDropDownItem.Selected += new EventHandler(FixTabDot);

            MenuItem developmentDropDownItem = releaseOptionsDropList.AddItem("Alpha".Localize(), "development");
            developmentDropDownItem.Selected += new EventHandler(FixTabDot);

            List<string> acceptableUpdateFeedTypeValues = new List<string>() { "release", "pre-release", "development" };
            string currentUpdateFeedType = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);

            if (acceptableUpdateFeedTypeValues.IndexOf(currentUpdateFeedType) == -1)
            {
                UserSettings.Instance.set(UserSettingsKey.UpdateFeedType, "release");
            }

            releaseOptionsDropList.SelectedValue = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);
            releaseOptionsDropList.SelectionChanged += new EventHandler(ReleaseOptionsDropList_SelectionChanged);

			string currentBuildNo = VersionInfo.Instance.BuildVersion;
			string currentBuildInfoLabel = String.Format("Current Build : {0}", currentBuildNo);
			currentBuildInfo = new TextWidget(currentBuildInfoLabel.Localize());
			currentBuildInfo.HAnchor = HAnchor.ParentLeftRight;
			currentBuildInfo.Margin = new BorderDouble(left: 5,bottom: 15, top: 20);
			currentBuildInfo.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			

            FlowLayoutWidget additionalInfoContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
            additionalInfoContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            additionalInfoContainer.HAnchor = HAnchor.ParentLeftRight;
            additionalInfoContainer.Padding = new BorderDouble(left: 6, top: 6);

            string aboutUpdateChannel = "Changing your update channel will change the version of MatterControl  \nthat you receive when updating:";
            updateChannelLabel = new TextWidget(aboutUpdateChannel);
            updateChannelLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
            updateChannelLabel.HAnchor = HAnchor.ParentLeftRight;
            updateChannelLabel.Margin = new BorderDouble(bottom: 20);
            additionalInfoContainer.AddChild(updateChannelLabel);
            
             
            string stableFeedInfoText = "Stable: The current release version of MatterControl (recommended).".Localize();
            stableInfoLabel = new TextWidget(stableFeedInfoText);
            stableInfoLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
            stableInfoLabel.HAnchor = HAnchor.ParentLeftRight;
            stableInfoLabel.Margin = new BorderDouble(bottom:10);
            additionalInfoContainer.AddChild(stableInfoLabel);

            string betaFeedInfoText = "Beta: The release candidate version of MatterControl.".Localize();
            betaInfoLabel = new TextWidget(betaFeedInfoText);
            betaInfoLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
            betaInfoLabel.HAnchor = HAnchor.ParentLeftRight;
            betaInfoLabel.Margin = new BorderDouble(bottom: 10);
            additionalInfoContainer.AddChild(betaInfoLabel);

            string alphaFeedInfoText = "Alpha: The in development version of MatterControl.".Localize();
            alphaInfoLabel = new TextWidget(alphaFeedInfoText);
            alphaInfoLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
            alphaInfoLabel.HAnchor = HAnchor.ParentLeftRight;
            alphaInfoLabel.Margin = new BorderDouble(bottom: 10);
            additionalInfoContainer.AddChild(alphaInfoLabel);

            FlowLayoutWidget buttonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
            buttonContainer.HAnchor = HAnchor.ParentLeftRight;
            buttonContainer.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
            
            Button closeButton = textImageButtonFactory.Generate("Close".Localize(), centerText: true);
            closeButton.Click += (sender, e) =>
            {
                CloseOnIdle();
            };

            Button whatsThisLink = linkButtonFactory.Generate("What's this?".Localize());
            whatsThisLink.VAnchor = VAnchor.ParentCenter;
            whatsThisLink.Margin = new BorderDouble(left: 6);
            whatsThisLink.Click += (sender, e) =>
            {
                UiThread.RunOnIdle(() =>
                {
                    if (!additionalInfoContainer.Visible)
                    {
                        additionalInfoContainer.Visible = true;
                    }
                    else
                    {
                        additionalInfoContainer.Visible = false;
                    }
                });
            };


            mainLabelContainer.AddChild(checkUpdateLabel);
            topToBottom.AddChild(mainLabelContainer);
            topToBottom.AddChild(updateStatusWidget);
			topToBottom.AddChild(currentBuildInfo);
            currentFeedAndDropDownContainer.AddChild(feedLabel);
            currentFeedAndDropDownContainer.AddChild(whatsThisLink);
            currentFeedAndDropDownContainer.AddChild(new HorizontalSpacer());
            currentFeedAndDropDownContainer.AddChild(releaseOptionsDropList);
            topToBottom.AddChild(currentFeedAndDropDownContainer);
			
            topToBottom.AddChild(additionalInfoContainer);
            buttonContainer.AddChild(new HorizontalSpacer());
            buttonContainer.AddChild(closeButton);
            topToBottom.AddChild(new VerticalSpacer());
            topToBottom.AddChild(buttonContainer);
            this.AddChild(topToBottom);

            additionalInfoContainer.Visible = false;
			if (UpdateControlData.Instance.UpdateRequired)
			{
				this.Title = "Update Required".Localize();
			}
			else
			{
				this.Title = "Check for Update".Localize();
			}
			this.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
            this.ShowAsSystemWindow();
            this.AlwaysOnTopOfMain = true;

        }
		private DropDownList CreateDropdown()
		{
			var dropDownList = new DropDownList(defaultMenuItemText, maxHeight: 300, useLeftIcons: true)
			{
				HAnchor = HAnchor.ParentLeftRight,
				MenuItemsPadding = new BorderDouble(10, 4, 10, 6),
			};

			dropDownList.Margin = new BorderDouble(0, 3);
			dropDownList.MinimumSize = new Vector2(dropDownList.LocalBounds.Width, dropDownList.LocalBounds.Height);

			MenuItem defaultMenuItem = dropDownList.AddItem(defaultMenuItemText, "");
			defaultMenuItem.Selected += MenuItem_Selected;

			var listSource = (layerType == NamedSettingsLayers.Material) ? ActiveSliceSettings.Instance.MaterialLayers : ActiveSliceSettings.Instance.QualityLayers;
			foreach (var layer in listSource)
			{
				MenuItem menuItem = dropDownList.AddItem(layer.Name, layer.LayerID);
				menuItem.Selected += MenuItem_Selected;
			}

			MenuItem addNewPreset = dropDownList.AddItem(StaticData.Instance.LoadIcon("icon_plus.png", 32, 32), "Add New Setting...", "new");
			addNewPreset.Selected += (s, e) =>
			{
				var newLayer = new PrinterSettingsLayer();
				if (layerType == NamedSettingsLayers.Quality)
				{
					newLayer.Name = "Quality" + ActiveSliceSettings.Instance.QualityLayers.Count;
					ActiveSliceSettings.Instance.QualityLayers.Add(newLayer);
					ActiveSliceSettings.Instance.ActiveQualityKey = newLayer.LayerID;
				}
				else
				{
					newLayer.Name = "Material" + ActiveSliceSettings.Instance.MaterialLayers.Count;
					ActiveSliceSettings.Instance.MaterialLayers.Add(newLayer);
					ActiveSliceSettings.Instance.SetMaterialPreset(this.extruderIndex, newLayer.LayerID);
				}

				RebuildDropDownList();

				editButton.ClickButton(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
			};

			try
			{
				string settingsKey;

				if (layerType == NamedSettingsLayers.Material)
				{
					settingsKey = ActiveSliceSettings.Instance.GetMaterialPresetKey(extruderIndex);

					ActiveSliceSettings.Instance.MaterialLayers.CollectionChanged += SettingsLayers_CollectionChanged;
					dropDownList.Closed += (s1, e1) =>
					{
						ActiveSliceSettings.Instance.MaterialLayers.CollectionChanged -= SettingsLayers_CollectionChanged;
					};
				}
				else
				{
					settingsKey = ActiveSliceSettings.Instance.ActiveQualityKey;

					ActiveSliceSettings.Instance.QualityLayers.CollectionChanged += SettingsLayers_CollectionChanged;
					dropDownList.Closed += (s1, e1) =>
					{
						ActiveSliceSettings.Instance.QualityLayers.CollectionChanged -= SettingsLayers_CollectionChanged;
					};
				}

				if (!string.IsNullOrEmpty(settingsKey))
				{
					dropDownList.SelectedValue = settingsKey;
				}
			}
			catch (Exception ex)
			{
				GuiWidget.BreakInDebugger(ex.Message);
			}
		
			return dropDownList;
		}
		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;
		}
		private static GuiWidget CreateQuickMenu(SliceSettingData settingData, PrinterSettingsLayer persistenceLayer, GuiWidget content, InternalTextEditWidget internalTextWidget, List<PrinterSettingsLayer> layerCascade)
		{
			string sliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade);
			FlowLayoutWidget totalContent = new FlowLayoutWidget();

			DropDownList selectableOptions = new DropDownList("Custom", maxHeight: 200);
			selectableOptions.Margin = new BorderDouble(0, 0, 10, 0);

			foreach (QuickMenuNameValue nameValue in settingData.QuickMenuSettings)
			{
				string valueLocal = nameValue.Value;

				MenuItem newItem = selectableOptions.AddItem(nameValue.MenuName);
				if (sliceSettingValue == valueLocal)
				{
					selectableOptions.SelectedLabel = nameValue.MenuName;
				}

				newItem.Selected += (sender, e) =>
				{
					ActiveSliceSettings.Instance.SetValue(settingData.SlicerConfigName, valueLocal, persistenceLayer);
					OnSettingsChanged(settingData);
					internalTextWidget.Text = valueLocal;
					internalTextWidget.OnEditComplete(null);
				};
			}

			// put in the custom menu to allow direct editing
			MenuItem customMenueItem = selectableOptions.AddItem("Custom");

			totalContent.AddChild(selectableOptions);
			content.VAnchor = VAnchor.ParentCenter;
			totalContent.AddChild(content);

			EventHandler localUnregisterEvents = null;

			SettingChanged.RegisterEvent((sender, e) =>
			{
				bool foundSetting = false;
				foreach (QuickMenuNameValue nameValue in settingData.QuickMenuSettings)
				{
					string localName = nameValue.MenuName;
					string newSliceSettingValue = GetActiveValue(settingData.SlicerConfigName, layerCascade);
					if (newSliceSettingValue == nameValue.Value)
					{
						selectableOptions.SelectedLabel = localName;
						foundSetting = true;
						break;
					}
				}

				if (!foundSetting)
				{
					selectableOptions.SelectedLabel = "Custom";
				}
			}, ref localUnregisterEvents);

			totalContent.Closed += (s, e) =>
			{
				localUnregisterEvents?.Invoke(s, e);
			};

			return totalContent;
		}
		private static void AddComMenuItems(SliceSettingData settingData, PrinterSettingsLayer persistenceLayer, SettingsRow settingsRow, DropDownList selectableOptions)
		{
			selectableOptions.MenuItems.Clear();
			string machineSpecificComPortValue = ActiveSliceSettings.Instance.Helpers.ComPort();
			foreach (string listItem in FrostedSerialPort.GetPortNames())
			{
				MenuItem newItem = selectableOptions.AddItem(listItem);
				if (newItem.Text == machineSpecificComPortValue)
				{
					selectableOptions.SelectedLabel = machineSpecificComPortValue;
				}

				newItem.Selected += (sender, e) =>
				{
					MenuItem menuItem = ((MenuItem)sender);

					// Directly set the ComPort
					if (persistenceLayer == null)
					{
						ActiveSliceSettings.Instance.Helpers.SetComPort(menuItem.Text);
					}
					else
					{
						ActiveSliceSettings.Instance.Helpers.SetComPort(menuItem.Text, persistenceLayer);
					}

					settingsRow.UpdateStyle();

					OnSettingsChanged(settingData);
				};
			}
		}
		public SliceSettingsDetailControl(List<PrinterSettingsLayer> layerCascade)
		{
			showHelpBox = new CheckBox(0, 0, "Show Help".Localize(), textSize: 10)
			{
				VAnchor = VAnchor.ParentCenter,
			};

			if (layerCascade == null)
			{
				// only turn of the help if in the main view and it is set to on
				showHelpBox.Checked = UserSettings.Instance.get(SliceSettingsShowHelpEntry) == "true";
			}

			// add in the ability to turn on and off help text
			showHelpBox.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			showHelpBox.Margin = new BorderDouble(right: 3);
			showHelpBox.VAnchor = VAnchor.ParentCenter;
			showHelpBox.Cursor = Cursors.Hand;
			showHelpBox.CheckedStateChanged += (s, e) =>
			{
				if (layerCascade == null)
				{
					// only save the help settings if in the main view
					UserSettings.Instance.set(SliceSettingsShowHelpEntry, showHelpBox.Checked.ToString().ToLower());
				}
				ShowHelpChanged?.Invoke(this, null);
			};

			this.AddChild(showHelpBox);

			settingsDetailSelector = new DropDownList("Basic", maxHeight: 200);
			settingsDetailSelector.Name = "User Level Dropdown";
			settingsDetailSelector.AddItem("Basic".Localize(), "Simple");
			settingsDetailSelector.AddItem("Standard".Localize(), "Intermediate");
			settingsDetailSelector.AddItem("Advanced".Localize(), "Advanced");

			if (layerCascade == null)
			{
				// set to the user requested value when in default view
				if (UserSettings.Instance.get(SliceSettingsLevelEntry) != null
					&& SliceSettingsOrganizer.Instance.UserLevels.ContainsKey(UserSettings.Instance.get(SliceSettingsLevelEntry)))
				{
					settingsDetailSelector.SelectedValue = UserSettings.Instance.get(SliceSettingsLevelEntry);
				}
			}
			else // in settings editor view
			{
				// set to advanced
				settingsDetailSelector.SelectedValue = "Advanced";
			}

			settingsDetailSelector.SelectionChanged += (s, e) => RebuildSlicerSettings(null, null); ;
			settingsDetailSelector.VAnchor = VAnchor.ParentCenter;
			settingsDetailSelector.Margin = new BorderDouble(5, 3);
			settingsDetailSelector.BorderColor = new RGBA_Bytes(ActiveTheme.Instance.SecondaryTextColor, 100);

			if (layerCascade == null)
			{
				// only add these in the default view
				this.AddChild(settingsDetailSelector);
				this.AddChild(GetSliceOptionsMenuDropList());
			}

			VAnchor = VAnchor.ParentCenter;
		}
		public void AddReleaseOptions(FlowLayoutWidget controlsTopToBottom)
		{
			AltGroupBox releaseOptionsGroupBox = new AltGroupBox(LocalizedString.Get("Update Feed"));

			releaseOptionsGroupBox.Margin = new BorderDouble(0);
			releaseOptionsGroupBox.TextColor = ActiveTheme.Instance.PrimaryTextColor;
			releaseOptionsGroupBox.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
			releaseOptionsGroupBox.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
			releaseOptionsGroupBox.VAnchor = Agg.UI.VAnchor.ParentTop;
			releaseOptionsGroupBox.Height = 68;

			FlowLayoutWidget controlsContainer = new FlowLayoutWidget();
			controlsContainer.HAnchor |= HAnchor.ParentCenter;

			var releaseOptionsDropList = new DropDownList("Development");
			releaseOptionsDropList.Margin = new BorderDouble(0, 3);

			MenuItem releaseOptionsDropDownItem = releaseOptionsDropList.AddItem("Release", "release");
			releaseOptionsDropDownItem.Selected += new EventHandler(FixTabDot);

			MenuItem preReleaseDropDownItem = releaseOptionsDropList.AddItem("Pre-Release", "pre-release");
			preReleaseDropDownItem.Selected += new EventHandler(FixTabDot);

			MenuItem developmentDropDownItem = releaseOptionsDropList.AddItem("Development", "development");
			developmentDropDownItem.Selected += new EventHandler(FixTabDot);

			releaseOptionsDropList.MinimumSize = new Vector2(releaseOptionsDropList.LocalBounds.Width, releaseOptionsDropList.LocalBounds.Height);

			List<string> acceptableUpdateFeedTypeValues = new List<string>() { "release", "pre-release", "development" };
			string currentUpdateFeedType = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);

			if (acceptableUpdateFeedTypeValues.IndexOf(currentUpdateFeedType) == -1)
			{
				UserSettings.Instance.set(UserSettingsKey.UpdateFeedType, "release");
			}

			releaseOptionsDropList.SelectedValue = UserSettings.Instance.get(UserSettingsKey.UpdateFeedType);

			releaseOptionsDropList.SelectionChanged += new EventHandler(ReleaseOptionsDropList_SelectionChanged);

			controlsContainer.AddChild(releaseOptionsDropList);
			releaseOptionsGroupBox.AddChild(controlsContainer);
			controlsTopToBottom.AddChild(releaseOptionsGroupBox);
		}