diff --git a/CodeEdit/Features/SplitView/Model/SplitViewData.swift b/CodeEdit/Features/SplitView/Model/SplitViewData.swift index d87c425d2..de2bd73f9 100644 --- a/CodeEdit/Features/SplitView/Model/SplitViewData.swift +++ b/CodeEdit/Features/SplitView/Model/SplitViewData.swift @@ -66,6 +66,18 @@ final class SplitViewData: ObservableObject { } } + func getTabGroup(with id: TabGroupData.ID) -> TabGroup? { + for tabgroup in tabgroups { + if case .one(let tabGroupData) = tabgroup { + if tabGroupData.id == id { + return tabgroup + } + } + } + + return nil + } + /// Flattens the splitviews. func flatten() { for index in tabgroups.indices { diff --git a/CodeEdit/Features/Tabs/Models/TabManager.swift b/CodeEdit/Features/Tabs/Models/TabManager.swift index 2562b61c5..17797594d 100644 --- a/CodeEdit/Features/Tabs/Models/TabManager.swift +++ b/CodeEdit/Features/Tabs/Models/TabManager.swift @@ -14,6 +14,8 @@ class TabManager: ObservableObject { /// Collection of all the tabgroups. @Published var tabGroups: TabGroup + @Published var isFocusingActiveTabGroup: Bool + /// The TabGroup with active focus. @Published var activeTabGroup: TabGroupData { didSet { @@ -36,6 +38,7 @@ class TabManager: ObservableObject { self.activeTabGroup = tab self.activeTabGroupHistory.prepend { [weak tab] in tab } self.tabGroups = .horizontal(.init(.horizontal, tabgroups: [.one(tab)])) + self.isFocusingActiveTabGroup = false switchToActiveTabGroup() } diff --git a/CodeEdit/Features/Tabs/TabGroup/TabGroupData.swift b/CodeEdit/Features/Tabs/TabGroup/TabGroupData.swift index cadc8ad2e..dc0e3cfec 100644 --- a/CodeEdit/Features/Tabs/TabGroup/TabGroupData.swift +++ b/CodeEdit/Features/Tabs/TabGroup/TabGroupData.swift @@ -77,6 +77,11 @@ final class TabGroupData: ObservableObject, Identifiable { parent?.closeTabGroup(with: id) } + /// Gets the tabgroup. + func getTabGroup() -> TabGroup? { + return parent?.getTabGroup(with: id) + } + /// Closes a tab in the tabgroup. /// This will also write any changes to the file on disk and will add the tab to the tab history. /// - Parameter item: the tab to close. diff --git a/CodeEdit/Features/Tabs/Views/TabBarAccessory.swift b/CodeEdit/Features/Tabs/Views/TabBarAccessory.swift index 6cbf3cbd8..488e83c58 100644 --- a/CodeEdit/Features/Tabs/Views/TabBarAccessory.swift +++ b/CodeEdit/Features/Tabs/Views/TabBarAccessory.swift @@ -13,19 +13,23 @@ struct TabBarAccessoryIcon: View { static let iconFont = Font.system(size: 14, weight: .regular, design: .default) private let icon: Image + private let isActive: Bool private let action: () -> Void - init(icon: Image, action: @escaping () -> Void) { + init(icon: Image, isActive: Bool = false, action: @escaping () -> Void) { self.icon = icon + self.isActive = isActive self.action = action } var body: some View { Button( action: action, - label: { icon } + label: { + icon + } ) - .buttonStyle(.icon(size: 24)) + .buttonStyle(.icon(isActive: isActive, size: 24)) } } diff --git a/CodeEdit/Features/Tabs/Views/TabBarView.swift b/CodeEdit/Features/Tabs/Views/TabBarView.swift index 30aa8417a..be12c5a5f 100644 --- a/CodeEdit/Features/Tabs/Views/TabBarView.swift +++ b/CodeEdit/Features/Tabs/Views/TabBarView.swift @@ -459,7 +459,7 @@ struct TabBarView: View { // MARK: Accessories private var leadingAccessories: some View { - HStack(spacing: 2) { + HStack(spacing: 0) { if let otherGroup = tabManager.tabGroups.findSomeTabGroup(except: tabgroup) { TabBarAccessoryIcon( icon: .init(systemName: "multiply"), @@ -477,6 +477,28 @@ struct TabBarView: View { } ) .help("Close this Editor") + .disabled(tabManager.isFocusingActiveTabGroup) + .opacity(tabManager.isFocusingActiveTabGroup ? 0.5 : 1) + + TabBarAccessoryIcon( + icon: .init( + systemName: tabManager.isFocusingActiveTabGroup + ? "arrow.down.forward.and.arrow.up.backward" + : "arrow.up.left.and.arrow.down.right" + ), + isActive: tabManager.isFocusingActiveTabGroup, + action: { + if !tabManager.isFocusingActiveTabGroup { + tabManager.activeTabGroup = tabgroup + } + tabManager.isFocusingActiveTabGroup.toggle() + } + ) + .help( + tabManager.isFocusingActiveTabGroup + ? "Unfocus this Editor" + : "Focus this Editor" + ) Divider() .frame(height: 10) @@ -547,7 +569,7 @@ struct TabBarView: View { } .foregroundColor(.secondary) .buttonStyle(.plain) - .padding(.horizontal, 7) + .padding(.horizontal, 5) .opacity(activeState != .inactive ? 1.0 : 0.5) .frame(maxHeight: .infinity) // Fill out vertical spaces. .background { @@ -558,10 +580,10 @@ struct TabBarView: View { } private var trailingAccessories: some View { - HStack(spacing: 2) { + HStack(spacing: 0) { splitviewButton } - .padding(.horizontal, 10) + .padding(.horizontal, 7) .opacity(activeState != .inactive ? 1.0 : 0.5) .frame(maxHeight: .infinity) // Fill out vertical spaces. .background { @@ -595,6 +617,8 @@ struct TabBarView: View { } } .buttonStyle(.icon) + .disabled(tabManager.isFocusingActiveTabGroup) + .opacity(tabManager.isFocusingActiveTabGroup ? 0.5 : 1) } func split(edge: Edge) { diff --git a/CodeEdit/WorkspaceView.swift b/CodeEdit/WorkspaceView.swift index d0a93cb7a..fd0970220 100644 --- a/CodeEdit/WorkspaceView.swift +++ b/CodeEdit/WorkspaceView.swift @@ -42,15 +42,20 @@ struct WorkspaceView: View { VStack { SplitViewReader { proxy in SplitView(axis: .vertical) { - EditorView(tabgroup: tabManager.tabGroups, focus: $focusedEditor) - .collapsable() - .collapsed($debugAreaModel.isMaximized) - .frame(minHeight: 170 + 29 + 29) - .frame(maxWidth: .infinity, maxHeight: .infinity) - .holdingPriority(.init(1)) - .safeAreaInset(edge: .bottom, spacing: 0) { - StatusBarView(proxy: proxy) - } + EditorView( + tabgroup: tabManager.isFocusingActiveTabGroup + ? tabManager.activeTabGroup.getTabGroup() ?? tabManager.tabGroups + : tabManager.tabGroups, + focus: $focusedEditor + ) + .collapsable() + .collapsed($debugAreaModel.isMaximized) + .frame(minHeight: 170 + 29 + 29) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .holdingPriority(.init(1)) + .safeAreaInset(edge: .bottom, spacing: 0) { + StatusBarView(proxy: proxy) + } DebugAreaView() .collapsable() .collapsed($debugAreaModel.isCollapsed)