Gondwana Game Engine Development (master) - 2.6.1
Gondwana is a cross-platform 2.5D game and rendering engine written in C#/.NET 8. It provides fine-grained control over rendering, timing, and scene composition, with built-in support for parallax, z-ordering, pixel overhang, collision detection, and particle effects. Gondwana targets desktop and web platforms using SkiaSharp for graphics and pluggable audio backends for desktop and browser targets.
Loading...
Searching...
No Matches
TabPageWidget.cs
1using System.Drawing;
2using System.Numerics;
5using SkiaSharp;
6
8
17public sealed class TabPageWidget : ContainerWidget
18{
19 private int _pageZOrder;
20 private string _title;
21
31 internal TabPageWidget(RenderSurfaceHostBase renderSurfaceHost,
33 Rectangle contentBounds,
34 string title,
35 char? mnemonic,
36 string? nickname)
37 : base(renderSurfaceHost, DirectDrawingMode.View, ValidateBounds(contentBounds).Location, nickname)
38 {
39 ArgumentNullException.ThrowIfNull(view);
40
41 _title = ValidateTitle(title);
42 Mnemonic = mnemonic;
43
44 Background = new DirectRectangle(DefaultBackgroundColor,
45 renderSurfaceHost,
46 view,
47 contentBounds,
48 $"{Nickname}.background")
49 .SetFilled(true)
50 .SetBorderColor(DefaultBorderColor)
51 .SetStrokeWidth(1f);
52
54
55 DisablePageInput();
56 }
57
67 internal TabPageWidget(RenderSurfaceHostBase renderSurfaceHost,
68 Gondwana.Scenes.SceneLayer sceneLayer,
69 Rectangle contentBounds,
70 string title,
71 char? mnemonic,
72 string? nickname)
73 : base(renderSurfaceHost, DirectDrawingMode.SceneLayer, ValidateBounds(contentBounds).Location, nickname)
74 {
75 ArgumentNullException.ThrowIfNull(sceneLayer);
76
77 _title = ValidateTitle(title);
78 Mnemonic = mnemonic;
79
80 Background = new DirectRectangle(DefaultBackgroundColor,
81 renderSurfaceHost,
82 sceneLayer,
83 contentBounds,
84 $"{Nickname}.background")
85 .SetFilled(true)
86 .SetBorderColor(DefaultBorderColor)
87 .SetStrokeWidth(1f);
88
90
91 DisablePageInput();
92 }
93
98
102 public string Title => _title;
103
107 public char? Mnemonic { get; }
108
113 ? Background.ScreenBounds
114 : Background.WorldBounds;
115
119 public Rectangle HeaderBounds { get; internal set; }
120
127 public TabPageWidget AddWidget(WidgetBase widget,
128 Point? offsetPx = null)
129 {
130 ArgumentNullException.ThrowIfNull(widget);
131
132 Point offset = offsetPx ?? Point.Empty;
133 Add(widget,
134 keepCurrentOffset: false,
135 explicitLocalOffsetPx: new Vector2(offset.X, offset.Y));
136 SetWidgetZOrder(widget, _pageZOrder + 1);
137
138 return this;
139 }
140
147 public TabPageWidget RemoveWidget(WidgetBase widget,
148 bool dispose = false)
149 {
150 RemoveChild(widget, dispose);
151 return this;
152 }
153
159 public TabPageWidget SetTitle(string title)
160 {
161 string validatedTitle = ValidateTitle(title);
162 if (string.Equals(_title, validatedTitle, StringComparison.Ordinal))
163 return this;
164
165 _title = validatedTitle;
166 TitleChanged?.Invoke(this);
167 return this;
168 }
169
175 public TabPageWidget SetBackgroundColor(Color color)
176 {
177 Background.SetColor(color);
178 RefreshBackground();
179 return this;
180 }
181
187 public TabPageWidget SetBorderColor(Color color)
188 {
189 Background.SetBorderColor(color);
190 RefreshBackground();
191 return this;
192 }
193
199 public TabPageWidget SetStrokeWidth(float width)
200 {
201 if (width < 0f)
202 throw new ArgumentOutOfRangeException(nameof(width), "The page border width cannot be negative.");
203
204 Background.SetStrokeWidth(width);
205 RefreshBackground();
206 return this;
207 }
208
214 public TabPageWidget SetCornerRadius(float radius)
215 {
216 if (radius < 0f)
217 throw new ArgumentOutOfRangeException(nameof(radius), "The page corner radius cannot be negative.");
218
219 Background.SetCornerRadius(radius);
220 RefreshBackground();
221 return this;
222 }
223
233 public TabPageWidget SetBackgroundImage(SKBitmap bitmap,
235 float scale = 1f,
236 SKPoint? offsetPx = null,
237 SKFilterQuality filterQuality = SKFilterQuality.Medium)
238 {
239 Background.SetFillImage(bitmap, mode, scale, offsetPx, filterQuality);
240 return this;
241 }
242
252 public TabPageWidget SetBackgroundImage(SKImage image,
254 float scale = 1f,
255 SKPoint? offsetPx = null,
256 SKFilterQuality filterQuality = SKFilterQuality.Medium)
257 {
258 Background.SetFillImage(image, mode, scale, offsetPx, filterQuality);
259 return this;
260 }
261
266 public TabPageWidget ClearBackgroundImage()
267 {
268 Background.ClearFillImage();
269 return this;
270 }
271
275 internal event Action<TabPageWidget>? TitleChanged;
276
281 internal void SetContentBounds(Rectangle bounds)
282 {
283 ValidateBounds(bounds);
284
285 if (Mode == DirectDrawingMode.View)
286 Background.ScreenBounds = new Rectangle(Background.ScreenBounds.Location, bounds.Size);
287 else
288 Background.WorldBounds = new Rectangle(Background.WorldBounds.Location, bounds.Size);
289 }
290
295 internal void SetPageZOrder(int zOrder)
296 {
297 _pageZOrder = zOrder;
298 Background.ZOrder = zOrder;
299
300 foreach (WidgetBase widget in ChildWidgets)
301 SetWidgetZOrder(widget, zOrder + 1);
302 }
303
304 private const int DefaultBackgroundAlpha = 235;
305
306 private static readonly Color DefaultBackgroundColor = Color.FromArgb(DefaultBackgroundAlpha, 25, 28, 36);
307 private static readonly Color DefaultBorderColor = Color.FromArgb(255, 110, 120, 140);
308
309 private void DisablePageInput()
310 {
311 IsInputEnabled = false;
312 IsPointerInputEnabled = false;
314 CanReceiveFocus = false;
315 }
316
317 private void RefreshBackground()
318 {
320 }
321
322 private static Rectangle ValidateBounds(Rectangle bounds)
323 {
324 if (bounds.Width <= 0 || bounds.Height <= 0)
325 {
326 throw new ArgumentOutOfRangeException(
327 nameof(bounds),
328 bounds,
329 "Tab-page bounds must have positive width and height.");
330 }
331
332 return bounds;
333 }
334
335 private static string ValidateTitle(string title)
336 {
337 ArgumentException.ThrowIfNullOrWhiteSpace(title);
338 return title;
339 }
340
341 private static void SetWidgetZOrder(WidgetBase widget,
342 int zOrder)
343 {
344 DirectDrawingBase[] visuals = EnumerateVisuals(widget).ToArray();
345 if (visuals.Length == 0)
346 return;
347
348 int currentMinimum = visuals.Min(static visual => visual.ZOrder);
349 int delta = zOrder - currentMinimum;
350
351 foreach (DirectDrawingBase visual in visuals)
352 visual.ZOrder += delta;
353 }
354
355 private static IEnumerable<DirectDrawingBase> EnumerateVisuals(IDirectCompositeContainer container)
356 {
357 foreach (IDirectCompositeChild child in container.Children)
358 {
359 if (child is DirectDrawingBase drawing)
360 yield return drawing;
361
362 if (child is IDirectCompositeContainer nestedContainer)
363 {
364 foreach (DirectDrawingBase nestedDrawing in EnumerateVisuals(nestedContainer))
365 yield return nestedDrawing;
366 }
367 }
368 }
369}
DirectDrawingMode Mode
Gets the coordinate mode shared by the composite and its children.
Rectangle WorldBounds
Gets or sets the world-space bounds of this direct drawing in pixels.
Rectangle ScreenBounds
Gets or sets the screen-space bounds of this direct drawing in pixels.
Vector2 GetPosition()
Gets the current position of this direct drawing in pixel coordinates.
void SetPosition(Vector2 p)
Sets the position of this direct drawing to the specified pixel coordinates.
Renders a configurable rectangle with support for fill, border, rounded corners, dash patterns,...
DirectRectangle SetFilled(bool isFilled)
Sets whether the rectangle interior is filled with the base color (or pattern).
DirectRectangle SetBorderColor(Color color)
Sets a distinct border (stroke) color, independent of the fill color.
DirectRectangle SetStrokeWidth(float width)
Sets the width (thickness) of the rectangle's stroke (outline) in pixels.
ImageFillMode
Defines how an image fills the rectangle interior.
Represents a base class for hosting a render surface, providing functionality for managing rendering ...
Represents a rendered view of a scene, combining a camera position with a viewport configuration to c...
Definition View.cs:14
Represents a single layer within a Scene, containing a grid of tiles and supporting various coordinat...
Definition SceneLayer.cs:40
bool RemoveChild(WidgetBase widget, bool dispose=false)
Removes a child widget from the container.
override DirectComposite Add(IDirectCompositeChild child, bool keepCurrentOffset=true, Vector2? explicitLocalOffsetPx=null)
Adds a composite-compatible direct drawable as a child.The current composite.
ContainerWidget(RenderSurfaceHostBase renderSurfaceHost, DirectDrawingMode mode, PointF anchor=default, string? nickname=null)
Initializes a new instance of the ContainerWidget class.
IReadOnlyList< WidgetBase > ChildWidgets
Gets a snapshot of the child widgets directly owned by this container.
Rectangle ContentBounds
Gets the page's content bounds in its native coordinate space.
TabPageWidget SetStrokeWidth(float width)
Sets the page border width.
TabPageWidget AddWidget(WidgetBase widget, Point? offsetPx=null)
Adds a widget at an offset from the page content area's upper-left corner.
TabPageWidget SetCornerRadius(float radius)
Sets the page corner radius.
Rectangle HeaderBounds
Gets the bounds occupied by this page's tab header in its native coordinate space.
TabPageWidget SetBackgroundImage(SKBitmap bitmap, DirectRectangle.ImageFillMode mode=DirectRectangle.ImageFillMode.Stretch, float scale=1f, SKPoint? offsetPx=null, SKFilterQuality filterQuality=SKFilterQuality.Medium)
Uses a bitmap as the page background.
DirectRectangle Background
Gets the direct rectangle used for this page's content background.
TabPageWidget SetBackgroundColor(Color color)
Sets the page background fill color.
TabPageWidget SetBackgroundImage(SKImage image, DirectRectangle.ImageFillMode mode=DirectRectangle.ImageFillMode.Stretch, float scale=1f, SKPoint? offsetPx=null, SKFilterQuality filterQuality=SKFilterQuality.Medium)
Uses an image as the page background.
TabPageWidget ClearBackgroundImage()
Removes an image background and restores the configured color fill.
char? Mnemonic
Gets the optional Alt-key mnemonic that selects this page.
TabPageWidget RemoveWidget(WidgetBase widget, bool dispose=false)
Removes a child widget from the page.
TabPageWidget SetTitle(string title)
Changes the title displayed by the owning tab control.
string Title
Gets the title displayed by the page's tab header.
TabPageWidget SetBorderColor(Color color)
Sets the page border color.
Provides the base implementation for widgets that can be drawn and receive pointer,...
Definition WidgetBase.cs:12
bool CanReceiveFocus
Gets or sets a value indicating whether the widget can receive keyboard focus.
bool IsPointerInputEnabled
Gets or sets a value indicating whether the widget can receive pointer input.
WidgetBase(RenderSurfaceHostBase renderSurfaceHost, DirectDrawingMode mode, PointF anchor=default, string? nickname=null)
Initializes a new instance of the WidgetBase class.
Definition WidgetBase.cs:95
bool IsKeyboardInputEnabled
Gets or sets a value indicating whether the widget can receive keyboard input.
bool IsInputEnabled
Gets or sets a value indicating whether the widget can participate in input routing.
IReadOnlyCollection< IDirectCompositeChild > Children
Gets the read-only collection of child elements in this container.
@ Rectangle
Particles are spawned uniformly within a rectangular area. This is the default distribution.
DirectDrawingMode
Specifies where direct drawing operations are applied within the rendering pipeline.
@ View
Performs direct drawing at the view level using screen-space coordinates.