A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using osu.Framework.Graphics;
5using osu.Framework.Graphics.Containers;
6using osu.Framework.Graphics.Effects;
7using osu.Framework.Graphics.Shapes;
8using osu.Framework.Graphics.Sprites;
9using osuTK;
10using osuTK.Graphics;
11
12namespace osu.Framework.Tests.Visual.Sprites
13{
14 [System.ComponentModel.Description("word-wrap and paragraphs")]
15 public class TestSceneTextFlow : FrameworkTestScene
16 {
17 public TestSceneTextFlow()
18 {
19 FillFlowContainer flow;
20
21 Children = new Drawable[]
22 {
23 new BasicScrollContainer
24 {
25 RelativeSizeAxes = Axes.Both,
26 Children = new[]
27 {
28 flow = new FillFlowContainer
29 {
30 Anchor = Anchor.TopLeft,
31 AutoSizeAxes = Axes.Y,
32 RelativeSizeAxes = Axes.X,
33 Direction = FillDirection.Vertical,
34 }
35 }
36 }
37 };
38
39 FillFlowContainer paragraphContainer;
40 TextFlowContainer textFlowContainer;
41 flow.Add(paragraphContainer = new FillFlowContainer
42 {
43 AutoSizeAxes = Axes.Y,
44 RelativeSizeAxes = Axes.X,
45 Width = 0.5f,
46 Direction = FillDirection.Vertical,
47 Children = new Drawable[]
48 {
49 textFlowContainer = new TextFlowContainer
50 {
51 FirstLineIndent = 5,
52 ContentIndent = 10,
53 RelativeSizeAxes = Axes.X,
54 AutoSizeAxes = Axes.Y,
55 }
56 }
57 });
58
59 textFlowContainer.AddText("the considerably swift vermilion reynard bounds above the slothful mahogany hound.", t => t.Colour = Color4.Yellow);
60 textFlowContainer.AddText("\nTHE ", t => t.Colour = Color4.Red);
61 textFlowContainer.AddText("CONSIDERABLY", t => t.Colour = Color4.Pink);
62 textFlowContainer.AddText(" SWIFT VERMILION REYNARD BOUNDS ABOVE THE SLOTHFUL MAHOGANY HOUND!!", t => t.Colour = Color4.Red);
63 textFlowContainer.AddText("\n\n0123456789!@#$%^&*()_-+-[]{}.,<>;'\\\\", t => t.Colour = Color4.Blue);
64 var textSize = 48f;
65 textFlowContainer.AddParagraph("Multiple Text Sizes", t =>
66 {
67 t.Font = t.Font.With(size: textSize);
68 textSize -= 12f;
69 });
70 textFlowContainer.AddText("\nI'm a paragraph\nnewlines are cool", t => t.Colour = Color4.Beige);
71 textFlowContainer.AddText(" (and so are inline styles!)", t => t.Colour = Color4.Yellow);
72 textFlowContainer.AddParagraph("There's 2 line breaks\n\ninside this paragraph!", t => t.Colour = Color4.GreenYellow);
73 textFlowContainer.AddParagraph("Make\nTextFlowContainer\ngreat\nagain!", t => t.Colour = Color4.Red);
74
75 paragraphContainer.Add(new TextFlowContainer
76 {
77 RelativeSizeAxes = Axes.X,
78 AutoSizeAxes = Axes.Y,
79 Text =
80 @"osu! is a freeware rhythm game developed by Dean ""peppy"" Herbert, originally for Microsoft Windows. The game has also been ported to macOS, iOS, Android, and Windows Phone.[1] Its game play is based on commercial titles including Osu! Tatakae! Ouendan, Elite Beat Agents, Taiko no Tatsujin, beatmania IIDX, O2Jam, and DJMax.
81
82osu! is written in C# on the .NET Framework. On August 28, 2016, osu!'s source code was open-sourced under the MIT License. [2] [3] Dubbed as ""Lazer"", the project aims to make osu! available to more platforms and transparent. [4] The community includes over 9 million registered users, with a total of 6 billion ranked plays.[5]"
83 });
84
85 paragraphContainer.Add(new CustomText
86 {
87 RelativeSizeAxes = Axes.X,
88 AutoSizeAxes = Axes.Y,
89 Placeholders = new Drawable[]
90 {
91 new LineBaseBox
92 {
93 Colour = Color4.Purple,
94 LineBaseHeight = 25f,
95 Size = new Vector2(25, 25)
96 }.WithEffect(new OutlineEffect
97 {
98 Strength = 20f,
99 PadExtent = true,
100 BlurSigma = new Vector2(5f),
101 Colour = Color4.White
102 })
103 },
104 Text = "Test icons [RedBox] interleaved\n[GreenBox] with other [0] text, also [[0]] escaping stuff is possible."
105 });
106
107 paragraphContainer.Add(new Container
108 {
109 Size = new Vector2(300),
110 Children = new Drawable[]
111 {
112 new Box
113 {
114 Name = "Background",
115 RelativeSizeAxes = Axes.Both,
116 Alpha = 0.1f
117 },
118 new TextFlowContainer
119 {
120 RelativeSizeAxes = Axes.Both,
121 TextAnchor = Anchor.TopLeft,
122 Text = "TopLeft"
123 },
124 new TextFlowContainer
125 {
126 RelativeSizeAxes = Axes.Both,
127 TextAnchor = Anchor.TopCentre,
128 Text = "TopCentre"
129 },
130 new TextFlowContainer
131 {
132 RelativeSizeAxes = Axes.Both,
133 TextAnchor = Anchor.TopRight,
134 Text = "TopRight"
135 },
136 new TextFlowContainer
137 {
138 RelativeSizeAxes = Axes.Both,
139 TextAnchor = Anchor.BottomLeft,
140 Text = "BottomLeft"
141 },
142 new TextFlowContainer
143 {
144 RelativeSizeAxes = Axes.Both,
145 TextAnchor = Anchor.BottomCentre,
146 Text = "BottomCentre"
147 },
148 new TextFlowContainer
149 {
150 RelativeSizeAxes = Axes.Both,
151 TextAnchor = Anchor.BottomRight,
152 Text = "BottomRight"
153 },
154 new TextFlowContainer
155 {
156 RelativeSizeAxes = Axes.Both,
157 TextAnchor = Anchor.CentreLeft,
158 Text = "CentreLeft"
159 },
160 new TextFlowContainer
161 {
162 RelativeSizeAxes = Axes.Both,
163 TextAnchor = Anchor.Centre,
164 Text = "Centre"
165 },
166 new TextFlowContainer
167 {
168 RelativeSizeAxes = Axes.Both,
169 TextAnchor = Anchor.CentreRight,
170 Text = "CentreRight"
171 }
172 }
173 });
174
175 AddStep(@"resize paragraph 1", () => { paragraphContainer.Width = 1f; });
176 AddStep(@"resize paragraph 2", () => { paragraphContainer.Width = 0.6f; });
177 AddStep(@"header inset", () => { textFlowContainer.FirstLineIndent += 2; });
178 AddStep(@"body inset", () => { textFlowContainer.ContentIndent += 4; });
179 AddToggleStep(@"Zero paragraph spacing", state => textFlowContainer.ParagraphSpacing = state ? 0 : 0.5f);
180 AddToggleStep(@"Non-zero line spacing", state => textFlowContainer.LineSpacing = state ? 1 : 0);
181 }
182
183 private class LineBaseBox : Box, IHasLineBaseHeight
184 {
185 public float LineBaseHeight { get; set; }
186 }
187
188 private class CustomText : CustomizableTextContainer
189 {
190 public CustomText()
191 {
192 AddIconFactory("RedBox", makeRedBox);
193 AddIconFactory("GreenBox", makeGreenBox);
194 }
195
196 private Drawable makeGreenBox() => new LineBaseBox
197 {
198 Colour = Color4.Green,
199 LineBaseHeight = 25f,
200 Size = new Vector2(25, 20)
201 };
202
203 private Drawable makeRedBox() => new LineBaseBox
204 {
205 Colour = Color4.Red,
206 LineBaseHeight = 10f,
207 Size = new Vector2(25, 25)
208 };
209 }
210 }
211}