|
|
@@ -180,6 +180,11 @@ private struct DocumentStyle {
|
|
180
|
180
|
/// Full-width résumé layout that injects `SavedProfile` into the visual language of `CVTemplate`.
|
|
181
|
181
|
final class CVProfileDocumentView: NSView {
|
|
182
|
182
|
|
|
|
183
|
+ /// Card width used in the CV preview; also the horizontal fitting size for this view.
|
|
|
184
|
+ /// Without this, a parent `NSStackView` that only pins `width ≤ …` sizes the document from
|
|
|
185
|
+ /// editable `NSTextField` intrinsic widths (~0) and the whole page collapses to a thin strip.
|
|
|
186
|
+ private static let cardWidth: CGFloat = 640
|
|
|
187
|
+
|
|
183
|
188
|
private let profile: SavedProfile
|
|
184
|
189
|
private let template: CVTemplate
|
|
185
|
190
|
private let style: DocumentStyle
|
|
|
@@ -198,6 +203,8 @@ final class CVProfileDocumentView: NSView {
|
|
198
|
203
|
wantsLayer = true
|
|
199
|
204
|
layer?.backgroundColor = NSColor.clear.cgColor
|
|
200
|
205
|
userInterfaceLayoutDirection = .leftToRight
|
|
|
206
|
+ // Let the preview stack stretch us to the scroll view width; don’t shrink to editable fields.
|
|
|
207
|
+ setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
201
|
208
|
|
|
202
|
209
|
let card = NSView()
|
|
203
|
210
|
card.translatesAutoresizingMaskIntoConstraints = false
|
|
|
@@ -218,7 +225,7 @@ final class CVProfileDocumentView: NSView {
|
|
218
|
225
|
card.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
219
|
226
|
card.topAnchor.constraint(equalTo: topAnchor),
|
|
220
|
227
|
card.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
221
|
|
- card.widthAnchor.constraint(equalToConstant: 640),
|
|
|
228
|
+ card.widthAnchor.constraint(equalToConstant: Self.cardWidth),
|
|
222
|
229
|
|
|
223
|
230
|
root.leadingAnchor.constraint(equalTo: card.leadingAnchor, constant: 36),
|
|
224
|
231
|
root.trailingAnchor.constraint(equalTo: card.trailingAnchor, constant: -36),
|
|
|
@@ -232,6 +239,41 @@ final class CVProfileDocumentView: NSView {
|
|
232
|
239
|
fatalError("init(coder:) has not been implemented")
|
|
233
|
240
|
}
|
|
234
|
241
|
|
|
|
242
|
+ override var intrinsicContentSize: NSSize {
|
|
|
243
|
+ NSSize(width: Self.cardWidth, height: NSView.noIntrinsicMetric)
|
|
|
244
|
+ }
|
|
|
245
|
+
|
|
|
246
|
+ override func layout() {
|
|
|
247
|
+ super.layout()
|
|
|
248
|
+ // Editable wrapping `NSTextField`s default to a very small intrinsic width until
|
|
|
249
|
+ // `preferredMaxLayoutWidth` tracks the column width — stacks then collapse and text
|
|
|
250
|
+ // reflows like a narrow strip (broken CV layout in “Edit text in place” mode).
|
|
|
251
|
+ updateWrappingTextPreferredWidths()
|
|
|
252
|
+ }
|
|
|
253
|
+
|
|
|
254
|
+ /// Any wrapping body (`maximumNumberOfLines == 0`) needs a concrete wrap width inside stack-driven layout.
|
|
|
255
|
+ private func updateWrappingTextPreferredWidths() {
|
|
|
256
|
+ for field in Self.collectWrappingTextFields(in: self) {
|
|
|
257
|
+ guard let parent = field.superview, parent.bounds.width > 2 else { continue }
|
|
|
258
|
+ let w = parent.bounds.width
|
|
|
259
|
+ if abs(field.preferredMaxLayoutWidth - w) > 0.5 {
|
|
|
260
|
+ field.preferredMaxLayoutWidth = w
|
|
|
261
|
+ }
|
|
|
262
|
+ }
|
|
|
263
|
+ }
|
|
|
264
|
+
|
|
|
265
|
+ private static func collectWrappingTextFields(in root: NSView) -> [NSTextField] {
|
|
|
266
|
+ var out: [NSTextField] = []
|
|
|
267
|
+ func visit(_ v: NSView) {
|
|
|
268
|
+ if let tf = v as? NSTextField, tf.maximumNumberOfLines == 0 {
|
|
|
269
|
+ out.append(tf)
|
|
|
270
|
+ }
|
|
|
271
|
+ for c in v.subviews { visit(c) }
|
|
|
272
|
+ }
|
|
|
273
|
+ visit(root)
|
|
|
274
|
+ return out
|
|
|
275
|
+ }
|
|
|
276
|
+
|
|
235
|
277
|
// MARK: - Composition
|
|
236
|
278
|
|
|
237
|
279
|
private func buildRoot() -> NSView {
|
|
|
@@ -1228,6 +1270,12 @@ final class CVProfileDocumentView: NSView {
|
|
1228
|
1270
|
t.isBordered = false
|
|
1229
|
1271
|
t.drawsBackground = false
|
|
1230
|
1272
|
t.focusRingType = .default
|
|
|
1273
|
+ t.usesSingleLineMode = false
|
|
|
1274
|
+ if isWrapping, let cell = t.cell as? NSTextFieldCell {
|
|
|
1275
|
+ cell.wraps = true
|
|
|
1276
|
+ cell.isScrollable = false
|
|
|
1277
|
+ }
|
|
|
1278
|
+ t.setContentHuggingPriority(.defaultLow, for: .horizontal)
|
|
1231
|
1279
|
}
|
|
1232
|
1280
|
return t
|
|
1233
|
1281
|
}
|