浏览代码

Integrate the home top strip into the titlebar and remove duplicate traffic lights.

This unifies the left chrome and right top controls into a single titlebar-aligned header while preserving existing actions and visual theme.

Made-with: Cursor
huzaifahayat12 6 天之前
父节点
当前提交
fafaf19cf8
共有 1 个文件被更改,包括 101 次插入54 次删除
  1. 101 54
      zoom_app/ViewController.swift

+ 101 - 54
zoom_app/ViewController.swift

@@ -69,8 +69,14 @@ class ViewController: NSViewController {
69 69
 
70 70
     override func viewDidAppear() {
71 71
         super.viewDidAppear()
72
-        view.window?.setContentSize(NSSize(width: 1020, height: 690))
73
-        view.window?.title = "zoom Workplace"
72
+        if let window = view.window {
73
+            window.setContentSize(NSSize(width: 1020, height: 690))
74
+            // Use full-size content view so custom top chrome sits in the titlebar region.
75
+            window.titleVisibility = .hidden
76
+            window.titlebarAppearsTransparent = true
77
+            window.isMovableByWindowBackground = true
78
+            window.styleMask.insert(.fullSizeContentView)
79
+        }
74 80
         if isUserLoggedIn() {
75 81
             showHomeView(profile: nil)
76 82
         } else {
@@ -648,33 +654,69 @@ class ViewController: NSViewController {
648 654
         shell.layer?.cornerRadius = appShellCornerRadius
649 655
         shell.layer?.borderWidth = 1
650 656
         shell.layer?.borderColor = NSColor.white.withAlphaComponent(0.06).cgColor
657
+        let chromeColumn = NSView()
658
+        chromeColumn.wantsLayer = true
659
+        chromeColumn.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.03).cgColor
660
+        let chromeDivider = NSView()
661
+        chromeDivider.wantsLayer = true
662
+        chromeDivider.layer?.backgroundColor = NSColor.black.withAlphaComponent(0.32).cgColor
663
+        let chromeHeader = NSView()
664
+        chromeHeader.wantsLayer = true
665
+        chromeHeader.layer?.backgroundColor = NSColor.clear.cgColor
651 666
         let sidebar = makeSidebar(items: ["Home", "Meetings", "Chat", "Scheduler", "Hub", "More"], selected: "Home", style: .home)
652 667
         let content = NSView()
653 668
         content.wantsLayer = true
654 669
         content.layer?.backgroundColor = NSColor.clear.cgColor
655 670
 
656 671
         root.addSubview(shell)
657
-        shell.addSubview(sidebar)
672
+        shell.addSubview(chromeColumn)
658 673
         shell.addSubview(content)
674
+        chromeColumn.addSubview(chromeDivider)
675
+        chromeColumn.addSubview(chromeHeader)
676
+        chromeColumn.addSubview(sidebar)
659 677
         shell.translatesAutoresizingMaskIntoConstraints = false
678
+        chromeColumn.translatesAutoresizingMaskIntoConstraints = false
679
+        chromeDivider.translatesAutoresizingMaskIntoConstraints = false
680
+        chromeHeader.translatesAutoresizingMaskIntoConstraints = false
660 681
         sidebar.translatesAutoresizingMaskIntoConstraints = false
661 682
         content.translatesAutoresizingMaskIntoConstraints = false
662 683
 
663 684
         NSLayoutConstraint.activate([
664
-            shell.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 10),
665
-            shell.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -10),
666
-            shell.topAnchor.constraint(equalTo: root.topAnchor, constant: 10),
667
-            shell.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -10),
668
-            sidebar.leadingAnchor.constraint(equalTo: shell.leadingAnchor),
669
-            sidebar.topAnchor.constraint(equalTo: shell.topAnchor),
670
-            sidebar.bottomAnchor.constraint(equalTo: shell.bottomAnchor),
671
-            sidebar.widthAnchor.constraint(equalToConstant: sidebarWidth),
672
-            content.leadingAnchor.constraint(equalTo: sidebar.trailingAnchor),
685
+            shell.leadingAnchor.constraint(equalTo: root.leadingAnchor, constant: 8),
686
+            shell.trailingAnchor.constraint(equalTo: root.trailingAnchor, constant: -8),
687
+            shell.topAnchor.constraint(equalTo: root.topAnchor, constant: 0),
688
+            shell.bottomAnchor.constraint(equalTo: root.bottomAnchor, constant: -8),
689
+            chromeColumn.leadingAnchor.constraint(equalTo: shell.leadingAnchor),
690
+            chromeColumn.topAnchor.constraint(equalTo: shell.topAnchor),
691
+            chromeColumn.bottomAnchor.constraint(equalTo: shell.bottomAnchor),
692
+            chromeColumn.widthAnchor.constraint(equalToConstant: 146),
693
+            chromeDivider.topAnchor.constraint(equalTo: chromeColumn.topAnchor),
694
+            chromeDivider.bottomAnchor.constraint(equalTo: chromeColumn.bottomAnchor),
695
+            chromeDivider.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
696
+            chromeDivider.widthAnchor.constraint(equalToConstant: 1),
697
+            chromeHeader.topAnchor.constraint(equalTo: chromeColumn.topAnchor),
698
+            chromeHeader.leadingAnchor.constraint(equalTo: chromeColumn.leadingAnchor),
699
+            chromeHeader.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
700
+            chromeHeader.heightAnchor.constraint(equalToConstant: 56),
701
+            sidebar.leadingAnchor.constraint(equalTo: chromeColumn.leadingAnchor),
702
+            sidebar.trailingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
703
+            sidebar.topAnchor.constraint(equalTo: chromeHeader.bottomAnchor, constant: 2),
704
+            sidebar.bottomAnchor.constraint(equalTo: chromeColumn.bottomAnchor),
705
+            content.leadingAnchor.constraint(equalTo: chromeColumn.trailingAnchor),
673 706
             content.trailingAnchor.constraint(equalTo: shell.trailingAnchor),
674 707
             content.topAnchor.constraint(equalTo: shell.topAnchor),
675 708
             content.bottomAnchor.constraint(equalTo: shell.bottomAnchor)
676 709
         ])
677 710
 
711
+        let brandStack = NSStackView()
712
+        brandStack.orientation = .vertical
713
+        brandStack.spacing = 0
714
+        brandStack.alignment = .leading
715
+        let brandTop = makeLabel("zoom", size: 14, color: primaryText, weight: .semibold, centered: false)
716
+        let brandBottom = makeLabel("Workplace", size: 27, color: primaryText, weight: .bold, centered: false)
717
+        brandBottom.font = .systemFont(ofSize: 14, weight: .bold)
718
+        [brandTop, brandBottom].forEach { brandStack.addArrangedSubview($0) }
719
+
678 720
         let topBar = NSView()
679 721
         topBar.wantsLayer = true
680 722
         topBar.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.03).cgColor
@@ -689,15 +731,6 @@ class ViewController: NSViewController {
689 731
         searchPill.layer?.cornerRadius = 10
690 732
         let search = makeLabel("Search (\u{2318}E)", size: 13, color: mutedText, weight: .regular, centered: true)
691 733
         
692
-        let brandStack = NSStackView()
693
-        brandStack.orientation = .vertical
694
-        brandStack.spacing = 0
695
-        brandStack.alignment = .leading
696
-        let brandTop = makeLabel("zoom", size: 14, color: primaryText, weight: .semibold, centered: false)
697
-        let brandBottom = makeLabel("Workplace", size: 27, color: primaryText, weight: .bold, centered: false)
698
-        brandBottom.font = .systemFont(ofSize: 14, weight: .bold)
699
-        [brandTop, brandBottom].forEach { brandStack.addArrangedSubview($0) }
700
-        
701 734
         let leftTopBarCluster = NSStackView()
702 735
         leftTopBarCluster.orientation = .horizontal
703 736
         leftTopBarCluster.spacing = 10
@@ -779,38 +812,65 @@ class ViewController: NSViewController {
779 812
         openRecordings.layer?.borderWidth = 1
780 813
         openRecordings.layer?.borderColor = NSColor.white.withAlphaComponent(0.07).cgColor
781 814
 
815
+        let contentPanel = NSView()
816
+        contentPanel.wantsLayer = true
817
+        contentPanel.layer?.backgroundColor = contentShellBackground.cgColor
818
+        contentPanel.layer?.cornerRadius = 12
819
+        contentPanel.layer?.borderWidth = 1
820
+        contentPanel.layer?.borderColor = NSColor.white.withAlphaComponent(0.04).cgColor
782 821
         let contentColumn = NSView()
783 822
         contentColumn.translatesAutoresizingMaskIntoConstraints = false
784
-        content.addSubview(contentColumn)
823
+        content.addSubview(topBar)
824
+        content.addSubview(topBarDivider)
825
+        content.addSubview(contentPanel)
826
+        contentPanel.addSubview(contentColumn)
785 827
 
786
-        [topBar, topBarDivider, brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search, welcome, timeTitle, dateTitle, actions, panel, panelHeaderStrip, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
828
+        [brandStack, leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
829
+            $0.translatesAutoresizingMaskIntoConstraints = false
830
+        }
831
+        [brandStack].forEach {
832
+            chromeHeader.addSubview($0)
833
+        }
834
+        [leftTopBarCluster, rightTopBarCluster, searchPill, search].forEach {
835
+            $0.translatesAutoresizingMaskIntoConstraints = false
836
+            topBar.addSubview($0)
837
+        }
838
+        [welcome, timeTitle, dateTitle, actions, panel, panelHeaderStrip, panelHeader, meetingsStatus, noMeeting, meetingsScrollView, openRecordings].forEach {
787 839
             $0.translatesAutoresizingMaskIntoConstraints = false
788 840
             contentColumn.addSubview($0)
789 841
         }
842
+        topBar.translatesAutoresizingMaskIntoConstraints = false
843
+        topBarDivider.translatesAutoresizingMaskIntoConstraints = false
844
+        contentPanel.translatesAutoresizingMaskIntoConstraints = false
790 845
         meetingsDocument.translatesAutoresizingMaskIntoConstraints = false
791 846
         meetingsStack.translatesAutoresizingMaskIntoConstraints = false
792 847
         meetingsScrollView.documentView = meetingsDocument
793 848
         meetingsDocument.addSubview(meetingsStack)
794 849
 
795 850
         NSLayoutConstraint.activate([
796
-            contentColumn.topAnchor.constraint(equalTo: content.topAnchor),
797
-            contentColumn.bottomAnchor.constraint(equalTo: content.bottomAnchor),
798
-            contentColumn.leadingAnchor.constraint(equalTo: content.leadingAnchor),
799
-            contentColumn.trailingAnchor.constraint(equalTo: content.trailingAnchor),
800
-
801
-            topBar.topAnchor.constraint(equalTo: contentColumn.topAnchor),
802
-            topBar.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor),
803
-            topBar.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor),
804
-            topBar.heightAnchor.constraint(equalToConstant: 48),
851
+            brandStack.leadingAnchor.constraint(equalTo: chromeHeader.leadingAnchor, constant: 60),
852
+            brandStack.centerYAnchor.constraint(equalTo: chromeHeader.centerYAnchor),
853
+
854
+            topBar.topAnchor.constraint(equalTo: content.topAnchor),
855
+            topBar.leadingAnchor.constraint(equalTo: content.leadingAnchor),
856
+            topBar.trailingAnchor.constraint(equalTo: content.trailingAnchor),
857
+            topBar.heightAnchor.constraint(equalToConstant: 56),
805 858
             topBarDivider.topAnchor.constraint(equalTo: topBar.bottomAnchor),
806
-            topBarDivider.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor),
807
-            topBarDivider.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor),
859
+            topBarDivider.leadingAnchor.constraint(equalTo: content.leadingAnchor),
860
+            topBarDivider.trailingAnchor.constraint(equalTo: content.trailingAnchor),
808 861
             topBarDivider.heightAnchor.constraint(equalToConstant: 1),
809 862
 
810
-            brandStack.leadingAnchor.constraint(equalTo: topBar.leadingAnchor, constant: 12),
811
-            brandStack.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
863
+            contentPanel.topAnchor.constraint(equalTo: topBarDivider.bottomAnchor, constant: 6),
864
+            contentPanel.leadingAnchor.constraint(equalTo: content.leadingAnchor, constant: 8),
865
+            contentPanel.trailingAnchor.constraint(equalTo: content.trailingAnchor, constant: -8),
866
+            contentPanel.bottomAnchor.constraint(equalTo: content.bottomAnchor, constant: -8),
867
+
868
+            contentColumn.topAnchor.constraint(equalTo: contentPanel.topAnchor),
869
+            contentColumn.bottomAnchor.constraint(equalTo: contentPanel.bottomAnchor),
870
+            contentColumn.leadingAnchor.constraint(equalTo: contentPanel.leadingAnchor),
871
+            contentColumn.trailingAnchor.constraint(equalTo: contentPanel.trailingAnchor),
812 872
 
813
-            leftTopBarCluster.leadingAnchor.constraint(equalTo: brandStack.trailingAnchor, constant: 18),
873
+            leftTopBarCluster.leadingAnchor.constraint(equalTo: topBar.leadingAnchor, constant: 16),
814 874
             leftTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
815 875
             rightTopBarCluster.trailingAnchor.constraint(equalTo: topBar.trailingAnchor, constant: -12),
816 876
             rightTopBarCluster.centerYAnchor.constraint(equalTo: topBar.centerYAnchor),
@@ -827,7 +887,7 @@ class ViewController: NSViewController {
827 887
             profileChip.widthAnchor.constraint(equalToConstant: 34),
828 888
             profileChip.heightAnchor.constraint(equalToConstant: 34),
829 889
 
830
-            welcome.topAnchor.constraint(equalTo: topBar.bottomAnchor, constant: 22),
890
+            welcome.topAnchor.constraint(equalTo: contentColumn.topAnchor, constant: 22),
831 891
             welcome.centerXAnchor.constraint(equalTo: contentColumn.centerXAnchor),
832 892
 
833 893
             timeTitle.topAnchor.constraint(equalTo: welcome.bottomAnchor, constant: 12),
@@ -845,7 +905,7 @@ class ViewController: NSViewController {
845 905
             panel.leadingAnchor.constraint(equalTo: contentColumn.leadingAnchor, constant: 26),
846 906
             panel.trailingAnchor.constraint(equalTo: contentColumn.trailingAnchor, constant: -26),
847 907
             panel.heightAnchor.constraint(equalToConstant: 316),
848
-            panel.bottomAnchor.constraint(lessThanOrEqualTo: contentColumn.bottomAnchor, constant: -20),
908
+            panel.bottomAnchor.constraint(lessThanOrEqualTo: contentColumn.bottomAnchor, constant: -24),
849 909
             
850 910
             panelHeaderStrip.topAnchor.constraint(equalTo: panel.topAnchor, constant: 10),
851 911
             panelHeaderStrip.leadingAnchor.constraint(equalTo: panel.leadingAnchor, constant: 10),
@@ -911,19 +971,6 @@ class ViewController: NSViewController {
911 971
         let sidebar = NSView()
912 972
         sidebar.wantsLayer = true
913 973
         sidebar.layer?.backgroundColor = (style == .home ? NSColor.white.withAlphaComponent(0.03) : sidebarBackground).cgColor
914
-        if style == .home {
915
-            let divider = NSView()
916
-            divider.wantsLayer = true
917
-            divider.layer?.backgroundColor = NSColor.white.withAlphaComponent(0.06).cgColor
918
-            divider.translatesAutoresizingMaskIntoConstraints = false
919
-            sidebar.addSubview(divider)
920
-            NSLayoutConstraint.activate([
921
-                divider.topAnchor.constraint(equalTo: sidebar.topAnchor),
922
-                divider.bottomAnchor.constraint(equalTo: sidebar.bottomAnchor),
923
-                divider.trailingAnchor.constraint(equalTo: sidebar.trailingAnchor),
924
-                divider.widthAnchor.constraint(equalToConstant: 1)
925
-            ])
926
-        }
927 974
 
928 975
         let stack = NSStackView()
929 976
         stack.orientation = .vertical
@@ -981,7 +1028,7 @@ class ViewController: NSViewController {
981 1028
         }
982 1029
 
983 1030
         NSLayoutConstraint.activate([
984
-            stack.topAnchor.constraint(equalTo: sidebar.topAnchor, constant: style == .home ? 16 : 18),
1031
+            stack.topAnchor.constraint(equalTo: sidebar.topAnchor, constant: style == .home ? 8 : 18),
985 1032
             stack.leadingAnchor.constraint(equalTo: sidebar.leadingAnchor, constant: 4),
986 1033
             stack.trailingAnchor.constraint(equalTo: sidebar.trailingAnchor, constant: -4)
987 1034
         ])
@@ -991,7 +1038,7 @@ class ViewController: NSViewController {
991 1038
 
992 1039
         return sidebar
993 1040
     }
994
-    
1041
+
995 1042
     private func makeTopBarIconButton(symbol: String, action: Selector?) -> NSButton {
996 1043
         let button = NSButton(title: "", target: action == nil ? nil : self, action: action)
997 1044
         button.isBordered = false