ApplicationImpl.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. /// Creates a new instance of the Application backend.
  11. /// </summary>
  12. public 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. // Private static readonly Lazy instance of Application
  20. private static Lazy<IApplication> _lazyInstance = new (() => new ApplicationImpl ());
  21. /// <summary>
  22. /// Change the singleton implementation, should not be called except before application
  23. /// startup. This method lets you provide alternative implementations of core static gateway
  24. /// methods of <see cref="Application"/>.
  25. /// </summary>
  26. /// <param name="newApplication"></param>
  27. public static void ChangeInstance (IApplication? newApplication) { _lazyInstance = new (newApplication!); }
  28. /// <summary>
  29. /// Gets the currently configured backend implementation of <see cref="Application"/> gateway methods.
  30. /// Change to your own implementation by using <see cref="ChangeInstance"/> (before init).
  31. /// </summary>
  32. public static IApplication Instance => _lazyInstance.Value;
  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 { Application = 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 { Application = this };
  63. }
  64. return _keyboard;
  65. }
  66. set => _keyboard = value ?? throw new ArgumentNullException (nameof (value));
  67. }
  68. #endregion Input
  69. #region View Management
  70. /// <inheritdoc/>
  71. public ApplicationPopover? Popover { get; set; }
  72. /// <inheritdoc/>
  73. public ApplicationNavigation? Navigation { get; set; }
  74. /// <inheritdoc/>
  75. public Toplevel? Current { get; set; }
  76. // BUGBUG: Technically, this is not the full lst of sessions. There be dragons here, e.g. see how Toplevel.Id is used. What
  77. /// <inheritdoc/>
  78. public ConcurrentStack<Toplevel> SessionStack { get; } = new ();
  79. /// <inheritdoc/>
  80. public Toplevel? CachedSessionTokenToplevel { get; set; }
  81. #endregion View Management
  82. }