Ver código fonte

Move in-app browser controls into titlebar

Hide the old browser toolbar, center the page title in the titlebar, and add back/forward/reload/home controls next to the traffic lights for a cleaner native macOS browser window.

Made-with: Cursor
huzaifahayat12 1 semana atrás
pai
commit
47c64e1330
1 arquivos alterados com 104 adições e 2 exclusões
  1. 104 2
      classroom_app/ViewController.swift

+ 104 - 2
classroom_app/ViewController.swift

@@ -6967,6 +6967,12 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
6967 6967
     private var reloadStopButton: NSButton!
6968 6968
     private var goButton: NSButton!
6969 6969
     private var progressBar: NSProgressIndicator!
6970
+    private weak var centeredTitleLabel: NSTextField?
6971
+    private weak var titlebarButtonsContainer: NSStackView?
6972
+    private weak var titlebarBackButton: NSButton?
6973
+    private weak var titlebarForwardButton: NSButton?
6974
+    private weak var titlebarReloadButton: NSButton?
6975
+    private weak var titlebarHomeButton: NSButton?
6970 6976
 
6971 6977
     private var lastLoadedURL: URL?
6972 6978
     private var navigationPolicy: InAppBrowserURLPolicy = .allowAll
@@ -7008,6 +7014,7 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7008 7014
         toolbar.spacing = 8
7009 7015
         toolbar.alignment = .centerY
7010 7016
         toolbar.edgeInsets = NSEdgeInsets(top: 6, left: 10, bottom: 6, right: 10)
7017
+        toolbar.isHidden = true
7011 7018
 
7012 7019
         backButton = makeToolbarButton(title: "◀", symbolName: "chevron.backward", accessibilityDescription: "Back")
7013 7020
         backButton.target = self
@@ -7037,6 +7044,7 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7037 7044
         toolbar.addArrangedSubview(field)
7038 7045
         toolbar.addArrangedSubview(goButton)
7039 7046
         field.widthAnchor.constraint(greaterThanOrEqualToConstant: 240).isActive = true
7047
+        toolbar.heightAnchor.constraint(equalToConstant: 0).isActive = true
7040 7048
 
7041 7049
         let bar = NSProgressIndicator()
7042 7050
         bar.translatesAutoresizingMaskIntoConstraints = false
@@ -7067,7 +7075,7 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7067 7075
 
7068 7076
             bar.leadingAnchor.constraint(equalTo: root.leadingAnchor),
7069 7077
             bar.trailingAnchor.constraint(equalTo: root.trailingAnchor),
7070
-            bar.topAnchor.constraint(equalTo: toolbar.bottomAnchor),
7078
+            bar.topAnchor.constraint(equalTo: root.topAnchor),
7071 7079
             bar.heightAnchor.constraint(equalToConstant: 3),
7072 7080
 
7073 7081
             separator.leadingAnchor.constraint(equalTo: root.leadingAnchor),
@@ -7085,6 +7093,16 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7085 7093
         syncToolbarFromWebView()
7086 7094
     }
7087 7095
 
7096
+    override func viewDidAppear() {
7097
+        super.viewDidAppear()
7098
+        if let window = view.window {
7099
+            installTitlebarButtonsIfNeeded(on: window)
7100
+            installCenteredTitleIfNeeded(on: window)
7101
+            syncWindowTitle()
7102
+            syncToolbarFromWebView()
7103
+        }
7104
+    }
7105
+
7088 7106
     private func makeWebView() -> WKWebView {
7089 7107
         let wv = WKWebView(frame: .zero, configuration: InAppBrowserWebKitSupport.makeWebViewConfiguration())
7090 7108
         wv.translatesAutoresizingMaskIntoConstraints = false
@@ -7157,21 +7175,31 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7157 7175
     private func syncToolbarFromWebView() {
7158 7176
         backButton?.isEnabled = webView.canGoBack
7159 7177
         forwardButton?.isEnabled = webView.canGoForward
7178
+        titlebarBackButton?.isEnabled = webView.canGoBack
7179
+        titlebarForwardButton?.isEnabled = webView.canGoForward
7160 7180
         if webView.isLoading {
7161 7181
             if #available(macOS 11.0, *), let img = NSImage(systemSymbolName: "xmark", accessibilityDescription: "Stop") {
7162 7182
                 reloadStopButton.image = img
7163 7183
                 reloadStopButton.imagePosition = .imageOnly
7164 7184
                 reloadStopButton.title = ""
7185
+                titlebarReloadButton?.image = img
7186
+                titlebarReloadButton?.imagePosition = .imageOnly
7187
+                titlebarReloadButton?.title = ""
7165 7188
             } else {
7166 7189
                 reloadStopButton.title = "Stop"
7190
+                titlebarReloadButton?.title = "Stop"
7167 7191
             }
7168 7192
         } else {
7169 7193
             if #available(macOS 11.0, *), let img = NSImage(systemSymbolName: "arrow.clockwise", accessibilityDescription: "Reload") {
7170 7194
                 reloadStopButton.image = img
7171 7195
                 reloadStopButton.imagePosition = .imageOnly
7172 7196
                 reloadStopButton.title = ""
7197
+                titlebarReloadButton?.image = img
7198
+                titlebarReloadButton?.imagePosition = .imageOnly
7199
+                titlebarReloadButton?.title = ""
7173 7200
             } else {
7174 7201
                 reloadStopButton.title = "Reload"
7202
+                titlebarReloadButton?.title = "Reload"
7175 7203
             }
7176 7204
         }
7177 7205
         syncProgressFromWebView()
@@ -7196,7 +7224,76 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7196 7224
     private func syncWindowTitle() {
7197 7225
         let t = webView.title?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
7198 7226
         let host = webView.url?.host ?? ""
7199
-        view.window?.title = t.isEmpty ? (host.isEmpty ? "Browser" : host) : t
7227
+        let title = t.isEmpty ? (host.isEmpty ? "Browser" : host) : t
7228
+        view.window?.title = title
7229
+        centeredTitleLabel?.stringValue = title
7230
+    }
7231
+
7232
+    private func installCenteredTitleIfNeeded(on window: NSWindow) {
7233
+        guard centeredTitleLabel == nil else { return }
7234
+        guard let titlebarView = window.standardWindowButton(.closeButton)?.superview else { return }
7235
+
7236
+        let label = NSTextField(labelWithString: window.title)
7237
+        label.translatesAutoresizingMaskIntoConstraints = false
7238
+        label.alignment = .center
7239
+        label.font = NSFont.titleBarFont(ofSize: 0)
7240
+        label.textColor = .labelColor
7241
+        label.lineBreakMode = .byTruncatingTail
7242
+        label.maximumNumberOfLines = 1
7243
+
7244
+        titlebarView.addSubview(label)
7245
+
7246
+        NSLayoutConstraint.activate([
7247
+            label.centerXAnchor.constraint(equalTo: titlebarView.centerXAnchor),
7248
+            label.centerYAnchor.constraint(equalTo: titlebarView.centerYAnchor),
7249
+            label.leadingAnchor.constraint(greaterThanOrEqualTo: titlebarView.leadingAnchor, constant: 220),
7250
+            label.trailingAnchor.constraint(lessThanOrEqualTo: titlebarView.trailingAnchor, constant: -90)
7251
+        ])
7252
+
7253
+        window.titleVisibility = .hidden
7254
+        centeredTitleLabel = label
7255
+    }
7256
+
7257
+    private func installTitlebarButtonsIfNeeded(on window: NSWindow) {
7258
+        guard titlebarButtonsContainer == nil else { return }
7259
+        guard let titlebarView = window.standardWindowButton(.closeButton)?.superview else { return }
7260
+        guard let zoomButton = window.standardWindowButton(.zoomButton) else { return }
7261
+
7262
+        let stack = NSStackView()
7263
+        stack.translatesAutoresizingMaskIntoConstraints = false
7264
+        stack.orientation = .horizontal
7265
+        stack.alignment = .centerY
7266
+        stack.spacing = 6
7267
+
7268
+        let back = makeToolbarButton(title: "◀", symbolName: "chevron.backward", accessibilityDescription: "Back")
7269
+        back.target = self
7270
+        back.action = #selector(goBack)
7271
+        let forward = makeToolbarButton(title: "▶", symbolName: "chevron.forward", accessibilityDescription: "Forward")
7272
+        forward.target = self
7273
+        forward.action = #selector(goForward)
7274
+        let reload = makeToolbarButton(title: "Reload", symbolName: "arrow.clockwise", accessibilityDescription: "Reload")
7275
+        reload.target = self
7276
+        reload.action = #selector(reloadOrStop)
7277
+        let home = makeToolbarButton(title: "Home", symbolName: "house", accessibilityDescription: "Home")
7278
+        home.target = self
7279
+        home.action = #selector(goHome)
7280
+
7281
+        stack.addArrangedSubview(back)
7282
+        stack.addArrangedSubview(forward)
7283
+        stack.addArrangedSubview(reload)
7284
+        stack.addArrangedSubview(home)
7285
+        titlebarView.addSubview(stack)
7286
+
7287
+        NSLayoutConstraint.activate([
7288
+            stack.leadingAnchor.constraint(equalTo: zoomButton.trailingAnchor, constant: 12),
7289
+            stack.centerYAnchor.constraint(equalTo: zoomButton.centerYAnchor)
7290
+        ])
7291
+
7292
+        titlebarButtonsContainer = stack
7293
+        titlebarBackButton = back
7294
+        titlebarForwardButton = forward
7295
+        titlebarReloadButton = reload
7296
+        titlebarHomeButton = home
7200 7297
     }
7201 7298
 
7202 7299
     func load(url: URL) {
@@ -7223,6 +7320,11 @@ private final class InAppBrowserContainerViewController: NSViewController, WKNav
7223 7320
         }
7224 7321
     }
7225 7322
 
7323
+    @objc private func goHome() {
7324
+        guard let homeURL = URL(string: "https://classroom.google.com/") else { return }
7325
+        load(url: homeURL)
7326
+    }
7327
+
7226 7328
     @objc private func addressFieldSubmitted() {
7227 7329
         let raw = urlField?.stringValue.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
7228 7330
         guard raw.isEmpty == false else { return }