Skip to content

Commit 34f606d

Browse files
committed
Insets are updating on mode change, still a WIP.
1 parent 8d9dbd1 commit 34f606d

10 files changed

+121
-48
lines changed

Sources/CodeEditSourceEditor/Controller/TextViewController+FindPanelTarget.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ extension TextViewController: FindPanelTarget {
1919
gutterView.frame.origin.y = -scrollView.contentInsets.top
2020
}
2121

22+
func findPanelModeDidChange(to mode: FindPanelMode, panelHeight: CGFloat) {
23+
scrollView.contentInsets.top += mode == .replace ? panelHeight/2 : -panelHeight
24+
gutterView.frame.origin.y = -scrollView.contentInsets.top
25+
}
26+
2227
var emphasisManager: EmphasisManager? {
2328
textView?.emphasisManager
2429
}

Sources/CodeEditSourceEditor/Controller/TextViewController+StyleViews.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ extension TextViewController {
7878
scrollView.contentInsets.top += additionalTextInsets?.top ?? 0
7979
scrollView.contentInsets.bottom += additionalTextInsets?.bottom ?? 0
8080

81-
scrollView.contentInsets.top += (findViewController?.isShowingFindPanel ?? false) ? FindPanel.height : 0
81+
scrollView.contentInsets.top += (findViewController?.isShowingFindPanel ?? false)
82+
? findViewController?.panelHeight ?? 0
83+
: 0
8284
}
8385
}

Sources/CodeEditSourceEditor/Find/FindPanelDelegate.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ protocol FindPanelDelegate: AnyObject {
1111
func findPanelOnSubmit()
1212
func findPanelOnDismiss()
1313
func findPanelDidUpdate(_ searchText: String)
14+
func findPanelDidUpdateMode(_ mode: FindPanelMode)
15+
func findPanelDidUpdateWrapAround(_ wrapAround: Bool)
16+
func findPanelDidUpdateMatchCase(_ matchCase: Bool)
17+
func findPanelDidUpdateReplaceText(_ text: String)
1418
func findPanelPrevButtonClicked()
1519
func findPanelNextButtonClicked()
1620
func findPanelUpdateMatchCount(_ count: Int)

Sources/CodeEditSourceEditor/Find/FindPanelTarget.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ protocol FindPanelTarget: AnyObject {
1818

1919
func findPanelWillShow(panelHeight: CGFloat)
2020
func findPanelWillHide(panelHeight: CGFloat)
21+
func findPanelModeDidChange(to mode: FindPanelMode, panelHeight: CGFloat)
2122
}

Sources/CodeEditSourceEditor/Find/FindViewController+FindPanelDelegate.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import AppKit
99
import CodeEditTextView
1010

1111
extension FindViewController: FindPanelDelegate {
12+
var findPanelMode: FindPanelMode { mode }
13+
var findPanelWrapAround: Bool { wrapAround }
14+
var findPanelMatchCase: Bool { matchCase }
15+
var findPanelReplaceText: String { replaceText }
16+
1217
func findPanelOnSubmit() {
1318
findPanelNextButtonClicked()
1419
}
@@ -61,6 +66,28 @@ extension FindViewController: FindPanelDelegate {
6166
find(text: text)
6267
}
6368

69+
func findPanelDidUpdateMode(_ mode: FindPanelMode) {
70+
self.mode = mode
71+
if isShowingFindPanel {
72+
target?.findPanelModeDidChange(to: mode, panelHeight: panelHeight)
73+
}
74+
}
75+
76+
func findPanelDidUpdateWrapAround(_ wrapAround: Bool) {
77+
self.wrapAround = wrapAround
78+
}
79+
80+
func findPanelDidUpdateMatchCase(_ matchCase: Bool) {
81+
self.matchCase = matchCase
82+
if !findText.isEmpty {
83+
performFind()
84+
}
85+
}
86+
87+
func findPanelDidUpdateReplaceText(_ text: String) {
88+
self.replaceText = text
89+
}
90+
6491
func findPanelPrevButtonClicked() {
6592
guard let textViewController = target as? TextViewController,
6693
let emphasisManager = target?.emphasisManager else { return }

Sources/CodeEditSourceEditor/Find/FindViewController+Toggle.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,24 @@ extension FindViewController {
2222
return
2323
}
2424

25+
if mode == .replace {
26+
mode = .find
27+
findPanel.updateMode(mode)
28+
}
29+
2530
isShowingFindPanel = true
2631

2732
// Smooth out the animation by placing the find panel just outside the correct position before animating.
2833
findPanel.isHidden = false
29-
findPanelVerticalConstraint.constant = resolvedTopPadding - FindPanel.height
34+
findPanelVerticalConstraint.constant = resolvedTopPadding - panelHeight
35+
3036
view.layoutSubtreeIfNeeded()
3137

3238
// Perform the animation
3339
conditionalAnimated(animated) {
3440
// SwiftUI breaks things here, and refuses to return the correct `findPanel.fittingSize` so we
3541
// are forced to use a constant number.
36-
target?.findPanelWillShow(panelHeight: FindPanel.height)
42+
target?.findPanelWillShow(panelHeight: panelHeight)
3743
setFindPanelConstraintShow()
3844
} onComplete: { }
3945

@@ -54,7 +60,7 @@ extension FindViewController {
5460
findPanel?.removeEventMonitor()
5561

5662
conditionalAnimated(animated) {
57-
target?.findPanelWillHide(panelHeight: FindPanel.height)
63+
target?.findPanelWillHide(panelHeight: panelHeight)
5864
setFindPanelConstraintHide()
5965
} onComplete: { [weak self] in
6066
self?.findPanel.isHidden = true
@@ -113,7 +119,7 @@ extension FindViewController {
113119
// SwiftUI hates us. It refuses to move views outside of the safe are if they don't have the `.ignoresSafeArea`
114120
// modifier, but with that modifier on it refuses to allow it to be animated outside the safe area.
115121
// The only way I found to fix it was to multiply the height by 3 here.
116-
findPanelVerticalConstraint.constant = resolvedTopPadding - (FindPanel.height * 3)
122+
findPanelVerticalConstraint.constant = resolvedTopPadding - (panelHeight * 3)
117123
findPanelVerticalConstraint.isActive = true
118124
}
119125
}

Sources/CodeEditSourceEditor/Find/FindViewController.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,13 @@ final class FindViewController: NSViewController {
2626
var findPanel: FindPanel!
2727
var findMatches: [NSRange] = []
2828

29+
// TODO: we might make this nil if no current match so we can disable the match button in the find panel
2930
var currentFindMatchIndex: Int = 0
3031
var findText: String = ""
32+
var replaceText: String = ""
33+
var matchCase: Bool = false
34+
var wrapAround: Bool = true
35+
var mode: FindPanelMode = .find
3136
var findPanelVerticalConstraint: NSLayoutConstraint!
3237

3338
var isShowingFindPanel: Bool = false
@@ -38,6 +43,11 @@ final class FindViewController: NSViewController {
3843
(topPadding ?? view.safeAreaInsets.top)
3944
}
4045

46+
/// The height of the find panel.
47+
var panelHeight: CGFloat {
48+
return self.mode == .replace ? 56 : 28
49+
}
50+
4151
init(target: FindPanelTarget, childView: NSView) {
4252
self.target = target
4353
self.childView = childView

Sources/CodeEditSourceEditor/Find/PanelView/FindPanel.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@ import Combine
1111

1212
// NSView wrapper for using SwiftUI view in AppKit
1313
final class FindPanel: NSView {
14-
/// The height of the find panel.
15-
static var height: CGFloat {
16-
if let findPanel = NSApp.windows.first(where: { $0.contentView is FindPanel })?.contentView as? FindPanel {
17-
return findPanel.viewModel.mode == .replace ? 56 : 28
18-
}
19-
return 28
20-
}
21-
2214
weak var findDelegate: FindPanelDelegate?
2315
private var hostingView: NSHostingView<FindPanelView>!
2416
private var viewModel: FindPanelViewModel!
@@ -118,6 +110,10 @@ final class FindPanel: NSView {
118110
viewModel.updateMatchCount(count)
119111
}
120112

113+
func updateMode(_ mode: FindPanelMode) {
114+
viewModel.mode = mode
115+
}
116+
121117
// MARK: - Search Text Management
122118

123119
func updateSearchText(_ text: String) {

Sources/CodeEditSourceEditor/Find/PanelView/FindPanelView.swift

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,6 @@ struct FindPanelView: View {
6161
)
6262
.controlSize(.small)
6363
.focused($isFocused)
64-
.onChange(of: viewModel.findText) { newValue in
65-
viewModel.onFindTextChange(newValue)
66-
}
67-
.onChange(of: viewModel.isFocused) { newValue in
68-
isFocused = newValue
69-
if !newValue {
70-
viewModel.removeEmphasis()
71-
}
72-
}
7364
.onChange(of: isFocused) { newValue in
7465
viewModel.setFocus(newValue)
7566
}
@@ -126,43 +117,31 @@ struct FindPanelView: View {
126117
.frame(width: viewModel.findModePickerWidth, alignment: .leading)
127118
Divider()
128119
},
129-
helperText: viewModel.findText.isEmpty
130-
? nil
131-
: "\(viewModel.matchCount) \(viewModel.matchCount == 1 ? "match" : "matches")",
132120
clearable: true
133121
)
134122
.controlSize(.small)
135-
.onChange(of: viewModel.findText) { newValue in
136-
viewModel.onFindTextChange(newValue)
137-
}
138-
.onChange(of: viewModel.isFocused) { newValue in
139-
isFocused = newValue
140-
if !newValue {
141-
viewModel.removeEmphasis()
142-
}
143-
}
144-
.onChange(of: isFocused) { newValue in
145-
viewModel.setFocus(newValue)
146-
}
147-
.onSubmit {
148-
viewModel.onSubmit()
149-
}
123+
// TODO: Handle replace text field focus and submit
150124
HStack(spacing: 4) {
151125
ControlGroup {
152-
Button(action: viewModel.prevButtonClicked) {
126+
Button(action: {
127+
// TODO: Replace action
128+
}) {
153129
Text("Replace")
154-
.opacity(viewModel.matchCount == 0 ? 0.33 : 1)
130+
.opacity(viewModel.findText.isEmpty || viewModel.matchCount == 0 ? 0.33 : 1)
155131
.frame(width: viewModel.findControlsWidth/2 - 12 - 0.5)
156132
}
157-
.disabled(viewModel.matchCount == 0)
133+
// TODO: disable if there is not an active match
134+
.disabled(viewModel.findText.isEmpty || viewModel.matchCount == 0)
158135
Divider()
159136
.overlay(Color(nsColor: .tertiaryLabelColor))
160-
Button(action: viewModel.nextButtonClicked) {
137+
Button(action: {
138+
// TODO: Replace all action
139+
}) {
161140
Text("All")
162-
.opacity(viewModel.matchCount == 0 ? 0.33 : 1)
141+
.opacity(viewModel.findText.isEmpty || viewModel.matchCount == 0 ? 0.33 : 1)
163142
.frame(width: viewModel.findControlsWidth/2 - 12 - 0.5)
164143
}
165-
.disabled(viewModel.matchCount == 0)
144+
.disabled(viewModel.findText.isEmpty || viewModel.matchCount == 0)
166145
}
167146
.controlGroupStyle(PanelControlGroupStyle())
168147
.fixedSize()
@@ -171,8 +150,30 @@ struct FindPanelView: View {
171150
.padding(.horizontal, 5)
172151
}
173152
}
174-
.frame(height: viewModel.mode == .replace ? FindPanel.height * 2 : FindPanel.height)
153+
.frame(height: viewModel.panelHeight)
175154
.background(.bar)
155+
.onChange(of: viewModel.findText) { newValue in
156+
viewModel.onFindTextChange(newValue)
157+
}
158+
.onChange(of: viewModel.replaceText) { newValue in
159+
viewModel.onReplaceTextChange(newValue)
160+
}
161+
.onChange(of: viewModel.mode) { newMode in
162+
viewModel.onModeChange(newMode)
163+
}
164+
.onChange(of: viewModel.wrapAround) { newValue in
165+
viewModel.onWrapAroundChange(newValue)
166+
}
167+
.onChange(of: viewModel.matchCase) { newValue in
168+
viewModel.onMatchCaseChange(newValue)
169+
}
170+
.onChange(of: viewModel.isFocused) { newValue in
171+
isFocused = newValue
172+
if !newValue {
173+
viewModel.removeEmphasis()
174+
}
175+
}
176+
176177
}
177178
}
178179

Sources/CodeEditSourceEditor/Find/PanelView/FindPanelViewModel.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ class FindPanelViewModel: ObservableObject {
2626
@Published var findText: String = ""
2727
@Published var replaceText: String = ""
2828
@Published var mode: FindPanelMode = .find
29-
@Published var wrapAround: Bool = false
29+
@Published var wrapAround: Bool = true
3030
@Published var matchCount: Int = 0
3131
@Published var isFocused: Bool = false
3232
@Published var findModePickerWidth: CGFloat = 0
3333
@Published var findControlsWidth: CGFloat = 0
3434
@Published var matchCase: Bool = false
3535

36+
var panelHeight: CGFloat {
37+
return mode == .replace ? 56 : 28
38+
}
39+
3640
private weak var delegate: FindPanelDelegate?
3741

3842
init(delegate: FindPanelDelegate?) {
@@ -49,6 +53,22 @@ class FindPanelViewModel: ObservableObject {
4953
delegate?.findPanelDidUpdate(text)
5054
}
5155

56+
func onReplaceTextChange(_ text: String) {
57+
delegate?.findPanelDidUpdateReplaceText(text)
58+
}
59+
60+
func onModeChange(_ mode: FindPanelMode) {
61+
delegate?.findPanelDidUpdateMode(mode)
62+
}
63+
64+
func onWrapAroundChange(_ wrapAround: Bool) {
65+
delegate?.findPanelDidUpdateWrapAround(wrapAround)
66+
}
67+
68+
func onMatchCaseChange(_ matchCase: Bool) {
69+
delegate?.findPanelDidUpdateMatchCase(matchCase)
70+
}
71+
5272
func onSubmit() {
5373
delegate?.findPanelOnSubmit()
5474
}
@@ -83,5 +103,6 @@ class FindPanelViewModel: ObservableObject {
83103

84104
func toggleWrapAround() {
85105
wrapAround.toggle()
106+
delegate?.findPanelDidUpdateWrapAround(wrapAround)
86107
}
87108
}

0 commit comments

Comments
 (0)