99#endregion
1010
1111using System ;
12+ using System . Runtime . CompilerServices ;
1213using System . Threading ;
1314using Exomia . Framework . Game ;
1415using Exomia . Framework . Graphics ;
1516using Exomia . Framework . Input ;
1617using Exomia . Framework . UI . Controls ;
18+ using SharpDX ;
1719
1820namespace Exomia . Framework . UI
1921{
2022 /// <summary>
2123 /// A ui manager. This class cannot be inherited.
2224 /// </summary>
23- public sealed class UiManager : Renderer , IInputHandler
25+ public sealed class UiManager : IComponent , IInitializable , IDrawable , IDisposable , IInputHandler
2426 {
2527 internal const int INITIAL_LIST_SIZE = 8 ;
2628
29+ /// <summary>
30+ /// Occurs when the <see cref="DrawOrder" /> property changes.
31+ /// </summary>
32+ public event EventHandler ? DrawOrderChanged ;
33+
34+ /// <summary>
35+ /// Occurs when the <see cref="Visible" /> property changes.
36+ /// </summary>
37+ public event EventHandler ? VisibleChanged ;
38+
39+ /// <summary>
40+ /// Flag to identify, if the component is already initialized.
41+ /// </summary>
42+ private bool _isInitialized ;
43+
44+ private readonly DisposeCollector _collector ;
45+ private int _drawOrder ;
46+ private bool _visible ;
47+
2748 private Control [ ] _controls ;
2849 private Control [ ] _currentlyControls ;
2950 private int _controlCount ;
@@ -37,13 +58,57 @@ public sealed class UiManager : Renderer, IInputHandler
3758 private Control ? _focusedControl ;
3859 private Control ? _enteredControl ;
3960
61+ /// <inheritdoc />
62+ public int DrawOrder
63+ {
64+ get { return _drawOrder ; }
65+ set
66+ {
67+ if ( _drawOrder != value )
68+ {
69+ _drawOrder = value ;
70+ DrawOrderChanged ? . Invoke ( ) ;
71+ }
72+ }
73+ }
74+
75+ /// <inheritdoc />
76+ public string Name { get ; }
77+
78+ /// <inheritdoc />
79+ public bool Visible
80+ {
81+ get { return _visible ; }
82+ set
83+ {
84+ if ( _visible != value )
85+ {
86+ _visible = value ;
87+ VisibleChanged ? . Invoke ( ) ;
88+ }
89+ }
90+ }
91+
92+ /// <summary>
93+ /// Gets the input handler.
94+ /// </summary>
95+ /// <value>
96+ /// The input handler.
97+ /// </value>
98+ public IInputHandler InputHandler
99+ {
100+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
101+ get { return this ; }
102+ }
103+
40104 /// <summary>
41105 /// Initializes a new instance of the <see cref="UiManager" /> class.
42106 /// </summary>
43107 /// <param name="name"> The name. </param>
44108 public UiManager ( string name )
45- : base ( name )
46109 {
110+ Name = name ?? throw new ArgumentNullException ( nameof ( name ) ) ;
111+ _collector = new DisposeCollector ( ) ;
47112 _controls = new Control [ INITIAL_LIST_SIZE ] ;
48113 _currentlyControls = new Control [ INITIAL_LIST_SIZE ] ;
49114 }
@@ -69,9 +134,13 @@ void IInputHandler.UnregisterInput(IInputDevice device)
69134 device . UnregisterKeyUp ( KeyUp ) ;
70135 device . UnregisterKeyPress ( KeyPress ) ;
71136 }
72-
73- /// <inheritdoc />
74- public override void Draw ( GameTime gameTime )
137+
138+ bool IDrawable . BeginDraw ( )
139+ {
140+ return _visible ;
141+ }
142+
143+ void IDrawable . Draw ( GameTime gameTime )
75144 {
76145 if ( _isDirty )
77146 {
@@ -104,12 +173,15 @@ public override void Draw(GameTime gameTime)
104173
105174 _canvas . End ( ) ;
106175 }
176+
177+ void IDrawable . EndDraw ( ) { }
107178
108179 /// <summary>
109180 /// Adds the <paramref name="control" /> to this ui manger.
110181 /// </summary>
111182 /// <param name="control"> The control to add. </param>
112- public void Add ( Control control )
183+ /// <returns>The <paramref name="control"/></returns>
184+ public Control Add ( Control control )
113185 {
114186 if ( control . GetUiManager ( ) != null || control . _parent != null )
115187 {
@@ -128,14 +200,18 @@ public void Add(Control control)
128200 }
129201
130202 _isDirty = true ;
203+
204+ return _collector . Collect ( control ) ;
131205 }
132206
133207 /// <summary>
134208 /// Removes the given <paramref name="control" /> from this ui manager.
135209 /// </summary>
136210 /// <param name="control"> The control to remove. </param>
211+ /// <param name="dispose"> True to dispose the control after removing. </param>
212+ /// <returns>The <paramref name="control"/></returns>
137213 /// <exception cref="InvalidOperationException"> Thrown when the requested operation is invalid. </exception>
138- public void Remove ( Control control )
214+ public Control Remove ( Control control , bool dispose = false )
139215 {
140216 if ( control . _parent != null )
141217 {
@@ -144,6 +220,15 @@ public void Remove(Control control)
144220 }
145221
146222 RemoveAt ( control . _uiListIndex ) ;
223+
224+ _collector . Remove ( control ) ;
225+
226+ if ( dispose )
227+ {
228+ control . Dispose ( ) ;
229+ }
230+
231+ return control ;
147232 }
148233
149234 /// <summary>
@@ -181,9 +266,13 @@ public void Clear()
181266 }
182267
183268 /// <inheritdoc />
184- protected override void OnInitialize ( IServiceRegistry registry )
269+ void IInitializable . Initialize ( IServiceRegistry registry )
185270 {
186- _canvas = new Canvas ( registry . GetService < IGraphicsDevice > ( ) ) ;
271+ if ( ! _isInitialized )
272+ {
273+ _canvas = new Canvas ( registry . GetService < IGraphicsDevice > ( ) ) ;
274+ _isInitialized = true ;
275+ }
187276 }
188277
189278 internal void SetFocusedControl ( Control control , bool focus )
@@ -303,5 +392,42 @@ private EventAction MouseUp(in MouseEventArgs e)
303392
304393 return EventAction . Continue ;
305394 }
395+
396+ #region IDisposable Support
397+
398+ private bool _disposed ;
399+
400+ /// <inheritdoc />
401+ /// <summary>
402+ /// Performs application-defined tasks associated with freeing, releasing, or resetting
403+ /// unmanaged/managed resources.
404+ /// </summary>
405+ public void Dispose ( )
406+ {
407+ Dispose ( true ) ;
408+ GC . SuppressFinalize ( this ) ;
409+ }
410+
411+ /// <summary>
412+ /// Performs application-defined tasks associated with freeing, releasing, or resetting
413+ /// unmanaged/managed resources.
414+ /// </summary>
415+ /// <param name="disposing"> true if user code; false called by finalizer. </param>
416+ private void Dispose ( bool disposing )
417+ {
418+ if ( ! _disposed )
419+ {
420+ _collector . DisposeAndClear ( disposing ) ;
421+ _disposed = true ;
422+ }
423+ }
424+
425+ /// <inheritdoc />
426+ ~ UiManager ( )
427+ {
428+ Dispose ( false ) ;
429+ }
430+
431+ #endregion
306432 }
307433}
0 commit comments