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
WidgetBase.cs
1using System.Drawing;
5
6namespace Gondwana.Widgets;
7
11public abstract class WidgetBase : DirectComposite
12{
13 private bool _isInputEnabled = true;
14 private bool _isPointerInputEnabled = true;
15 private bool _isKeyboardInputEnabled;
16 private bool _canReceiveFocus;
17
21 public event Action? Shown;
22
26 public event Action? Hidden;
27
31 public event Action? Activated;
32
36 public event Action? Cancelled;
37
41 public event Action<WidgetPointerEventArgs>? PointerEnter;
42
46 public event Action<WidgetPointerEventArgs>? PointerLeave;
47
51 public event Action<WidgetPointerEventArgs>? PointerDown;
52
56 public event Action<WidgetPointerEventArgs>? PointerMove;
57
61 public event Action<WidgetPointerEventArgs>? PointerUp;
62
66 public event Action<WidgetPointerEventArgs>? PointerClick;
67
71 public event Action<WidgetMouseWheelEventArgs>? MouseWheel;
72
76 public event Action? FocusGained;
77
81 public event Action? FocusLost;
82
86 public event Action<WidgetKeyboardEventArgs>? KeyboardInput;
87
95 protected WidgetBase(RenderSurfaceHostBase renderSurfaceHost,
97 PointF anchor = default,
98 string? nickname = null)
99 : base(renderSurfaceHost, mode, anchor, nickname)
100 {
101 }
102
109 public bool IsInputEnabled
110 {
111 get => _isInputEnabled;
112 set
113 {
114 if (_isInputEnabled == value)
115 return;
116
117 _isInputEnabled = value;
118
119 if (!value)
120 WidgetInputRouterRegistry.NotifyInputDisabled(this);
121 }
122 }
123
131 {
132 get => _isPointerInputEnabled;
133 set
134 {
135 if (_isPointerInputEnabled == value)
136 return;
137
138 _isPointerInputEnabled = value;
139
140 if (!value)
141 WidgetInputRouterRegistry.NotifyPointerInputDisabled(this);
142 }
143 }
144
152 {
153 get => _isKeyboardInputEnabled;
154 set
155 {
156 if (_isKeyboardInputEnabled == value)
157 return;
158
159 _isKeyboardInputEnabled = value;
160
161 if (!value)
162 WidgetInputRouterRegistry.NotifyKeyboardFocusDisabled(this);
163 }
164 }
165
172 public bool CanReceiveFocus
173 {
174 get => _canReceiveFocus;
175 set
176 {
177 if (_canReceiveFocus == value)
178 return;
179
180 _canReceiveFocus = value;
181
182 if (!value)
183 WidgetInputRouterRegistry.NotifyKeyboardFocusDisabled(this);
184 }
185 }
186
193 public bool IsFocused { get; internal set; }
194
203 public virtual bool HitTest(View view,
204 Point screenPositionPx)
205 {
206 ArgumentNullException.ThrowIfNull(view);
207
208 if (!IsInputEnabled ||
210 !Visible)
211 {
212 return false;
213 }
214
215 if (Mode == DirectDrawingMode.View
216 && !ReferenceEquals(View, view))
217 {
218 return false;
219 }
220
221 if (Mode == DirectDrawingMode.SceneLayer && SceneLayer is { } layer &&
222 (layer.WrapHorizontally || layer.WrapVertically))
223 return GetWrappedHitOffset(view, screenPositionPx).HasValue;
224
225 RectangleF screenBounds = GetDrawLocationScreen(view);
226
227 return !screenBounds.IsEmpty
228 && screenBounds.Contains(screenPositionPx.X, screenPositionPx.Y);
229 }
230
231 internal PointF? GetWrappedHitOffset(View view, Point screenPositionPx)
232 {
233 if (Mode != DirectDrawingMode.SceneLayer || SceneLayer is not { } layer)
234 return PointF.Empty;
235 var world = view.ScreenPxToWorldPx(layer, screenPositionPx);
236 foreach (var offset in layer.GetWrappedOffsets(WorldBounds, new RectangleF(world.X, world.Y, 0.01f, 0.01f)))
237 {
238 RectangleF bounds = WorldBounds;
239 bounds.Offset(offset);
240 if (bounds.Contains(world)) return offset;
241 }
242 return null;
243 }
244
252 public virtual bool HitTest(Point screenPositionPx)
253 {
254 var views = RenderSurfaceHost.ViewManager.Views;
255
256 for (int index = views.Count - 1; index >= 0; index--)
257 {
258 View view = views[index];
259
260 if (!view.Viewport.TargetRectPx.Contains(screenPositionPx))
261 {
262 continue;
263 }
264
265 return HitTest(view, screenPositionPx);
266 }
267
268 return false;
269 }
270
276 {
277 WidgetInputRouterRegistry.TryRegister(this);
278
279 SetIsVisible(true);
280
281 ProcessShown();
282 OnShown();
283 Shown?.Invoke();
284
285 return this;
286 }
287
293 {
294 WidgetInputRouterRegistry.NotifyHidden(this);
295
296 SetIsVisible(false);
297
299 OnHidden();
300 Hidden?.Invoke();
301
302 return this;
303 }
304
310 {
311 WidgetInputRouterRegistry.TryBringToFront(this);
312
314 OnActivated();
315 Activated?.Invoke();
316
317 return this;
318 }
319
325 {
327 OnCancelled();
328 Cancelled?.Invoke();
329
330 return this;
331 }
332
337 protected internal void DispatchPointerEnter(WidgetPointerEventArgs args)
338 {
339 ArgumentNullException.ThrowIfNull(args);
340
342 OnPointerEnter(args);
343 PointerEnter?.Invoke(args);
344 }
345
350 protected internal void DispatchPointerLeave(WidgetPointerEventArgs args)
351 {
352 ArgumentNullException.ThrowIfNull(args);
353
355 OnPointerLeave(args);
356 PointerLeave?.Invoke(args);
357 }
358
363 protected internal void DispatchPointerDown(WidgetPointerEventArgs args)
364 {
365 ArgumentNullException.ThrowIfNull(args);
366
367 ProcessPointerDown(args);
368 OnPointerDown(args);
369 PointerDown?.Invoke(args);
370 }
371
376 protected internal void DispatchPointerMove(WidgetPointerEventArgs args)
377 {
378 ArgumentNullException.ThrowIfNull(args);
379
380 ProcessPointerMove(args);
381 OnPointerMove(args);
382 PointerMove?.Invoke(args);
383 }
384
389 protected internal void DispatchPointerUp(WidgetPointerEventArgs args)
390 {
391 ArgumentNullException.ThrowIfNull(args);
392
393 ProcessPointerUp(args);
394 OnPointerUp(args);
395 PointerUp?.Invoke(args);
396 }
397
402 protected internal void DispatchPointerClick(WidgetPointerEventArgs args)
403 {
404 ArgumentNullException.ThrowIfNull(args);
405
407 return;
408
409 OnPointerClick(args);
410 PointerClick?.Invoke(args);
411 }
412
417 protected internal void DispatchMouseWheel(WidgetMouseWheelEventArgs args)
418 {
419 ArgumentNullException.ThrowIfNull(args);
420
421 OnMouseWheel(args);
422 MouseWheel?.Invoke(args);
423 }
424
428 protected internal void DispatchFocusGained()
429 {
430 IsFocused = true;
431
434 FocusGained?.Invoke();
435 }
436
440 protected internal void DispatchFocusLost()
441 {
442 IsFocused = false;
443
445 OnFocusLost();
446 FocusLost?.Invoke();
447 }
448
453 protected internal void DispatchKeyboardInput(WidgetKeyboardEventArgs args)
454 {
455 ArgumentNullException.ThrowIfNull(args);
456
458 OnKeyboardInput(args);
459 KeyboardInput?.Invoke(args);
460 }
461
465 protected virtual void ProcessShown() { }
466
470 protected virtual void ProcessHidden() { }
471
475 protected virtual void ProcessActivated() { }
476
480 protected virtual void ProcessCancelled() { }
481
486 protected virtual void ProcessPointerEnter(WidgetPointerEventArgs args) { }
487
492 protected virtual void ProcessPointerLeave(WidgetPointerEventArgs args) { }
493
498 protected virtual void ProcessPointerDown(WidgetPointerEventArgs args) { }
499
504 protected virtual void ProcessPointerMove(WidgetPointerEventArgs args) { }
505
510 protected virtual void ProcessPointerUp(WidgetPointerEventArgs args) { }
511
515 protected virtual void ProcessFocusGained() { }
516
520 protected virtual void ProcessFocusLost() { }
521
526 protected virtual void ProcessKeyboardInput(WidgetKeyboardEventArgs args) { }
527
536 {
537 return true;
538 }
539
543 protected virtual void OnShown() { }
544
548 protected virtual void OnHidden() { }
549
553 protected virtual void OnActivated() { }
554
558 protected virtual void OnCancelled() { }
559
564 protected virtual void OnPointerEnter(WidgetPointerEventArgs args) { }
565
570 protected virtual void OnPointerLeave(WidgetPointerEventArgs args) { }
571
576 protected virtual void OnPointerDown(WidgetPointerEventArgs args) { }
577
582 protected virtual void OnPointerMove(WidgetPointerEventArgs args) { }
583
588 protected virtual void OnPointerUp(WidgetPointerEventArgs args) { }
589
594 protected virtual void OnMouseWheel(WidgetMouseWheelEventArgs args) { }
595
600 protected virtual void OnPointerClick(WidgetPointerEventArgs args) { }
601
605 protected virtual void OnFocusGained() { }
606
610 protected virtual void OnFocusLost() { }
611
616 protected virtual void OnKeyboardInput(WidgetKeyboardEventArgs args) { }
617}
bool Visible
Gets or sets the visibility of all descendants.
RenderSurfaceHostBase RenderSurfaceHost
Gets the render surface host shared by the composite and its children.
SceneLayer? SceneLayer
Gets the scene layer shared by all children in scene-layer mode.
RectangleF GetDrawLocationScreen(View view)
Gets the union of all visible descendants as projected through a view.
DirectComposite SetIsVisible(bool visible)
Applies one visibility value to every descendant.
Rectangle WorldBounds
Gets the union of all visible descendants' world-space bounds.
View? View
Gets the view shared by all children in view mode.
DirectComposite(RenderSurfaceHostBase renderSurfaceHost, DirectDrawingMode mode, PointF anchor=default, string? nickname=null)
Initializes a new instance of the DirectComposite class.
DirectDrawingMode Mode
Gets the coordinate mode shared by the composite and its children.
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
PointF ScreenPxToWorldPx(SceneLayer layer, PointF screenPx)
Converts a screen-space pixel position into world-space coordinates for the specified scene layer,...
Definition View.cs:233
Viewport Viewport
Gets the viewport that defines the screen-space rectangle, zoom level, and other rendering parameters...
Definition View.cs:44
Rectangle TargetRectPx
Screen-space rectangle (in SCREEN / RenderSurface pixels) where this view is drawn....
Definition Viewport.cs:35
virtual void ProcessCancelled()
Performs processing when the widget is cancelled before notification callbacks are invoked.
WidgetBase Show()
Shows the widget and registers it for input routing.
virtual void OnMouseWheel(WidgetMouseWheelEventArgs args)
Called when mouse-wheel input is routed to the widget.
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.
virtual void ProcessShown()
Performs processing when the widget is shown before notification callbacks are invoked.
WidgetBase(RenderSurfaceHostBase renderSurfaceHost, DirectDrawingMode mode, PointF anchor=default, string? nickname=null)
Initializes a new instance of the WidgetBase class.
Definition WidgetBase.cs:95
WidgetBase Activate()
Activates the widget and brings it to the front of the input order.
bool IsFocused
Gets a value indicating whether the widget currently has keyboard focus.
virtual void OnPointerDown(WidgetPointerEventArgs args)
Called when a pointer press begins on the widget.
Action< WidgetPointerEventArgs >? PointerMove
Occurs when a pointer moves while routed to the widget.
Definition WidgetBase.cs:56
Action< WidgetPointerEventArgs >? PointerEnter
Occurs when a pointer enters the widget bounds.
Definition WidgetBase.cs:41
virtual void OnPointerEnter(WidgetPointerEventArgs args)
Called when a pointer enters the widget bounds.
virtual void ProcessFocusGained()
Performs processing when the widget gains focus before notification callbacks are invoked.
virtual void ProcessKeyboardInput(WidgetKeyboardEventArgs args)
Performs processing when keyboard input is routed to the widget before notification callbacks are inv...
Action? Cancelled
Occurs when the widget is cancelled.
Definition WidgetBase.cs:36
Action? Shown
Occurs when the widget is shown.
Definition WidgetBase.cs:21
virtual void OnPointerMove(WidgetPointerEventArgs args)
Called when pointer movement is routed to the widget.
virtual void ProcessPointerEnter(WidgetPointerEventArgs args)
Performs processing when a pointer enters the widget before notification callbacks are invoked.
virtual void OnPointerClick(WidgetPointerEventArgs args)
Called when a pointer click is dispatched to the widget.
virtual void ProcessPointerDown(WidgetPointerEventArgs args)
Performs processing when a pointer press begins on the widget before notification callbacks are invok...
Action< WidgetPointerEventArgs >? PointerClick
Occurs when a pointer press and release completes as a click on the widget.
Definition WidgetBase.cs:66
WidgetBase Hide()
Hides the widget and releases any routed input state.
virtual void OnCancelled()
Called when the widget is cancelled.
virtual void OnHidden()
Called when the widget is hidden.
Action? FocusLost
Occurs when the widget loses keyboard focus.
Definition WidgetBase.cs:81
virtual void ProcessActivated()
Performs processing when the widget is activated before notification callbacks are invoked.
Action< WidgetKeyboardEventArgs >? KeyboardInput
Occurs when keyboard input is routed to the widget.
Definition WidgetBase.cs:86
virtual void OnActivated()
Called when the widget is activated.
Action? Hidden
Occurs when the widget is hidden.
Definition WidgetBase.cs:26
virtual void OnKeyboardInput(WidgetKeyboardEventArgs args)
Called when keyboard input is routed to the widget.
Action< WidgetPointerEventArgs >? PointerUp
Occurs when a pointer button or touch press is released for the widget.
Definition WidgetBase.cs:61
Action? FocusGained
Occurs when the widget gains keyboard focus.
Definition WidgetBase.cs:76
virtual bool HitTest(Point screenPositionPx)
Determines whether the widget can be hit at the specified screen position.
virtual void OnPointerLeave(WidgetPointerEventArgs args)
Called when a pointer leaves the widget bounds.
Action< WidgetMouseWheelEventArgs >? MouseWheel
Occurs when mouse-wheel input is routed to the widget while the pointer is over it.
Definition WidgetBase.cs:71
virtual void ProcessPointerLeave(WidgetPointerEventArgs args)
Performs processing when a pointer leaves the widget before notification callbacks are invoked.
WidgetBase Cancel()
Cancels the widget.
virtual bool ShouldDispatchPointerClick(WidgetPointerEventArgs args)
Determines whether a pointer-click event should be dispatched for the specified pointer event data.
virtual void OnFocusLost()
Called when the widget loses focus.
Action< WidgetPointerEventArgs >? PointerLeave
Occurs when a pointer leaves the widget bounds.
Definition WidgetBase.cs:46
bool IsKeyboardInputEnabled
Gets or sets a value indicating whether the widget can receive keyboard input.
virtual void ProcessPointerMove(WidgetPointerEventArgs args)
Performs processing when pointer movement is routed to the widget before notification callbacks are i...
Action< WidgetPointerEventArgs >? PointerDown
Occurs when a pointer button or touch press begins on the widget.
Definition WidgetBase.cs:51
Action? Activated
Occurs when the widget is activated.
Definition WidgetBase.cs:31
virtual void ProcessFocusLost()
Performs processing when the widget loses focus before notification callbacks are invoked.
virtual void OnShown()
Called when the widget is shown.
virtual void ProcessHidden()
Performs processing when the widget is hidden before notification callbacks are invoked.
virtual void ProcessPointerUp(WidgetPointerEventArgs args)
Performs processing when a pointer press is released for the widget before notification callbacks are...
bool IsInputEnabled
Gets or sets a value indicating whether the widget can participate in input routing.
virtual void OnPointerUp(WidgetPointerEventArgs args)
Called when a pointer press is released for the widget.
virtual void OnFocusGained()
Called when the widget gains focus.
virtual bool HitTest(View view, Point screenPositionPx)
Determines whether the widget can be hit at the specified screen position within the specified view.
Provides data for widget keyboard input events routed by WidgetInputRouter.
Event arguments for mouse-wheel input routed to a widget.
Event arguments for pointer-based widget callbacks.
DirectDrawingMode
Specifies where direct drawing operations are applied within the rendering pipeline.
@ SceneLayer
Performs direct drawing within a scene layer using world-space coordinates.