krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Sources/Orgstar/ColumnViewSheet.swift

main
orgstar/Sources/Orgstar/ColumnViewSheet.swift history · blame · raw

62 lines · 2478 bytes

2 symbols in this file
 1import OrgCore
 2import SwiftUI
 3
 4/// `org-columns`, read-only: one row per entry, one column per column-format field, with
 5/// summaries. Clicking a row goes to its heading.
 6struct ColumnViewSheet: View {
 7    let view: ColumnView.View
 8    let jump: (Int) -> Void
 9    @Environment(\.dismiss) private var dismiss
10
11    var body: some View {
12        VStack(alignment: .leading, spacing: 0) {
13            HStack {
14                Text("Column View").font(.headline)
15                Spacer()
16                Button("Done") { dismiss() }.keyboardShortcut(.cancelAction)
17            }
18            .padding(10)
19            Divider()
20            ScrollView([.horizontal, .vertical]) {
21                Grid(alignment: .leading, horizontalSpacing: 14, verticalSpacing: 4) {
22                    GridRow {
23                        ForEach(view.specs.indices, id: \.self) { i in
24                            Text(view.specs[i].title).bold().foregroundStyle(.secondary)
25                        }
26                    }
27                    Divider()
28                    ForEach(view.rows.indices, id: \.self) { r in
29                        let row = view.rows[r]
30                        GridRow {
31                            ForEach(view.specs.indices, id: \.self) { i in
32                                Text(cell(row, i))
33                                    .lineLimit(1)
34                                    .frame(maxWidth: view.specs[i].width.map { CGFloat($0) * 8.5 }, alignment: .leading)
35                            }
36                        }
37                        .contentShape(Rectangle())
38                        .accessibilityAddTraits(.isButton)
39                        .accessibilityAction {
40                            jump(row.start)
41                            dismiss()
42                        }
43                        .onTapGesture {
44                            jump(row.start)
45                            dismiss()
46                        }
47                    }
48                }
49                .font(.system(.body, design: .monospaced))
50                .padding(10)
51            }
52            .defaultScrollAnchor(.topLeading)
53        }
54        .frame(minWidth: 640, minHeight: 360)
55    }
56
57    /// ITEM with the heading's stars, as org shows it.
58    private func cell(_ row: ColumnView.Row, _ i: Int) -> String {
59        guard view.specs[i].property == "ITEM" else { return row.values[i] }
60        return String(repeating: "*", count: row.level) + " " + row.values[i]
61    }
62}