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(); } }
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); }
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); }
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."); }
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); }
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."); }
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); }
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); } }
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); } }
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."); }
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); }
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; } }
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."); } }
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); } }
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); } }
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."); }
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."); }
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); }
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(); } }
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."); }
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(); }
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)); } }
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(); }
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."); }
private void RebuildDropDownList() { pullDownContainer.CloseAllChildren(); pullDownContainer.AddChild(GetPulldownContainer()); }
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(); }
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); } }
private void AddSettingsRow(GuiWidget widget, GuiWidget container) { container.AddChild(widget); widget.Padding = widget.Padding.Clone(right: 10); }
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 }
private static void AddInline(GuiWidget parent, GuiWidget inline) { parent.AddChild(inline); }
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."); }
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); }
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); }
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); } }
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; } }
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; }
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); }
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(); }
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."); }
public override void AddChild(GuiWidget childToAdd, int indexInChildrenList = -1) { clientArea.AddChild(childToAdd, indexInChildrenList); }
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); }
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(); }
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 // }); //} }
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; }