Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Tabs #126

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion CodeEdit/Documents/WorkspaceDocument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {

@Published var selectedId: String?
@Published var openFileItems: [WorkspaceClient.FileItem] = []
@Published var sortFoldersOnTop: Bool = true
@Published var sortFoldersOnTop: Bool = true
@Published var fileItems: [WorkspaceClient.FileItem] = []

var selected: WorkspaceClient.FileItem? {
guard let selectedId = selectedId else { return nil }
return fileItems.first(where: { $0.id == selectedId })
}

var quickOpenState: QuickOpenState?

var openedCodeFiles: [WorkspaceClient.FileItem: CodeFileDocument] = [:]
Expand Down Expand Up @@ -49,6 +54,27 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
}
}

func closeFileTabs<Items>(items: Items) where Items: Collection, Items.Element == WorkspaceClient.FileItem {
// TODO: Could potentially be optimized
for item in items {
closeFileTab(item: item)
}
}

func closeFileTab(where predicate: (WorkspaceClient.FileItem) -> Bool) {
closeFileTabs(items: openFileItems.filter(predicate))
}

func closeFileTabs(after item: WorkspaceClient.FileItem) {
guard let startIdx = openFileItems.firstIndex(where: { $0.id == item.id }) else {
assert(false, "Expected file item to be present in openFileItems")
return
}

let range = openFileItems[(startIdx+1)...]
closeFileTabs(items: range)
}

func openFile(item: WorkspaceClient.FileItem) {
do {
let codeFile = try CodeFileDocument(
Expand Down
47 changes: 4 additions & 43 deletions CodeEdit/TabBar/TabBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,38 +31,10 @@ struct TabBar: View {
ScrollViewReader { value in
HStack(alignment: .center, spacing: 0.0) {
ForEach(workspace.openFileItems, id: \.id) { item in
let isActive = workspace.selectedId == item.id

Button(
action: { workspace.selectedId = item.id },
label: {
if isActive {
TabBarItem(
item: item,
windowController: windowController,
workspace: workspace
)
.background(
BlurView(
material: NSVisualEffectView.Material.titlebar,
blendingMode: NSVisualEffectView.BlendingMode.withinWindow
)
)
} else {
TabBarItem(
item: item,
windowController: windowController,
workspace: workspace
)
}
}
)
.animation(.easeOut(duration: 0.2), value: workspace.openFileItems)
.buttonStyle(.plain)
.id(item.id)
.keyboardShortcut(
self.getTabId(fileName: item.fileName),
modifiers: [.command]
TabBarItem(
item: item,
windowController: windowController,
workspace: workspace
)
}
}
Expand All @@ -75,15 +47,4 @@ struct TabBar: View {
.background(BlurView(material: NSVisualEffectView.Material.windowBackground,
blendingMode: NSVisualEffectView.BlendingMode.withinWindow))
}

func getTabId(fileName: String) -> KeyEquivalent {
for counter in 0..<9 where workspace.openFileItems.count > counter &&
workspace.openFileItems[counter].fileName == fileName {
return KeyEquivalent.init(
Character.init("\(counter + 1)")
)
}

return "0"
}
}
62 changes: 59 additions & 3 deletions CodeEdit/TabBar/TabBarItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ import WorkspaceClient

struct TabBarItem: View {
@State var isHovering: Bool = false
var item: WorkspaceClient.FileItem
var item: WorkspaceClient.FileItem
var windowController: NSWindowController
@ObservedObject var workspace: WorkspaceDocument
var tabBarHeight: Double = 28.0
var body: some View {
let isActive = item.id == workspace.selectedId

var isActive: Bool {
item.id == workspace.selectedId
}

@ViewBuilder
var content: some View {
HStack(spacing: 0.0) {
FileTabRow(fileItem: item, isSelected: isActive, isHovering: isHovering) {
withAnimation {
Expand All @@ -42,4 +47,55 @@ struct TabBarItem: View {
}
}
}

var body: some View {
Button(
action: { workspace.selectedId = item.id },
label: {
content
.background(
isActive ? AnyView(BlurView(
material: NSVisualEffectView.Material.titlebar,
blendingMode: NSVisualEffectView.BlendingMode.withinWindow
)) : AnyView(EmptyView())
)
})
.animation(.easeOut(duration: 0.2), value: workspace.openFileItems)
.buttonStyle(.plain)
.id(item.id)
.keyboardShortcut(
workspace.getTabKeyEquivalent(item: item),
modifiers: [.command]
)
.contextMenu {
Button("Close Tab") {
withAnimation {
workspace.closeFileTab(item: item)
}
}
Button("Close Other Tab") {
withAnimation {
workspace.closeFileTab(where: { $0.id != item.id })
}
}
Button("Close Tabs to the Right") {
withAnimation {
workspace.closeFileTabs(after: item)
}
}
}
}
}

fileprivate extension WorkspaceDocument {
func getTabKeyEquivalent(item: WorkspaceClient.FileItem) -> KeyEquivalent {
for counter in 0..<9 where self.openFileItems.count > counter &&
self.openFileItems[counter].fileName == item.fileName {
return KeyEquivalent.init(
Character.init("\(counter + 1)")
)
}

return "0"
}
}