Przeglądaj źródła

Add bordered content panel to home screen and refine header layout.

Introduce a shared ContentPanelView for consistent card-style borders on home and settings, with tuned spacing for the title and scroll content.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 5 godzin temu
rodzic
commit
8ee51b05ee

+ 5 - 0
smart_printer/AppTheme.swift

@@ -29,6 +29,11 @@ enum AppTheme {
29 29
     static let cornerRadius: CGFloat = 14
30 30
     static let cardCornerRadius: CGFloat = 20
31 31
     static let featureCardCornerRadius: CGFloat = 16
32
+    static let contentPanelCornerRadius: CGFloat = 24
33
+    static let contentPanelInset: CGFloat = 16
34
+    static let headerTopInset: CGFloat = 14
35
+    static let headerHeight: CGFloat = 32
36
+    static let contentBelowHeaderGap: CGFloat = 2
32 37
 
33 38
     private static var isDark: Bool { AppSettings.darkModeEnabled }
34 39
 

+ 1 - 22
smart_printer/SettingsView.swift

@@ -29,7 +29,7 @@ final class SettingsView: NSView, AppearanceRefreshable {
29 29
         let document = FlippedSettingsDocumentView()
30 30
         document.translatesAutoresizingMaskIntoConstraints = false
31 31
 
32
-        let panel = SettingsPanelView()
32
+        let panel = ContentPanelView(cornerRadius: 22)
33 33
         panel.translatesAutoresizingMaskIntoConstraints = false
34 34
 
35 35
         let stack = NSStackView()
@@ -137,27 +137,6 @@ final class SettingsView: NSView, AppearanceRefreshable {
137 137
     }
138 138
 }
139 139
 
140
-// MARK: - Panel
141
-
142
-private final class SettingsPanelView: NSView, AppearanceRefreshable {
143
-    init() {
144
-        super.init(frame: .zero)
145
-        wantsLayer = true
146
-        layer?.cornerRadius = 22
147
-        layer?.borderWidth = 1.5
148
-        applyCardShadow()
149
-        refreshAppearance()
150
-    }
151
-
152
-    func refreshAppearance() {
153
-        layer?.backgroundColor = AppTheme.cardBackground.cgColor
154
-        layer?.borderColor = AppTheme.paywallBorder.cgColor
155
-    }
156
-
157
-    @available(*, unavailable)
158
-    required init?(coder: NSCoder) { nil }
159
-}
160
-
161 140
 private final class SettingsGroupCard: NSView, AppearanceRefreshable {
162 141
     private let stack = NSStackView()
163 142
 

+ 21 - 0
smart_printer/UIComponents.swift

@@ -1,5 +1,26 @@
1 1
 import Cocoa
2 2
 
3
+// MARK: - Content Panel
4
+
5
+final class ContentPanelView: NSView, AppearanceRefreshable {
6
+    init(cornerRadius: CGFloat = AppTheme.contentPanelCornerRadius) {
7
+        super.init(frame: .zero)
8
+        wantsLayer = true
9
+        layer?.cornerRadius = cornerRadius
10
+        layer?.borderWidth = 1.5
11
+        applyCardShadow()
12
+        refreshAppearance()
13
+    }
14
+
15
+    @available(*, unavailable)
16
+    required init?(coder: NSCoder) { nil }
17
+
18
+    func refreshAppearance() {
19
+        layer?.backgroundColor = AppTheme.cardBackground.cgColor
20
+        layer?.borderColor = AppTheme.paywallBorder.cgColor
21
+    }
22
+}
23
+
3 24
 // MARK: - Gradient Card View
4 25
 
5 26
 final class GradientCardView: NSView {

+ 24 - 11
smart_printer/ViewController.swift

@@ -91,8 +91,8 @@ class ViewController: NSViewController {
91 91
 
92 92
         view.addSubview(sidebar)
93 93
         view.addSubview(mainContentView)
94
-        mainContentView.addSubview(headerView)
95 94
         mainContentView.addSubview(contentContainer)
95
+        mainContentView.addSubview(headerView, positioned: .above, relativeTo: contentContainer)
96 96
 
97 97
         sidebar.onDestinationSelected = { [weak self] destination in
98 98
             self?.showDestination(destination)
@@ -110,8 +110,8 @@ class ViewController: NSViewController {
110 110
 
111 111
             headerView.leadingAnchor.constraint(equalTo: mainContentView.leadingAnchor),
112 112
             headerView.trailingAnchor.constraint(equalTo: mainContentView.trailingAnchor),
113
-            headerView.topAnchor.constraint(equalTo: mainContentView.topAnchor, constant: 16),
114
-            headerView.heightAnchor.constraint(equalToConstant: 44),
113
+            headerView.topAnchor.constraint(equalTo: mainContentView.topAnchor, constant: AppTheme.headerTopInset),
114
+            headerView.heightAnchor.constraint(equalToConstant: AppTheme.headerHeight),
115 115
 
116 116
             contentContainer.leadingAnchor.constraint(equalTo: mainContentView.leadingAnchor),
117 117
             contentContainer.trailingAnchor.constraint(equalTo: mainContentView.trailingAnchor),
@@ -123,7 +123,10 @@ class ViewController: NSViewController {
123 123
         pinContentView(scanAndHomeContentView)
124 124
         pinContentView(settingsContentView)
125 125
 
126
-        contentTopBelowHeader = contentContainer.topAnchor.constraint(equalTo: headerView.bottomAnchor, constant: 8)
126
+        contentTopBelowHeader = contentContainer.topAnchor.constraint(
127
+            equalTo: headerView.bottomAnchor,
128
+            constant: AppTheme.contentBelowHeaderGap
129
+        )
127 130
         contentTopBelowWindow = contentContainer.topAnchor.constraint(equalTo: mainContentView.topAnchor, constant: 12)
128 131
         contentTopBelowHeader.isActive = true
129 132
 
@@ -189,14 +192,24 @@ class ViewController: NSViewController {
189 192
         let container = NSView()
190 193
         container.translatesAutoresizingMaskIntoConstraints = false
191 194
 
195
+        let panel = ContentPanelView()
196
+        panel.translatesAutoresizingMaskIntoConstraints = false
197
+
192 198
         let scrollView = makeScrollView()
193
-        container.addSubview(scrollView)
199
+        panel.addSubview(scrollView)
200
+        container.addSubview(panel)
194 201
 
202
+        let inset = AppTheme.contentPanelInset
195 203
         NSLayoutConstraint.activate([
196
-            scrollView.leadingAnchor.constraint(equalTo: container.leadingAnchor),
197
-            scrollView.trailingAnchor.constraint(equalTo: container.trailingAnchor),
198
-            scrollView.topAnchor.constraint(equalTo: container.topAnchor),
199
-            scrollView.bottomAnchor.constraint(equalTo: container.bottomAnchor),
204
+            panel.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: inset),
205
+            panel.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -inset),
206
+            panel.topAnchor.constraint(equalTo: container.topAnchor),
207
+            panel.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -inset),
208
+
209
+            scrollView.leadingAnchor.constraint(equalTo: panel.leadingAnchor),
210
+            scrollView.trailingAnchor.constraint(equalTo: panel.trailingAnchor),
211
+            scrollView.topAnchor.constraint(equalTo: panel.topAnchor),
212
+            scrollView.bottomAnchor.constraint(equalTo: panel.bottomAnchor),
200 213
         ])
201 214
 
202 215
         return container
@@ -286,7 +299,7 @@ class ViewController: NSViewController {
286 299
 
287 300
         NSLayoutConstraint.activate([
288 301
             titleLabel.centerXAnchor.constraint(equalTo: header.centerXAnchor),
289
-            titleLabel.centerYAnchor.constraint(equalTo: header.centerYAnchor),
302
+            titleLabel.topAnchor.constraint(equalTo: header.topAnchor, constant: 2),
290 303
         ])
291 304
 
292 305
         return header
@@ -345,7 +358,7 @@ class ViewController: NSViewController {
345 358
 
346 359
             quickStartSection.leadingAnchor.constraint(equalTo: documentView.leadingAnchor, constant: AppTheme.contentPadding),
347 360
             quickStartSection.trailingAnchor.constraint(equalTo: documentView.trailingAnchor, constant: -AppTheme.contentPadding),
348
-            quickStartSection.topAnchor.constraint(equalTo: documentView.topAnchor, constant: 8),
361
+            quickStartSection.topAnchor.constraint(equalTo: documentView.topAnchor, constant: 20),
349 362
 
350 363
             createPrintSection.leadingAnchor.constraint(equalTo: documentView.leadingAnchor, constant: AppTheme.contentPadding),
351 364
             createPrintSection.trailingAnchor.constraint(equalTo: documentView.trailingAnchor, constant: -AppTheme.contentPadding),