tabs_state.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. part of 'tabs_bloc.dart';
  2. class TabsState {
  3. final int currentIndex;
  4. final List<PageManager> _pageManagers;
  5. int get pages => _pageManagers.length;
  6. PageManager get currentPageManager => _pageManagers[currentIndex];
  7. List<PageManager> get pageManagers => _pageManagers;
  8. TabsState({
  9. this.currentIndex = 0,
  10. List<PageManager>? pageManagers,
  11. }) : _pageManagers = pageManagers ?? [PageManager()];
  12. /// This opens a new tab given a [Plugin] and a [View].
  13. ///
  14. /// If the [Plugin.id] is already associated with an open tab,
  15. /// then it selects that tab.
  16. ///
  17. TabsState openView(Plugin plugin, ViewPB view) {
  18. final selectExistingPlugin = _selectPluginIfOpen(plugin.id);
  19. if (selectExistingPlugin == null) {
  20. _pageManagers.add(PageManager()..setPlugin(plugin));
  21. return copyWith(newIndex: pages - 1, pageManagers: [..._pageManagers]);
  22. }
  23. return selectExistingPlugin;
  24. }
  25. TabsState closeView(String pluginId) {
  26. // Avoid closing the only open tab
  27. if (_pageManagers.length == 1) {
  28. return this;
  29. }
  30. _pageManagers.removeWhere((pm) => pm.plugin.id == pluginId);
  31. /// If currentIndex is greater than the amount of allowed indices
  32. /// And the current selected tab isn't the first (index 0)
  33. /// as currentIndex cannot be -1
  34. /// Then decrease currentIndex by 1
  35. final newIndex = currentIndex > pages - 1 && currentIndex > 0
  36. ? currentIndex - 1
  37. : currentIndex;
  38. return copyWith(
  39. newIndex: newIndex,
  40. pageManagers: [..._pageManagers],
  41. );
  42. }
  43. /// This opens a plugin in the current selected tab,
  44. /// due to how Document currently works, only one tab
  45. /// per plugin can currently be active.
  46. ///
  47. /// If the plugin is already open in a tab, then that tab
  48. /// will become selected.
  49. ///
  50. TabsState openPlugin({required Plugin plugin}) {
  51. final selectExistingPlugin = _selectPluginIfOpen(plugin.id);
  52. if (selectExistingPlugin == null) {
  53. final pageManagers = [..._pageManagers];
  54. pageManagers[currentIndex].setPlugin(plugin);
  55. return copyWith(pageManagers: pageManagers);
  56. }
  57. return selectExistingPlugin;
  58. }
  59. /// Checks if a [Plugin.id] is already associated with an open tab.
  60. /// Returns a [TabState] with new index if there is a match.
  61. ///
  62. /// If no match it returns null
  63. ///
  64. TabsState? _selectPluginIfOpen(String id) {
  65. final index = _pageManagers.indexWhere((pm) => pm.plugin.id == id);
  66. if (index == -1) {
  67. return null;
  68. }
  69. if (index == currentIndex) {
  70. return this;
  71. }
  72. return copyWith(newIndex: index);
  73. }
  74. TabsState copyWith({
  75. int? newIndex,
  76. List<PageManager>? pageManagers,
  77. }) =>
  78. TabsState(
  79. currentIndex: newIndex ?? currentIndex,
  80. pageManagers: pageManagers ?? _pageManagers,
  81. );
  82. }