Ariver
2026-06-19 6f2856fa70722dad7f7c69a3addaa05ea9fd6e94
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import AppKit
import AlignerCore
 
@MainActor
final class SettingsWindowController: NSWindowController {
    private let modeProvider: () -> QuickSwitchWaterfallViewMode
    private let onWaterfallViewModeChanged: (QuickSwitchWaterfallViewMode) -> Void
    private let tabView = NSTabView()
    private let verticalColumnsButton = NSButton(
        radioButtonWithTitle: "纵栏瀑布",
        target: nil,
        action: nil
    )
    private let horizontalMasonryButton = NSButton(
        radioButtonWithTitle: "横栏瀑布",
        target: nil,
        action: nil
    )
 
    init(
        modeProvider: @escaping () -> QuickSwitchWaterfallViewMode,
        onWaterfallViewModeChanged: @escaping (QuickSwitchWaterfallViewMode) -> Void
    ) {
        self.modeProvider = modeProvider
        self.onWaterfallViewModeChanged = onWaterfallViewModeChanged
 
        let window = NSWindow(
            contentRect: NSRect(x: 0, y: 0, width: 520, height: 340),
            styleMask: [.titled, .closable, .miniaturizable],
            backing: .buffered,
            defer: false
        )
        window.title = "Aligner 设置"
        window.isReleasedWhenClosed = false
        window.center()
 
        super.init(window: window)
        window.contentView = makeContentView()
        refreshWaterfallViewMode()
    }
 
    @available(*, unavailable)
    required init?(coder: NSCoder) {
        nil
    }
 
    override func showWindow(_ sender: Any?) {
        refreshWaterfallViewMode()
        tabView.selectTabViewItem(withIdentifier: "view")
        super.showWindow(sender)
        window?.makeKeyAndOrderFront(sender)
    }
 
    func refreshWaterfallViewMode() {
        let mode = modeProvider()
        verticalColumnsButton.state = mode == .verticalColumns ? .on : .off
        horizontalMasonryButton.state = mode == .horizontalMasonry ? .on : .off
    }
 
    func reportDictionary() -> [String: Any] {
        [
            "exists": true,
            "visible": window?.isVisible ?? false,
            "title": window?.title ?? "",
            "selectedTabLabel": tabView.selectedTabViewItem?.label ?? "",
            "selectedTabIdentifier": tabView.selectedTabViewItem?.identifier as? String ?? "",
            "waterfallViewMode": modeProvider().rawValue,
            "hasViewTab": tabView.tabViewItems.contains { $0.identifier as? String == "view" },
            "usesSwiftUI": false
        ]
    }
 
    private func makeContentView() -> NSView {
        tabView.translatesAutoresizingMaskIntoConstraints = false
        tabView.tabViewType = .topTabsBezelBorder
        tabView.addTabViewItem(makeViewTab())
 
        let root = NSView()
        root.addSubview(tabView)
        NSLayoutConstraint.activate([
            tabView.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 20),
            tabView.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -20),
            tabView.topAnchor.constraint(equalTo: root.topAnchor, constant: 18),
            tabView.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -20)
        ])
        return root
    }
 
    private func makeViewTab() -> NSTabViewItem {
        let tab = NSTabViewItem(identifier: "view")
        tab.label = "视图"
        tab.view = makeViewSettingsView()
        return tab
    }
 
    private func makeViewSettingsView() -> NSView {
        let title = NSTextField(labelWithString: "Quick Switch 视图")
        title.font = .systemFont(ofSize: 18, weight: .semibold)
 
        let subtitle = NSTextField(wrappingLabelWithString: "切换后立即生效。")
        subtitle.textColor = .secondaryLabelColor
 
        verticalColumnsButton.target = self
        verticalColumnsButton.action = #selector(selectVerticalColumns)
        horizontalMasonryButton.target = self
        horizontalMasonryButton.action = #selector(selectHorizontalMasonry)
 
        let modeStack = NSStackView(views: [verticalColumnsButton, horizontalMasonryButton])
        modeStack.orientation = .vertical
        modeStack.alignment = .leading
        modeStack.spacing = 10
 
        let stack = NSStackView(views: [title, subtitle, modeStack])
        stack.orientation = .vertical
        stack.alignment = .leading
        stack.spacing = 14
        stack.translatesAutoresizingMaskIntoConstraints = false
 
        let view = NSView()
        view.addSubview(stack)
        NSLayoutConstraint.activate([
            stack.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 22),
            stack.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -22),
            stack.topAnchor.constraint(equalTo: view.topAnchor, constant: 24)
        ])
        return view
    }
 
    @objc private func selectVerticalColumns() {
        onWaterfallViewModeChanged(.verticalColumns)
        refreshWaterfallViewMode()
    }
 
    @objc private func selectHorizontalMasonry() {
        onWaterfallViewModeChanged(.horizontalMasonry)
        refreshWaterfallViewMode()
    }
}