ApplicationImpl.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using System.Collections.Concurrent;
  2. namespace Terminal.Gui.App;
  3. /// <summary>
  4. /// Implementation of core <see cref="Application"/> methods using the modern
  5. /// main loop architecture with component factories for different platforms.
  6. /// </summary>
  7. public partial class ApplicationImpl : IApplication
  8. {
  9. /// <summary>
  10. /// INTERNAL: Creates a new instance of the Application backend.
  11. /// </summary>
  12. internal ApplicationImpl () { }
  13. /// <summary>
  14. /// INTERNAL: Creates a new instance of the Application backend.
  15. /// </summary>
  16. /// <param name="componentFactory"></param>
  17. internal ApplicationImpl (IComponentFactory componentFactory) { _componentFactory = componentFactory; }
  18. #region Singleton
  19. /// <summary>
  20. /// Configures the singleton instance of <see cref="Application"/> to use the specified backend implementation.
  21. /// </summary>
  22. /// <param name="app"></param>
  23. public static void SetInstance (IApplication? app)
  24. {
  25. _instance = app;
  26. }
  27. // Private static readonly Lazy instance of Application
  28. private static IApplication? _instance;
  29. /// <summary>
  30. /// Gets the currently configured backend implementation of <see cref="Application"/> gateway methods.
  31. /// </summary>
  32. public static IApplication Instance => _instance ??= new ApplicationImpl ();
  33. #endregion Singleton
  34. private string? _driverName;
  35. #region Input
  36. private IMouse? _mouse;
  37. /// <summary>
  38. /// Handles mouse event state and processing.
  39. /// </summary>
  40. public IMouse Mouse
  41. {
  42. get
  43. {
  44. if (_mouse is null)
  45. {
  46. _mouse = new MouseImpl { App = this };
  47. }
  48. return _mouse;
  49. }
  50. set => _mouse = value ?? throw new ArgumentNullException (nameof (value));
  51. }
  52. private IKeyboard? _keyboard;
  53. /// <summary>
  54. /// Handles keyboard input and key bindings at the Application level
  55. /// </summary>
  56. public IKeyboard Keyboard
  57. {
  58. get
  59. {
  60. if (_keyboard is null)
  61. {
  62. _keyboard = new KeyboardImpl { App = this };
  63. }
  64. return _keyboard;
  65. }
  66. set => _keyboard = value ?? throw new ArgumentNullException (nameof (value));
  67. }
  68. #endregion Input
  69. #region View Management
  70. private ApplicationPopover? _popover;
  71. /// <inheritdoc/>
  72. public ApplicationPopover? Popover
  73. {
  74. get
  75. {
  76. if (_popover is null)
  77. {
  78. _popover = new () { App = this };
  79. }
  80. return _popover;
  81. }
  82. set => _popover = value;
  83. }
  84. private ApplicationNavigation? _navigation;
  85. /// <inheritdoc/>
  86. public ApplicationNavigation? Navigation
  87. {
  88. get
  89. {
  90. if (_navigation is null)
  91. {
  92. _navigation = new () { App = this };
  93. }
  94. return _navigation;
  95. }
  96. set => _navigation = value ?? throw new ArgumentNullException (nameof (value));
  97. }
  98. private Toplevel? _current;
  99. /// <inheritdoc/>
  100. public Toplevel? Current
  101. {
  102. get => _current;
  103. set
  104. {
  105. _current = value;
  106. if (_current is { })
  107. {
  108. _current.App = this;
  109. }
  110. }
  111. }
  112. // BUGBUG: Technically, this is not the full lst of sessions. There be dragons here, e.g. see how Toplevel.Id is used. What
  113. /// <inheritdoc/>
  114. public ConcurrentStack<Toplevel> SessionStack { get; } = new ();
  115. /// <inheritdoc/>
  116. public Toplevel? CachedSessionTokenToplevel { get; set; }
  117. #endregion View Management
  118. /// <inheritdoc/>
  119. public new string ToString () => Driver?.ToString () ?? string.Empty;
  120. }