ApplicationImpl.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #nullable enable
  2. using System.Collections.Concurrent;
  3. namespace Terminal.Gui.App;
  4. /// <summary>
  5. /// Implementation of core <see cref="Application"/> methods using the modern
  6. /// main loop architecture with component factories for different platforms.
  7. /// </summary>
  8. public partial class ApplicationImpl : IApplication
  9. {
  10. /// <summary>
  11. /// Creates a new instance of the Application backend.
  12. /// </summary>
  13. public ApplicationImpl () { }
  14. /// <summary>
  15. /// INTERNAL: Creates a new instance of the Application backend.
  16. /// </summary>
  17. /// <param name="componentFactory"></param>
  18. internal ApplicationImpl (IComponentFactory componentFactory) { _componentFactory = componentFactory; }
  19. #region Singleton
  20. // Private static readonly Lazy instance of Application
  21. private static Lazy<IApplication> _lazyInstance = new (() => new ApplicationImpl ());
  22. /// <summary>
  23. /// Change the singleton implementation, should not be called except before application
  24. /// startup. This method lets you provide alternative implementations of core static gateway
  25. /// methods of <see cref="Application"/>.
  26. /// </summary>
  27. /// <param name="newApplication"></param>
  28. public static void ChangeInstance (IApplication? newApplication) { _lazyInstance = new (newApplication!); }
  29. /// <summary>
  30. /// Gets the currently configured backend implementation of <see cref="Application"/> gateway methods.
  31. /// Change to your own implementation by using <see cref="ChangeInstance"/> (before init).
  32. /// </summary>
  33. public static IApplication Instance => _lazyInstance.Value;
  34. #endregion Singleton
  35. private string? _driverName;
  36. #region Input
  37. private IMouse? _mouse;
  38. /// <summary>
  39. /// Handles mouse event state and processing.
  40. /// </summary>
  41. public IMouse Mouse
  42. {
  43. get
  44. {
  45. if (_mouse is null)
  46. {
  47. _mouse = new MouseImpl { Application = this };
  48. }
  49. return _mouse;
  50. }
  51. set => _mouse = value ?? throw new ArgumentNullException (nameof (value));
  52. }
  53. private IKeyboard? _keyboard;
  54. /// <summary>
  55. /// Handles keyboard input and key bindings at the Application level
  56. /// </summary>
  57. public IKeyboard Keyboard
  58. {
  59. get
  60. {
  61. if (_keyboard is null)
  62. {
  63. _keyboard = new KeyboardImpl { Application = this };
  64. }
  65. return _keyboard;
  66. }
  67. set => _keyboard = value ?? throw new ArgumentNullException (nameof (value));
  68. }
  69. #endregion Input
  70. #region View Management
  71. /// <inheritdoc/>
  72. public ApplicationPopover? Popover { get; set; }
  73. /// <inheritdoc/>
  74. public ApplicationNavigation? Navigation { get; set; }
  75. /// <inheritdoc/>
  76. public Toplevel? Top { get; set; }
  77. // BUGBUG: Technically, this is not the full lst of TopLevels. There be dragons here, e.g. see how Toplevel.Id is used. What
  78. /// <inheritdoc/>
  79. public ConcurrentStack<Toplevel> TopLevels { get; } = new ();
  80. /// <inheritdoc/>
  81. public Toplevel? CachedSessionTokenToplevel { get; set; }
  82. #endregion View Management
  83. }