From 18b3677d0894d27310ab525d7c63a47b9d919d2c Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 17 Feb 2024 10:26:53 -0700 Subject: [PATCH] Added dialog box to sample FRB forms project. Dialog box now breaks on pages. --- .../Controls/Games/DialogBox.cs | 73 +++++++- .../Content/GumLastChangeFilePath.txt | 2 +- .../Components/Controls/DialogBox.gucx | 10 +- .../GumProject/EventExport/gum_events.json | 100 +++++++++++ .../Content/GumProject/GumProject.gumx | 7 +- .../GumProject/Screens/MainMenuGum.gusx | 168 +++++++++++++++++- .../GumProject/Screens/TestScreen.gusx | 69 +++++++ .../FormsSampleProject.csproj | 9 + .../GumRuntimes/TestScreenRuntime.cs | 13 ++ .../FormsSampleProject/Screens/MainMenu.cs | 24 +++ 10 files changed, 460 insertions(+), 15 deletions(-) create mode 100644 Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/TestScreen.gusx create mode 100644 Samples/FormsSampleProject/FormsSampleProject/GumRuntimes/TestScreenRuntime.cs diff --git a/Engines/Forms/FlatRedBall.Forms/FlatRedBall.Forms.Shared/Controls/Games/DialogBox.cs b/Engines/Forms/FlatRedBall.Forms/FlatRedBall.Forms.Shared/Controls/Games/DialogBox.cs index 509ac23b1..d1c00a9a4 100644 --- a/Engines/Forms/FlatRedBall.Forms/FlatRedBall.Forms.Shared/Controls/Games/DialogBox.cs +++ b/Engines/Forms/FlatRedBall.Forms/FlatRedBall.Forms.Shared/Controls/Games/DialogBox.cs @@ -68,7 +68,8 @@ public override bool IsFocused } /// - /// The number of letters to show per second when printing out in "typewriter style". If null, 0, or negative, then the text will be shown immediately. + /// The number of letters to show per second when printing out in "typewriter style". + /// If null, 0, or negative, then the text is shown immediately. /// public int? LettersPerSecond { get; set; } = 20; @@ -132,6 +133,7 @@ protected override void ReactToVisualChanged() #endregion + #region Show Methods /// /// Shows the dialog box (adds it to managers and sets IsVisible to true) and begins showing the text. /// @@ -165,7 +167,12 @@ public void Show(IEnumerable pages, FlatRedBall.Graphics.Layer frbLayer /// /// The text to print out, either immediately or letter-by-letter according to LettersPerSecond. /// A task which completes when the text has been displayed and the DialogBox has been dismissed. - public Task ShowAsync(string text) => ShowAsync(new string[] { text }); + public Task ShowAsync(string text) + { + var pages = ConvertToPages(text); + return ShowAsync(pages); + } + public async Task ShowAsync(IEnumerable pages, FlatRedBall.Graphics.Layer frbLayer = null) { @@ -368,6 +375,68 @@ private void ShowInternal(string text, bool forceImmediatePrint) } } + + private string[] ConvertToPages(string text) + { + var limitsLines = + this.coreTextObject.MaxNumberOfLines != null || + this.textComponent.HeightUnits != global::Gum.DataTypes.DimensionUnitType.RelativeToChildren; + + if(!limitsLines) + { + // it can show any number of lines, it's up to the user to handle spillover + // by limiting the page length or by expanding the dialog box. + return new string[] { text }; + } + else + { + var unlimitedLines = new List(); + var oldVerticalMode = this.coreTextObject.TextOverflowVerticalMode; + this.coreTextObject.TextOverflowVerticalMode = RenderingLibrary.Graphics.TextOverflowVerticalMode.SpillOver; + coreTextObject.RawText = text; + coreTextObject.UpdateLines(unlimitedLines); + + this.coreTextObject.TextOverflowVerticalMode = oldVerticalMode; + this.textComponent.SetProperty("Text", text); + + var limitedLines = coreTextObject.WrappedText; + + if (unlimitedLines.Count == limitedLines.Count) + { + // no need to break it up + return new string[] { text }; + } + else + { + var pages = new List(); + + var absoluteLineNumber = 0; + + var currentPage = new StringBuilder(); + currentPage.Clear(); + + StringBuilder stringBuilder = new StringBuilder(); + while(absoluteLineNumber < unlimitedLines.Count) + { + stringBuilder.Clear(); + + for(int i = 0; i < limitedLines.Count && absoluteLineNumber < unlimitedLines.Count; i++) + { + stringBuilder.Append(unlimitedLines[absoluteLineNumber]); + absoluteLineNumber++; + } + pages.Add(stringBuilder.ToString()); + } + + return pages.ToArray(); + } + } + + + } + + #endregion + #region Event Handler Methods private void HandleClick(IWindow window) diff --git a/Samples/FormsSampleProject/FormsSampleProject/Content/GumLastChangeFilePath.txt b/Samples/FormsSampleProject/FormsSampleProject/Content/GumLastChangeFilePath.txt index 39bbfe961..f61efb8ba 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/Content/GumLastChangeFilePath.txt +++ b/Samples/FormsSampleProject/FormsSampleProject/Content/GumLastChangeFilePath.txt @@ -1 +1 @@ -2024-02-12T13:42:42.0957334Z \ No newline at end of file +2024-02-17T17:18:42.7810060Z \ No newline at end of file diff --git a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Components/Controls/DialogBox.gucx b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Components/Controls/DialogBox.gucx index bc3ee8f35..16de546e6 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Components/Controls/DialogBox.gucx +++ b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Components/Controls/DialogBox.gucx @@ -108,13 +108,13 @@ float TextInstance.Height - 0 + -32 true DimensionUnitType TextInstance.Height Units - 4 + 2 true @@ -129,6 +129,12 @@ This is a dialog box. This text will be displayed one character at a time. Typically a dialog box is added to a Screen such as the GameScreen, but it defaults to being invisible. true + + TextOverflowVerticalMode + TextInstance.TextOverflowVerticalMode + 1 + true + float TextInstance.Width diff --git a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/EventExport/gum_events.json b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/EventExport/gum_events.json index aecefa323..dc07ba1e7 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/EventExport/gum_events.json +++ b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/EventExport/gum_events.json @@ -162,6 +162,106 @@ "EventType": 7, "TimestampUtc": "2024-02-12T13:42:41.0259382Z" } + ], + "Owner": [ + { + "NewName": "MainMenuGum.ContainerInstance1", + "OldName": null, + "ElementType": "Screens", + "EventType": 5, + "TimestampUtc": "2024-02-17T13:16:58.849265Z" + }, + { + "NewName": "MainMenuGum.SecondStack", + "OldName": "MainMenuGum.ContainerInstance1", + "ElementType": "Screens", + "EventType": 7, + "TimestampUtc": "2024-02-17T13:17:04.3539667Z" + }, + { + "NewName": "MainMenuGum.ButtonStandardInstance1", + "OldName": null, + "ElementType": "Screens", + "EventType": 5, + "TimestampUtc": "2024-02-17T13:18:49.0225153Z" + }, + { + "NewName": "MainMenuGum.ButtonStandardInstance1", + "OldName": "MainMenuGum.ButtonStandardInstance1", + "ElementType": "Screens", + "EventType": 7, + "TimestampUtc": "2024-02-17T13:19:26.0550836Z" + }, + { + "NewName": "MainMenuGum.ShowDialogButton", + "OldName": "MainMenuGum.ButtonStandardInstance1", + "ElementType": "Screens", + "EventType": 7, + "TimestampUtc": "2024-02-17T13:19:31.3723099Z" + }, + { + "NewName": "MainMenuGum.TextInstance", + "OldName": null, + "ElementType": "Screens", + "EventType": 5, + "TimestampUtc": "2024-02-17T13:30:44.7249579Z" + }, + { + "NewName": null, + "OldName": "MainMenuGum.Text TextInstance in MainMenuGum", + "ElementType": "Screens", + "EventType": 6, + "TimestampUtc": "2024-02-17T13:46:43.7318549Z" + }, + { + "NewName": "TestScreen", + "OldName": null, + "ElementType": "Screens", + "EventType": 0, + "TimestampUtc": "2024-02-17T14:25:22.4718202Z" + }, + { + "NewName": "TestScreen.ColoredRectangleInstance", + "OldName": null, + "ElementType": "Screens", + "EventType": 5, + "TimestampUtc": "2024-02-17T14:25:25.9520485Z" + }, + { + "NewName": "TestScreen.ColoredRectangleInstance1", + "OldName": null, + "ElementType": "Screens", + "EventType": 5, + "TimestampUtc": "2024-02-17T14:25:27.7887566Z" + }, + { + "NewName": "TestScreen.BlueRectangle", + "OldName": "TestScreen.ColoredRectangleInstance1", + "ElementType": "Screens", + "EventType": 7, + "TimestampUtc": "2024-02-17T14:25:45.1195673Z" + }, + { + "NewName": "TestScreen.WhiteRectangle", + "OldName": "TestScreen.ColoredRectangleInstance", + "ElementType": "Screens", + "EventType": 7, + "TimestampUtc": "2024-02-17T14:25:50.2923384Z" + }, + { + "NewName": "MainMenuGum.TextInstance", + "OldName": null, + "ElementType": "Screens", + "EventType": 5, + "TimestampUtc": "2024-02-17T16:58:12.0981079Z" + }, + { + "NewName": null, + "OldName": "MainMenuGum.Text TextInstance in MainMenuGum", + "ElementType": "Screens", + "EventType": 6, + "TimestampUtc": "2024-02-17T17:18:41.945088Z" + } ] } } \ No newline at end of file diff --git a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/GumProject.gumx b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/GumProject.gumx index 9926b5807..ce2d4395c 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/GumProject.gumx +++ b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/GumProject.gumx @@ -5,7 +5,7 @@ 1 800 600 - true + false true true true @@ -21,6 +21,11 @@ Screen ReferenceOriginal + + TestScreen + Screen + ReferenceOriginal + Controls/ButtonClose Component diff --git a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/MainMenuGum.gusx b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/MainMenuGum.gusx index e533e28cc..e972ed5b3 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/MainMenuGum.gusx +++ b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/MainMenuGum.gusx @@ -15,22 +15,46 @@ UserAdd true + + string + AddItemButton.Parent + SecondStack + true + float AddItemButton.Width - 256 + 0 + true + + + DimensionUnitType + AddItemButton.Width Units + 2 true float AddItemButton.X - 255 + 0 + true + + + HorizontalAlignment + AddItemButton.X Origin + 1 + true + + + PositionUnitType + AddItemButton.X Units + 6 true float AddItemButton.Y - 180 + 0 true @@ -276,19 +300,43 @@ string ListBoxInstance.Parent - ContainerInstance + SecondStack + true + + + float + ListBoxInstance.Width + 0 + true + + + DimensionUnitType + ListBoxInstance.Width Units + 2 true float ListBoxInstance.X - 247 + 0 + true + + + HorizontalAlignment + ListBoxInstance.X Origin + 1 + true + + + PositionUnitType + ListBoxInstance.X Units + 6 true float ListBoxInstance.Y - 24 + 0 true @@ -300,19 +348,37 @@ string ListBoxLabel.Parent - ContainerInstance + SecondStack true float ListBoxLabel.Width - 217 + 0 + true + + + DimensionUnitType + ListBoxLabel.Width Units + 2 true float ListBoxLabel.X - 247 + 0 + true + + + HorizontalAlignment + ListBoxLabel.X Origin + 1 + true + + + PositionUnitType + ListBoxLabel.X Units + 6 true @@ -453,6 +519,78 @@ Radio Button 3 true + + ChildrenLayout + SecondStack.Children Layout + 1 + true + + + float + SecondStack.Height + 0 + true + + + DimensionUnitType + SecondStack.Height Units + 2 + true + + + string + SecondStack.Parent + ContainerInstance + true + + + float + SecondStack.Width + 237 + true + + + float + SecondStack.X + 239 + true + + + float + SecondStack.Y + 0 + true + + + string + ShowDialogButton.ButtonDisplayText + Show Dialog + true + + + string + ShowDialogButton.Parent + SecondStack + true + + + float + ShowDialogButton.Width + 0 + true + + + DimensionUnitType + ShowDialogButton.Width Units + 2 + true + + + float + ShowDialogButton.Y + 16 + true + string SliderInstance.Parent @@ -537,6 +675,7 @@ FirstStack Container false + true ListBoxLabel @@ -593,5 +732,16 @@ Controls/ButtonStandardIcon false + + ShowDialogButton + Controls/ButtonStandard + false + + + SecondStack + Container + false + true + \ No newline at end of file diff --git a/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/TestScreen.gusx b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/TestScreen.gusx new file mode 100644 index 000000000..4f5dc257a --- /dev/null +++ b/Samples/FormsSampleProject/FormsSampleProject/Content/GumProject/Screens/TestScreen.gusx @@ -0,0 +1,69 @@ + + + TestScreen + + Default + + int + BlueRectangle.Blue + 255 + true + + + int + BlueRectangle.Green + 16 + true + + + int + BlueRectangle.Red + 0 + true + + + float + BlueRectangle.X + 227 + true + + + float + BlueRectangle.Y + 133 + true + + + float + WhiteRectangle.X + 227 + true + + + float + WhiteRectangle.Y + 38 + true + + + string + WhiteRectangle.VariableReferences + false + false + + X = Screens/TestScreen.BlueRectangle.X + + + + + WhiteRectangle + ColoredRectangle + false + + + BlueRectangle + ColoredRectangle + false + + + \ No newline at end of file diff --git a/Samples/FormsSampleProject/FormsSampleProject/FormsSampleProject.csproj b/Samples/FormsSampleProject/FormsSampleProject/FormsSampleProject.csproj index b79bf924b..1793c8a08 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/FormsSampleProject.csproj +++ b/Samples/FormsSampleProject/FormsSampleProject/FormsSampleProject.csproj @@ -247,6 +247,10 @@ PreserveNewest MainMenuGum + + PreserveNewest + testscreen + PreserveNewest circle @@ -292,6 +296,7 @@ + Game1.cs @@ -480,6 +485,10 @@ + + + TestScreenRuntime.cs + diff --git a/Samples/FormsSampleProject/FormsSampleProject/GumRuntimes/TestScreenRuntime.cs b/Samples/FormsSampleProject/FormsSampleProject/GumRuntimes/TestScreenRuntime.cs new file mode 100644 index 000000000..93f2b2cc7 --- /dev/null +++ b/Samples/FormsSampleProject/FormsSampleProject/GumRuntimes/TestScreenRuntime.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace FormsSampleProject.GumRuntimes +{ + public partial class TestScreenRuntime + { + partial void CustomInitialize () + { + } + } +} diff --git a/Samples/FormsSampleProject/FormsSampleProject/Screens/MainMenu.cs b/Samples/FormsSampleProject/FormsSampleProject/Screens/MainMenu.cs index f6417649d..0711ffb76 100644 --- a/Samples/FormsSampleProject/FormsSampleProject/Screens/MainMenu.cs +++ b/Samples/FormsSampleProject/FormsSampleProject/Screens/MainMenu.cs @@ -15,6 +15,7 @@ using Microsoft.Xna.Framework; using FlatRedBall.Forms.Controls.Popups; using FormsSampleProject.ViewModels; +using FlatRedBall.Forms.Controls.Games; @@ -45,7 +46,30 @@ void CustomInitialize() Forms.ButtonStandardInstance.Click += HandleButtonClicked; Forms.AddItemButton.Click += HandleAddItemClicked; + Forms.ShowDialogButton.Click += HandleShowDialogButtonClicked; + + } + + private async void HandleShowDialogButtonClicked(object sender, EventArgs e) + { + var dialog = new DialogBox(); + //dialog.LettersPerSecond = 24; + dialog.LettersPerSecond = null; + dialog.IsFocused = true; + var dialogVisual = dialog.Visual; + dialogVisual.XUnits = Gum.Converters.GeneralUnitType.PixelsFromMiddle; + dialogVisual.XOrigin = RenderingLibrary.Graphics.HorizontalAlignment.Center; + dialogVisual.Y = 20; + + + await dialog.ShowAsync("This is some really long text. We want to show long text so that it " + + "line wraps and so that it has enough text to fill an entire page. The DialogBox control " + + "should automatically detect if the text is too long for a single page and it should break " + + "it up into multiple pages. You can advance this dialog by clicking on it with the mouse or " + + "by pressing the space bar on the keyboard"); + + dialog.Visual.RemoveFromManagers(); } private void HandleButtonClicked(object sender, EventArgs e)