Exemple #1
0
		public void BottomAndTopTextControl(double controlPadding, double buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(200, 300);
			containerControl.DoubleBuffer = true;
			containerControl.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
			TextWidget controlButton1 = new TextWidget("text1");
			controlButton1.Margin = new BorderDouble(buttonMargin);
			controlButton1.OriginRelativeParent = new VectorMath.Vector2(-controlButton1.LocalBounds.Left, -controlButton1.LocalBounds.Bottom + controlPadding + buttonMargin);
			controlButton1.LocalBounds = new RectangleDouble(controlButton1.LocalBounds.Left, controlButton1.LocalBounds.Bottom, controlButton1.LocalBounds.Right, controlButton1.LocalBounds.Bottom + containerControl.Height - (controlPadding + buttonMargin) * 2);
			containerControl.AddChild(controlButton1);
			containerControl.OnDraw(containerControl.NewGraphics2D());

			GuiWidget containerTest = new GuiWidget(200, 200);
			containerTest.Padding = new BorderDouble(controlPadding);
			containerTest.DoubleBuffer = true;
			containerTest.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);

			TextWidget testButton1 = new TextWidget("text1");
			testButton1.Margin = new BorderDouble(buttonMargin);
			testButton1.VAnchor = VAnchor.ParentBottom | VAnchor.ParentTop;
			containerTest.AddChild(testButton1);
			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			// now change it's size
			containerTest.LocalBounds = containerControl.LocalBounds;
			containerTest.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");
		}
		public void TextWidgetVisibleTest()
		{
			{
				GuiWidget rectangleWidget = new GuiWidget(100, 50);
				TextWidget itemToAdd = new TextWidget("test Item", 10, 10);
				rectangleWidget.AddChild(itemToAdd);
				rectangleWidget.DoubleBuffer = true;
				rectangleWidget.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
				rectangleWidget.OnDraw(rectangleWidget.BackBuffer.NewGraphics2D());

				ImageBuffer textOnly = new ImageBuffer(75, 20, 32, new BlenderBGRA());
				textOnly.NewGraphics2D().Clear(RGBA_Bytes.White);

				textOnly.NewGraphics2D().DrawString("test Item", 1, 1);

				if (saveImagesForDebug)
				{
					ImageTgaIO.Save(rectangleWidget.BackBuffer, "-rectangleWidget.tga");
					//ImageTgaIO.Save(itemToAdd.Children[0].BackBuffer, "-internalTextWidget.tga");
					ImageTgaIO.Save(textOnly, "-textOnly.tga");
				}

				Assert.IsTrue(rectangleWidget.BackBuffer.FindLeastSquaresMatch(textOnly, 1), "TextWidgets need to be drawing.");
				rectangleWidget.Close();
			}

			{
				GuiWidget rectangleWidget = new GuiWidget(100, 50);
				TextEditWidget itemToAdd = new TextEditWidget("test Item", 10, 10);
				rectangleWidget.AddChild(itemToAdd);
				rectangleWidget.DoubleBuffer = true;
				rectangleWidget.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
				rectangleWidget.OnDraw(rectangleWidget.BackBuffer.NewGraphics2D());

				ImageBuffer textOnly = new ImageBuffer(75, 20, 32, new BlenderBGRA());
				textOnly.NewGraphics2D().Clear(RGBA_Bytes.White);

				TypeFacePrinter stringPrinter = new TypeFacePrinter("test Item", 12);
				IVertexSource offsetText = new VertexSourceApplyTransform(stringPrinter, Affine.NewTranslation(1, -stringPrinter.LocalBounds.Bottom));
				textOnly.NewGraphics2D().Render(offsetText, RGBA_Bytes.Black);

				if (saveImagesForDebug)
				{
					ImageTgaIO.Save(rectangleWidget.BackBuffer, "-rectangleWidget.tga");
					//ImageTgaIO.Save(itemToAdd.Children[0].BackBuffer, "-internalTextWidget.tga");
					ImageTgaIO.Save(textOnly, "-textOnly.tga");
				}

				Assert.IsTrue(rectangleWidget.BackBuffer.FindLeastSquaresMatch(textOnly, 1), "TextWidgets need to be drawing.");
				rectangleWidget.Close();
			}
		}
Exemple #3
0
		public void TextEditTextSelectionTests()
		{
			GuiWidget container = new GuiWidget();
			container.LocalBounds = new RectangleDouble(0, 0, 200, 200);
			TextEditWidget editField1 = new TextEditWidget("", 0, 0, pixelWidth: 51);
			container.AddChild(editField1);

			// select the conrol and type something in it
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0));
			SendKey(Keys.A, 'a', container);
			Assert.IsTrue(editField1.Text == "a", "It should have a in it.");

			// select the begining again and type something else in it
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0));
			SendKey(Keys.B, 'b', container);
			Assert.IsTrue(editField1.Text == "ba", "It should have ba in it.");

			// select the ba and delete them
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
			container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 0, 15, 0, 0));
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, 15, 0, 0));
			SendKey(Keys.Back, ' ', container);
			Assert.IsTrue(editField1.Text == "", "It should have nothing in it.");

			// select the other way
			editField1.Text = "ab";
			Assert.IsTrue(editField1.Text == "ab", "It should have ab in it.");
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 15, 0, 0));
			container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0));
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0));
			SendKey(Keys.Back, ' ', container);
			Assert.IsTrue(editField1.Text == "", "It should have nothing in it.");

			// select the other way but start far to the right
			editField1.Text = "abc";
			Assert.IsTrue(editField1.Text == "abc", "It should have abc in it.");
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 30, 0, 0));
			container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0));
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0));
			SendKey(Keys.Back, ' ', container);
			Assert.IsTrue(editField1.Text == "", "It should have nothing in it.");

			container.Close();
		}
		public void ValidateOnlyTopWidgetGetsLeftClick()
		{
			bool gotClick = false;
			GuiWidget container = new GuiWidget();
			container.Name = "container";
			container.LocalBounds = new RectangleDouble(0, 0, 200, 200);
			Button button = new Button("Test", 100, 100);
			button.Name = "button";
			button.Click += (sender, e) => { gotClick = true; };
			container.AddChild(button);

			GuiWidget blockingWidegt = new GuiWidget();
			blockingWidegt.Name = "blockingWidegt";
			blockingWidegt.LocalBounds = new RectangleDouble(105, 105, 125, 125);
			container.AddChild(blockingWidegt);

			// the widget is not in the way
			Assert.IsTrue(gotClick == false);
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 101, 101, 0));
			Assert.IsTrue(container.MouseCaptured == false);
			Assert.IsTrue(blockingWidegt.MouseCaptured == false);
			Assert.IsTrue(container.ChildHasMouseCaptured == true);
			Assert.IsTrue(blockingWidegt.ChildHasMouseCaptured == false);
			Assert.IsTrue(button.MouseCaptured == true);
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 101, 101, 0));
			Assert.IsTrue(container.MouseCaptured == false);
			Assert.IsTrue(blockingWidegt.MouseCaptured == false);
			Assert.IsTrue(button.MouseCaptured == false);
			Assert.IsTrue(gotClick == true);

			gotClick = false;

			// the widget is in the way
			Assert.IsTrue(gotClick == false);
			container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 110, 110, 0));
			Assert.IsTrue(container.MouseCaptured == false);
			Assert.IsTrue(blockingWidegt.MouseCaptured == true);
			Assert.IsTrue(button.MouseCaptured == false);
			container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 110, 110, 0));
			Assert.IsTrue(container.MouseCaptured == false);
			Assert.IsTrue(blockingWidegt.MouseCaptured == false);
			Assert.IsTrue(button.MouseCaptured == false);
			Assert.IsTrue(gotClick == false);
		}
Exemple #5
0
		public void TopToBottomContainerAppliesExpectedMargin()
		{
			int marginSize = 40;
			int dimensions = 300;

			GuiWidget outerContainer = new GuiWidget(dimensions, dimensions);

			FlowLayoutWidget topToBottomContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
			{
				HAnchor = HAnchor.ParentLeftRight,
				VAnchor = UI.VAnchor.ParentBottomTop,
			};
			outerContainer.AddChild(topToBottomContainer);

			GuiWidget childWidget = new GuiWidget()
			{
				HAnchor = HAnchor.ParentLeftRight,
				VAnchor = VAnchor.ParentBottomTop,
				Margin = new BorderDouble(marginSize),
				BackgroundColor = RGBA_Bytes.Red,
			};

			topToBottomContainer.AddChild(childWidget);
			topToBottomContainer.AnchorAll();
			topToBottomContainer.PerformLayout();

			outerContainer.DoubleBuffer = true;
			outerContainer.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
			outerContainer.OnDraw(outerContainer.NewGraphics2D());

			// For troubleshooting or visual validation
			//saveImagesForDebug = true;
			//OutputImages(outerContainer, outerContainer);

			var bounds = childWidget.BoundsRelativeToParent;
			Assert.IsTrue(bounds.Left == marginSize, "Left margin is incorrect");
			Assert.IsTrue(bounds.Right == dimensions - marginSize, "Right margin is incorrect");
			Assert.IsTrue(bounds.Top == dimensions - marginSize, "Top margin is incorrect");
			Assert.IsTrue(bounds.Bottom == marginSize, "Bottom margin is incorrect");
		}
        public void ValidateSimpleLeftClick()
        {
            GuiWidget container = new GuiWidget();
            container.Name = "Container";
            container.LocalBounds = new RectangleDouble(0, 0, 200, 200);
            Button button = new Button("Test", 100, 100);
            button.Name = "button";
            bool gotClick = false;
            button.Click += (sender, e) => { gotClick = true; };
            container.AddChild(button);

            Assert.IsTrue(gotClick == false);
            Assert.IsTrue(button.Focused == false);

            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 10, 10, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 10, 10, 0));
            Assert.IsTrue(gotClick == false);
            Assert.IsTrue(button.Focused == false);
            
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 110, 110, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 10, 10, 0));
            Assert.IsTrue(gotClick == false);
            Assert.IsTrue(button.Focused == true, "Down click triggers focused."); 

            Assert.IsTrue(gotClick == false);
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 110, 110, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 110, 110, 0));
            Assert.IsTrue(gotClick == true);
            Assert.IsTrue(button.Focused == true);

            gotClick = false;
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 10, 10, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 10, 10, 0));
            Assert.IsTrue(gotClick == false);
            Assert.IsTrue(button.Focused == false);

        }
Exemple #7
0
        public void FlowLayoutAndListBoxShouldLookTheSameWhenNoScrollBar()
        {
            GuiWidget control = new GuiWidget(200, 300);
            control.DoubleBuffer = true;
            FlowLayoutWidget flowItemContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
            flowItemContainer.HAnchor = HAnchor.LeftRight;
            flowItemContainer.HAnchor = HAnchor.LeftRight;
            flowItemContainer.VAnchor = VAnchor.BottomTop;
            //flowItemContainer.HAnchor = HAnchor.LeftRight;
            //flowItemContainer.HAnchor = HAnchor.Left;
            //flowItemContainer.VAnchor = VAnchor.Top;
            AddContents(flowItemContainer);
            control.AddChild(flowItemContainer);
            control.OnDraw(control.NewGraphics2D());
            OutputImage(control.BackBuffer, "control.tga");

            GuiWidget test = new GuiWidget(200, 300);
            test.DoubleBuffer = true;
            ListBox listItemContainer = new ListBox();
            AddContents(listItemContainer);
            test.AddChild(listItemContainer);
            test.OnDraw(test.NewGraphics2D());
            OutputImage(test.BackBuffer, "test.tga");

            Assert.IsTrue(control.BackBuffer.FindLeastSquaresMatch(test.BackBuffer, 0), "The test and control need to match.");
        }
Exemple #8
0
        public async Task ClickFiresOnCorrectWidgets()
        {
            int blueClickCount   = 0;
            int orangeClickCount = 0;
            int purpleClickCount = 0;

            lastClicked = null;

            double waitTime = .5;

            AutomationTest testToRun = (testRunner) =>
            {
                testRunner.Wait(2);
                testRunner.ClickByName("rootClickable", 5);
                testRunner.Wait(waitTime);

                Assert.AreEqual(blueClickCount, 1, "Expected 1 click on blue widget");
                Assert.AreEqual(orangeClickCount, 0, "Expected 0 clicks on orange widget");
                Assert.AreEqual(purpleClickCount, 0, "Expected 1 click on purple widget");

                testRunner.ClickByName("orangeClickable", 1);
                testRunner.Wait(waitTime);
                Assert.AreEqual(blueClickCount, 1, "Expected 1 click on blue widget");
                Assert.AreEqual(orangeClickCount, 1, "Expected 1 clicks on orange widget");
                Assert.AreEqual(purpleClickCount, 0, "Expected 0 click on purple widget");

                testRunner.ClickByName("rootClickable", 1);
                testRunner.Wait(waitTime);
                Assert.AreEqual(blueClickCount, 2, "Expected 1 click on blue widget");
                Assert.AreEqual(orangeClickCount, 1, "Expected 0 clicks on orange widget");
                Assert.AreEqual(purpleClickCount, 0, "Expected 1 click on purple widget");

                testRunner.ClickByName("orangeClickable", 1);
                testRunner.Wait(waitTime);
                Assert.AreEqual(blueClickCount, 2, "Expected 1 click on root widget");
                Assert.AreEqual(orangeClickCount, 2, "Expected 2 clicks on orange widget");
                Assert.AreEqual(purpleClickCount, 0, "Expected 0 click on purple widget");

                testRunner.ClickByName("purpleClickable", 1);
                testRunner.Wait(waitTime);
                Assert.AreEqual(blueClickCount, 2, "Expected 1 click on blue widget");
                Assert.AreEqual(orangeClickCount, 2, "Expected 2 clicks on orange widget");
                Assert.AreEqual(purpleClickCount, 1, "Expected 1 click on purple widget");

                return(Task.FromResult(0));
            };

            SystemWindow systemWindow = new SystemWindow(300, 200)
            {
                Padding = new BorderDouble(20)
            };

            var rootClickable = new GuiWidget()
            {
                Width           = 50,
                HAnchor         = HAnchor.ParentLeftRight,
                VAnchor         = VAnchor.ParentBottomTop,
                Margin          = new BorderDouble(50),
                Name            = "rootClickable",
                BackgroundColor = RGBA_Bytes.Blue
            };

            rootClickable.Click += (sender, e) =>
            {
                var widget = sender as GuiWidget;
                blueClickCount += 1;
                var color = rootClickable.BackgroundColor.AdjustSaturation(0.4);
                systemWindow.BackgroundColor = color.GetAsRGBA_Bytes();
                lastClicked = rootClickable;
            };
            rootClickable.AfterDraw += widget_DrawSelection;

            var orangeClickable = new GuiWidget()
            {
                Width  = 35,
                Height = 25,
                OriginRelativeParent = new VectorMath.Vector2(10, 10),
                Name            = "orangeClickable",
                Margin          = new BorderDouble(10),
                BackgroundColor = RGBA_Bytes.Orange
            };

            orangeClickable.Click += (sender, e) =>
            {
                var widget = sender as GuiWidget;
                orangeClickCount += 1;

                var color = widget.BackgroundColor.AdjustSaturation(0.4);
                systemWindow.BackgroundColor = color.GetAsRGBA_Bytes();
                lastClicked = widget;
            };
            orangeClickable.AfterDraw += widget_DrawSelection;
            rootClickable.AddChild(orangeClickable);

            var purpleClickable = new GuiWidget()
            {
                Width  = 35,
                Height = 25,
                OriginRelativeParent = new VectorMath.Vector2(0, 10),
                HAnchor         = HAnchor.ParentRight,
                Name            = "purpleClickable",
                Margin          = new BorderDouble(10),
                BackgroundColor = new RGBA_Bytes(141, 0, 206)
            };

            purpleClickable.Click += (sender, e) =>
            {
                var widget = sender as GuiWidget;

                purpleClickCount += 1;

                var color = widget.BackgroundColor.AdjustSaturation(0.4);
                systemWindow.BackgroundColor = color.GetAsRGBA_Bytes();
                lastClicked = widget;
            };
            purpleClickable.AfterDraw += widget_DrawSelection;
            rootClickable.AddChild(purpleClickable);

            systemWindow.AddChild(rootClickable);

            await AutomationRunner.ShowWindowAndExecuteTests(systemWindow, testToRun, 25);
        }
Exemple #9
0
		public void CenterBothOffsetBoundsTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(200, 300);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;
			GuiWidget controlRectangle = new GuiWidget(100, 100);
			controlRectangle.BackgroundColor = RGBA_Bytes.Red;
			controlRectangle.Margin = buttonMargin;
			double controlCenterX = controlPadding.Left + (containerControl.Width - controlPadding.Left - controlPadding.Right) / 2;
			double buttonX = controlCenterX - (controlRectangle.Width + controlRectangle.Margin.Left + controlRectangle.Margin.Right) / 2 + controlRectangle.Margin.Left;
			double controlCenterY = controlPadding.Bottom + (containerControl.Height - controlPadding.Bottom - controlPadding.Top) / 2 + controlRectangle.Margin.Bottom;
			double buttonY = controlCenterY - (controlRectangle.Height + controlRectangle.Margin.Bottom + controlRectangle.Margin.Top) / 2;
			controlRectangle.OriginRelativeParent = new VectorMath.Vector2(buttonX, buttonY);
			containerControl.AddChild(controlRectangle);
			containerControl.OnDraw(containerControl.NewGraphics2D());

			GuiWidget containerTest = new GuiWidget(200, 300);
			containerTest.Padding = controlPadding;
			containerTest.DoubleBuffer = true;

			GuiWidget testRectangle = new GuiWidget(100, 100);
			RectangleDouble offsetBounds = testRectangle.LocalBounds;
			offsetBounds.Offset(-10, -10);
			testRectangle.LocalBounds = offsetBounds;
			testRectangle.BackgroundColor = RGBA_Bytes.Red;
			testRectangle.Margin = buttonMargin;
			testRectangle.VAnchor = VAnchor.ParentCenter;
			testRectangle.HAnchor = HAnchor.ParentCenter;
			containerTest.AddChild(testRectangle);

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");
		}
Exemple #10
0
        public ApplicationMenuRow()
            : base(FlowDirection.LeftToRight)
        {
            linkButtonFactory.textColor = ActiveTheme.Instance.PrimaryTextColor;
            linkButtonFactory.fontSize  = 8;

            Button signInLink = linkButtonFactory.Generate("(Sign Out)");

            signInLink.ToolTipText = "Sign in to your MatterControl account".Localize();
            signInLink.VAnchor     = Agg.UI.VAnchor.ParentCenter;
            signInLink.Margin      = new BorderDouble(top: 0);

            this.HAnchor         = HAnchor.ParentLeftRight;
            this.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;

            // put in the file menu
            MenuOptionFile menuOptionFile = new MenuOptionFile();

            this.AddChild(menuOptionFile);

            MenuOptionSettings menuOptionSettings = new MenuOptionSettings();

            this.AddChild(menuOptionSettings);

            // put in the help menu
            MenuOptionHelp menuOptionHelp = new MenuOptionHelp();

            this.AddChild(menuOptionHelp);

            //linkButtonFactory.textColor = ActiveTheme.Instance.SecondaryAccentColor;
            linkButtonFactory.fontSize = 10;

            Button updateStatusMessage = linkButtonFactory.Generate("Update Available");

            UpdateControlData.Instance.UpdateStatusChanged.RegisterEvent(SetUpdateNotification, ref unregisterEvents);
            popUpAboutPage         = new FlowLayoutWidget();
            popUpAboutPage.Margin  = new BorderDouble(30, 0, 0, 0);
            popUpAboutPage.HAnchor = HAnchor.FitToChildren;
            popUpAboutPage.VAnchor = VAnchor.FitToChildren | VAnchor.ParentCenter;
            popUpAboutPage.AddChild(updateStatusMessage);
            updateStatusMessage.Click += (sender, e) =>
            {
                UiThread.RunOnIdle(CheckForUpdateWindow.Show);
            };
            this.AddChild(popUpAboutPage);
            SetUpdateNotification(this, null);

            // put in a spacer
            this.AddChild(new HorizontalSpacer());

            // make an object that can hold custom content on the right (like the sign in)
            rightElement        = new FlowLayoutWidget(FlowDirection.LeftToRight);
            rightElement.Height = 24;
            rightElement.Margin = new BorderDouble(bottom: 4);
            this.AddChild(rightElement);

            this.Padding = new BorderDouble(0, 0, 6, 0);

            if (AddRightElement != null)
            {
                AddRightElement(rightElement);
            }

            // When the application is first started, plugins are loaded after the MainView control has been initialize,
            // and such they not around when this constructor executes. In that case, we run the AddRightElement
            // delegate after the plugins get initialized via the PluginsLoaded event
            ApplicationController.Instance.PluginsLoaded.RegisterEvent(PluginsLoaded, ref unregisterEvents);
        }
Exemple #11
0
		public void NestedFitToChildrenParentWidth()
		{
			// child of flow layout is ParentLeftRight
			{
				//  _________________________________________
				//  |            containerControl            |
				//  | _____________________________________  |
				//  | |    Max_FitToChildren_ParentWidth   | |
				//  | | ________________________ ________  | |
				//  | | |                      | |       | | |
				//  | | |    ParentLeftRight   | | 10x10 | | |
				//  | | |______________________| |_______| | |
				//  | |____________________________________| |
				//  |________________________________________|
				//

				GuiWidget containerControl = new GuiWidget(300, 200); // containerControl = 0, 0, 300, 200
				containerControl.DoubleBuffer = true;
				FlowLayoutWidget flowWidget = new FlowLayoutWidget()
				{
					HAnchor = HAnchor.Max_FitToChildren_ParentWidth,
				};
				containerControl.AddChild(flowWidget); // flowWidget = 0, 0, 300, 0
				GuiWidget fitToChildrenOrParent = new GuiWidget(20, 20)
				{
					HAnchor = HAnchor.ParentLeftRight,
				};
				flowWidget.AddChild(fitToChildrenOrParent); // flowWidget = 0, 0, 300, 20  fitToChildrenOrParent = 0, 0, 300, 20
				GuiWidget fixed10x10 = new GuiWidget(10, 10);
				flowWidget.AddChild(fixed10x10); // flowWidget = 0, 0, 300, 20  fitToChildrenOrParent = 0, 0, 290, 20
				containerControl.OnDraw(containerControl.NewGraphics2D());

				//OutputImage(containerControl, "countainer");

				Assert.IsTrue(flowWidget.Width == containerControl.Width);
				Assert.IsTrue(fitToChildrenOrParent.Width + fixed10x10.Width == containerControl.Width);

				containerControl.Width = 350;
				Assert.IsTrue(flowWidget.Width == containerControl.Width);
				Assert.IsTrue(fitToChildrenOrParent.Width + fixed10x10.Width == containerControl.Width);

				containerControl.Width = 310;
				Assert.IsTrue(flowWidget.Width == containerControl.Width);
				Assert.IsTrue(fitToChildrenOrParent.Width + fixed10x10.Width == containerControl.Width);
			}

			// child of flow layout is Max_FitToChildren_ParentWidth
			{
				//  ___________________________________________________
				//  |            containerControl                      |
				//  | _______________________________________________  |
				//  | |    Max_FitToChildren_ParentWidth             | |
				//  | | _________________________________   _______  | |
				//  | | |                                | |       | | |
				//  | | | Max_FitToChildren_ParentWidth  | | 10x10 | | |
				//  | | |________________________________| |_______| | |
				//  | |______________________________________________| |
				//  |__________________________________________________|
				//

				GuiWidget containerControl = new GuiWidget(300, 200); // containerControl = 0, 0, 300, 200
				containerControl.DoubleBuffer = true;
				FlowLayoutWidget flowWidget = new FlowLayoutWidget()
				{
					HAnchor = HAnchor.Max_FitToChildren_ParentWidth,
				};
				containerControl.AddChild(flowWidget);
				GuiWidget fitToChildrenOrParent = new GuiWidget(20, 20)
				{
					Name = "fitToChildrenOrParent",
					HAnchor = HAnchor.Max_FitToChildren_ParentWidth,
				};
				flowWidget.AddChild(fitToChildrenOrParent); // flowWidget = 0, 0, 300, 20  fitToChildrenOrParent = 0, 0, 300, 20
				GuiWidget fixed10x10 = new GuiWidget(10, 10);
				flowWidget.AddChild(fixed10x10); // flowWidget = 0, 0, 300, 20  fitToChildrenOrParent = 0, 0, 290, 20
				containerControl.OnDraw(containerControl.NewGraphics2D());

				//OutputImage(containerControl, "countainer");

				Assert.IsTrue(flowWidget.Width == containerControl.Width);
				Assert.IsTrue(fitToChildrenOrParent.Width + fixed10x10.Width == containerControl.Width);

				containerControl.Width = 350;
				Assert.IsTrue(flowWidget.Width == containerControl.Width);
				Assert.IsTrue(fitToChildrenOrParent.Width + fixed10x10.Width == containerControl.Width);

				containerControl.Width = 310;
				Assert.IsTrue(flowWidget.Width == containerControl.Width);
				Assert.IsTrue(fitToChildrenOrParent.Width + fixed10x10.Width == containerControl.Width);
			}
		}
Exemple #12
0
		public void ChildHAnchorPriority()
		{
			// make sure a middle spacer grows and shrinks correctly
			{
				FlowLayoutWidget leftRightFlowLayout = new FlowLayoutWidget();
				Assert.IsTrue(leftRightFlowLayout.HAnchor == HAnchor.FitToChildren); // flow layout starts with FitToChildren
				leftRightFlowLayout.HAnchor |= HAnchor.ParentLeftRight; // add to the existing flags ParentLeftRight (starts with FitToChildren)
				// [<-><->] // attempting to make a visual descrition of what is happening
				Assert.IsTrue(leftRightFlowLayout.Width == 0); // nothing is forcing it to have a width so it doesn't
				GuiWidget leftWidget = new GuiWidget(10, 10); // we call it left widget as it will be the first one in the left to right flow layout
				leftRightFlowLayout.AddChild(leftWidget); // add in a child with a width of 10
				// [<->(10)<->] // the flow layout should now be forced to be 10 wide
				Assert.IsTrue(leftRightFlowLayout.Width == 10);

				GuiWidget middleSpacer = new GuiWidget(0, 10); // this widget will hold the space
				middleSpacer.HAnchor = HAnchor.ParentLeftRight; // by resizing to whatever width it can be
				leftRightFlowLayout.AddChild(middleSpacer);
				// [<->(10)(<->)<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 10);
				Assert.IsTrue(middleSpacer.Width == 0);

				GuiWidget rightItem = new GuiWidget(10, 10);
				leftRightFlowLayout.AddChild(rightItem);
				// [<->(10)(<->)(10)<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 20);

				GuiWidget container = new GuiWidget(40, 20);
				container.AddChild(leftRightFlowLayout);
				// (40[<->(10)(<->)(10)<->]) // the extra 20 must be put into the expandable (<->)
				Assert.IsTrue(container.Width == 40);
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 20);

				container.Width = 50;
				// (50[<->(10)(<->)(10)<->]) // the extra 30 must be put into the expandable (<->)
				Assert.IsTrue(container.Width == 50);
				Assert.IsTrue(leftRightFlowLayout.Width == 50);
				Assert.IsTrue(middleSpacer.Width == 30);

				container.Width = 40;
				// (40[<->(10)(<->)(10)<->]) // the extra 20 must be put into the expandable (<->) by shrinking it
				Assert.IsTrue(container.Width == 40);
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 20);

				Assert.IsTrue(container.MinimumSize.x == 40); // minimum size is set to the construction size for normal GuiWidgets
				container.MinimumSize = new Vector2(0, 0); // make sure we can make this smaller
				container.Width = 10;
				// (10[<->(10)(<->)(10)<->]) // the extra 20 must be put into the expandable (<->) by shrinking it
				Assert.IsTrue(container.Width == 10); // nothing should be keeping this big
				Assert.IsTrue(leftRightFlowLayout.Width == 20); // it can't get smaller than its contents
				Assert.IsTrue(middleSpacer.Width == 0);
			}

			// make sure the middle spacer works the same when in a flow layout
			{
				FlowLayoutWidget leftRightFlowLayout = new FlowLayoutWidget();
				leftRightFlowLayout.Name = "leftRightFlowLayout";
				Assert.IsTrue(leftRightFlowLayout.HAnchor == HAnchor.FitToChildren); // flow layout starts with FitToChildren
				leftRightFlowLayout.HAnchor |= HAnchor.ParentLeftRight; // add to the existing flags ParentLeftRight (starts with FitToChildren)
				// [<-><->] // attempting to make a visual descrition of what is happening
				Assert.IsTrue(leftRightFlowLayout.Width == 0); // nothing is forcing it to have a width so it doesn't
				GuiWidget leftWidget = new GuiWidget(10, 10); // we call it left widget as it will be the first one in the left to right flow layout
				leftWidget.Name = "leftWidget";
				leftRightFlowLayout.AddChild(leftWidget); // add in a child with a width of 10
				// [<->(10)<->] // the flow layout should now be forced to be 10 wide
				Assert.IsTrue(leftRightFlowLayout.Width == 10);

				FlowLayoutWidget middleFlowLayoutWrapper = new FlowLayoutWidget(); // we are going to wrap the implicitly middle items to test nested resizing
				middleFlowLayoutWrapper.Name = "middleFlowLayoutWrapper";
				middleFlowLayoutWrapper.HAnchor |= HAnchor.ParentLeftRight;
				GuiWidget middleSpacer = new GuiWidget(0, 10); // this widget will hold the space
				middleSpacer.Name = "middleSpacer";
				middleSpacer.HAnchor = HAnchor.ParentLeftRight; // by resizing to whatever width it can be
				middleFlowLayoutWrapper.AddChild(middleSpacer);
				// {<->(<->)<->}
				leftRightFlowLayout.AddChild(middleFlowLayoutWrapper);
				// [<->(10){<->(<->)<->}<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 10);
				Assert.IsTrue(middleFlowLayoutWrapper.Width == 0);
				Assert.IsTrue(middleSpacer.Width == 0);

				GuiWidget rightWidget = new GuiWidget(10, 10);
				rightWidget.Name = "rightWidget";
				leftRightFlowLayout.AddChild(rightWidget);
				// [<->(10){<->(<->)<->}(10)<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 20);

				GuiWidget container = new GuiWidget(40, 20);
				container.Name = "container";
				container.AddChild(leftRightFlowLayout);
				// (40[<->(10){<->(<->)<->}(10)<->]) // the extra 20 must be put into the expandable (<->)
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleFlowLayoutWrapper.Width == 20);
				Assert.IsTrue(middleSpacer.Width == 20);

				container.Width = 50;
				// (50[<->(10){<->(<->)<->}(10)<->]) // the extra 30 must be put into the expandable (<->)
				Assert.IsTrue(leftRightFlowLayout.Width == 50);
				Assert.IsTrue(middleSpacer.Width == 30);

				container.Width = 40;
				// (50[<->(10){<->(<->)<->}(10)<->]) // the extra 20 must be put into the expandable (<->) by shrinking it
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 20);
			}

			// make sure a middle spacer grows and shrinks correctly when in another guiwidget (not a flow widget) that is LeftRight
			{
				FlowLayoutWidget leftRightFlowLayout = new FlowLayoutWidget();
				leftRightFlowLayout.Name = "leftRightFlowLayout";
				Assert.IsTrue(leftRightFlowLayout.HAnchor == HAnchor.FitToChildren); // flow layout starts with FitToChildren
				leftRightFlowLayout.HAnchor |= HAnchor.ParentLeftRight; // add to the existing flags ParentLeftRight (starts with FitToChildren)
				// [<-><->] // attempting to make a visual descrition of what is happening
				Assert.IsTrue(leftRightFlowLayout.Width == 0); // nothing is forcing it to have a width so it doesn't

				GuiWidget middleSpacer = new GuiWidget(0, 10); // this widget will hold the space
				middleSpacer.Name = "middleSpacer";
				middleSpacer.HAnchor = HAnchor.ParentLeftRight; // by resizing to whatever width it can be
				leftRightFlowLayout.AddChild(middleSpacer);
				// [<->(<->)<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 0);
				Assert.IsTrue(middleSpacer.Width == 0);

				Assert.IsTrue(leftRightFlowLayout.Width == 0);

				GuiWidget containerOuter = new GuiWidget(40, 20);
				containerOuter.Name = "containerOuter";
				GuiWidget containerInner = new GuiWidget(0, 20);
				containerInner.HAnchor = HAnchor.ParentLeftRight | HAnchor.FitToChildren;
				containerInner.Name = "containerInner";
				containerOuter.AddChild(containerInner);
				Assert.IsTrue(containerInner.Width == 40);
				containerInner.AddChild(leftRightFlowLayout);
				// (40(<-[<->(<->)<->]->)) // the extra 20 must be put into the expandable (<->)
				Assert.IsTrue(containerInner.Width == 40);
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 40);

				containerOuter.Width = 50;
				// (50(<-[<->(<->)<->]->) // the extra 30 must be put into the expandable (<->)
				Assert.IsTrue(containerInner.Width == 50);
				Assert.IsTrue(leftRightFlowLayout.Width == 50);
				Assert.IsTrue(middleSpacer.Width == 50);

				containerOuter.Width = 40;
				// (40(<-[<->(<->)<->]->) // the extra 20 must be put into the expandable (<->) by shrinking it
				Assert.IsTrue(containerInner.Width == 40);
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 40);
			}

			// make sure a middle spacer grows and shrinks correctly when in another guiwidget (not a flow widget) that is LeftRight
			{
				FlowLayoutWidget leftRightFlowLayout = new FlowLayoutWidget();
				Assert.IsTrue(leftRightFlowLayout.HAnchor == HAnchor.FitToChildren); // flow layout starts with FitToChildren
				leftRightFlowLayout.HAnchor |= HAnchor.ParentLeftRight; // add to the existing flags ParentLeftRight (starts with FitToChildren)
				// [<-><->] // attempting to make a visual descrition of what is happening
				Assert.IsTrue(leftRightFlowLayout.Width == 0); // nothing is forcing it to have a width so it doesn't
				GuiWidget leftWidget = new GuiWidget(10, 10); // we call it left widget as it will be the first one in the left to right flow layout
				leftRightFlowLayout.AddChild(leftWidget); // add in a child with a width of 10
				// [<->(10)<->] // the flow layout should now be forced to be 10 wide
				Assert.IsTrue(leftRightFlowLayout.Width == 10);

				GuiWidget middleSpacer = new GuiWidget(0, 10); // this widget will hold the space
				middleSpacer.HAnchor = HAnchor.ParentLeftRight; // by resizing to whatever width it can be
				leftRightFlowLayout.AddChild(middleSpacer);
				// [<->(10)(<->)<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 10);
				Assert.IsTrue(middleSpacer.Width == 0);

				GuiWidget rightItem = new GuiWidget(10, 10);
				leftRightFlowLayout.AddChild(rightItem);
				// [<->(10)(<->)(10)<->]
				Assert.IsTrue(leftRightFlowLayout.Width == 20);

				GuiWidget containerOuter = new GuiWidget(40, 20);
				containerOuter.Name = "containerOuter";
				GuiWidget containerInner = new GuiWidget(0, 20);
				containerInner.HAnchor = HAnchor.ParentLeftRight | HAnchor.FitToChildren;
				containerInner.Name = "containerInner";
				containerOuter.AddChild(containerInner);
				Assert.IsTrue(containerInner.Width == 40);
				containerInner.AddChild(leftRightFlowLayout);
				// (40(<-[<->(10)(<->)(10)<->]->)) // the extra 20 must be put into the expandable (<->)
				Assert.IsTrue(containerInner.Width == 40);
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 20);

				containerOuter.Width = 50;
				// (50(<-[<->(10)(<->)(10)<->]->) // the extra 30 must be put into the expandable (<->)
				Assert.IsTrue(containerInner.Width == 50);
				Assert.IsTrue(leftRightFlowLayout.Width == 50);
				Assert.IsTrue(middleSpacer.Width == 30);

				containerOuter.Width = 40;
				// (40(<-[<->(10)(<->)(10)<->]->) // the extra 20 must be put into the expandable (<->) by shrinking it
				Assert.IsTrue(containerInner.Width == 40);
				Assert.IsTrue(leftRightFlowLayout.Width == 40);
				Assert.IsTrue(middleSpacer.Width == 20);
			}
		}
Exemple #13
0
		public void EnsureFlowLayoutMinSizeFitsChildrenMinSize()
		{
			// This test is to prove that a flow layout widget always has it's min size set
			// to the enclosing bounds size of all it's childrens min size.
			// The code to be tested will expand the flow layouts min size as it's children's min size change.
			GuiWidget containerTest = new GuiWidget(640, 480);
			FlowLayoutWidget topToBottomFlowLayoutAll = new FlowLayoutWidget(FlowDirection.TopToBottom);
			containerTest.AddChild(topToBottomFlowLayoutAll);
			containerTest.DoubleBuffer = true;

			FlowLayoutWidget topLeftToRight = new FlowLayoutWidget(FlowDirection.LeftToRight);
			topToBottomFlowLayoutAll.AddChild(topLeftToRight);
			GuiWidget bottomLeftToRight = new FlowLayoutWidget(FlowDirection.LeftToRight);
			topToBottomFlowLayoutAll.AddChild(bottomLeftToRight);

			topLeftToRight.AddChild(new Button("top button"));

			FlowLayoutWidget bottomContentTopToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);
			bottomLeftToRight.AddChild(bottomContentTopToBottom);

			Button button1 = new Button("button1");
			Assert.IsTrue(button1.MinimumSize.x > 0, "Buttons should set their min size on construction.");
			bottomContentTopToBottom.AddChild(button1);
			//Assert.IsTrue(bottomContentTopToBottom.MinimumSize.x >= button1.MinimumSize.x, "There should be space for the button.");
			bottomContentTopToBottom.AddChild(new Button("button2"));
			Button wideButton = new Button("button3 Wide");
			bottomContentTopToBottom.AddChild(wideButton);
			//Assert.IsTrue(bottomContentTopToBottom.MinimumSize.x >= wideButton.MinimumSize.x, "These should be space for the button.");

			containerTest.BackgroundColor = RGBA_Bytes.White;
			containerTest.OnDrawBackground(containerTest.NewGraphics2D());
			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImage(containerTest.BackBuffer, "zFlowLaoutsGetMinSize.tga");

			Assert.IsTrue(bottomLeftToRight.Width > 0, "This needs to have been expanded when the bottomContentTopToBottom grew.");
			Assert.IsTrue(bottomLeftToRight.MinimumSize.x >= bottomContentTopToBottom.MinimumSize.x, "These should be space for the next flowLayout.");
			Assert.IsTrue(containerTest.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
		}
Exemple #14
0
        private void RefreshGCodeDetails(PrinterConfig printer)
        {
            loadedGCodeSection.CloseAllChildren();

            if (sceneContext.LoadedGCode?.LineCount > 0)
            {
                bool renderSpeeds = printer.Bed.RendererOptions.GCodeLineColorStyle == "Speeds";
                loadedGCodeSection.AddChild(
                    speedsWidget = new SectionWidget(
                        "Speeds".Localize(),
                        new SpeedsLegend(sceneContext.LoadedGCode, theme)
                {
                    HAnchor = HAnchor.Stretch,
                    Visible = renderSpeeds,
                    Padding = new BorderDouble(15, 4)
                },
                        theme)
                {
                    HAnchor = HAnchor.Stretch,
                    VAnchor = VAnchor.Fit
                });

                speedsWidget.Visible = renderSpeeds;

                // Single instance shared across widgets
                var gcodeDetails = new GCodeDetails(printer, printer.Bed.LoadedGCode);

                loadedGCodeSection.AddChild(
                    new SectionWidget(
                        "Details".Localize(),
                        new GCodeDetailsView(gcodeDetails, theme)
                {
                    HAnchor = HAnchor.Stretch,
                    Margin  = new BorderDouble(bottom: 3),
                    Padding = new BorderDouble(15, 4)
                },
                        theme)
                {
                    HAnchor = HAnchor.Stretch,
                    VAnchor = VAnchor.Fit
                });

                loadedGCodeSection.AddChild(
                    new SectionWidget(
                        "Layer".Localize(),
                        new GCodeLayerDetailsView(gcodeDetails, sceneContext, theme)
                {
                    HAnchor = HAnchor.Stretch,
                    Margin  = new BorderDouble(bottom: 3),
                    Padding = new BorderDouble(15, 4)
                },
                        theme)
                {
                    HAnchor = HAnchor.Stretch,
                    VAnchor = VAnchor.Fit
                });
            }

            // Enforce panel padding in sidebar
            this.EnsureSectionWidgetStyling(loadedGCodeSection.Children <SectionWidget>());

            this.Invalidate();
        }
        public MarkdownEditPage(UIField uiField)
        {
            this.WindowTitle = "MatterControl - " + "Markdown Edit".Localize();
            this.HeaderText  = "Edit Page".Localize() + ":";

            var tabControl = new SimpleTabs(theme, new GuiWidget())
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
            };

            tabControl.TabBar.BackgroundColor = theme.TabBarBackground;
            tabControl.TabBar.Padding         = 0;

            contentRow.AddChild(tabControl);
            contentRow.Padding = 0;

            var editContainer = new GuiWidget()
            {
                HAnchor         = HAnchor.Stretch,
                VAnchor         = VAnchor.Stretch,
                Padding         = theme.DefaultContainerPadding,
                BackgroundColor = theme.ActiveTabColor
            };

            editWidget = new MHTextEditWidget("", multiLine: true, typeFace: ApplicationController.GetTypeFace(NamedTypeFace.Liberation_Mono))
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
                Name    = this.Name
            };
            editWidget.DrawFromHintedCache();
            editWidget.ActualTextEditWidget.VAnchor = VAnchor.Stretch;

            editContainer.AddChild(editWidget);

            markdownWidget = new MarkdownWidget(theme, true)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
                Margin  = 0,
                Padding = 0,
            };

            var previewTab = new ToolTab("Preview".Localize(), tabControl, markdownWidget, theme, hasClose: false)
            {
                Name = "Preview Tab"
            };

            tabControl.AddTab(previewTab);

            var editTab = new ToolTab("Edit".Localize(), tabControl, editContainer, theme, hasClose: false)
            {
                Name = "Edit Tab"
            };

            tabControl.AddTab(editTab);

            tabControl.ActiveTabChanged += (s, e) =>
            {
                if (tabControl.SelectedTabIndex == 1)
                {
                    markdownWidget.Markdown = editWidget.Text;
                }
            };

            tabControl.SelectedTabIndex = 0;

            var saveButton = theme.CreateDialogButton("Save".Localize());

            saveButton.Click += (s, e) =>
            {
                uiField.SetValue(
                    editWidget.Text.Replace("\n", "\\n"),
                    userInitiated: true);

                this.DialogWindow.CloseOnIdle();
            };
            this.AddPageAction(saveButton);

            var link = new LinkLabel("Markdown Help", theme)
            {
                Margin  = new BorderDouble(right: 20),
                VAnchor = VAnchor.Center
            };

            link.Click += (s, e) =>
            {
                ApplicationController.Instance.LaunchBrowser("https://guides.github.com/features/mastering-markdown/");
            };
            footerRow.AddChild(link, 0);
        }
Exemple #16
0
        public AboutPage()
            : base("Close".Localize())
        {
            this.WindowTitle = "About".Localize() + " " + ApplicationController.Instance.ProductName;
            this.MinimumSize = new Vector2(480 * GuiWidget.DeviceScale, 520 * GuiWidget.DeviceScale);
            this.WindowSize  = new Vector2(500 * GuiWidget.DeviceScale, 550 * GuiWidget.DeviceScale);

            contentRow.BackgroundColor = Color.Transparent;

            headerRow.Visible = false;

            var altHeadingRow = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Absolute,
                Height  = 100,
            };

            contentRow.AddChild(altHeadingRow);

            var productInfo = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Center | HAnchor.Fit,
                VAnchor = VAnchor.Center | VAnchor.Fit
            };

            var productTitle = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Center | HAnchor.Fit
            };

            productTitle.AddChild(new TextWidget("MatterControl".Localize(), textColor: theme.TextColor, pointSize: 20)
            {
                Margin = new BorderDouble(right: 3)
            });
            productTitle.AddChild(new TextWidget("TM".Localize(), textColor: theme.TextColor, pointSize: 7)
            {
                VAnchor = VAnchor.Top
            });

            altHeadingRow.AddChild(productInfo);
            productInfo.AddChild(productTitle);

            var spinnerPanel = new GuiWidget()
            {
                HAnchor = HAnchor.Absolute | HAnchor.Left,
                VAnchor = VAnchor.Absolute,
                Height  = 100,
                Width   = 100,
            };

            altHeadingRow.AddChild(spinnerPanel);
            var accentColor = theme.PrimaryAccentColor;

            var spinner = new LogoSpinner(spinnerPanel, 4, 0.2, 0, rotateX: 0);

            productInfo.AddChild(
                new TextWidget("Version".Localize() + " " + VersionInfo.Instance.BuildVersion, textColor: theme.TextColor, pointSize: theme.DefaultFontSize)
            {
                HAnchor = HAnchor.Center
            });

            productInfo.AddChild(
                new TextWidget("Developed By".Localize() + ": " + "MatterHackers", textColor: theme.TextColor, pointSize: theme.DefaultFontSize)
            {
                HAnchor = HAnchor.Center
            });

            contentRow.AddChild(
                new WrappedTextWidget(
                    "MatterControl is made possible by the team at MatterHackers and other open source software".Localize() + ":",
                    pointSize: theme.DefaultFontSize,
                    textColor: theme.TextColor)
            {
                Margin = new BorderDouble(0, 15)
            });

            var licensePanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Margin  = new BorderDouble(bottom: 15)
            };

            var data = JsonConvert.DeserializeObject <List <LibraryLicense> >(StaticData.Instance.ReadAllText(Path.Combine("License", "license.json")));

            var linkIcon = StaticData.Instance.LoadIcon("fa-link_16.png", 16, 16).SetToColor(theme.TextColor);

            SectionWidget section = null;

            foreach (var item in data.OrderBy(i => i.Name))
            {
                var linkButton = new IconButton(linkIcon, theme);
                linkButton.Click += (s, e) => UiThread.RunOnIdle(() =>
                {
                    ApplicationController.LaunchBrowser(item.Url);
                });

                section = new SectionWidget(item.Title ?? item.Name, new LazyLicenseText(item.Name, theme), theme, linkButton, expanded: false)
                {
                    HAnchor = HAnchor.Stretch
                };
                licensePanel.AddChild(section);
            }

            // Apply a bottom border to the last time for balance
            if (section != null)
            {
                section.Border = section.Border.Clone(bottom: 1);
            }

            var scrollable = new ScrollableWidget(autoScroll: true)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch,
                Margin  = new BorderDouble(bottom: 10),
            };

            scrollable.ScrollArea.HAnchor = HAnchor.Stretch;
            scrollable.AddChild(licensePanel);
            contentRow.AddChild(scrollable);

            contentRow.AddChild(
                new TextWidget("Copyright © 2019 MatterHackers, Inc.", textColor: theme.TextColor, pointSize: theme.DefaultFontSize)
            {
                HAnchor = HAnchor.Center,
            });

            var siteLink = new LinkLabel("www.matterhackers.com", theme)
            {
                HAnchor   = HAnchor.Center,
                TextColor = theme.TextColor
            };

            siteLink.Click += (s, e) => UiThread.RunOnIdle(() =>
            {
                ApplicationController.LaunchBrowser("http://www.matterhackers.com");
            });
            contentRow.AddChild(siteLink);
        }
        public EditConnectionWidget(ConnectionWindow windowController, GuiWidget containerWindowToClose, Printer activePrinter = null, object state = null)
            : base(windowController, containerWindowToClose)
        {
            textImageButtonFactory.normalTextColor   = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.hoverTextColor    = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.disabledTextColor = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.pressedTextColor  = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.borderWidth       = 0;

            linkButtonFactory.textColor = ActiveTheme.Instance.PrimaryTextColor;
            linkButtonFactory.fontSize  = 8;

            this.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            this.AnchorAll();
            this.Padding = new BorderDouble(0);             //To be re-enabled once native borders are turned off

            GuiWidget mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);

            mainContainer.AnchorAll();
            mainContainer.Padding         = new BorderDouble(3, 3, 3, 5);
            mainContainer.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;

            string headerTitle;

            if (activePrinter == null)
            {
                headerTitle                 = string.Format("Add a Printer");
                this.addNewPrinterFlag      = true;
                this.ActivePrinter          = new Printer();
                this.ActivePrinter.Name     = "Default Printer";
                this.ActivePrinter.BaudRate = "250000";
                try
                {
                    this.ActivePrinter.ComPort = FrostedSerialPort.GetPortNames().FirstOrDefault();
                }
                catch (Exception e)
                {
                    Debug.Print(e.Message);
                    GuiWidget.BreakInDebugger();
                    //No active COM ports
                }
            }
            else
            {
                this.ActivePrinter = activePrinter;
                string editHeaderTitleTxt = LocalizedString.Get("Edit Printer");
                headerTitle = string.Format("{1} - {0}", this.ActivePrinter.Name, editHeaderTitleTxt);
                if (this.ActivePrinter.BaudRate == null)
                {
                    this.ActivePrinter.BaudRate = "250000";
                }
                if (this.ActivePrinter.ComPort == null)
                {
                    try
                    {
                        this.ActivePrinter.ComPort = FrostedSerialPort.GetPortNames().FirstOrDefault();
                    }
                    catch (Exception e)
                    {
                        Debug.Print(e.Message);
                        GuiWidget.BreakInDebugger();
                        //No active COM ports
                    }
                }
            }

            FlowLayoutWidget headerRow = new FlowLayoutWidget(FlowDirection.LeftToRight);

            headerRow.Margin  = new BorderDouble(0, 3, 0, 0);
            headerRow.Padding = new BorderDouble(0, 3, 0, 3);
            headerRow.HAnchor = HAnchor.ParentLeftRight;
            {
                TextWidget headerLabel = new TextWidget(headerTitle, pointSize: 14);
                headerLabel.TextColor = this.defaultTextColor;

                headerRow.AddChild(headerLabel);
            }

            ConnectionControlContainer                 = new FlowLayoutWidget(FlowDirection.TopToBottom);
            ConnectionControlContainer.Padding         = new BorderDouble(5);
            ConnectionControlContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            ConnectionControlContainer.HAnchor         = HAnchor.ParentLeftRight;
            {
                TextWidget printerNameLabel = new TextWidget(LocalizedString.Get("Name"), 0, 0, 10);
                printerNameLabel.TextColor = this.defaultTextColor;
                printerNameLabel.HAnchor   = HAnchor.ParentLeftRight;
                printerNameLabel.Margin    = new BorderDouble(0, 0, 0, 1);

                printerNameInput = new MHTextEditWidget(this.ActivePrinter.Name);

                printerNameInput.HAnchor |= HAnchor.ParentLeftRight;

                comPortLabelWidget = new FlowLayoutWidget();

                Button refreshComPorts = linkButtonFactory.Generate(LocalizedString.Get("(refresh)"));
                refreshComPorts.Margin  = new BorderDouble(left: 5);
                refreshComPorts.VAnchor = VAnchor.ParentBottom;
                refreshComPorts.Click  += new EventHandler(RefreshComPorts);

                FlowLayoutWidget comPortContainer = null;

#if !__ANDROID__
                TextWidget comPortLabel = new TextWidget(LocalizedString.Get("Serial Port"), 0, 0, 10);
                comPortLabel.TextColor = this.defaultTextColor;

                comPortLabelWidget.AddChild(comPortLabel);
                comPortLabelWidget.AddChild(refreshComPorts);
                comPortLabelWidget.Margin  = new BorderDouble(0, 0, 0, 10);
                comPortLabelWidget.HAnchor = HAnchor.ParentLeftRight;

                comPortContainer         = new FlowLayoutWidget(FlowDirection.TopToBottom);
                comPortContainer.Margin  = new BorderDouble(0);
                comPortContainer.HAnchor = HAnchor.ParentLeftRight;

                CreateSerialPortControls(comPortContainer, this.ActivePrinter.ComPort);
#endif

                TextWidget baudRateLabel = new TextWidget(LocalizedString.Get("Baud Rate"), 0, 0, 10);
                baudRateLabel.TextColor = this.defaultTextColor;
                baudRateLabel.Margin    = new BorderDouble(0, 0, 0, 10);
                baudRateLabel.HAnchor   = HAnchor.ParentLeftRight;

                baudRateWidget         = GetBaudRateWidget();
                baudRateWidget.HAnchor = HAnchor.ParentLeftRight;

                FlowLayoutWidget printerMakeContainer  = createPrinterMakeContainer();
                FlowLayoutWidget printerModelContainer = createPrinterModelContainer();

                enableAutoconnect           = new CheckBox(LocalizedString.Get("Auto Connect"));
                enableAutoconnect.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                enableAutoconnect.Margin    = new BorderDouble(top: 10);
                enableAutoconnect.HAnchor   = HAnchor.ParentLeft;
                if (this.ActivePrinter.AutoConnectFlag)
                {
                    enableAutoconnect.Checked = true;
                }

                if (state as StateBeforeRefresh != null)
                {
                    enableAutoconnect.Checked = ((StateBeforeRefresh)state).autoConnect;
                }

                SerialPortControl serialPortScroll = new SerialPortControl();

                if (comPortContainer != null)
                {
                    serialPortScroll.AddChild(comPortContainer);
                }

                ConnectionControlContainer.VAnchor = VAnchor.ParentBottomTop;
                ConnectionControlContainer.AddChild(printerNameLabel);
                ConnectionControlContainer.AddChild(printerNameInput);
                ConnectionControlContainer.AddChild(printerMakeContainer);
                ConnectionControlContainer.AddChild(printerModelContainer);
                ConnectionControlContainer.AddChild(comPortLabelWidget);
                ConnectionControlContainer.AddChild(serialPortScroll);
                ConnectionControlContainer.AddChild(baudRateLabel);
                ConnectionControlContainer.AddChild(baudRateWidget);
#if !__ANDROID__
                ConnectionControlContainer.AddChild(enableAutoconnect);
#endif
            }

            FlowLayoutWidget buttonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
            buttonContainer.HAnchor = HAnchor.ParentLeft | HAnchor.ParentRight;
            //buttonContainer.VAnchor = VAnchor.BottomTop;
            buttonContainer.Margin = new BorderDouble(0, 5, 0, 3);
            {
                //Construct buttons
                saveButton = textImageButtonFactory.Generate(LocalizedString.Get("Save"));
                //saveButton.VAnchor = VAnchor.Bottom;

                cancelButton = textImageButtonFactory.Generate(LocalizedString.Get("Cancel"));
                //cancelButton.VAnchor = VAnchor.Bottom;
                cancelButton.Click += new EventHandler(CancelButton_Click);

                //Add buttons to buttonContainer
                buttonContainer.AddChild(saveButton);
                buttonContainer.AddChild(new HorizontalSpacer());
                buttonContainer.AddChild(cancelButton);
            }

            //mainContainer.AddChild(new PrinterChooser());

            mainContainer.AddChild(headerRow);
            mainContainer.AddChild(ConnectionControlContainer);
            mainContainer.AddChild(buttonContainer);

#if __ANDROID__
            this.AddChild(new SoftKeyboardContentOffset(mainContainer));
#else
            this.AddChild(mainContainer);
#endif

            BindSaveButtonHandlers();
            BindBaudRateHandlers();
        }
        public static GuiWidget CreatePropertyEditor(EditableProperty property, UndoBuffer undoBuffer, PPEContext context, ThemeConfig theme)
        {
            var object3D             = property.Item;
            var propertyGridModifier = property.Item as IPropertyGridModifier;

            GuiWidget rowContainer = null;

            // Get reflected property value once, then test for each case below
            var propertyValue = property.Value;

            void RegisterValueChanged(UIField field, Func <string, object> valueFromString, Func <object, string> valueToString = null)
            {
                field.ValueChanged += (s, e) =>
                {
                    var newValue = field.Value;
                    var oldValue = property.Value.ToString();
                    if (valueToString != null)
                    {
                        oldValue = valueToString(property.Value);
                    }

                    //field.Content
                    if (undoBuffer != null)
                    {
                        undoBuffer.AddAndDo(new UndoRedoActions(() =>
                        {
                            property.SetValue(valueFromString(oldValue));
                            object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                            propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                        },
                                                                () =>
                        {
                            property.SetValue(valueFromString(newValue));
                            object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                            propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                        }));
                    }
                    else
                    {
                        property.SetValue(valueFromString(newValue));
                        object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                        propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                    }
                };
            }

            // create a double editor
            if (propertyValue is double doubleValue)
            {
                var field = new DoubleField(theme);
                field.Initialize(0);
                field.DoubleValue = doubleValue;
                RegisterValueChanged(field, (valueString) => { return(double.Parse(valueString)); });

                void RefreshField(object s, InvalidateArgs e)
                {
                    if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues))
                    {
                        double newValue = (double)property.Value;
                        if (newValue != field.DoubleValue)
                        {
                            field.DoubleValue = newValue;
                        }
                    }
                }

                object3D.Invalidated += RefreshField;
                field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField;

                rowContainer = CreateSettingsRow(property, field);
            }
            else if (propertyValue is Color color)
            {
                var field = new ColorField(theme, object3D.Color);
                field.Initialize(0);
                field.ValueChanged += (s, e) =>
                {
                    property.SetValue(field.Color);
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                rowContainer = CreateSettingsRow(property, field);
            }
            else if (propertyValue is Vector2 vector2)
            {
                var field = new Vector2Field(theme);
                field.Initialize(0);
                field.Vector2 = vector2;
                RegisterValueChanged(field,
                                     (valueString) => { return(Vector2.Parse(valueString)); },
                                     (value) =>
                {
                    var s = ((Vector2)value).ToString();
                    return(s.Substring(1, s.Length - 2));
                });
                rowContainer = CreateSettingsColumn(property, field);
            }
            else if (propertyValue is Vector3 vector3)
            {
                var field = new Vector3Field(theme);
                field.Initialize(0);
                field.Vector3 = vector3;
                RegisterValueChanged(field,
                                     (valueString) => { return(Vector3.Parse(valueString)); },
                                     (value) =>
                {
                    var s = ((Vector3)value).ToString();
                    return(s.Substring(1, s.Length - 2));
                });
                rowContainer = CreateSettingsColumn(property, field);
            }
            else if (propertyValue is DirectionVector directionVector)
            {
                var field = new DirectionVectorField(theme);
                field.Initialize(0);
                field.SetValue(directionVector);
                field.ValueChanged += (s, e) =>
                {
                    property.SetValue(field.DirectionVector);
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                rowContainer = CreateSettingsRow(property, field);
            }
            else if (propertyValue is DirectionAxis directionAxis)
            {
                rowContainer = CreateSettingsColumn(property);
                var newDirectionVector = new DirectionVector()
                {
                    Normal = directionAxis.Normal
                };
                var row1   = CreateSettingsRow("Axis".Localize());
                var field1 = new DirectionVectorField(theme);
                field1.Initialize(0);
                field1.SetValue(newDirectionVector);
                row1.AddChild(field1.Content);

                rowContainer.AddChild(row1);

                // the direction axis
                // the distance from the center of the part
                // create a double editor
                var field2 = new Vector3Field(theme);
                field2.Initialize(0);
                field2.Vector3 = directionAxis.Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center;
                var row2 = CreateSettingsColumn("Offset", field2);

                // update this when changed
                EventHandler <InvalidateArgs> updateData = (s, e) =>
                {
                    field2.Vector3 = ((DirectionAxis)property.Value).Origin - property.Item.Children.First().GetAxisAlignedBoundingBox().Center;
                };
                property.Item.Invalidated += updateData;
                field2.Content.Closed     += (s, e) =>
                {
                    property.Item.Invalidated -= updateData;
                };

                // update functions
                field1.ValueChanged += (s, e) =>
                {
                    property.SetValue(new DirectionAxis()
                    {
                        Normal = field1.DirectionVector.Normal,
                        Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3
                    });
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };
                field2.ValueChanged += (s, e) =>
                {
                    property.SetValue(new DirectionAxis()
                    {
                        Normal = field1.DirectionVector.Normal,
                        Origin = property.Item.Children.First().GetAxisAlignedBoundingBox().Center + field2.Vector3
                    });
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                rowContainer.AddChild(row2);
            }
            else if (propertyValue is SelectedChildren childSelector)
            {
                var showAsList = property.PropertyInfo.GetCustomAttributes(true).OfType <ShowAsListAttribute>().FirstOrDefault() != null;
                if (showAsList)
                {
                    UIField field = new ChildrenSelectorListField(property, theme);

                    field.Initialize(0);
                    RegisterValueChanged(field,
                                         (valueString) =>
                    {
                        var childrenSelector = new SelectedChildren();
                        foreach (var child in valueString.Split(','))
                        {
                            childrenSelector.Add(child);
                        }
                        return(childrenSelector);
                    });

                    rowContainer = CreateSettingsRow(property, field);
                }
                else                 // show the subtract editor for boolean subtract and subtract and replace
                {
                    rowContainer = CreateSettingsColumn(property);
                    if (property.Item is OperationSourceContainerObject3D sourceContainer)
                    {
                        rowContainer.AddChild(CreateSourceChildSelector(childSelector, sourceContainer, theme));
                    }
                    else
                    {
                        rowContainer.AddChild(CreateSelector(childSelector, property.Item, theme));
                    }
                }
            }
            else if (propertyValue is ImageBuffer imageBuffer)
            {
                rowContainer = CreateSettingsColumn(property);
                rowContainer.AddChild(CreateImageDisplay(imageBuffer, property.Item, theme));
            }
#if !__ANDROID__
            else if (propertyValue is List <string> stringList)
            {
                var selectedItem = ApplicationController.Instance.DragDropData.SceneContext.Scene.SelectedItem;

                var field = new SurfacedEditorsField(theme, selectedItem);
                field.Initialize(0);
                field.ListValue     = stringList;
                field.ValueChanged += (s, e) =>
                {
                    property.SetValue(field.ListValue);
                };

                rowContainer = CreateSettingsColumn(property, field);

                rowContainer.Descendants <HorizontalSpacer>().FirstOrDefault()?.Close();
            }
#endif
            // create a int editor
            else if (propertyValue is int intValue)
            {
                var field = new IntField(theme);
                field.Initialize(0);
                field.IntValue = intValue;
                RegisterValueChanged(field, (valueString) => { return(int.Parse(valueString)); });

                void RefreshField(object s, InvalidateArgs e)
                {
                    if (e.InvalidateType.HasFlag(InvalidateType.DisplayValues))
                    {
                        int newValue = (int)property.Value;
                        if (newValue != field.IntValue)
                        {
                            field.IntValue = newValue;
                        }
                    }
                }

                object3D.Invalidated += RefreshField;
                field.Content.Closed += (s, e) => object3D.Invalidated -= RefreshField;

                rowContainer = CreateSettingsRow(property, field);
            }
            // create a bool editor
            else if (propertyValue is bool boolValue)
            {
                var field = new ToggleboxField(theme);
                field.Initialize(0);
                field.Checked = boolValue;

                RegisterValueChanged(field,
                                     (valueString) => { return(valueString == "1"); },
                                     (value) => { return(((bool)(value)) ? "1" : "0"); });
                rowContainer = CreateSettingsRow(property, field);
            }
            // create a string editor
            else if (propertyValue is string stringValue)
            {
                var field = new TextField(theme);
                field.Initialize(0);
                field.SetValue(stringValue, false);
                field.Content.HAnchor = HAnchor.Stretch;
                RegisterValueChanged(field, (valueString) => valueString);
                rowContainer = CreateSettingsRow(property, field);

                var label = rowContainer.Children.First();

                if (field is TextField)
                {
                    var spacer = rowContainer.Children.OfType <HorizontalSpacer>().FirstOrDefault();
                    spacer.HAnchor = HAnchor.Absolute;
                    spacer.Width   = Math.Max(0, 100 - label.Width);
                }
            }
            // create a char editor
            else if (propertyValue is char charValue)
            {
                var field = new CharField(theme);
                field.Initialize(0);
                field.SetValue(charValue.ToString(), false);
                field.ValueChanged += (s, e) =>
                {
                    property.SetValue(Convert.ToChar(field.Value));
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                rowContainer = CreateSettingsRow(property, field);
            }
            // create an enum editor
            else if (property.PropertyType.IsEnum)
            {
                UIField field;
                var     iconsAttribute = property.PropertyInfo.GetCustomAttributes(true).OfType <IconsAttribute>().FirstOrDefault();
                if (iconsAttribute != null)
                {
                    field = new IconEnumField(property, iconsAttribute, theme)
                    {
                        InitialValue = propertyValue.ToString()
                    };
                }
                else
                {
                    field = new EnumField(property, theme);
                }

                field.Initialize(0);
                RegisterValueChanged(field,
                                     (valueString) =>
                {
                    return(Enum.Parse(property.PropertyType, valueString));
                });

                field.ValueChanged += (s, e) =>
                {
                    property.SetValue(Enum.Parse(property.PropertyType, field.Value));
                    object3D?.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    propertyGridModifier?.UpdateControls(new PublicPropertyChange(context, property.PropertyInfo.Name));
                };

                rowContainer = CreateSettingsRow(property, field, theme);
            }
            // Use known IObject3D editors
            else if (propertyValue is IObject3D item &&
                     ApplicationController.Instance.Extensions.GetEditorsForType(property.PropertyType)?.FirstOrDefault() is IObject3DEditor iObject3DEditor)
            {
                rowContainer = iObject3DEditor.Create(item, theme);
            }

            // remember the row name and widget
            context.editRows.Add(property.PropertyInfo.Name, rowContainer);

            return(rowContainer);
        }
        public void SetActiveItem(ISceneContext sceneContext)
        {
            var selectedItem = sceneContext?.Scene?.SelectedItem;

            if (this.item == selectedItem)
            {
                return;
            }

            this.item = selectedItem;
            editorPanel.CloseAllChildren();

            // Allow caller to clean up with passing null for selectedItem
            if (item == null)
            {
                editorSectionWidget.Text = editorTitle;
                return;
            }

            var selectedItemType = selectedItem.GetType();

            primaryActionsPanel.RemoveAllChildren();

            IEnumerable <SceneOperation> primaryActions;

            if ((primaryActions = SceneOperations.GetPrimaryOperations(selectedItemType)) == null)
            {
                primaryActions = new List <SceneOperation>();
            }
            else
            {
                // Loop over primary actions creating a button for each
                foreach (var primaryAction in primaryActions)
                {
                    // TODO: Run visible/enable rules on actions, conditionally add/enable as appropriate
                    var button = new IconButton(primaryAction.Icon(theme.InvertIcons), theme)
                    {
                        // Name = namedAction.Title + " Button",
                        ToolTipText     = primaryAction.Title,
                        Margin          = theme.ButtonSpacing,
                        BackgroundColor = theme.ToolbarButtonBackground,
                        HoverColor      = theme.ToolbarButtonHover,
                        MouseDownColor  = theme.ToolbarButtonDown,
                    };

                    button.Click += (s, e) =>
                    {
                        primaryAction.Action.Invoke(sceneContext);
                    };

                    primaryActionsPanel.AddChild(button);
                }
            }

            if (primaryActionsPanel.Children.Any())
            {
                // add in a separator from the apply and cancel buttons
                primaryActionsPanel.AddChild(new ToolbarSeparator(theme));
            }

            editorSectionWidget.Text = selectedItem.Name ?? selectedItemType.Name;

            HashSet <IObject3DEditor> mappedEditors = ApplicationController.Instance.Extensions.GetEditorsForType(selectedItemType);

            var undoBuffer = sceneContext.Scene.UndoBuffer;

            // put in a color edit field
            var colorField = new ColorField(theme, selectedItem.Color);

            colorField.Initialize(0);
            colorField.ValueChanged += (s, e) =>
            {
                if (selectedItem.Color != colorField.Color)
                {
                    undoBuffer.AddAndDo(new ChangeColor(selectedItem, colorField.Color));
                }
            };

            colorField.Content.MouseDown += (s, e) =>
            {
                // make sure the render mode is set to shaded or outline
                if (sceneContext.ViewState.RenderType != RenderOpenGl.RenderTypes.Shaded &&
                    sceneContext.ViewState.RenderType != RenderOpenGl.RenderTypes.Outlines)
                {
                    // make sure the render mode is set to outline
                    sceneContext.ViewState.RenderType = RenderOpenGl.RenderTypes.Outlines;
                }
            };

            // color row
            var row = new SettingsRow("Color".Localize(), null, colorField.Content, theme);

            // Special top border style for first item in editor
            row.Border = new BorderDouble(0, 1);

            editorPanel.AddChild(row);

            // put in a material edit field
            var materialField = new MaterialIndexField(theme, selectedItem.MaterialIndex);

            materialField.Initialize(0);
            materialField.ValueChanged += (s, e) =>
            {
                if (selectedItem.MaterialIndex != materialField.MaterialIndex)
                {
                    undoBuffer.AddAndDo(new ChangeMaterial(selectedItem, materialField.MaterialIndex));
                }
            };

            materialField.Content.MouseDown += (s, e) =>
            {
                if (sceneContext.ViewState.RenderType != RenderOpenGl.RenderTypes.Materials)
                {
                    // make sure the render mode is set to material
                    sceneContext.ViewState.RenderType = RenderOpenGl.RenderTypes.Materials;
                }
            };

            // material row
            editorPanel.AddChild(
                new SettingsRow("Material".Localize(), null, materialField.Content, theme));

            // put in the normal editor
            if (selectedItem is ComponentObject3D componentObject &&
                componentObject.Finalized)
            {
                PublicPropertyEditor.AddUnlockLinkIfRequired(selectedItem, editorPanel, theme);
                foreach (var selector in componentObject.SurfacedEditors)
                {
                    // Get the named property via reflection
                    // Selector example:            '$.Children<CylinderObject3D>'
                    var match = pathResolver.Select(componentObject, selector).ToList();

                    //// TODO: Create editor row for each property
                    //// - Use the type of the property to find a matching editor (ideally all datatype -> editor functionality would resolve consistently)
                    //// - Add editor row for each

                    foreach (var instance in match)
                    {
                        if (instance is IObject3D object3D)
                        {
                            if (ApplicationController.Instance.Extensions.GetEditorsForType(object3D.GetType())?.FirstOrDefault() is IObject3DEditor editor)
                            {
                                ShowObjectEditor((editor, object3D, object3D.Name), selectedItem);
                            }
                        }
                        else if (JsonPath.JsonPathContext.ReflectionValueSystem.LastMemberValue is ReflectionTarget reflectionTarget)
                        {
                            var context = new PPEContext();

                            if (reflectionTarget.Source is IObject3D editedChild)
                            {
                                context.item = editedChild;
                            }
                            else
                            {
                                context.item = item;
                            }

                            var editableProperty = new EditableProperty(reflectionTarget.PropertyInfo, reflectionTarget.Source);

                            var editor = PublicPropertyEditor.CreatePropertyEditor(editableProperty, undoBuffer, context, theme);
                            if (editor != null)
                            {
                                editorPanel.AddChild(editor);
                            }
                        }
                    }
                }

                // Enforce panel padding
                foreach (var sectionWidget in editorPanel.Descendants <SectionWidget>())
                {
                    sectionWidget.Margin = 0;
                }
            }
Exemple #20
0
        public void SingleItemVisibleTest()
        {
            {
                ListBox containerListBox = new ListBox(new RectangleDouble(0, 0, 100, 100));
                ListBoxTextItem itemToAddToList = new ListBoxTextItem("test Item", "test data for item");
                itemToAddToList.Name = "list item";
                containerListBox.AddChild(itemToAddToList);
                containerListBox.DoubleBuffer = true;
                containerListBox.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
                containerListBox.OnDraw(containerListBox.BackBuffer.NewGraphics2D());

                ImageBuffer textImage = new ImageBuffer(80, 16, 32, new BlenderBGRA());
                textImage.NewGraphics2D().Clear(RGBA_Bytes.White);
                textImage.NewGraphics2D().DrawString("test Item", 1, 1);

                OutputImage(containerListBox.BackBuffer, "test.tga");
                OutputImage(textImage, "control.tga");

                double maxError = 20000000;
                Vector2 bestPosition;
                double leastSquares;
                containerListBox.BackBuffer.FindLeastSquaresMatch(textImage, out bestPosition, out leastSquares, maxError);

                Assert.IsTrue(leastSquares < maxError, "The list box need to be showing the item we added to it.");
            }

            {
                GuiWidget container = new GuiWidget(202, 302);
                container.DoubleBuffer = true;
                container.NewGraphics2D().Clear(RGBA_Bytes.White);
                FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget();
                leftToRightLayout.AnchorAll();
                {
                    {
                        ListBox listBox = new ListBox(new RectangleDouble(0, 0, 200, 300));
                        //listBox.BackgroundColor = RGBA_Bytes.Red;
                        listBox.Name = "listBox";
                        listBox.VAnchor = UI.VAnchor.ParentTop;
                        listBox.ScrollArea.Margin = new BorderDouble(15);
                        leftToRightLayout.AddChild(listBox);

                        for (int i = 0; i < 1; i++)
                        {
                            ListBoxTextItem newItem = new ListBoxTextItem("hand" + i.ToString() + ".stl", "c:\\development\\hand" + i.ToString() + ".stl");
                            newItem.Name = "ListBoxItem" + i.ToString();
                            listBox.AddChild(newItem);
                        }
                    }
                }

                container.AddChild(leftToRightLayout);
                container.OnDraw(container.NewGraphics2D());

                ImageBuffer textImage = new ImageBuffer(80, 16, 32, new BlenderBGRA());
                textImage.NewGraphics2D().Clear(RGBA_Bytes.White);
                textImage.NewGraphics2D().DrawString("hand0.stl", 1, 1);

                OutputImage(container.BackBuffer, "control.tga");
                OutputImage(textImage, "test.tga");

                double maxError = 1000000;
                Vector2 bestPosition;
                double leastSquares;
                container.BackBuffer.FindLeastSquaresMatch(textImage, out bestPosition, out leastSquares, maxError);

                Assert.IsTrue(leastSquares < maxError, "The list box need to be showing the item we added to it.");
            }
        }
Exemple #21
0
        public void ListMenuTests()
        {
            string menuSelected = "";

            GuiWidget container = new GuiWidget(400, 400);
            TextWidget menueView = new TextWidget("Edit");
            Menu listMenu = new Menu(menueView);
            listMenu.OriginRelativeParent = new Vector2(10, 300);
            
            MenuItem cutMenuItem = new MenuItem(new TextWidget("Cut"));
            cutMenuItem.Selected += (sender, e) => { menuSelected = "Cut"; };
            listMenu.MenuItems.Add(cutMenuItem);

            MenuItem copyMenuItem = new MenuItem(new TextWidget("Copy"));
            copyMenuItem.Selected += (sender, e) => { menuSelected = "Copy"; };
            listMenu.MenuItems.Add(copyMenuItem);
            
            MenuItem pastMenuItem = new MenuItem(new TextWidget("Paste"));
            pastMenuItem.Selected += (sender, e) => { menuSelected = "Paste"; };
            listMenu.MenuItems.Add(pastMenuItem);

            container.AddChild(listMenu);

            Assert.IsTrue(!listMenu.IsOpen);

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // all the menu itmes should be added to the open menu
            Assert.IsTrue(cutMenuItem.Parent != null);
            Assert.IsTrue(copyMenuItem.Parent != null);
            Assert.IsTrue(pastMenuItem.Parent != null);

            // click on menu again to close
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            // all the mune itmes should be removed from the closed menu
            Assert.IsTrue(cutMenuItem.Parent == null);
            Assert.IsTrue(copyMenuItem.Parent == null);
            Assert.IsTrue(pastMenuItem.Parent == null);

            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);

            // all the menu itmes should be removed from the closed menu
            Assert.IsTrue(cutMenuItem.Parent == null);
            Assert.IsTrue(copyMenuItem.Parent == null);
            Assert.IsTrue(pastMenuItem.Parent == null);

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            // all the menu itmes should be added to the open menu
            Assert.IsTrue(cutMenuItem.Parent != null);
            Assert.IsTrue(copyMenuItem.Parent != null);
            Assert.IsTrue(pastMenuItem.Parent != null);

            // click off menu to close
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 5, 299, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            // all the mune itmes should be removed from the closed menu
            Assert.IsTrue(cutMenuItem.Parent == null);
            Assert.IsTrue(copyMenuItem.Parent == null);
            Assert.IsTrue(pastMenuItem.Parent == null);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 5, 299, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);

            // open the menu again
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // select the first item
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            Assert.IsTrue(menuSelected == "Cut");

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // select the second item
            menuSelected = "";
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 275, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 275, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            Assert.IsTrue(menuSelected == "Copy");

            // make sure click down then move off item does not select it.
            menuSelected = "";
            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // click down on the first item
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            // move off of it
            container.OnMouseMove(new MouseEventArgs(MouseButtons.None, 1, 5, 290, 0));
            UiThread.DoRunAllPending();
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 5, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            Assert.IsTrue(menuSelected == "");

            // make sure click down and then move to new items selects the new item.

            // click and draw down to item should work as well
        }
        private void AddChildElements()
        {
            GuiWidget mainContainer = new GuiWidget();

            mainContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
            mainContainer.VAnchor = VAnchor.ParentBottomTop;

            TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
            {
                GuiWidget indicator = new GuiWidget();
                indicator.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
                indicator.Width   = 15;
                if (printTask.PrintComplete)
                {
                    indicator.BackgroundColor = new RGBA_Bytes(38, 147, 51, 180);
                }
                else
                {
                    indicator.BackgroundColor = new RGBA_Bytes(252, 209, 22, 180);
                }

                FlowLayoutWidget middleColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
                middleColumn.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
                middleColumn.Padding = new BorderDouble(6, 3);
                {
                    FlowLayoutWidget labelContainer = new FlowLayoutWidget();
                    labelContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;

                    string labelName = textInfo.ToTitleCase(printTask.PrintName);
                    labelName           = labelName.Replace('_', ' ');
                    partLabel           = new TextWidget(labelName, pointSize: 15 * pointSizeFactor);
                    partLabel.TextColor = WidgetTextColor;

                    labelContainer.AddChild(partLabel);

                    middleColumn.AddChild(labelContainer);
                }

                RGBA_Bytes timeTextColor = new RGBA_Bytes(34, 34, 34);

                FlowLayoutWidget buttonContainer = new FlowLayoutWidget();
                buttonContainer.Margin  = new BorderDouble(0);
                buttonContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
                {
                    TextWidget statusIndicator = new TextWidget("Status: Completed".Localize(), pointSize: 8 * pointSizeFactor);
                    statusIndicator.Margin = new BorderDouble(right: 3);
                    //buttonContainer.AddChild(statusIndicator);

                    string     printTimeLabel     = "Time".Localize().ToUpper();
                    string     printTimeLabelFull = string.Format("{0}: ", printTimeLabel);
                    TextWidget timeLabel          = new TextWidget(printTimeLabelFull, pointSize: 8 * pointSizeFactor);
                    timeLabel.TextColor = timeTextColor;

                    TextWidget timeIndicator;
                    int        minutes = printTask.PrintTimeMinutes;
                    if (minutes < 0)
                    {
                        timeIndicator = new TextWidget("Unknown".Localize());
                    }
                    else if (minutes > 60)
                    {
                        timeIndicator = new TextWidget("{0}hrs {1}min".FormatWith(printTask.PrintTimeMinutes / 60, printTask.PrintTimeMinutes % 60), pointSize: 12 * pointSizeFactor);
                    }
                    else
                    {
                        timeIndicator = new TextWidget(string.Format("{0}min", printTask.PrintTimeMinutes), pointSize: 12 * pointSizeFactor);
                    }

                    if (printTask.PercentDone > 0)
                    {
                        timeIndicator.AutoExpandBoundsToText = true;
                        timeIndicator.Text += $" ({printTask.PercentDone:0.0}%)";

                        if (printTask.RecoveryCount > 0)
                        {
                            if (printTask.RecoveryCount == 1)
                            {
                                timeIndicator.Text += " - " + "recovered once".Localize();
                            }
                            else
                            {
                                timeIndicator.Text += " - " + "recovered {0} times".FormatWith(printTask.RecoveryCount);
                            }
                        }
                    }

                    timeIndicator.Margin    = new BorderDouble(right: 6);
                    timeIndicator.TextColor = timeTextColor;

                    buttonContainer.AddChild(timeLabel);
                    buttonContainer.AddChild(timeIndicator);
                    buttonContainer.AddChild(new HorizontalSpacer());
                    middleColumn.AddChild(buttonContainer);
                }

                GuiWidget primaryContainer = new GuiWidget();
                primaryContainer.HAnchor = HAnchor.ParentLeftRight;
                primaryContainer.VAnchor = VAnchor.ParentBottomTop;

                FlowLayoutWidget primaryFlow = new FlowLayoutWidget(FlowDirection.LeftToRight);
                primaryFlow.HAnchor = HAnchor.ParentLeftRight;
                primaryFlow.VAnchor = VAnchor.ParentBottomTop;

                primaryFlow.AddChild(indicator);
                primaryFlow.AddChild(middleColumn);

                primaryContainer.AddChild(primaryFlow);

                rightButtonOverlay         = new SlideWidget();
                rightButtonOverlay.VAnchor = VAnchor.ParentBottomTop;
                rightButtonOverlay.HAnchor = Agg.UI.HAnchor.ParentRight;
                rightButtonOverlay.Width   = rightOverlayWidth;
                rightButtonOverlay.Visible = false;

                FlowLayoutWidget rightMiddleColumnContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);
                rightMiddleColumnContainer.VAnchor = VAnchor.ParentBottomTop;
                {
                    TextWidget viewLabel = new TextWidget("View".Localize());
                    viewLabel.TextColor = RGBA_Bytes.White;
                    viewLabel.VAnchor   = VAnchor.ParentCenter;
                    viewLabel.HAnchor   = HAnchor.ParentCenter;

                    FatFlatClickWidget viewButton = new FatFlatClickWidget(viewLabel);
                    viewButton.VAnchor         = VAnchor.ParentBottomTop;
                    viewButton.BackgroundColor = ActiveTheme.Instance.SecondaryAccentColor;
                    viewButton.Width           = actionButtonSize;
                    viewButton.Click          += ViewButton_Click;
                    rightMiddleColumnContainer.AddChild(viewButton);

                    TextWidget printLabel = new TextWidget("Print".Localize());
                    printLabel.TextColor = RGBA_Bytes.White;
                    printLabel.VAnchor   = VAnchor.ParentCenter;
                    printLabel.HAnchor   = HAnchor.ParentCenter;

                    FatFlatClickWidget printButton = new FatFlatClickWidget(printLabel);
                    printButton.VAnchor         = VAnchor.ParentBottomTop;
                    printButton.BackgroundColor = ActiveTheme.Instance.PrimaryAccentColor;
                    printButton.Width           = actionButtonSize;
                    printButton.Click          += (sender, e) =>
                    {
                        UiThread.RunOnIdle(() =>
                        {
                            if (!PrinterCommunication.PrinterConnectionAndCommunication.Instance.PrintIsActive)
                            {
                                QueueData.Instance.AddItem(new PrintItemWrapper(printTask.PrintItemId), 0);
                                QueueData.Instance.SelectedIndex = 0;
                                PrinterCommunication.PrinterConnectionAndCommunication.Instance.PrintActivePartIfPossible();
                            }
                            else
                            {
                                QueueData.Instance.AddItem(new PrintItemWrapper(printTask.PrintItemId));
                            }
                            rightButtonOverlay.SlideOut();
                        });
                    };
                    rightMiddleColumnContainer.AddChild(printButton);
                }
                rightButtonOverlay.AddChild(rightMiddleColumnContainer);

                if (showTimestamp)
                {
                    FlowLayoutWidget timestampColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
                    timestampColumn.VAnchor         = Agg.UI.VAnchor.ParentBottomTop;
                    timestampColumn.BackgroundColor = RGBA_Bytes.LightGray;
                    timestampColumn.Padding         = new BorderDouble(6, 0);

                    FlowLayoutWidget startTimeContainer = new FlowLayoutWidget();
                    startTimeContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
                    startTimeContainer.Padding = new BorderDouble(0, 3);

                    string     startLabelFull = "{0}:".FormatWith("Start".Localize().ToUpper());
                    TextWidget startLabel     = new TextWidget(startLabelFull, pointSize: 8 * pointSizeFactor);
                    startLabel.TextColor = timeTextColor;

                    string     startTimeString = printTask.PrintStart.ToString("MMM d yyyy h:mm ") + printTask.PrintStart.ToString("tt").ToLower();
                    TextWidget startDate       = new TextWidget(startTimeString, pointSize: 12 * pointSizeFactor);
                    startDate.TextColor = timeTextColor;

                    startTimeContainer.AddChild(startLabel);
                    startTimeContainer.AddChild(new HorizontalSpacer());
                    startTimeContainer.AddChild(startDate);

                    FlowLayoutWidget endTimeContainer = new FlowLayoutWidget();
                    endTimeContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
                    endTimeContainer.Padding = new BorderDouble(0, 3);

                    string     endLabelFull = "{0}:".FormatWith("End".Localize().ToUpper());
                    TextWidget endLabel     = new TextWidget(endLabelFull, pointSize: 8 * pointSizeFactor);
                    endLabel.TextColor = timeTextColor;

                    string endTimeString;
                    if (printTask.PrintEnd != DateTime.MinValue)
                    {
                        endTimeString = printTask.PrintEnd.ToString("MMM d yyyy h:mm ") + printTask.PrintEnd.ToString("tt").ToLower();
                    }
                    else
                    {
                        endTimeString = "Unknown".Localize();
                    }

                    TextWidget endDate = new TextWidget(endTimeString, pointSize: 12 * pointSizeFactor);
                    endDate.TextColor = timeTextColor;

                    endTimeContainer.AddChild(endLabel);
                    endTimeContainer.AddChild(new HorizontalSpacer());
                    endTimeContainer.AddChild(endDate);

                    HorizontalLine horizontalLine = new HorizontalLine();
                    horizontalLine.BackgroundColor = RGBA_Bytes.Gray;

                    timestampColumn.AddChild(endTimeContainer);
                    timestampColumn.AddChild(horizontalLine);
                    timestampColumn.AddChild(startTimeContainer);

                    timestampColumn.HAnchor = HAnchor.ParentLeftRight;
                    timestampColumn.Padding = new BorderDouble(5, 0, 15, 0);

                    primaryFlow.AddChild(timestampColumn);
                }

                mainContainer.AddChild(primaryContainer);
                mainContainer.AddChild(rightButtonOverlay);

                this.AddChild(mainContainer);
            }
        }
Exemple #23
0
		internal void EnsureNestedAreMinimumSize()
		{
			{
				GuiWidget containerTest = new GuiWidget(640, 480);
				containerTest.DoubleBuffer = true;
				FlowLayoutWidget leftToRightLayout = new FlowLayoutWidget(FlowDirection.LeftToRight);
				containerTest.AddChild(leftToRightLayout);

				GuiWidget item1 = new GuiWidget(10, 11);
				GuiWidget item2 = new GuiWidget(20, 22);
				GuiWidget item3 = new GuiWidget(30, 33);
				item3.HAnchor = HAnchor.ParentLeftRight;

				leftToRightLayout.AddChild(item1);
				leftToRightLayout.AddChild(item2);
				leftToRightLayout.AddChild(item3);

				containerTest.OnDraw(containerTest.NewGraphics2D());
				Assert.IsTrue(leftToRightLayout.Width == 60);
				Assert.IsTrue(leftToRightLayout.MinimumSize.x == 0);
				Assert.IsTrue(leftToRightLayout.Height == 33);
				Assert.IsTrue(leftToRightLayout.MinimumSize.y == 0);
				Assert.IsTrue(item3.Width == 30);

				containerTest.Width = 650;
				containerTest.OnDraw(containerTest.NewGraphics2D());
				Assert.IsTrue(leftToRightLayout.Width == 60);
				Assert.IsTrue(leftToRightLayout.MinimumSize.x == 0);
				Assert.IsTrue(leftToRightLayout.Height == 33);
				Assert.IsTrue(leftToRightLayout.MinimumSize.y == 0);
				Assert.IsTrue(item3.Width == 30);
			}
		}
Exemple #24
0
		public void NestedFlowWidgetsTopToBottomTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(300, 500);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;

			{
				Button buttonTop = new Button("buttonTop");
				Button buttonBottom = new Button("buttonBottom");
				buttonTop.OriginRelativeParent = new VectorMath.Vector2(buttonTop.OriginRelativeParent.x, containerControl.LocalBounds.Top - buttonMargin.Top - controlPadding.Top - buttonTop.Height);
				buttonBottom.OriginRelativeParent = new VectorMath.Vector2(buttonBottom.OriginRelativeParent.x, buttonTop.BoundsRelativeToParent.Bottom - buttonBottom.Height - buttonMargin.Height);
				containerControl.AddChild(buttonTop);
				containerControl.AddChild(buttonBottom);
				containerControl.OnDraw(containerControl.NewGraphics2D());
			}

			GuiWidget containerTest = new GuiWidget(300, 500);
			containerTest.DoubleBuffer = true;
			{
				FlowLayoutWidget topToBottomFlowLayoutAll = new FlowLayoutWidget(FlowDirection.TopToBottom);
				topToBottomFlowLayoutAll.AnchorAll();
				topToBottomFlowLayoutAll.Padding = controlPadding;
				{
					FlowLayoutWidget topToBottomFlowLayoutTop = new FlowLayoutWidget(FlowDirection.TopToBottom);
					Button buttonTop = new Button("buttonTop");
					buttonTop.Margin = buttonMargin;
					topToBottomFlowLayoutTop.AddChild(buttonTop);
					topToBottomFlowLayoutTop.SetBoundsToEncloseChildren();
					topToBottomFlowLayoutAll.AddChild(topToBottomFlowLayoutTop);
				}

				{
					FlowLayoutWidget topToBottomFlowLayoutBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);
					Button buttonBottom = new Button("buttonBottom");
					buttonBottom.Margin = buttonMargin;
					topToBottomFlowLayoutBottom.AddChild(buttonBottom);
					topToBottomFlowLayoutBottom.SetBoundsToEncloseChildren();
					topToBottomFlowLayoutAll.AddChild(topToBottomFlowLayoutBottom);
				}

				containerTest.AddChild(topToBottomFlowLayoutAll);
			}

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");
		}
Exemple #25
0
		public void NestedLayoutTopToBottomTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(300, 200);
			containerControl.DoubleBuffer = true;
			containerControl.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
			{
				Button topButtonC = new Button("top button");
				Button bottomButtonC = new Button("bottom wide button");
				topButtonC.LocalBounds = new RectangleDouble(0, 0, bottomButtonC.LocalBounds.Width, 40);
				topButtonC.OriginRelativeParent = new Vector2(bottomButtonC.OriginRelativeParent.x + buttonMargin.Left, containerControl.Height - controlPadding.Top - topButtonC.Height - buttonMargin.Top);
				containerControl.AddChild(topButtonC);
				bottomButtonC.OriginRelativeParent = new Vector2(bottomButtonC.OriginRelativeParent.x + buttonMargin.Left, topButtonC.OriginRelativeParent.y - buttonMargin.Height - bottomButtonC.Height);
				containerControl.AddChild(bottomButtonC);
			}
			containerControl.OnDraw(containerControl.NewGraphics2D());

			GuiWidget containerTest = new GuiWidget(300, 200);
			containerTest.DoubleBuffer = true;
			containerTest.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);

			FlowLayoutWidget allButtons = new FlowLayoutWidget(FlowDirection.TopToBottom);
			allButtons.AnchorAll();
			Button topButtonT;
			Button bottomButtonT;
			FlowLayoutWidget topButtonBar;
			FlowLayoutWidget bottomButtonBar;
			allButtons.Padding = controlPadding;
			{
				bottomButtonT = new Button("bottom wide button");

				topButtonBar = new FlowLayoutWidget();
				{
					topButtonT = new Button("top button");
					topButtonT.LocalBounds = new RectangleDouble(0, 0, bottomButtonT.LocalBounds.Width, 40);
					topButtonT.Margin = buttonMargin;
					topButtonBar.AddChild(topButtonT);
				}
				allButtons.AddChild(topButtonBar);

				bottomButtonBar = new FlowLayoutWidget();
				{
					bottomButtonT.Margin = buttonMargin;
					bottomButtonBar.AddChild(bottomButtonT);
				}
				allButtons.AddChild(bottomButtonBar);
			}
			containerTest.AddChild(allButtons);
			containerTest.OnDraw(containerTest.NewGraphics2D());

			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerTest.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerTest.BackBuffer.Equals(containerControl.BackBuffer, 1), "The test should contain the same image as the control.");
		}
Exemple #26
0
        public void ClickSuppressedOnMouseUpWithinChild()
        {
            // FixNeeded - Agg currently fires mouse up events in child controls when the parent has the mouse captured
            // and is performing drag like operations. If the mouse goes down in the parent and comes up on the child
            // neither control should get a click event

            int rootClickCount  = 0;
            int childClickCount = 0;

            lastClicked = null;

            var systemWindow = new TestHostWindow(300, 200)
            {
                Padding         = new BorderDouble(20),
                BackgroundColor = RGBA_Bytes.Gray,
                Name            = "System Window",
            };

            var rootClickable = new GuiWidget()
            {
                Width           = 50,
                HAnchor         = HAnchor.ParentLeftRight,
                VAnchor         = VAnchor.ParentBottomTop,
                Margin          = new BorderDouble(50),
                Name            = "rootClickable",
                BackgroundColor = RGBA_Bytes.Blue
            };

            rootClickable.Click += (sender, e) =>
            {
                var widget = sender as GuiWidget;

                rootClickCount += 1;
                var color = widget.BackgroundColor.AdjustSaturation(0.4);
                systemWindow.BackgroundColor = color.GetAsRGBA_Bytes();
                lastClicked = widget;
            };
            rootClickable.AfterDraw += widget_DrawSelection;

            var childClickable = new GuiWidget()
            {
                Width  = 35,
                Height = 25,
                OriginRelativeParent = new VectorMath.Vector2(20, 15),
                Name            = "childClickable",
                Margin          = new BorderDouble(10),
                BackgroundColor = RGBA_Bytes.Orange
            };

            childClickable.Click += (sender, e) =>
            {
                var widget = sender as GuiWidget;
                childClickCount += 1;

                var color = widget.BackgroundColor.AdjustSaturation(0.4);
                systemWindow.BackgroundColor = color.GetAsRGBA_Bytes();
                lastClicked = widget;
            };
            childClickable.AfterDraw += widget_DrawSelection;

            rootClickable.AddChild(childClickable);
            systemWindow.AddChild(rootClickable);

            var    bounds = rootClickable.BoundsRelativeToParent;
            double x      = bounds.Left + 25;
            double y      = bounds.Bottom + 8;

            var    childBounds = childClickable.BoundsRelativeToParent;
            double childX      = bounds.Left + childBounds.Left + 16;
            double childY      = bounds.Bottom + childBounds.Bottom + 10;

            UiThread.RunOnIdle((Action)(async() =>
            {
                try
                {
                    MouseEventArgs mouseEvent;
                    AutomationRunner testRunner = new AutomationRunner();

                    // Click should occur on mouse[down/up] within the controls bounds
                    {
                        // Move to a position within rootClickable for mousedown
                        mouseEvent = new MouseEventArgs(MouseButtons.Left, 1, x, y, 0);
                        testRunner.SetMouseCursorPosition(systemWindow, (int)mouseEvent.X, (int)mouseEvent.Y);
                        systemWindow.OnMouseDown(mouseEvent);
                        await Task.Delay(1000);

                        // Move to a position within rootClickable for mouseup
                        mouseEvent = new MouseEventArgs(MouseButtons.Left, 1, x + 119, y + 40, 0);
                        testRunner.SetMouseCursorPosition(systemWindow, (int)mouseEvent.X, (int)mouseEvent.Y);
                        systemWindow.OnMouseUp(mouseEvent);
                        await Task.Delay(1000);

                        Assert.IsTrue(rootClickCount == 1, "Expected 1 click on root widget");
                    }

                    lastClicked = null;
                    systemWindow.BackgroundColor = RGBA_Bytes.Gray;
                    await Task.Delay(1000);

                    // Click should not occur when mouse up occurs on child controls
                    {
                        // Move to a position within rootClickable for mousedown
                        mouseEvent = new MouseEventArgs(MouseButtons.Left, 1, x, y, 0);
                        testRunner.SetMouseCursorPosition(systemWindow, (int)mouseEvent.X, (int)mouseEvent.Y);
                        systemWindow.OnMouseDown(mouseEvent);
                        await Task.Delay(1000);

                        // Move to a position with the childClickable for mouseup
                        mouseEvent = new MouseEventArgs(MouseButtons.Left, 1, childX, childY, 0);
                        testRunner.SetMouseCursorPosition(systemWindow, (int)mouseEvent.X, (int)mouseEvent.Y);
                        systemWindow.OnMouseUp(mouseEvent);
                        await Task.Delay(1000);

                        // There should be no increment in the click count
                        Assert.IsTrue(rootClickCount == 1, "Expected click count to not increment on mouse up within child control");
                    }
                }
                catch (Exception ex)
                {
                    systemWindow.ErrorMessage = ex.Message;
                    systemWindow.TestsPassed = false;
                }

                UiThread.RunOnIdle(systemWindow.Close, 1);
            }), 1);
            systemWindow.ShowAsSystemWindow();

            Assert.IsTrue(systemWindow.TestsPassed, systemWindow.ErrorMessage);
        }
        public GuiWidget Create(IObject3D item, ThemeConfig theme)
        {
            var mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch
            };

            // TODO: Long term we should have a solution where editors can extend Draw and Undo without this hack
            var view3DWidget = ApplicationController.Instance.DragDropData.View3DWidget;
            var undoBuffer   = view3DWidget.sceneContext.Scene.UndoBuffer;

            if (item != null)
            {
                var context = new PPEContext()
                {
                    item = item
                };

                // CreateEditor
                AddUnlockLinkIfRequired(context, mainContainer, theme);

                GuiWidget scope = mainContainer;

                // Create a field editor for each editable property detected via reflection
                foreach (var property in GetEditablePropreties(context.item))
                {
                    // Create SectionWidget for SectionStartAttributes
                    if (property.PropertyInfo.GetCustomAttributes(true).OfType <SectionStartAttribute>().FirstOrDefault() is SectionStartAttribute sectionStart)
                    {
                        var column = new FlowLayoutWidget()
                        {
                            FlowDirection = FlowDirection.TopToBottom,
                            Padding       = new BorderDouble(theme.DefaultContainerPadding).Clone(top: 0)
                        };

                        var section = new SectionWidget(sectionStart.Title, column, theme);
                        theme.ApplyBoxStyle(section);

                        mainContainer.AddChild(section);

                        scope = column;
                    }

                    // Create SectionWidget for SectionStartAttributes
                    if (property.PropertyInfo.GetCustomAttributes(true).OfType <SectionEndAttribute>().Any())
                    {
                        // Push scope back to mainContainer on
                        scope = mainContainer;
                    }

                    var editor = CreatePropertyEditor(property, undoBuffer, context, theme);
                    if (editor != null)
                    {
                        scope.AddChild(editor);
                    }
                }

                AddWebPageLinkIfRequired(context, mainContainer, theme);

                // add in an Update button if applicable
                var showUpdate = context.item.GetType().GetCustomAttributes(typeof(ShowUpdateButtonAttribute), true).FirstOrDefault() as ShowUpdateButtonAttribute;
                if (showUpdate != null)
                {
                    var updateButton = new TextButton("Update".Localize(), theme)
                    {
                        Margin          = 5,
                        BackgroundColor = theme.MinimalShade,
                        HAnchor         = HAnchor.Right,
                        VAnchor         = VAnchor.Absolute
                    };
                    updateButton.Click += (s, e) =>
                    {
                        context.item.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties));
                    };
                    mainContainer.AddChild(updateButton);
                }

                // Init with custom 'UpdateControls' hooks
                (context.item as IPropertyGridModifier)?.UpdateControls(new PublicPropertyChange(context, "Update_Button"));
            }

            return(mainContainer);
        }
Exemple #28
0
        public void SetUpdateNotification(object sender, EventArgs widgetEvent)
        {
            switch (UpdateControlData.Instance.UpdateStatus)
            {
            case UpdateControlData.UpdateStatusStates.MayBeAvailable:
            {
                popUpAboutPage.RemoveAllChildren();
                Button updateStatusMessage = linkButtonFactory.Generate("Check For Update".Localize());
                updateStatusMessage.Click += (sender2, e) =>
                {
                    UiThread.RunOnIdle(CheckForUpdateWindow.Show);
                };
                popUpAboutPage.AddChild(updateStatusMessage);
                popUpAboutPage.Visible = true;
            }
            break;

            case UpdateControlData.UpdateStatusStates.ReadyToInstall:
            case UpdateControlData.UpdateStatusStates.UpdateAvailable:
            case UpdateControlData.UpdateStatusStates.UpdateDownloading:
            {
                popUpAboutPage.RemoveAllChildren();
                Button updateStatusMessage = linkButtonFactory.Generate("Update Available".Localize());
                updateStatusMessage.Click += (sender2, e) =>
                {
                    UiThread.RunOnIdle(CheckForUpdateWindow.Show);
                };
                var updateMark = new UpdateNotificationMark();
                updateMark.Margin  = new BorderDouble(0, 0, 3, 2);
                updateMark.VAnchor = VAnchor.ParentTop;
                popUpAboutPage.AddChild(updateMark);
                popUpAboutPage.AddChild(updateStatusMessage);
                popUpAboutPage.Visible = true;
            }
            break;

            case UpdateControlData.UpdateStatusStates.UpToDate:
                if (AlwaysShowUpdateStatus)
                {
                    popUpAboutPage.RemoveAllChildren();
                    TextWidget updateStatusMessage = new TextWidget("Up to Date".Localize(), textColor: linkButtonFactory.textColor, pointSize: linkButtonFactory.fontSize);
                    updateStatusMessage.VAnchor = VAnchor.ParentCenter;
                    popUpAboutPage.AddChild(updateStatusMessage);
                    popUpAboutPage.Visible = true;

                    UiThread.RunOnIdle((state) => popUpAboutPage.Visible = false, 3);
                    AlwaysShowUpdateStatus = false;
                }
                else
                {
                    popUpAboutPage.Visible = false;
                }
                break;

            case UpdateControlData.UpdateStatusStates.CheckingForUpdate:
                if (AlwaysShowUpdateStatus)
                {
                    popUpAboutPage.RemoveAllChildren();
                    TextWidget updateStatusMessage = new TextWidget("Checking For Update...".Localize(), textColor: linkButtonFactory.textColor, pointSize: linkButtonFactory.fontSize);
                    updateStatusMessage.VAnchor = VAnchor.ParentCenter;
                    popUpAboutPage.AddChild(updateStatusMessage);
                    popUpAboutPage.Visible = true;
                }
                else
                {
                    popUpAboutPage.Visible = false;
                }
                break;

            default:
                throw new NotImplementedException();
            }
        }
Exemple #29
0
		public void NestedFlowWidgetsLeftToRightTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(500, 300);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;

			{
				Button buttonRight = new Button("buttonRight");
				Button buttonLeft = new Button("buttonLeft");
				buttonLeft.OriginRelativeParent = new VectorMath.Vector2(controlPadding.Left + buttonMargin.Left, buttonLeft.OriginRelativeParent.y);
				buttonRight.OriginRelativeParent = new VectorMath.Vector2(buttonLeft.BoundsRelativeToParent.Right + buttonMargin.Width, buttonRight.OriginRelativeParent.y);
				containerControl.AddChild(buttonRight);
				containerControl.AddChild(buttonLeft);
				containerControl.OnDraw(containerControl.NewGraphics2D());
			}

			GuiWidget containerTest = new GuiWidget(500, 300);
			containerTest.DoubleBuffer = true;
			{
				FlowLayoutWidget leftToRightFlowLayoutAll = new FlowLayoutWidget(FlowDirection.LeftToRight);
				leftToRightFlowLayoutAll.AnchorAll();
				leftToRightFlowLayoutAll.Padding = controlPadding;
				{
					FlowLayoutWidget leftToRightFlowLayoutLeft = new FlowLayoutWidget(FlowDirection.LeftToRight);
					Button buttonTop = new Button("buttonLeft");
					buttonTop.Margin = buttonMargin;
					leftToRightFlowLayoutLeft.AddChild(buttonTop);
					leftToRightFlowLayoutLeft.SetBoundsToEncloseChildren();
					leftToRightFlowLayoutAll.AddChild(leftToRightFlowLayoutLeft);
				}

				{
					FlowLayoutWidget leftToRightFlowLayoutRight = new FlowLayoutWidget(FlowDirection.LeftToRight);
					Button buttonBottom = new Button("buttonRight");
					buttonBottom.Margin = buttonMargin;
					leftToRightFlowLayoutRight.AddChild(buttonBottom);
					leftToRightFlowLayoutRight.SetBoundsToEncloseChildren();
					leftToRightFlowLayoutAll.AddChild(leftToRightFlowLayoutRight);
				}

				containerTest.AddChild(leftToRightFlowLayoutAll);
			}

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");
		}
Exemple #30
0
        public SectionWidget(string sectionTitle, GuiWidget sectionContent, ThemeConfig theme, GuiWidget rightAlignedContent = null, int headingPointSize = -1, bool expandingContent = true, bool expanded = true, string serializationKey = null, bool defaultExpansion = false, bool setContentVAnchor = true)
            : base(FlowDirection.TopToBottom)
        {
            this.HAnchor = HAnchor.Stretch;
            this.VAnchor = VAnchor.Fit;

            theme.ApplyBorder(this, new BorderDouble(top: 1));

            this.setContentVAnchor = setContentVAnchor;

            if (!string.IsNullOrEmpty(sectionTitle))
            {
                // Add heading
                var pointSize = (headingPointSize) == -1 ? theme.DefaultFontSize : headingPointSize;

                // If the control is expandable and a serialization key is supplied, set expanded from persisted value
                if (serializationKey != null && expandingContent)
                {
                    string dbValue = UserSettings.Instance.get(serializationKey);
                    expanded = dbValue == "1" || (dbValue == null && defaultExpansion);
                }

                checkbox = new ExpandCheckboxButton(sectionTitle, theme, pointSize: pointSize, expandable: expandingContent)
                {
                    HAnchor = HAnchor.Stretch,
                    Checked = expanded,
                    Padding = 0
                };
                checkbox.CheckedStateChanged += (s, e) =>
                {
                    if (expandingContent)
                    {
                        ContentPanel.Visible = checkbox.Checked;
                    }
                    // TODO: Remove this Height = 10 and figure out why the layout engine is not sizing these correctly without this.
                    ContentPanel.Height = 10;
                };

                if (serializationKey != null)
                {
                    checkbox.CheckedStateChanged += (s, e) =>
                    {
                        UserSettings.Instance.set(serializationKey, checkbox.Checked ? "1" : "0");
                    };
                }

                if (rightAlignedContent == null)
                {
                    this.AddChild(checkbox);
                }
                else
                {
                    rightAlignedContent.HAnchor |= HAnchor.Right;

                    var headingRow = new GuiWidget()
                    {
                        VAnchor = VAnchor.Fit,
                        HAnchor = HAnchor.Stretch
                    };
                    headingRow.AddChild(checkbox);
                    headingRow.AddChild(rightAlignedContent);
                    this.AddChild(headingRow);
                }

                this.rightAlignedContent = rightAlignedContent;
            }

            sectionContent.Visible = expanded;

            this.SetContentWidget(sectionContent);
        }
        public PrintHistoryListItem(ListViewItem listViewItem, int thumbWidth, int thumbHeight, PrintTask printTask, ThemeConfig theme)
            : base(listViewItem, thumbWidth, thumbHeight, theme)
        {
            this.HAnchor   = HAnchor.Stretch;
            this.VAnchor   = VAnchor.Fit;
            this.Padding   = new BorderDouble(0);
            this.Margin    = new BorderDouble(6, 0, 6, 6);
            this.printTask = printTask;

            var mainContainer = new GuiWidget
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };

            {
                indicator = new GuiWidget
                {
                    VAnchor = VAnchor.Stretch,
                    Width   = 15
                };

                SetIndicatorColor();

                var middleColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
                {
                    HAnchor = HAnchor.Stretch,
                    Padding = new BorderDouble(6, 3)
                };

                var labelContainer = new FlowLayoutWidget
                {
                    HAnchor = HAnchor.Stretch
                };

                printInfoWidget = new TextWidget(GetPrintInfo(), pointSize: 12)
                {
                    TextColor = Color.Black,
                    AutoExpandBoundsToText = true,
                };

                labelContainer.AddChild(printInfoWidget);

                middleColumn.AddChild(labelContainer);

                var timeTextColor = new Color(34, 34, 34);

                var detailsRow = new FlowLayoutWidget
                {
                    Margin  = new BorderDouble(0),
                    HAnchor = HAnchor.Stretch
                };
                {
                    var timeLabel = new TextWidget("Time".Localize().ToUpper() + ": ", pointSize: 8)
                    {
                        TextColor = timeTextColor
                    };

                    TextWidget timeIndicator;
                    int        minutes = printTask.PrintTimeMinutes;
                    if (minutes < 0)
                    {
                        timeIndicator = new TextWidget("Unknown".Localize());
                    }
                    else if (minutes > 60)
                    {
                        timeIndicator = new TextWidget("{0}hrs {1}min".FormatWith(printTask.PrintTimeMinutes / 60, printTask.PrintTimeMinutes % 60), pointSize: 12);
                    }
                    else
                    {
                        timeIndicator = new TextWidget(string.Format("{0}min", printTask.PrintTimeMinutes), pointSize: 12);
                    }

                    if (printTask.PercentDone > 0)
                    {
                        timeIndicator.AutoExpandBoundsToText = true;
                        timeIndicator.Text += $" ({printTask.PercentDone:0.0}%)";

                        if (printTask.RecoveryCount > 0)
                        {
                            if (printTask.RecoveryCount == 1)
                            {
                                timeIndicator.Text += " - " + "recovered once".Localize();
                            }
                            else
                            {
                                timeIndicator.Text += " - " + "recovered {0} times".FormatWith(printTask.RecoveryCount);
                            }
                        }
                    }

                    if (printTask.PrintCanceled)
                    {
                        timeIndicator.Text += " - Canceled";
                    }

                    timeIndicator.Margin    = new BorderDouble(right: 6);
                    timeIndicator.TextColor = timeTextColor;

                    detailsRow.AddChild(timeLabel);
                    detailsRow.AddChild(timeIndicator);
                    detailsRow.AddChild(new HorizontalSpacer());
                    middleColumn.AddChild(detailsRow);
                }

                var primaryContainer = new GuiWidget
                {
                    HAnchor = HAnchor.Stretch,
                    VAnchor = VAnchor.Fit
                };

                var primaryFlow = new FlowLayoutWidget(FlowDirection.LeftToRight)
                {
                    HAnchor = HAnchor.Stretch,
                    VAnchor = VAnchor.Fit
                };

                primaryFlow.AddChild(indicator);
                primaryFlow.AddChild(middleColumn);

                primaryContainer.AddChild(primaryFlow);

                AddTimeStamp(printTask, timeTextColor, primaryFlow);

                mainContainer.AddChild(primaryContainer);

                this.AddChild(mainContainer);
            }

            this.BackgroundColor = new Color(255, 255, 255, 255);
        }
        void CreateAndAddChildren(object state)
        {
            RemoveAllChildren();

            FlowLayoutWidget mainContainerTopToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);

            mainContainerTopToBottom.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
            mainContainerTopToBottom.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight;

            buttonBottomPanel                 = new FlowLayoutWidget(FlowDirection.LeftToRight);
            buttonBottomPanel.HAnchor         = HAnchor.ParentLeftRight;
            buttonBottomPanel.Padding         = new BorderDouble(3, 3);
            buttonBottomPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;

            generateGCodeButton        = textImageButtonFactory.Generate(new LocalizedString("Generate").Translated);
            generateGCodeButton.Click += new ButtonBase.ButtonEventHandler(generateButton_Click);
            buttonBottomPanel.AddChild(generateGCodeButton);

            layerSelectionButtonsPannel         = new FlowLayoutWidget(FlowDirection.RightToLeft);
            layerSelectionButtonsPannel.HAnchor = HAnchor.ParentLeftRight;
            layerSelectionButtonsPannel.Padding = new BorderDouble(0);

            closeButton = textImageButtonFactory.Generate(new LocalizedString("Close").Translated);

            layerSelectionButtonsPannel.AddChild(closeButton);

            FlowLayoutWidget centerPartPreviewAndControls = new FlowLayoutWidget(FlowDirection.LeftToRight);

            centerPartPreviewAndControls.AnchorAll();

            gcodeDispalyWidget = new GuiWidget(HAnchor.ParentLeftRight, Agg.UI.VAnchor.ParentBottomTop);

            string startingMessage = new LocalizedString("Loading GCode...").Translated;

            if (Path.GetExtension(printItem.FileLocation).ToUpper() == ".GCODE")
            {
                gcodeDispalyWidget.AddChild(CreateGCodeViewWidget(printItem.FileLocation));
            }
            else
            {
                string gcodePathAndFileName = printItem.GCodePathAndFileName;
                bool   gcodeFileIsComplete  = printItem.IsGCodeFileComplete(gcodePathAndFileName);

                if (gcodeProcessingStateInfoText != null && gcodeProcessingStateInfoText.Text == "Slicing Error")
                {
                    startingMessage = "Slicing Error. Please review your slice settings.";
                }
                else
                {
                    startingMessage = new LocalizedString("Press 'generate' to view layers").Translated;
                }

                if (File.Exists(gcodePathAndFileName) && gcodeFileIsComplete)
                {
                    gcodeDispalyWidget.AddChild(CreateGCodeViewWidget(gcodePathAndFileName));
                }

                // we only hook these up to make sure we can regenerate the gcode when we want
                printItem.SlicingOutputMessage += sliceItem_SlicingOutputMessage;
                printItem.Done += new EventHandler(sliceItem_Done);
            }

            centerPartPreviewAndControls.AddChild(gcodeDispalyWidget);

            buttonRightPanel = CreateRightButtonPannel();
            centerPartPreviewAndControls.AddChild(buttonRightPanel);

            // add in a spacer
            layerSelectionButtonsPannel.AddChild(new GuiWidget(HAnchor.ParentLeftRight));
            buttonBottomPanel.AddChild(layerSelectionButtonsPannel);

            mainContainerTopToBottom.AddChild(centerPartPreviewAndControls);
            mainContainerTopToBottom.AddChild(buttonBottomPanel);
            this.AddChild(mainContainerTopToBottom);

            AddProcessingMessage(startingMessage);

            AddViewControls();

            AddHandlers();
        }
Exemple #33
0
        public void BackBuffersAreScreenAligned()
        {
            // make sure draw string and a text widget produce the same result when drawn to the same spot
            {
                ImageBuffer drawStringImage = new ImageBuffer(100, 20, 24, new BlenderBGR());
                {
                    Graphics2D drawStringGraphics = drawStringImage.NewGraphics2D();
                    drawStringGraphics.Clear(RGBA_Bytes.White);
                    drawStringGraphics.DrawString("test", 0, 0);
                    SaveImage(drawStringImage, "z draw string.tga");
                }

                ImageBuffer textWidgetImage = new ImageBuffer(100, 20, 24, new BlenderBGR());
                {
                    TextWidget textWidget         = new TextWidget("test");
                    Graphics2D textWidgetGraphics = textWidgetImage.NewGraphics2D();
                    textWidgetGraphics.Clear(RGBA_Bytes.White);
                    textWidget.OnDraw(textWidgetGraphics);
                }

                Assert.IsTrue(drawStringImage == textWidgetImage);
            }

            // make sure that a back buffer is always trying to draw 1:1 pixels to the buffer above
            {
                ImageBuffer drawStringOffsetImage = new ImageBuffer(100, 20, 32, new BlenderBGRA());
                {
                    Graphics2D drawStringGraphics = drawStringOffsetImage.NewGraphics2D();
                    drawStringGraphics.Clear(RGBA_Bytes.White);
                    drawStringGraphics.DrawString("test", 23.3, 0);
                    SaveImage(drawStringOffsetImage, "z draw offset string.tga");
                }

                GuiWidget container = new GuiWidget(100, 20);
                container.DoubleBuffer = true;
                {
                    TextWidget textWidget = new TextWidget("test", 23.3);
                    container.AddChild(textWidget);
                    container.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
                    container.OnDraw(container.BackBuffer.NewGraphics2D());
                    SaveImage(container.BackBuffer, "z offset text widget.tga");
                }

                Vector2 bestPosition;
                double  bestLeastSquares;
                double  maxError = 10;
                container.BackBuffer.FindLeastSquaresMatch(drawStringOffsetImage, out bestPosition, out bestLeastSquares, maxError);
                Assert.IsTrue(bestLeastSquares < maxError);
            }

            {
                ImageBuffer drawStringOffsetImage = new ImageBuffer(100, 20, 32, new BlenderBGRA());
                {
                    Graphics2D drawStringGraphics = drawStringOffsetImage.NewGraphics2D();
                    drawStringGraphics.Clear(RGBA_Bytes.White);
                    drawStringGraphics.DrawString("test", 23.8, 0);
                    SaveImage(drawStringOffsetImage, "z draw offset string.tga");
                }

                GuiWidget container1 = new GuiWidget(100, 20);
                container1.DoubleBuffer = true;
                GuiWidget container2 = new GuiWidget(90, 20);
                container2.OriginRelativeParent = new Vector2(.5, 0);
                container1.AddChild(container2);
                {
                    TextWidget textWidget = new TextWidget("test", 23.3);
                    container2.AddChild(textWidget);
                    container1.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
                    container1.OnDraw(container1.BackBuffer.NewGraphics2D());
                    SaveImage(container1.BackBuffer, "z offset text widget.tga");
                }

                Assert.IsTrue(container1.BackBuffer.FindLeastSquaresMatch(drawStringOffsetImage, 5));
            }
        }
Exemple #34
0
        public View3DBrailleBuilder(Vector3 viewerVolume, Vector2 bedCenter, BedShape bedShape)
        {
            monoSpacedTypeFace = ApplicationController.MonoSpacedTypeFace;

            brailTypeFace = TypeFace.LoadFrom(StaticData.Instance.ReadAllText(Path.Combine("Fonts", "Braille.svg")));

            MeshGroupExtraData = new List <PlatingMeshGroupData>();

            FlowLayoutWidget mainContainerTopToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);

            mainContainerTopToBottom.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
            mainContainerTopToBottom.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight;

            FlowLayoutWidget centerPartPreviewAndControls = new FlowLayoutWidget(FlowDirection.LeftToRight);

            centerPartPreviewAndControls.AnchorAll();

            GuiWidget viewArea = new GuiWidget();

            viewArea.AnchorAll();
            {
                meshViewerWidget = new MeshViewerWidget(viewerVolume, bedCenter, bedShape);
                meshViewerWidget.AllowBedRenderingWhenEmpty = true;
                meshViewerWidget.AnchorAll();
            }
            viewArea.AddChild(meshViewerWidget);

            centerPartPreviewAndControls.AddChild(viewArea);
            mainContainerTopToBottom.AddChild(centerPartPreviewAndControls);

            FlowLayoutWidget buttonBottomPanel = new FlowLayoutWidget(FlowDirection.LeftToRight);

            buttonBottomPanel.HAnchor         = HAnchor.ParentLeftRight;
            buttonBottomPanel.Padding         = new BorderDouble(3, 3);
            buttonBottomPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;

            buttonRightPanel = CreateRightButtonPanel(viewerVolume.y);

            // add in the plater tools
            {
                FlowLayoutWidget editToolBar = new FlowLayoutWidget();

                processingProgressControl         = new ProgressControl("Finding Parts:".Localize(), ActiveTheme.Instance.PrimaryTextColor, ActiveTheme.Instance.PrimaryAccentColor);
                processingProgressControl.VAnchor = Agg.UI.VAnchor.ParentCenter;
                editToolBar.AddChild(processingProgressControl);
                editToolBar.VAnchor |= Agg.UI.VAnchor.ParentCenter;

                editPlateButtonsContainer = new FlowLayoutWidget();

                textToAddWidget         = new MHTextEditWidget("", pixelWidth: 300, messageWhenEmptyAndNotSelected: "Enter Text Here".Localize());
                textToAddWidget.VAnchor = VAnchor.ParentCenter;
                textToAddWidget.Margin  = new BorderDouble(5);
                editPlateButtonsContainer.AddChild(textToAddWidget);
                textToAddWidget.ActualTextEditWidget.EnterPressed += (object sender, KeyEventArgs keyEvent) =>
                {
                    InsertTextNow(textToAddWidget.Text);
                };

                Button insertTextButton = textImageButtonFactory.Generate("Insert".Localize());
                editPlateButtonsContainer.AddChild(insertTextButton);
                insertTextButton.Click += (sender, e) =>
                {
                    InsertTextNow(textToAddWidget.Text);
                };

                editToolBar.AddChild(editPlateButtonsContainer);
                buttonBottomPanel.AddChild(editToolBar);
            }

            GuiWidget buttonRightPanelHolder = new GuiWidget(HAnchor.FitToChildren, VAnchor.ParentBottomTop);

            centerPartPreviewAndControls.AddChild(buttonRightPanelHolder);
            buttonRightPanelHolder.AddChild(buttonRightPanel);

            viewControls3D = new ViewControls3D(meshViewerWidget);

            viewControls3D.ResetView += (sender, e) =>
            {
                meshViewerWidget.ResetView();
            };

            buttonRightPanelDisabledCover = new Cover(HAnchor.ParentLeftRight, VAnchor.ParentBottomTop);
            buttonRightPanelDisabledCover.BackgroundColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryBackgroundColor, 150);
            buttonRightPanelHolder.AddChild(buttonRightPanelDisabledCover);
            LockEditControls();

            GuiWidget leftRightSpacer = new GuiWidget();

            leftRightSpacer.HAnchor = HAnchor.ParentLeftRight;
            buttonBottomPanel.AddChild(leftRightSpacer);

            closeButton = textImageButtonFactory.Generate("Close".Localize());
            buttonBottomPanel.AddChild(closeButton);

            mainContainerTopToBottom.AddChild(buttonBottomPanel);

            this.AddChild(mainContainerTopToBottom);
            this.AnchorAll();

            meshViewerWidget.TrackballTumbleWidget.TransformState = TrackBallController.MouseDownType.Rotation;

            AddChild(viewControls3D);

            // set the view to be a good angle and distance
            meshViewerWidget.ResetView();

            AddHandlers();
            UnlockEditControls();
            // but make sure we can't use the right panel yet
            buttonRightPanelDisabledCover.Visible = true;

            //meshViewerWidget.RenderType = RenderTypes.Outlines;
            viewControls3D.PartSelectVisible = false;
            meshViewerWidget.ResetView();
        }
Exemple #35
0
		public void HCenterHRightAndVCenterVTopTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(200, 300);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;
			Button controlButton1 = new Button("button1");
			controlButton1.OriginRelativeParent = new VectorMath.Vector2(
				controlPadding.Left + buttonMargin.Left + (containerControl.Width - (controlPadding.Left + controlPadding.Right)) / 2,
				controlPadding.Bottom + buttonMargin.Bottom + (containerControl.Height - (controlPadding.Bottom + controlPadding.Top)) / 2);
			controlButton1.LocalBounds = new RectangleDouble(
				controlButton1.LocalBounds.Left,
				controlButton1.LocalBounds.Bottom,
				controlButton1.LocalBounds.Left + containerControl.Width / 2 - (controlPadding.Left + controlPadding.Right) / 2 - (buttonMargin.Left + buttonMargin.Right),
				controlButton1.LocalBounds.Bottom + containerControl.Height / 2 - (controlPadding.Bottom + controlPadding.Top) / 2 - (buttonMargin.Bottom + buttonMargin.Top));
			containerControl.AddChild(controlButton1);
			containerControl.OnDraw(containerControl.NewGraphics2D());

			GuiWidget containerTest = new GuiWidget(200, 300);
			containerTest.Padding = controlPadding;
			containerTest.DoubleBuffer = true;

			Button testButton1 = new Button("button1");
			testButton1.Margin = buttonMargin;
			testButton1.VAnchor = VAnchor.ParentCenter | VAnchor.ParentTop;
			testButton1.HAnchor = HAnchor.ParentCenter | HAnchor.ParentRight;
			containerTest.AddChild(testButton1);

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");
		}
Exemple #36
0
 private void RebuildDropDownList()
 {
     pullDownContainer.CloseAllChildren();
     pullDownContainer.AddChild(GetPulldownContainer());
 }
Exemple #37
0
        public void ScrollPositionStartsCorrect()
        {
            GuiWidget contents = new GuiWidget(300, 300);
            contents.DoubleBuffer = true;
            ListBox container = new ListBox(new RectangleDouble(0, 0, 200, 300));
            //container.BackgroundColor = RGBA_Bytes.Red;
            container.Name = "containerListBox";
            container.VAnchor = UI.VAnchor.ParentTop;
            container.Margin = new BorderDouble(15);
            
            contents.AddChild(container);

            container.AddChild(new ListBoxTextItem("hand.stl", "c:\\development\\hand.stl"));

            contents.OnDraw(contents.NewGraphics2D());

            Assert.IsTrue(container.TopLeftOffset.y == 0);
        }
        public EditConnectionWidget(ConnectionWindow windowController, GuiWidget containerWindowToClose, Printer activePrinter = null)
            : base(windowController, containerWindowToClose)
        {
            textImageButtonFactory.normalTextColor   = RGBA_Bytes.White;
            textImageButtonFactory.hoverTextColor    = RGBA_Bytes.White;
            textImageButtonFactory.disabledTextColor = RGBA_Bytes.White;
            textImageButtonFactory.pressedTextColor  = RGBA_Bytes.White;
            textImageButtonFactory.borderWidth       = 0;

            linkButtonFactory.textColor = RGBA_Bytes.White;
            linkButtonFactory.fontSize  = 8;

            this.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            this.AnchorAll();
            this.Padding = new BorderDouble(0); //To be re-enabled once native borders are turned off

            GuiWidget mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);

            mainContainer.AnchorAll();
            mainContainer.Padding         = new BorderDouble(3, 0, 3, 5);
            mainContainer.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;

            string headerTitle;

            if (activePrinter == null)
            {
                headerTitle                 = string.Format("Add a Printer");
                this.addNewPrinterFlag      = true;
                this.ActivePrinter          = new Printer();
                this.ActivePrinter.Name     = "Default Printer";
                this.ActivePrinter.BaudRate = "250000";
                try
                {
                    this.ActivePrinter.ComPort = SerialPort.GetPortNames()[0];
                }
                catch
                {
                    //No active COM ports
                }
            }
            else
            {
                this.ActivePrinter = activePrinter;
                string editHeaderTitleTxt = new LocalizedString("Edit").Translated;
                headerTitle = string.Format("{1} - {0}", this.ActivePrinter.Name, editHeaderTitleTxt);
                if (this.ActivePrinter.BaudRate == null)
                {
                    this.ActivePrinter.BaudRate = "250000";
                }
                if (this.ActivePrinter.ComPort == null)
                {
                    try
                    {
                        this.ActivePrinter.ComPort = SerialPort.GetPortNames()[0];
                    }
                    catch
                    {
                        //No active COM ports
                    }
                }
            }

            FlowLayoutWidget headerRow = new FlowLayoutWidget(FlowDirection.LeftToRight);

            headerRow.Margin  = new BorderDouble(0, 3, 0, 0);
            headerRow.Padding = new BorderDouble(0, 3, 0, 3);
            headerRow.HAnchor = HAnchor.ParentLeftRight;
            {
                TextWidget headerLabel = new TextWidget(headerTitle, pointSize: 14);
                headerLabel.TextColor = this.defaultTextColor;

                headerRow.AddChild(headerLabel);
            }

            ConnectionControlContainer                 = new FlowLayoutWidget(FlowDirection.TopToBottom);
            ConnectionControlContainer.Padding         = new BorderDouble(5);
            ConnectionControlContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            ConnectionControlContainer.HAnchor         = HAnchor.ParentLeftRight;
            {
                TextWidget printerNameLabel = new TextWidget(new LocalizedString("Printer Name").Translated, 0, 0, 10);
                printerNameLabel.TextColor = this.defaultTextColor;
                printerNameLabel.HAnchor   = HAnchor.ParentLeftRight;
                printerNameLabel.Margin    = new BorderDouble(0, 0, 0, 1);

                printerNameInput = new MHTextEditWidget(this.ActivePrinter.Name);

                printerNameInput.HAnchor |= HAnchor.ParentLeftRight;

                comPortLabelWidget = new FlowLayoutWidget();

                Button refreshComPorts = linkButtonFactory.Generate(new LocalizedString("(refresh)").Translated);
                refreshComPorts.Margin  = new BorderDouble(left: 5);
                refreshComPorts.VAnchor = VAnchor.ParentBottom;
                refreshComPorts.Click  += new ButtonBase.ButtonEventHandler(RefreshComPorts);

                TextWidget comPortLabel = new TextWidget(new LocalizedString("Serial Port").Translated, 0, 0, 10);
                comPortLabel.TextColor = this.defaultTextColor;

                comPortLabelWidget.AddChild(comPortLabel);
                comPortLabelWidget.AddChild(refreshComPorts);
                comPortLabelWidget.Margin  = new BorderDouble(0, 0, 0, 10);
                comPortLabelWidget.HAnchor = HAnchor.ParentLeftRight;

                FlowLayoutWidget comPortContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
                comPortContainer.Margin  = new BorderDouble(0);
                comPortContainer.HAnchor = HAnchor.ParentLeftRight;


                int portIndex = 0;
                foreach (string serialPort in SerialPort.GetPortNames())
                {
                    //Filter com port list based on usb type (applies to Mac mostly)
                    bool looks_like_mac = serialPort.StartsWith("/dev/tty.");
                    bool looks_like_pc  = serialPort.StartsWith("COM");
                    if (looks_like_mac || looks_like_pc)
                    {
                        SerialPortIndexRadioButton comPortOption = createComPortOption(serialPort);
                        comPortContainer.AddChild(comPortOption);
                        portIndex++;
                    }
                }

                //If there are no com ports in the filtered list assume we are missing something and show the unfiltered list
                if (portIndex == 0)
                {
                    foreach (string serialPort in SerialPort.GetPortNames())
                    {
                        SerialPortIndexRadioButton comPortOption = createComPortOption(serialPort);
                        comPortContainer.AddChild(comPortOption);
                        portIndex++;
                    }
                }

                if (!printerComPortIsAvailable && this.ActivePrinter.ComPort != null)
                {
                    SerialPortIndexRadioButton comPortOption = createComPortOption(this.ActivePrinter.ComPort);
                    comPortOption.Enabled = false;
                    comPortContainer.AddChild(comPortOption);
                    portIndex++;
                }

                //If there are still no com ports show a message to that effect
                if (portIndex == 0)
                {
                    TextWidget comPortOption = new TextWidget(new LocalizedString("No COM ports available").Translated);
                    comPortOption.Margin    = new BorderDouble(3, 6, 5, 6);
                    comPortOption.TextColor = this.subContainerTextColor;
                    comPortContainer.AddChild(comPortOption);
                }


                TextWidget baudRateLabel = new TextWidget(new LocalizedString("Baud Rate").Translated, 0, 0, 10);
                baudRateLabel.TextColor = this.defaultTextColor;
                baudRateLabel.Margin    = new BorderDouble(0, 0, 0, 10);
                baudRateLabel.HAnchor   = HAnchor.ParentLeftRight;

                baudRateWidget         = GetBaudRateWidget();
                baudRateWidget.HAnchor = HAnchor.ParentLeftRight;

                FlowLayoutWidget printerMakeContainer  = createPrinterMakeContainer();
                FlowLayoutWidget printerModelContainer = createPrinterModelContainer();

                enableAutoconnect           = new CheckBox(new LocalizedString("Auto Connect").Translated);
                enableAutoconnect.TextColor = RGBA_Bytes.White;
                enableAutoconnect.Margin    = new BorderDouble(top: 10);
                enableAutoconnect.HAnchor   = HAnchor.ParentLeft;
                if (this.ActivePrinter.AutoConnectFlag)
                {
                    enableAutoconnect.Checked = true;
                }

                ConnectionControlContainer.VAnchor = VAnchor.ParentBottomTop;
                ConnectionControlContainer.AddChild(printerNameLabel);
                ConnectionControlContainer.AddChild(printerNameInput);
                ConnectionControlContainer.AddChild(printerMakeContainer);
                ConnectionControlContainer.AddChild(printerModelContainer);
                ConnectionControlContainer.AddChild(comPortLabelWidget);
                ConnectionControlContainer.AddChild(comPortContainer);
                ConnectionControlContainer.AddChild(baudRateLabel);
                ConnectionControlContainer.AddChild(baudRateWidget);
                ConnectionControlContainer.AddChild(enableAutoconnect);
            }

            FlowLayoutWidget buttonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);

            buttonContainer.HAnchor = HAnchor.ParentLeft | HAnchor.ParentRight;
            //buttonContainer.VAnchor = VAnchor.BottomTop;
            buttonContainer.Margin = new BorderDouble(0, 3);
            {
                //Construct buttons
                saveButton = textImageButtonFactory.Generate(new LocalizedString("Save").Translated);
                //saveButton.VAnchor = VAnchor.Bottom;

                cancelButton = textImageButtonFactory.Generate(new LocalizedString("Cancel").Translated);
                //cancelButton.VAnchor = VAnchor.Bottom;
                cancelButton.Click += new ButtonBase.ButtonEventHandler(CancelButton_Click);

                //Add buttons to buttonContainer
                buttonContainer.AddChild(saveButton);
                buttonContainer.AddChild(cancelButton);
            }

            //mainContainer.AddChild(new PrinterChooser());

            mainContainer.AddChild(headerRow);
            mainContainer.AddChild(ConnectionControlContainer);
            mainContainer.AddChild(buttonContainer);

            this.AddChild(mainContainer);

            BindSaveButtonHandlers();
            BindBaudRateHandlers();
        }
Exemple #39
0
        private static void AddContents(GuiWidget widgetToAddItemsTo)
        {
            string[] listItems = new string[] { "Item1", "Item2", "Item3", "Item4" };

            widgetToAddItemsTo.Padding = new BorderDouble(5);
            widgetToAddItemsTo.BackgroundColor = new RGBA_Bytes(68, 68, 68);

            //Get a list of printer records and add them to radio button list
            foreach (string listItem in listItems)
            {
                TextWidget textItem = new TextWidget(listItem);
                textItem.BackgroundColor = RGBA_Bytes.Blue;
                textItem.Margin = new BorderDouble(2);
                widgetToAddItemsTo.AddChild(textItem);
            }
        }
Exemple #40
0
 private void AddSettingsRow(GuiWidget widget, GuiWidget container)
 {
     container.AddChild(widget);
     widget.Padding = widget.Padding.Clone(right: 10);
 }
Exemple #41
0
        public void DropDownListTests()
        {
            string menuSelected = "";

            GuiWidget container = new GuiWidget(400, 400);
            DropDownList listMenu = new DropDownList("- Select Something -", RGBA_Bytes.Black, RGBA_Bytes.Gray);
            listMenu.OriginRelativeParent = new Vector2(10, 300);

            MenuItem cutMenuItem = new MenuItem(new TextWidget("Cut"));
            cutMenuItem.Selected += (sender, e) => { menuSelected = "Cut"; };
            listMenu.MenuItems.Add(cutMenuItem);

            MenuItem copyMenuItem = new MenuItem(new TextWidget("Copy"));
            copyMenuItem.Selected += (sender, e) => { menuSelected = "Copy"; };
            listMenu.MenuItems.Add(copyMenuItem);

            MenuItem pastMenuItem = new MenuItem(new TextWidget("Paste"));
            pastMenuItem.Selected += (sender, e) => { menuSelected = "Paste"; };
            listMenu.MenuItems.Add(pastMenuItem);

            container.AddChild(listMenu);

            Assert.IsTrue(!listMenu.IsOpen);

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // click on menu again to close
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // click off menu to close
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 5, 299, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 5, 299, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // select the first item
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            Assert.IsTrue(menuSelected == "Cut");

            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // select the second item
            menuSelected = "";
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 275, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 275, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            Assert.IsTrue(menuSelected == "Copy");

            // make sure click down then move off item does not select it.
            menuSelected = "";
            // open the menu
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 11, 300, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);

            // click down on the first item
            container.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, 11, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(listMenu.IsOpen);
            // move off of it
            container.OnMouseMove(new MouseEventArgs(MouseButtons.None, 1, 5, 290, 0));
            container.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, 5, 290, 0));
            UiThread.DoRunAllPending();
            Assert.IsTrue(!listMenu.IsOpen);
            Assert.IsTrue(menuSelected == "");

            // make sure click down and then move to new items selects the new item.

            // click and draw down to item should work as well
        }
Exemple #42
0
 private static void AddInline(GuiWidget parent, GuiWidget inline)
 {
     parent.AddChild(inline);
 }
Exemple #43
0
		public void TopBottomWithAnchorBottomTopChildTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			double buttonSize = 40;
			GuiWidget containerControl = new GuiWidget(buttonSize * 3, buttonSize * 8);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;

			RectangleDouble[] eightControlRectangles = new RectangleDouble[8];
			RGBA_Bytes[] eightColors = new RGBA_Bytes[] { RGBA_Bytes.Red, RGBA_Bytes.Orange, RGBA_Bytes.Yellow, RGBA_Bytes.YellowGreen, RGBA_Bytes.Green, RGBA_Bytes.Blue, RGBA_Bytes.Indigo, RGBA_Bytes.Violet };
			{
				double currentBottom = containerControl.Height - controlPadding.Top - buttonMargin.Top - buttonSize;
				double buttonWidthWithMargin = buttonSize + buttonMargin.Width;
				double scalledHeight = (containerControl.Height - controlPadding.Height - buttonMargin.Height * 8 - buttonSize * 2) / 6;
				// the bottom unsized rect
				eightControlRectangles[0] = new RectangleDouble(
						0,
						currentBottom,
						buttonSize,
						currentBottom + buttonSize);

				// left anchor
				currentBottom -= scalledHeight + buttonMargin.Height;
				double leftAnchorX = controlPadding.Left + buttonMargin.Left;
				eightControlRectangles[1] = new RectangleDouble(leftAnchorX, currentBottom, leftAnchorX + buttonSize, currentBottom + scalledHeight);

				// center anchor
				double centerXOfContainer = controlPadding.Left + (containerControl.Width - controlPadding.Width) / 2;
				currentBottom -= scalledHeight + buttonMargin.Height;
				eightControlRectangles[2] = new RectangleDouble(centerXOfContainer - buttonWidthWithMargin / 2 + buttonMargin.Left, currentBottom, centerXOfContainer + buttonWidthWithMargin / 2 - buttonMargin.Right, currentBottom + scalledHeight);

				// right anchor
				double rightAnchorX = containerControl.Width - controlPadding.Right - buttonMargin.Right;
				currentBottom -= scalledHeight + buttonMargin.Height;
				eightControlRectangles[3] = new RectangleDouble(rightAnchorX - buttonSize, currentBottom, rightAnchorX, currentBottom + scalledHeight);

				// left center anchor
				currentBottom -= scalledHeight + buttonMargin.Height;
				eightControlRectangles[4] = new RectangleDouble(leftAnchorX, currentBottom, centerXOfContainer - buttonMargin.Right, currentBottom + scalledHeight);

				// center right anchor
				currentBottom -= scalledHeight + buttonMargin.Height;
				eightControlRectangles[5] = new RectangleDouble(centerXOfContainer + buttonMargin.Left, currentBottom, rightAnchorX, currentBottom + scalledHeight);

				// left right anchor
				currentBottom -= scalledHeight + buttonMargin.Height;
				eightControlRectangles[6] = new RectangleDouble(leftAnchorX, currentBottom, rightAnchorX, currentBottom + scalledHeight);

				// top anchor
				currentBottom -= buttonSize + buttonMargin.Height;
				eightControlRectangles[7] = new RectangleDouble(0, currentBottom, buttonSize, currentBottom + buttonSize);

				Graphics2D graphics = containerControl.NewGraphics2D();
				for (int i = 0; i < 8; i++)
				{
					graphics.FillRectangle(eightControlRectangles[i], eightColors[i]);
				}
			}

			GuiWidget containerTest = new GuiWidget(containerControl.Width, containerControl.Height);
			FlowLayoutWidget bottomToTopFlowLayoutAll = new FlowLayoutWidget(FlowDirection.TopToBottom);
			containerTest.DoubleBuffer = true;
			{
				bottomToTopFlowLayoutAll.AnchorAll();
				bottomToTopFlowLayoutAll.Padding = controlPadding;
				{
					GuiWidget top = new GuiWidget(buttonSize, buttonSize);
					top.BackgroundColor = RGBA_Bytes.Red;
					top.Margin = buttonMargin;
					bottomToTopFlowLayoutAll.AddChild(top);

					bottomToTopFlowLayoutAll.AddChild(CreateBottomToTopMiddleWidget(buttonMargin, buttonSize, HAnchor.ParentLeft, RGBA_Bytes.Orange));
					bottomToTopFlowLayoutAll.AddChild(CreateBottomToTopMiddleWidget(buttonMargin, buttonSize, HAnchor.ParentCenter, RGBA_Bytes.Yellow));
					bottomToTopFlowLayoutAll.AddChild(CreateBottomToTopMiddleWidget(buttonMargin, buttonSize, HAnchor.ParentRight, RGBA_Bytes.YellowGreen));
					bottomToTopFlowLayoutAll.AddChild(CreateBottomToTopMiddleWidget(buttonMargin, buttonSize, HAnchor.ParentLeftCenter, RGBA_Bytes.Green));
					bottomToTopFlowLayoutAll.AddChild(CreateBottomToTopMiddleWidget(buttonMargin, buttonSize, HAnchor.ParentCenterRight, RGBA_Bytes.Blue));
					bottomToTopFlowLayoutAll.AddChild(CreateBottomToTopMiddleWidget(buttonMargin, buttonSize, HAnchor.ParentLeftRight, RGBA_Bytes.Indigo));

					GuiWidget bottom = new GuiWidget(buttonSize, buttonSize);
					bottom.BackgroundColor = RGBA_Bytes.Violet;
					bottom.Margin = buttonMargin;
					bottomToTopFlowLayoutAll.AddChild(bottom);
				}

				containerTest.AddChild(bottomToTopFlowLayoutAll);
			}

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			for (int i = 0; i < 8; i++)
			{
				Assert.IsTrue(eightControlRectangles[i].Equals(bottomToTopFlowLayoutAll.Children[i].BoundsRelativeToParent, .001));
			}

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");

			// we use a least squares match because the erase background that is setting the widgets is integer pixel based and the fill rectangle is not.
			Assert.IsTrue(containerControl.BackBuffer.FindLeastSquaresMatch(containerTest.BackBuffer, 0), "The test and control need to match.");
		}
Exemple #44
0
        public SearchPanel(ChromeTabs tabControl, GuiWidget searchButton, ThemeConfig theme)
            : base(theme, GrabBarSide.Left)
        {
            this.HAnchor         = HAnchor.Absolute;
            this.VAnchor         = VAnchor.Absolute;
            this.Width           = 500;
            this.Height          = 200;
            this.BackgroundColor = theme.SectionBackgroundColor;
            this.tabControl      = tabControl;
            this.searchButton    = searchButton;

            searchButton.BackgroundColor = theme.SectionBackgroundColor;

            GuiWidget searchResults = null;
            var       scrollable    = new ScrollableWidget(true)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Stretch
            };

            searchBox = new TextEditWithInlineCancel(theme)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Margin  = new BorderDouble(5, 8, 5, 5)
            };
            searchBox.TextEditWidget.ActualTextEditWidget.EnterPressed += async(s2, e2) =>
            {
                searchResults.CloseChildren();

                searchResults.AddChild(
                    new TextWidget("Searching".Localize() + "...", pointSize: theme.DefaultFontSize, textColor: theme.TextColor)
                {
                    Margin = 10
                });

                this.Invalidate();

                var searchHits = await Task.Run(() =>
                {
                    return(HelpIndex.Search(searchBox.TextEditWidget.Text));
                });

                searchResults.CloseChildren();

                foreach (var searchResult in searchHits)
                {
                    var resultsRow = new HelpSearchResultRow(searchResult, theme);
                    resultsRow.Click += this.ResultsRow_Click;

                    searchResults.AddChild(resultsRow);
                }

                if (searchResults.Children.Count == 0)
                {
                    searchResults.AddChild(new SettingsRow("No results found".Localize(), null, theme, StaticData.Instance.LoadIcon("StatusInfoTip_16x.png", 16, 16).SetPreMultiply()));
                }

                // Add top border to first child
                if (searchResults.Children.FirstOrDefault() is GuiWidget firstChild)
                {
                    searchResults.BorderColor = firstChild.BorderColor;
                    searchResults.Border      = new BorderDouble(top: 1);
                    // firstChild.Border = firstChild.Border.Clone(top: 1); - doesn't work for some reason, pushing border to parent above
                }

                scrollable.TopLeftOffset = Vector2.Zero;
            };
            searchBox.ResetButton.Click += (s2, e2) =>
            {
                searchBox.BackgroundColor     = Color.Transparent;
                searchBox.TextEditWidget.Text = "";

                searchResults.CloseChildren();
            };

            this.AddChild(searchBox);

            scrollable.ScrollArea.HAnchor = HAnchor.Stretch;
            scrollable.ScrollArea.VAnchor = VAnchor.Fit;

            this.AddChild(scrollable);
            searchResults = new FlowLayoutWidget(FlowDirection.TopToBottom)
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit
            };
            scrollable.AddChild(searchResults);
        }
Exemple #45
0
		public void ChildVisibilityChangeCauseResize()
		{
			//Test whether toggling the visibility of children changes the flow layout
			GuiWidget containerTest = new GuiWidget(640, 480);
			FlowLayoutWidget topToBottomFlowLayoutAll = new FlowLayoutWidget(FlowDirection.TopToBottom);
			containerTest.AddChild(topToBottomFlowLayoutAll);

			GuiWidget item1 = new GuiWidget(1, 20);
			GuiWidget item2 = new GuiWidget(1, 30);
			GuiWidget item3 = new GuiWidget(1, 40);

			topToBottomFlowLayoutAll.AddChild(item1);
			Assert.IsTrue(topToBottomFlowLayoutAll.Height == 20);
			topToBottomFlowLayoutAll.AddChild(item2);
			Assert.IsTrue(topToBottomFlowLayoutAll.Height == 50);
			topToBottomFlowLayoutAll.AddChild(item3);
			Assert.IsTrue(topToBottomFlowLayoutAll.Height == 90);

			item2.Visible = false;

			Assert.IsTrue(topToBottomFlowLayoutAll.Height == 60);
		}
Exemple #46
0
        private void AddLibraryButtonElements()
        {
            textImageButtonFactory.normalTextColor   = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.hoverTextColor    = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.pressedTextColor  = ActiveTheme.Instance.PrimaryTextColor;
            textImageButtonFactory.disabledTextColor = ActiveTheme.Instance.TabLabelUnselected;
            textImageButtonFactory.disabledFillColor = new RGBA_Bytes();
            buttonPanel.RemoveAllChildren();
            // the add button
            {
                addToLibraryButton             = textImageButtonFactory.Generate(LocalizedString.Get("Add"), "icon_circle_plus.png");
                addToLibraryButton.Enabled     = false;             // The library selector (the first library selected) is protected so we can't add to it.
                addToLibraryButton.ToolTipText = "Add an .stl, .amf, .gcode or .zip file to the Library".Localize();
                addToLibraryButton.Name        = "Library Add Button";
                buttonPanel.AddChild(addToLibraryButton);
                addToLibraryButton.Margin = new BorderDouble(0, 0, 3, 0);
                addToLibraryButton.Click += (sender, e) => UiThread.RunOnIdle(importToLibraryloadFile_ClickOnIdle);
            }

            // the create folder button
            {
                createFolderButton         = textImageButtonFactory.Generate(LocalizedString.Get("Create Folder"));
                createFolderButton.Enabled = false;                 // The library selector (the first library selected) is protected so we can't add to it.
                createFolderButton.Name    = "Create Folder From Library Button";
                buttonPanel.AddChild(createFolderButton);
                createFolderButton.Margin = new BorderDouble(0, 0, 3, 0);
                createFolderButton.Click += (sender, e) =>
                {
                    if (createFolderWindow == null)
                    {
                        createFolderWindow = new CreateFolderWindow((returnInfo) =>
                        {
                            this.libraryDataView.CurrentLibraryProvider.AddCollectionToLibrary(returnInfo.newName);
                        });
                        createFolderWindow.Closed += (sender2, e2) => { createFolderWindow = null; };
                    }
                    else
                    {
                        createFolderWindow.BringToFront();
                    }
                };
            }

            // add in the message widget
            {
                providerMessageWidget = new TextWidget("")
                {
                    PointSize = 8,
                    HAnchor   = HAnchor.ParentRight,
                    VAnchor   = VAnchor.ParentBottom,
                    TextColor = ActiveTheme.Instance.SecondaryTextColor,
                    Margin    = new BorderDouble(6),
                    AutoExpandBoundsToText = true,
                };

                providerMessageContainer = new GuiWidget()
                {
                    VAnchor = VAnchor.FitToChildren | VAnchor.ParentTop,
                    HAnchor = HAnchor.ParentLeftRight,
                    Visible = false,
                };

                providerMessageContainer.AddChild(providerMessageWidget);
                buttonPanel.AddChild(providerMessageContainer, -1);
            }
        }
Exemple #47
0
		public void EnsureCorrectSizeOnChildrenVisibleChange()
		{
			// just one column changes correctly
			{
				FlowLayoutWidget testColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
				testColumn.Name = "testColumn";

				GuiWidget item1 = new GuiWidget(10, 10);
				item1.Name = "item1";
				testColumn.AddChild(item1);

				Assert.IsTrue(testColumn.Height == 10);

				GuiWidget item2 = new GuiWidget(11, 11);
				item2.Name = "item2";
				testColumn.AddChild(item2);

				Assert.IsTrue(testColumn.Height == 21);

				GuiWidget item3 = new GuiWidget(12, 12);
				item3.Name = "item3";
				testColumn.AddChild(item3);

				Assert.IsTrue(testColumn.Height == 33);

				item2.Visible = false;

				Assert.IsTrue(testColumn.Height == 22);

				item2.Visible = true;

				Assert.IsTrue(testColumn.Height == 33);
			}

			// nested columns change correctly
			{
				GuiWidget.DefaultEnforceIntegerBounds = true;
				CheckBox hideCheckBox;
				FlowLayoutWidget leftColumn;
				FlowLayoutWidget topLeftStuff;
				GuiWidget everything = new GuiWidget(500, 500);
				GuiWidget firstItem;
				GuiWidget thingToHide;
				{
					FlowLayoutWidget twoColumns = new FlowLayoutWidget();
					twoColumns.Name = "twoColumns";
					twoColumns.VAnchor = UI.VAnchor.ParentTop;

					{
						leftColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
						leftColumn.Name = "leftColumn";
						{
							topLeftStuff = new FlowLayoutWidget(FlowDirection.TopToBottom);
							topLeftStuff.Name = "topLeftStuff";
							firstItem = new TextWidget("Top of Top Stuff");
							topLeftStuff.AddChild(firstItem);
							thingToHide = new Button("thing to hide");
							topLeftStuff.AddChild(thingToHide);
							topLeftStuff.AddChild(new TextWidget("Bottom of Top Stuff"));

							leftColumn.AddChild(topLeftStuff);
							//leftColumn.DebugShowBounds = true;
						}

						twoColumns.AddChild(leftColumn);
					}

					{
						FlowLayoutWidget rightColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
						rightColumn.Name = "rightColumn";
						hideCheckBox = new CheckBox("Hide Stuff");
						rightColumn.AddChild(hideCheckBox);
						hideCheckBox.CheckedStateChanged += (sender, e) =>
						{
							if (hideCheckBox.Checked)
							{
								thingToHide.Visible = false;
							}
							else
							{
								thingToHide.Visible = true;
							}
						};

						twoColumns.AddChild(rightColumn);
					}

					everything.AddChild(twoColumns);

					Assert.IsTrue(firstItem.OriginRelativeParent.y == 54);
					//Assert.IsTrue(firstItem.OriginRelativeParent.y - topLeftStuff.LocalBounds.Bottom == 54);
					Assert.IsTrue(twoColumns.BoundsRelativeToParent.Top == 500);
					Assert.IsTrue(leftColumn.BoundsRelativeToParent.Top == 67);
					Assert.IsTrue(leftColumn.BoundsRelativeToParent.Bottom == 0);
					Assert.IsTrue(leftColumn.OriginRelativeParent.y == 0);
					Assert.IsTrue(topLeftStuff.BoundsRelativeToParent.Top == 67);
					Assert.IsTrue(topLeftStuff.Height == 67);
					Assert.IsTrue(leftColumn.Height == 67);

					hideCheckBox.Checked = true;

					Assert.IsTrue(firstItem.OriginRelativeParent.y == 21);
					Assert.IsTrue(leftColumn.OriginRelativeParent.y == 0);
					Assert.IsTrue(leftColumn.BoundsRelativeToParent.Bottom == 0);
					Assert.IsTrue(topLeftStuff.Height == 34);
					Assert.IsTrue(leftColumn.Height == 34);
				}
				GuiWidget.DefaultEnforceIntegerBounds = false;
			}
		}
Exemple #48
0
        internal OpenMenuContents(ObservableCollection <MenuItem> MenuItems, GuiWidget widgetRelativeTo, Vector2 openOffset, Direction direction, RGBA_Bytes backgroundColor, RGBA_Bytes borderColor, int borderWidth, double maxHeight, bool alignToRightEdge)
        {
            this.MenuItems = new List <MenuItem>();
            this.MenuItems.AddRange(MenuItems);
            this.alignToRightEdge = alignToRightEdge;
            this.openOffset       = openOffset;
            this.borderWidth      = borderWidth;
            this.borderColor      = borderColor;
            this.BackgroundColor  = backgroundColor;

            this.direction        = direction;
            this.widgetRelativeTo = widgetRelativeTo;
            scrollingWindow       = new ScrollableWidget(true);
            {
                FlowLayoutWidget topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);
                foreach (MenuItem menu in MenuItems)
                {
                    menu.ClearRemovedFlag();
                    topToBottom.AddChild(menu);
                    menu.DoClickFunction = AllowClickingItems;
                }

                topToBottom.HAnchor = UI.HAnchor.ParentLeft | UI.HAnchor.FitToChildren;
                topToBottom.VAnchor = UI.VAnchor.ParentBottom;
                Width  = topToBottom.Width;
                Height = topToBottom.Height;

                scrollingWindow.AddChild(topToBottom);
            }

            scrollingWindow.HAnchor = HAnchor.ParentLeftRight;
            scrollingWindow.VAnchor = VAnchor.ParentBottomTop;
            if (maxHeight > 0 && Height > maxHeight)
            {
                MakeMenuHaveScroll(maxHeight);
            }
            AddChild(scrollingWindow);

            LostFocus += new EventHandler(DropListItems_LostFocus);

            GuiWidget topParent = widgetRelativeTo.Parent;

            while (topParent.Parent != null &&
                   topParent as SystemWindow == null)
            {
                // Regretably we don't know who it is that is the window that will actually think it is moving relative to its parent
                // but we need to know anytime our widgetRelativeTo has been moved by any change, so we hook them all.

                if (!widgetRefList.Contains(topParent))
                {
                    widgetRefList.Add(topParent);
                    topParent.PositionChanged += new EventHandler(widgetRelativeTo_PositionChanged);
                    topParent.BoundsChanged   += new EventHandler(widgetRelativeTo_PositionChanged);
                }

                topParent = topParent.Parent;
            }
            topParent.AddChild(this);

            widgetRelativeTo_PositionChanged(widgetRelativeTo, null);
            widgetRelativeTo.Closed += widgetRelativeTo_Closed;
        }
Exemple #49
0
		public void ChangingChildFlowWidgetVisiblityUpdatesParentFlow()
		{
			//  ___________________________________________________
			//  |       containerControl 300                      |
			//  | _______________________________________________ |
			//  | |     Flow1 ParentWidth  300                  | |
			//  | | __________________________________________  | |
			//  | | |   Flow2 FitToChildren 250              |  | |
			//  | | | ____________________________ _________ |  | |
			//  | | | | Flow 3 FitToChildren 200 | |Size2  | |  | |
			//  | | | | ________________________ | |50     | |  | |
			//  | | | | | Size1 200            | | |       | |  | |
			//  | | | | |______________________| | |       | |  | |
			//  | | | |__________________________| |_______| |  | |
			//  | | |________________________________________|  | |
			//  | |_____________________________________________| |
			//  |_________________________________________________|
			//

			GuiWidget containerControl = new GuiWidget(300, 200);
			containerControl.Name = "containerControl";

			FlowLayoutWidget flow1 = new FlowLayoutWidget(FlowDirection.LeftToRight);
			flow1.Name = "flow1";
			flow1.HAnchor = HAnchor.ParentLeftRight;
			flow1.Padding = new BorderDouble(3, 3);
			containerControl.AddChild(flow1);

			FlowLayoutWidget flow2 = new FlowLayoutWidget();
			flow2.Name = "flow2";
			flow1.AddChild(flow2);

			GuiWidget flow3 = new FlowLayoutWidget();
			flow3.Name = "flow3";
			flow2.AddChild(flow3);

			GuiWidget size1 = new GuiWidget(200, 20);
			size1.Name = "size2";
			flow3.AddChild(size1);

			GuiWidget size2 = new GuiWidget(50, 20);
			size2.Name = "size1";
			flow2.AddChild(size2);


			Assert.IsTrue(flow1.Width == containerControl.Width);
			Assert.IsTrue(flow3.Width == size1.Width);
			Assert.IsTrue(flow2.Width == size2.Width + flow3.Width);

			size1.Visible = false;
			//  ___________________________________________________
			//  |       containerControl 300                      |
			//  | _______________________________________________ |
			//  | |   Flow1 ParentWidth  300                    | |
			//  | | _____________                               | |
			//  | | | Flow2 50  |                               | |
			//  | | | _________ |                               | |
			//  | | | |Size2  | |                               | |
			//  | | | |50     | |                               | |
			//  | | | |       | |                               | |
			//  | | | |_______| |                               | |
			//  | | |___________|                               | |
			//  | |_____________________________________________| |
			//  |_________________________________________________|
			//

			Assert.IsTrue(flow1.Width == containerControl.Width);
			Assert.IsTrue(flow2.Width == size2.Width);
		}
Exemple #50
0
        protected void CreateGuiElements()
        {
            this.Cursor = Cursors.Hand;

            linkButtonFactory.fontSize  = 10;
            linkButtonFactory.textColor = RGBA_Bytes.White;

            WidgetTextColor       = RGBA_Bytes.Black;
            WidgetBackgroundColor = RGBA_Bytes.White;

            TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;

            SetDisplayAttributes();

            FlowLayoutWidget mainContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);

            mainContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
            mainContainer.VAnchor = VAnchor.ParentBottomTop;
            {
                partLabel = new TextWidget(this.ItemName.Replace('_', ' '), pointSize: 14);

                GuiWidget primaryContainer = new GuiWidget();
                primaryContainer.HAnchor = HAnchor.ParentLeftRight;
                primaryContainer.VAnchor = VAnchor.ParentBottomTop;
                primaryContainer.Name    = "Row Item " + partLabel.Text;

                FlowLayoutWidget primaryFlow = new FlowLayoutWidget(FlowDirection.LeftToRight);
                primaryFlow.HAnchor = HAnchor.ParentLeftRight;
                primaryFlow.VAnchor = VAnchor.ParentBottomTop;

                selectionCheckBoxContainer         = new GuiWidget();
                selectionCheckBoxContainer.VAnchor = VAnchor.ParentBottomTop;
                selectionCheckBoxContainer.Width   = 40;
                selectionCheckBoxContainer.Visible = false;
                selectionCheckBoxContainer.Margin  = new BorderDouble(left: 6);
                selectionCheckBox         = new CheckBox("");
                selectionCheckBox.Click  += selectionCheckBox_Click;
                selectionCheckBox.Name    = "Row Item Select Checkbox";
                selectionCheckBox.VAnchor = VAnchor.ParentCenter;
                selectionCheckBox.HAnchor = HAnchor.ParentCenter;
                selectionCheckBoxContainer.AddChild(selectionCheckBox);

                middleColumn         = new GuiWidget(0.0, 0.0);
                middleColumn.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
                middleColumn.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
                middleColumn.Margin  = new BorderDouble(10, 3);
                {
                    partLabel.TextColor   = WidgetTextColor;
                    partLabel.MinimumSize = new Vector2(1, 18);
                    partLabel.VAnchor     = VAnchor.ParentCenter;
                    middleColumn.AddChild(partLabel);

                    bool mouseDownOnMiddle = false;
                    middleColumn.MouseDown += (sender, e) =>
                    {
                        // Abort normal processing for view helpers
                        if (this.IsViewHelperItem)
                        {
                            return;
                        }
                        mouseDownOnMiddle = true;
                    };

                    middleColumn.MouseUp += (sender, e) =>
                    {
                        if (mouseDownOnMiddle &
                            middleColumn.LocalBounds.Contains(e.Position))
                        {
                            if (this.libraryDataView.EditMode)
                            {
                                if (this.IsSelectedItem)
                                {
                                    libraryDataView.SelectedItems.Remove(this);
                                }
                                else
                                {
                                    libraryDataView.SelectedItems.Add(this);
                                }
                                Invalidate();
                            }
                            else
                            {
                                // we only have single selection
                                if (this.IsSelectedItem)
                                {
                                    // It is already selected, do nothing.
                                }
                                else
                                {
                                    libraryDataView.ClearSelectedItems();
                                    libraryDataView.SelectedItems.Add(this);
                                    Invalidate();
                                }
                            }
                        }

                        mouseDownOnMiddle = false;
                    };
                }
                primaryFlow.AddChild(selectionCheckBoxContainer);

                primaryFlow.AddChild(thumbnailWidget);
                primaryFlow.AddChild(middleColumn);

                primaryContainer.AddChild(primaryFlow);

                rightButtonOverlay         = GetItemActionButtons();
                rightButtonOverlay.Visible = false;

                mainContainer.AddChild(primaryContainer);
                mainContainer.AddChild(rightButtonOverlay);
            }
            this.AddChild(mainContainer);

            AddHandlers();
        }
Exemple #51
0
		public void NestedLayoutTopToBottomWithResizeTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerTest = new GuiWidget(300, 200);
			containerTest.Padding = controlPadding;
			containerTest.DoubleBuffer = true;
			containerTest.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);

			FlowLayoutWidget allButtons = new FlowLayoutWidget(FlowDirection.TopToBottom);
			{
				FlowLayoutWidget topButtonBar = new FlowLayoutWidget();
				{
					Button button1 = new Button("button1");
					button1.Margin = buttonMargin;
					topButtonBar.AddChild(button1);
				}
				allButtons.AddChild(topButtonBar);

				FlowLayoutWidget bottomButtonBar = new FlowLayoutWidget();
				{
					Button button2 = new Button("wide button2");
					button2.Margin = buttonMargin;
					bottomButtonBar.AddChild(button2);
				}
				allButtons.AddChild(bottomButtonBar);
			}
			containerTest.AddChild(allButtons);
			containerTest.OnDraw(containerTest.NewGraphics2D());
			ImageBuffer controlImage = new ImageBuffer(containerTest.BackBuffer, new BlenderBGRA());

			OutputImage(controlImage, "image-control.tga");

			RectangleDouble oldBounds = containerTest.LocalBounds;
			RectangleDouble newBounds = oldBounds;
			newBounds.Right += 10;
			containerTest.LocalBounds = newBounds;
			containerTest.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImage(containerTest, "image-test.tga");

			containerTest.LocalBounds = oldBounds;
			containerTest.BackBuffer.NewGraphics2D().Clear(RGBA_Bytes.White);
			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImage(containerTest, "image-test.tga");

			Assert.IsTrue(containerTest.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerTest.BackBuffer == controlImage, "The control should contain the same image after being scaled away and back to the same size.");
		}
Exemple #52
0
 public override void AddChild(GuiWidget childToAdd, int indexInChildrenList = -1)
 {
     clientArea.AddChild(childToAdd, indexInChildrenList);
 }
Exemple #53
0
		private void LeftToRightAnchorLeftBottomTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(300, 200);
			containerControl.DoubleBuffer = true;
			Button controlButton1 = new Button("buttonLeft");
			controlButton1.OriginRelativeParent = new VectorMath.Vector2(controlPadding.Left + buttonMargin.Left, controlButton1.OriginRelativeParent.y + controlPadding.Bottom + buttonMargin.Bottom);
			containerControl.AddChild(controlButton1);
			Button controlButton2 = new Button("buttonRight");
			controlButton2.OriginRelativeParent = new VectorMath.Vector2(controlPadding.Left + buttonMargin.Width + buttonMargin.Left + controlButton1.Width, controlButton2.OriginRelativeParent.y + controlPadding.Bottom + buttonMargin.Bottom);
			containerControl.AddChild(controlButton2);
			containerControl.OnDraw(containerControl.NewGraphics2D());

			GuiWidget containerTest = new GuiWidget(300, 200);
			FlowLayoutWidget flowLayout = new FlowLayoutWidget(FlowDirection.LeftToRight);
			flowLayout.AnchorAll();
			flowLayout.Padding = controlPadding;
			containerTest.DoubleBuffer = true;

			Button testButton1 = new Button("buttonLeft");
			testButton1.VAnchor = VAnchor.ParentBottom;
			testButton1.Margin = buttonMargin;
			flowLayout.AddChild(testButton1);

			Button testButton2 = new Button("buttonRight");
			testButton2.VAnchor = VAnchor.ParentBottom;
			testButton2.Margin = buttonMargin;
			flowLayout.AddChild(testButton2);

			containerTest.AddChild(flowLayout);

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");

			// make sure it can resize without breaking
			RectangleDouble bounds = containerTest.LocalBounds;
			RectangleDouble newBounds = bounds;
			newBounds.Right += 10;
			containerTest.LocalBounds = newBounds;
			Assert.IsTrue(containerControl.BackBuffer != containerTest.BackBuffer, "The Anchored widget should not be the same size.");
			containerTest.LocalBounds = bounds;
			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);
			Assert.IsTrue(containerControl.BackBuffer == containerTest.BackBuffer, "The Anchored widget should be in the correct place.");
		}
        public EditTemperaturePresetsWindow(string windowTitle, string temperatureSettings, EventHandler functionToCallOnSave)
            : base(360, 300)
        {
            Title = LocalizedString.Get(windowTitle);

            FlowLayoutWidget topToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom);

            topToBottom.AnchorAll();
            topToBottom.Padding = new BorderDouble(3, 0, 3, 5);

            FlowLayoutWidget headerRow = new FlowLayoutWidget(FlowDirection.LeftToRight);

            headerRow.HAnchor = HAnchor.ParentLeftRight;
            headerRow.Margin  = new BorderDouble(0, 3, 0, 0);
            headerRow.Padding = new BorderDouble(0, 3, 0, 3);

            {
                string     tempShortcutPresetLabel     = LocalizedString.Get("Temperature Shortcut Presets");
                string     tempShortcutPresetLabelFull = string.Format("{0}:", tempShortcutPresetLabel);
                TextWidget elementHeader = new TextWidget(tempShortcutPresetLabelFull, pointSize: 14);
                elementHeader.TextColor = ActiveTheme.Instance.PrimaryTextColor;
                elementHeader.HAnchor   = HAnchor.ParentLeftRight;
                elementHeader.VAnchor   = Agg.UI.VAnchor.ParentBottom;


                headerRow.AddChild(elementHeader);
            }


            topToBottom.AddChild(headerRow);

            FlowLayoutWidget presetsFormContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);

            //ListBox printerListContainer = new ListBox();
            {
                presetsFormContainer.HAnchor         = HAnchor.ParentLeftRight;
                presetsFormContainer.VAnchor         = VAnchor.ParentBottomTop;
                presetsFormContainer.Padding         = new BorderDouble(3);
                presetsFormContainer.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
            }

            topToBottom.AddChild(presetsFormContainer);

            this.functionToCallOnSave = functionToCallOnSave;
            BackgroundColor           = ActiveTheme.Instance.PrimaryBackgroundColor;

            int oldHeight = textImageButtonFactory.FixedHeight;

            textImageButtonFactory.FixedHeight = 30;

            TextWidget tempTypeLabel = new TextWidget(windowTitle, textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 10);

            tempTypeLabel.Margin  = new BorderDouble(3);
            tempTypeLabel.HAnchor = HAnchor.ParentLeft;
            presetsFormContainer.AddChild(tempTypeLabel);

            FlowLayoutWidget leftRightLabels = new FlowLayoutWidget();

            leftRightLabels.Padding  = new BorderDouble(3, 6);
            leftRightLabels.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;

            GuiWidget hLabelSpacer = new GuiWidget();

            hLabelSpacer.HAnchor = HAnchor.ParentLeftRight;

            GuiWidget labelLabelContainer = new GuiWidget();

            labelLabelContainer.Width  = 66;
            labelLabelContainer.Height = 16;
            labelLabelContainer.Margin = new BorderDouble(3, 0);

            string     labelLabelTxt = LocalizedString.Get("Label");
            TextWidget labelLabel    = new TextWidget(string.Format(labelLabelTxt), textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 10);

            labelLabel.HAnchor = HAnchor.ParentLeft;
            labelLabel.VAnchor = VAnchor.ParentCenter;


            labelLabelContainer.AddChild(labelLabel);

            GuiWidget tempLabelContainer = new GuiWidget();

            tempLabelContainer.Width  = 66;
            tempLabelContainer.Height = 16;
            tempLabelContainer.Margin = new BorderDouble(3, 0);

            TextWidget tempLabel = new TextWidget(string.Format("Temp (C)"), textColor: ActiveTheme.Instance.PrimaryTextColor, pointSize: 10);

            tempLabel.HAnchor = HAnchor.ParentLeft;
            tempLabel.VAnchor = VAnchor.ParentCenter;

            tempLabelContainer.AddChild(tempLabel);

            leftRightLabels.AddChild(hLabelSpacer);
            leftRightLabels.AddChild(labelLabelContainer);
            leftRightLabels.AddChild(tempLabelContainer);

            presetsFormContainer.AddChild(leftRightLabels);

            // put in the temperature edit controls
            string[] settingsArray = temperatureSettings.Split(',');
            int      preset_count  = 1;
            int      tab_index     = 0;

            for (int i = 0; i < settingsArray.Count() - 1; i += 2)
            {
                FlowLayoutWidget leftRightEdit = new FlowLayoutWidget();
                leftRightEdit.Padding  = new BorderDouble(3);
                leftRightEdit.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;
                string     presetLabelTxt = LocalizedString.Get("Preset");
                TextWidget label          = new TextWidget(string.Format("{1} {0}.", preset_count, presetLabelTxt), textColor: ActiveTheme.Instance.PrimaryTextColor);
                label.VAnchor = VAnchor.ParentCenter;
                leftRightEdit.AddChild(label);

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

                leftRightEdit.AddChild(hSpacer);

                MHTextEditWidget typeEdit = new MHTextEditWidget(settingsArray[i], pixelWidth: 60, tabIndex: tab_index++);

                typeEdit.Margin = new BorderDouble(3);
                leftRightEdit.AddChild(typeEdit);
                listWithValues.Add(typeEdit);

                double temperatureValue = 0;
                double.TryParse(settingsArray[i + 1], out temperatureValue);
                MHNumberEdit valueEdit = new MHNumberEdit(temperatureValue, minValue: 0, pixelWidth: 60, tabIndex: tab_index++);
                valueEdit.Margin = new BorderDouble(3);
                leftRightEdit.AddChild(valueEdit);
                listWithValues.Add(valueEdit);

                //leftRightEdit.AddChild(textImageButtonFactory.Generate("Delete"));
                presetsFormContainer.AddChild(leftRightEdit);
                preset_count += 1;
            }

            {
                FlowLayoutWidget leftRightEdit = new FlowLayoutWidget();
                leftRightEdit.Padding  = new BorderDouble(3);
                leftRightEdit.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;

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

                TextWidget maxWidgetLabel = new TextWidget(LocalizedString.Get("Max Temp."), textColor: ActiveTheme.Instance.PrimaryTextColor);
                maxWidgetLabel.VAnchor = VAnchor.ParentCenter;
                leftRightEdit.AddChild(maxWidgetLabel);
                leftRightEdit.AddChild(hSpacer);

                double maxTemperature = 0;
                double.TryParse(settingsArray[settingsArray.Count() - 1], out maxTemperature);
                MHNumberEdit valueEdit = new MHNumberEdit(maxTemperature, minValue: 0, pixelWidth: 60, tabIndex: tab_index);
                valueEdit.Margin = new BorderDouble(3);
                leftRightEdit.AddChild(valueEdit);
                listWithValues.Add(valueEdit);

                presetsFormContainer.AddChild(leftRightEdit);
            }

            textImageButtonFactory.FixedHeight = oldHeight;

            ShowAsSystemWindow();
            MinimumSize = new Vector2(360, 300);

            Button savePresetsButton = textImageButtonFactory.Generate(LocalizedString.Get("Save"));

            savePresetsButton.Click += new ButtonBase.ButtonEventHandler(save_Click);

            Button cancelPresetsButton = textImageButtonFactory.Generate(LocalizedString.Get("Cancel"));

            cancelPresetsButton.Click += (sender, e) => { CloseOnIdle(); };

            FlowLayoutWidget buttonRow = new FlowLayoutWidget();

            buttonRow.HAnchor = HAnchor.ParentLeftRight;
            buttonRow.Padding = new BorderDouble(0, 3);

            GuiWidget hButtonSpacer = new GuiWidget();

            hButtonSpacer.HAnchor = HAnchor.ParentLeftRight;

            buttonRow.AddChild(savePresetsButton);
            buttonRow.AddChild(hButtonSpacer);
            buttonRow.AddChild(cancelPresetsButton);

            topToBottom.AddChild(buttonRow);

            AddChild(topToBottom);
        }
Exemple #55
0
		public void FlowTopBottomAnchorChildrenLeftRightTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(300, 500);
			containerControl.DoubleBuffer = true;
			Button controlButtonWide = new Button("Button Wide Text");
			containerControl.AddChild(controlButtonWide);
			Button controlButton1 = new Button("button1");
			controlButton1.OriginRelativeParent = new VectorMath.Vector2(controlPadding.Left + buttonMargin.Left + controlButton1.OriginRelativeParent.x, controlPadding.Bottom + buttonMargin.Bottom);
			controlButtonWide.OriginRelativeParent = new VectorMath.Vector2(controlPadding.Left + buttonMargin.Left + controlButtonWide.OriginRelativeParent.x, controlButton1.BoundsRelativeToParent.Top + buttonMargin.Height);
			controlButton1.LocalBounds = controlButtonWide.LocalBounds;
			containerControl.AddChild(controlButton1);
			containerControl.OnDraw(containerControl.NewGraphics2D());

			GuiWidget containerTest = new GuiWidget(300, 500);
			FlowLayoutWidget flowLayout = new FlowLayoutWidget(FlowDirection.TopToBottom);
			flowLayout.Padding = controlPadding;
			containerTest.DoubleBuffer = true;

			Button testButtonWide = new Button("Button Wide Text");
			testButtonWide.HAnchor = HAnchor.ParentLeft;
			testButtonWide.Margin = buttonMargin;
			flowLayout.AddChild(testButtonWide);

			double correctHeightOfFlowLayout = testButtonWide.Height + flowLayout.Padding.Height + testButtonWide.Margin.Height;
			Assert.AreEqual(flowLayout.Height, correctHeightOfFlowLayout, .001);

			Button testButton1 = new Button("button1");
			testButton1.Margin = buttonMargin;
			testButton1.HAnchor = HAnchor.ParentLeft | HAnchor.ParentRight;
			flowLayout.AddChild(testButton1);

			correctHeightOfFlowLayout += testButton1.Height + testButton1.Margin.Height;
			Assert.AreEqual(flowLayout.Height, correctHeightOfFlowLayout, .001);

			flowLayout.HAnchor = HAnchor.ParentLeft;
			flowLayout.VAnchor = VAnchor.ParentBottom;
			containerTest.AddChild(flowLayout);

			Vector2 controlButton1Pos = controlButton1.OriginRelativeParent;
			Vector2 testButton1Pos = testButton1.TransformToScreenSpace(Vector2.Zero);

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			Assert.IsTrue(containerControl.BackBuffer.Equals(containerTest.BackBuffer, 1), "The Anchored widget should be in the correct place.");

			// make sure it can resize without breaking
			RectangleDouble bounds = containerTest.LocalBounds;
			RectangleDouble newBounds = bounds;
			newBounds.Right += 10;
			containerTest.LocalBounds = newBounds;
			Assert.IsTrue(containerControl.BackBuffer != containerTest.BackBuffer, "The Anchored widget should not be the same size.");
			containerTest.LocalBounds = bounds;
			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);
			Assert.IsTrue(containerControl.BackBuffer.Equals(containerTest.BackBuffer, 1), "The Anchored widget should be in the correct place.");
		}
        public ToolsListItem(PrintItemWrapper printItem)
        {
            this.printItem              = printItem;
            linkButtonFactory.fontSize  = 10;
            linkButtonFactory.textColor = RGBA_Bytes.White;

            WidgetTextColor       = RGBA_Bytes.Black;
            WidgetBackgroundColor = RGBA_Bytes.White;

            TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;

            SetDisplayAttributes();

            FlowLayoutWidget mainContainer = new FlowLayoutWidget(FlowDirection.LeftToRight);

            mainContainer.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;
            {
                GuiWidget selectionCheckBoxContainer = new GuiWidget();
                selectionCheckBoxContainer.VAnchor = VAnchor.Max_FitToChildren_ParentHeight;
                selectionCheckBoxContainer.HAnchor = Agg.UI.HAnchor.FitToChildren;
                selectionCheckBoxContainer.Margin  = new BorderDouble(left: 6);
                selectionCheckBox         = new CheckBox("");
                selectionCheckBox.VAnchor = VAnchor.ParentCenter;
                selectionCheckBox.HAnchor = HAnchor.ParentCenter;
                selectionCheckBoxContainer.AddChild(selectionCheckBox);

                FlowLayoutWidget leftColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
                leftColumn.VAnchor |= VAnchor.ParentTop;

                FlowLayoutWidget middleColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
                middleColumn.VAnchor |= VAnchor.ParentTop;
                middleColumn.HAnchor |= HAnchor.ParentLeftRight;
                middleColumn.Padding  = new BorderDouble(6);
                middleColumn.Margin   = new BorderDouble(10, 0);
                {
                    string labelName = textInfo.ToTitleCase(printItem.Name);
                    labelName             = labelName.Replace('_', ' ');
                    partLabel             = new TextWidget(labelName, pointSize: 12);
                    partLabel.TextColor   = WidgetTextColor;
                    partLabel.MinimumSize = new Vector2(1, 16);
                    middleColumn.AddChild(partLabel);
                }

                FlowLayoutWidget rightColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
                rightColumn.VAnchor |= VAnchor.ParentCenter;

                buttonContainer         = new FlowLayoutWidget();
                buttonContainer.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
                buttonContainer.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight;
                {
                    viewLink         = linkButtonFactory.Generate("View");
                    viewLink.Margin  = new BorderDouble(left: 10, right: 10);
                    viewLink.VAnchor = VAnchor.ParentCenter;

                    removeLink         = linkButtonFactory.Generate("Remove");
                    removeLink.Margin  = new BorderDouble(right: 10);
                    removeLink.VAnchor = VAnchor.ParentCenter;

                    buttonContainer.AddChild(viewLink);
                    buttonContainer.AddChild(removeLink);
                }
                rightColumn.AddChild(buttonContainer);

                mainContainer.AddChild(selectionCheckBoxContainer);
                mainContainer.AddChild(leftColumn);
                mainContainer.AddChild(middleColumn);
                mainContainer.AddChild(rightColumn);
            }
            this.AddChild(mainContainer);
            AddHandlers();
        }
Exemple #57
0
		public void NestedFlowWidgetsRightToLeftTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			GuiWidget containerControl = new GuiWidget(500, 300);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;

			{
				Button buttonRight = new Button("buttonRight");
				Button buttonLeft = new Button("buttonLeft");
				buttonRight.OriginRelativeParent = new VectorMath.Vector2(containerControl.LocalBounds.Right - controlPadding.Right - buttonMargin.Right - buttonRight.Width, buttonRight.OriginRelativeParent.y + controlPadding.Bottom + buttonMargin.Bottom);
				buttonLeft.OriginRelativeParent = new VectorMath.Vector2(buttonRight.BoundsRelativeToParent.Left - buttonMargin.Width - buttonLeft.Width, buttonLeft.OriginRelativeParent.y + controlPadding.Bottom + buttonMargin.Bottom);
				containerControl.AddChild(buttonRight);
				containerControl.AddChild(buttonLeft);
				containerControl.OnDraw(containerControl.NewGraphics2D());
			}

			GuiWidget containerTest = new GuiWidget(500, 300);
			containerTest.DoubleBuffer = true;
			{
				FlowLayoutWidget rightToLeftFlowLayoutAll = new FlowLayoutWidget(FlowDirection.RightToLeft);
				rightToLeftFlowLayoutAll.AnchorAll();
				rightToLeftFlowLayoutAll.Padding = controlPadding;
				{
					FlowLayoutWidget rightToLeftFlowLayoutRight = new FlowLayoutWidget(FlowDirection.RightToLeft);
					Button buttonRight = new Button("buttonRight");
					buttonRight.Margin = buttonMargin;
					rightToLeftFlowLayoutRight.AddChild(buttonRight);
					rightToLeftFlowLayoutRight.SetBoundsToEncloseChildren();
					rightToLeftFlowLayoutRight.VAnchor = VAnchor.ParentBottom;
					rightToLeftFlowLayoutAll.AddChild(rightToLeftFlowLayoutRight);
				}

				{
					FlowLayoutWidget rightToLeftFlowLayoutLeft = new FlowLayoutWidget(FlowDirection.RightToLeft);
					Button buttonLeft = new Button("buttonLeft");
					buttonLeft.Margin = buttonMargin;
					rightToLeftFlowLayoutLeft.AddChild(buttonLeft);
					rightToLeftFlowLayoutLeft.SetBoundsToEncloseChildren();
					rightToLeftFlowLayoutLeft.VAnchor = VAnchor.ParentBottom;
					rightToLeftFlowLayoutAll.AddChild(rightToLeftFlowLayoutLeft);
				}

				containerTest.AddChild(rightToLeftFlowLayoutAll);
			}

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");
			// we use a least squares match because the erase background that is setting the widgets is integer pixel based and the fill rectangle is not.
			Assert.IsTrue(containerControl.BackBuffer.FindLeastSquaresMatch(containerTest.BackBuffer, 50), "The test and control need to match.");
			Assert.IsTrue(containerControl.BackBuffer.Equals(containerTest.BackBuffer, 1), "The Anchored widget should be in the correct place.");
		}
        //private void CreateProductDataWidgets(PrinterSettings printerSettings, ProductSkuData product)
        private void CreateProductDataWidgets(ProductSkuData product)
        {
            var row = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Stretch,
                Margin  = new BorderDouble(top: theme.DefaultContainerPadding)
            };

            productDataContainer.AddChild(row);

            var image = new ImageBuffer(150, 10);

            row.AddChild(new ImageWidget(image)
            {
                Margin  = new BorderDouble(right: theme.DefaultContainerPadding),
                VAnchor = VAnchor.Top
            });

            WebCache.RetrieveImageAsync(image, product.FeaturedImage.ImageUrl, scaleToImageX: true);

            var descriptionBackground = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit | VAnchor.Top,
                Padding = theme.DefaultContainerPadding
            };

            var description = new MarkdownWidget(theme)
            {
                MinimumSize = new VectorMath.Vector2(50, 0),
                HAnchor     = HAnchor.Stretch,
                VAnchor     = VAnchor.Fit,
                AutoScroll  = false,
                Markdown    = product.ProductDescription.Trim()
            };

            descriptionBackground.AddChild(description);
            descriptionBackground.BeforeDraw += (s, e) =>
            {
                var rect = new RoundedRect(descriptionBackground.LocalBounds, 3);
                e.Graphics2D.Render(rect, theme.SlightShade);
            };

            row.AddChild(descriptionBackground);

            if (this.ShowProducts)
            {
                var padding = theme.DefaultContainerPadding;

                var addonsColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)
                {
                    Padding = new BorderDouble(padding, padding, padding, 0),
                    HAnchor = HAnchor.Stretch
                };

                var addonsSection = new SectionWidget("Upgrades and Accessories", addonsColumn, theme);
                productDataContainer.AddChild(addonsSection);
                theme.ApplyBoxStyle(addonsSection);
                addonsSection.Margin = addonsSection.Margin.Clone(left: 0);



                foreach (var item in product.ProductListing.AddOns)
                {
                    var icon = new ImageBuffer(80, 0);
                    WebCache.RetrieveImageAsync(icon, item.FeaturedImage.ImageUrl, scaleToImageX: true);

                    var addOnRow = new AddOnRow(item.AddOnTitle, theme, null, icon)
                    {
                        HAnchor = HAnchor.Stretch,
                        Cursor  = Cursors.Hand
                    };

                    foreach (var child in addOnRow.Children)
                    {
                        child.Selectable = false;
                    }

                    addOnRow.Click += (s, e) =>
                    {
                        ApplicationController.Instance.LaunchBrowser($"https://www.matterhackers.com/store/l/{item.AddOnListingReference}/sk/{item.AddOnSkuReference}");
                    };

                    addonsColumn.AddChild(addOnRow);
                }
            }

            //if (false)
            //{
            //	var settingsPanel = new GuiWidget()
            //	{
            //		HAnchor = HAnchor.Stretch,
            //		VAnchor = VAnchor.Stretch,
            //		MinimumSize = new VectorMath.Vector2(20, 20),
            //		DebugShowBounds = true
            //	};

            //	settingsPanel.Load += (s, e) =>
            //	{
            //		var printer = new PrinterConfig(printerSettings);

            //		var settingsContext = new SettingsContext(
            //			printer,
            //			null,
            //			NamedSettingsLayers.All);

            //		settingsPanel.AddChild(
            //			new ConfigurePrinterWidget(settingsContext, printer, theme)
            //			{
            //				HAnchor = HAnchor.Stretch,
            //				VAnchor = VAnchor.Stretch,
            //			});
            //	};

            //	this.AddChild(new SectionWidget("Settings", settingsPanel, theme, expanded: false, setContentVAnchor: false)
            //	{
            //		VAnchor = VAnchor.Stretch
            //	});
            //}
        }
Exemple #59
0
		public void LeftRightWithAnchorLeftRightChildTest(BorderDouble controlPadding, BorderDouble buttonMargin)
		{
			double buttonSize = 40;
			GuiWidget containerControl = new GuiWidget(buttonSize * 8, buttonSize * 3);
			containerControl.Padding = controlPadding;
			containerControl.DoubleBuffer = true;

			RectangleDouble[] eightControlRectangles = new RectangleDouble[8];
			RGBA_Bytes[] eightColors = new RGBA_Bytes[] { RGBA_Bytes.Red, RGBA_Bytes.Orange, RGBA_Bytes.Yellow, RGBA_Bytes.YellowGreen, RGBA_Bytes.Green, RGBA_Bytes.Blue, RGBA_Bytes.Indigo, RGBA_Bytes.Violet };
			{
				double currentleft = controlPadding.Left + buttonMargin.Left;
				double buttonHeightWithMargin = buttonSize + buttonMargin.Height;
				double scalledWidth = (containerControl.Width - controlPadding.Width - buttonMargin.Width * 8 - buttonSize * 2) / 6;
				// the left unsized rect
				eightControlRectangles[0] = new RectangleDouble(
						currentleft,
						0,
						currentleft + buttonSize,
						buttonSize);

				// a bottom anchor
				currentleft += buttonSize + buttonMargin.Width;
				double bottomAnchorY = controlPadding.Bottom + buttonMargin.Bottom;
				eightControlRectangles[1] = new RectangleDouble(currentleft, bottomAnchorY, currentleft + scalledWidth, bottomAnchorY + buttonSize);

				// center anchor
				double centerYOfContainer = controlPadding.Bottom + (containerControl.Height - controlPadding.Height) / 2;
				currentleft += scalledWidth + buttonMargin.Width;
				eightControlRectangles[2] = new RectangleDouble(currentleft, centerYOfContainer - buttonHeightWithMargin / 2 + buttonMargin.Bottom, currentleft + scalledWidth, centerYOfContainer + buttonHeightWithMargin / 2 - buttonMargin.Top);

				// top anchor
				double topAnchorY = containerControl.Height - controlPadding.Top - buttonMargin.Top;
				currentleft += scalledWidth + buttonMargin.Width;
				eightControlRectangles[3] = new RectangleDouble(currentleft, topAnchorY - buttonSize, currentleft + scalledWidth, topAnchorY);

				// bottom center anchor
				currentleft += scalledWidth + buttonMargin.Width;
				eightControlRectangles[4] = new RectangleDouble(currentleft, bottomAnchorY, currentleft + scalledWidth, centerYOfContainer - buttonMargin.Top);

				// center top anchor
				currentleft += scalledWidth + buttonMargin.Width;
				eightControlRectangles[5] = new RectangleDouble(currentleft, centerYOfContainer + buttonMargin.Bottom, currentleft + scalledWidth, topAnchorY);

				// bottom top anchor
				currentleft += scalledWidth + buttonMargin.Width;
				eightControlRectangles[6] = new RectangleDouble(currentleft, bottomAnchorY, currentleft + scalledWidth, topAnchorY);

				// right anchor
				currentleft += scalledWidth + buttonMargin.Width;
				eightControlRectangles[7] = new RectangleDouble(currentleft, 0, currentleft + buttonSize, buttonSize);

				Graphics2D graphics = containerControl.NewGraphics2D();
				for (int i = 0; i < 8; i++)
				{
					graphics.FillRectangle(eightControlRectangles[i], eightColors[i]);
				}
			}

			GuiWidget containerTest = new GuiWidget(containerControl.Width, containerControl.Height);
			FlowLayoutWidget leftToRightFlowLayoutAll = new FlowLayoutWidget(FlowDirection.LeftToRight);
			containerTest.DoubleBuffer = true;
			{
				leftToRightFlowLayoutAll.AnchorAll();
				leftToRightFlowLayoutAll.Padding = controlPadding;
				{
					GuiWidget left = new GuiWidget(buttonSize, buttonSize);
					left.BackgroundColor = RGBA_Bytes.Red;
					left.Margin = buttonMargin;
					leftToRightFlowLayoutAll.AddChild(left);

					leftToRightFlowLayoutAll.AddChild(CreateLeftToRightMiddleWidget(buttonMargin, buttonSize, VAnchor.ParentBottom, RGBA_Bytes.Orange));
					leftToRightFlowLayoutAll.AddChild(CreateLeftToRightMiddleWidget(buttonMargin, buttonSize, VAnchor.ParentCenter, RGBA_Bytes.Yellow));
					leftToRightFlowLayoutAll.AddChild(CreateLeftToRightMiddleWidget(buttonMargin, buttonSize, VAnchor.ParentTop, RGBA_Bytes.YellowGreen));
					leftToRightFlowLayoutAll.AddChild(CreateLeftToRightMiddleWidget(buttonMargin, buttonSize, VAnchor.ParentBottomCenter, RGBA_Bytes.Green));
					leftToRightFlowLayoutAll.AddChild(CreateLeftToRightMiddleWidget(buttonMargin, buttonSize, VAnchor.ParentCenterTop, RGBA_Bytes.Blue));
					leftToRightFlowLayoutAll.AddChild(CreateLeftToRightMiddleWidget(buttonMargin, buttonSize, VAnchor.ParentBottomTop, RGBA_Bytes.Indigo));

					GuiWidget right = new GuiWidget(buttonSize, buttonSize);
					right.BackgroundColor = RGBA_Bytes.Violet;
					right.Margin = buttonMargin;
					leftToRightFlowLayoutAll.AddChild(right);
				}

				containerTest.AddChild(leftToRightFlowLayoutAll);
			}

			containerTest.OnDraw(containerTest.NewGraphics2D());
			OutputImages(containerControl, containerTest);

			for (int i = 0; i < 8; i++)
			{
				Assert.IsTrue(eightControlRectangles[i] == leftToRightFlowLayoutAll.Children[i].BoundsRelativeToParent);
			}

			Assert.IsTrue(containerControl.BackBuffer != null, "When we set a guiWidget to DoubleBuffer it needs to create one.");

			// we use a least squares match because the erase background that is setting the widgets is integer pixel based and the fill rectangle is not.
			Assert.IsTrue(containerControl.BackBuffer.FindLeastSquaresMatch(containerTest.BackBuffer, 0), "The test and control need to match.");
		}
        public RunningTaskRow(string title, RunningTaskDetails taskDetails, ThemeConfig theme)
            : base(FlowDirection.TopToBottom)
        {
            this.taskDetails = taskDetails;
            this.theme       = theme;

            this.MinimumSize = new Vector2(100 * GuiWidget.DeviceScale, 20 * GuiWidget.DeviceScale);

            var detailsPanel = new GuiWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
            };

            var rowContainer = new GuiWidget()
            {
                VAnchor = VAnchor.Fit,
                HAnchor = HAnchor.Stretch,
            };

            this.AddChild(rowContainer);

            var topRow = new FlowLayoutWidget()
            {
                HAnchor = HAnchor.Stretch,
                VAnchor = VAnchor.Fit,
                Padding = 0,
            };

            rowContainer.AddChild(topRow);

            progressBar = new ProgressBar()
            {
                HAnchor     = HAnchor.Stretch,
                Height      = 2 * GuiWidget.DeviceScale,
                VAnchor     = VAnchor.Absolute | VAnchor.Bottom,
                FillColor   = theme.PrimaryAccentColor,
                BorderColor = Color.Transparent,
                Margin      = new BorderDouble(32, 7, theme.ButtonHeight * 2 + 14, 0),
                Visible     = !taskDetails.IsExpanded
            };
            rowContainer.AddChild(progressBar);

            expandButton = new ExpandCheckboxButton(!string.IsNullOrWhiteSpace(title) ? title : taskDetails.Title, theme, 10)
            {
                VAnchor         = VAnchor.Center | VAnchor.Fit,
                HAnchor         = HAnchor.Stretch,
                Checked         = false,
                Padding         = 0,
                AlwaysShowArrow = true
            };
            expandButton.CheckedStateChanged += (s, e) =>
            {
                taskDetails.IsExpanded = expandButton.Checked;
                SetExpansionMode(theme, detailsPanel, expandButton.Checked);
            };
            topRow.AddChild(expandButton);

            GuiWidget resumeButton = null;

            GuiWidget pauseButton = CreateIconOrTextButton("fa-pause_12.png",
                                                           taskDetails.Options?.PauseText,
                                                           taskDetails.Options?.PauseAction,
                                                           taskDetails.Options?.PauseToolTip ?? "Pause".Localize(),
                                                           "",
                                                           theme,
                                                           0);

            if (taskDetails.Options?.IsPaused != null)
            {
                RunningInterval runningInterval = null;
                runningInterval = UiThread.SetInterval(() =>
                {
                    if (taskDetails.Options.IsPaused())
                    {
                        pauseButton.Visible  = false;
                        resumeButton.Visible = true;
                    }
                    else
                    {
                        pauseButton.Visible  = true;
                        resumeButton.Visible = false;
                    }

                    if (this.HasBeenClosed)
                    {
                        UiThread.ClearInterval(runningInterval);
                    }
                }, .2);
            }
            pauseButton.Click += (s, e) =>
            {
                taskDetails.Options?.PauseAction();
                pauseButton.Visible  = false;
                resumeButton.Visible = true;
            };
            topRow.AddChild(pauseButton);


            resumeButton = CreateIconOrTextButton("fa-play_12.png",
                                                  taskDetails.Options?.ResumeText,
                                                  taskDetails.Options?.ResumeAction,
                                                  taskDetails.Options?.ResumeToolTip ?? "Resume".Localize(),
                                                  "Resume Task Button",
                                                  theme,
                                                  0);
            // start with it hidden
            resumeButton.Visible = false;

            resumeButton.Click += (s, e) =>
            {
                taskDetails.Options?.ResumeAction();
                pauseButton.Visible  = true;
                resumeButton.Visible = false;
            };
            topRow.AddChild(resumeButton);

            var stopButton = CreateIconOrTextButton("fa-stop_12.png",
                                                    taskDetails.Options?.StopText,
                                                    taskDetails.Options?.StopAction,
                                                    taskDetails.Options?.StopToolTip ?? "Cancel".Localize(),
                                                    "Stop Task Button",
                                                    theme,
                                                    5);

            stopButton.Enabled = true;

            stopButton.Click += (s, e) =>
            {
                var stopAction = taskDetails.Options?.StopAction;
                if (stopAction == null)
                {
                    taskDetails.CancelTask();
                }
                else
                {
                    stopAction.Invoke(() =>
                    {
                        stopButton.Enabled = true;
                    });
                }

                stopButton.Enabled = false;
            };
            topRow.AddChild(stopButton);

            this.AddChild(detailsPanel);

            // Add rich progress controls
            if (taskDetails.Options?.RichProgressWidget?.Invoke() is GuiWidget guiWidget)
            {
                detailsPanel.AddChild(guiWidget);
            }
            else
            {
                expandButton.Expandable = false;
            }

            if (taskDetails.Options?.ReadOnlyReporting == true)
            {
                stopButton.Visible   = false;
                pauseButton.Visible  = false;
                resumeButton.Visible = false;

                // Ensure the top row is as big as it would be with buttons
                topRow.MinimumSize = new Vector2(0, resumeButton.Height);
            }

            SetExpansionMode(theme, detailsPanel, taskDetails.IsExpanded);

            taskDetails.ProgressChanged += TaskDetails_ProgressChanged;
        }