Skip to content

Commit ef9e244

Browse files
committed
Finish Refactor
1 parent a78905e commit ef9e244

File tree

17 files changed

+248
-232
lines changed

17 files changed

+248
-232
lines changed

Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/CodeEditSourceEditor/Controller/TextViewController+FindPanelTarget.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ extension TextViewController: FindPanelTarget {
2121
updateContentInsets()
2222
}
2323

24-
func findPanelModeDidChange(to mode: FindPanelMode, panelHeight: CGFloat) {
25-
scrollView.contentInsets.top += mode == .replace ? panelHeight : -(panelHeight/2)
26-
gutterView.frame.origin.y = -scrollView.contentInsets.top
24+
func findPanelModeDidChange(to mode: FindPanelMode) {
25+
updateContentInsets()
2726
}
2827

2928
var emphasisManager: EmphasisManager? {

Sources/CodeEditSourceEditor/Controller/TextViewController+StyleViews.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ extension TextViewController {
9696
minimapView.scrollView.contentInsets.bottom += additionalTextInsets?.bottom ?? 0
9797

9898
// Inset the top by the find panel height
99-
let findInset = (findViewController?.isShowingFindPanel ?? false) ? FindPanel.height : 0
99+
let findInset: CGFloat = if findViewController?.viewModel.isShowingFindPanel ?? false {
100+
findViewController?.viewModel.panelHeight ?? 0
101+
} else {
102+
0
103+
}
100104
scrollView.contentInsets.top += findInset
101105
minimapView.scrollView.contentInsets.top += findInset
102106

Sources/CodeEditSourceEditor/Find/PanelView/FindPanelMode.swift renamed to Sources/CodeEditSourceEditor/Find/FindPanelMode.swift

File renamed without changes.

Sources/CodeEditSourceEditor/Find/FindPanelTarget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ protocol FindPanelTarget: AnyObject {
1919

2020
func findPanelWillShow(panelHeight: CGFloat)
2121
func findPanelWillHide(panelHeight: CGFloat)
22-
func findPanelModeDidChange(to mode: FindPanelMode, panelHeight: CGFloat)
22+
func findPanelModeDidChange(to mode: FindPanelMode)
2323
}

Sources/CodeEditSourceEditor/Find/FindViewController+Toggle.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extension FindViewController {
1818
func showFindPanel(animated: Bool = true) {
1919
if viewModel.isShowingFindPanel {
2020
// If panel is already showing, just focus the text field
21-
_ = findPanel.becomeFirstResponder()
21+
viewModel.isFocused = true
2222
return
2323
}
2424

@@ -30,15 +30,15 @@ extension FindViewController {
3030

3131
// Smooth out the animation by placing the find panel just outside the correct position before animating.
3232
findPanel.isHidden = false
33-
findPanelVerticalConstraint.constant = resolvedTopPadding - panelHeight
33+
findPanelVerticalConstraint.constant = resolvedTopPadding - viewModel.panelHeight
3434

3535
view.layoutSubtreeIfNeeded()
3636

3737
// Perform the animation
3838
conditionalAnimated(animated) {
3939
// SwiftUI breaks things here, and refuses to return the correct `findPanel.fittingSize` so we
4040
// are forced to use a constant number.
41-
viewModel.target?.findPanelWillShow(panelHeight: panelHeight)
41+
viewModel.target?.findPanelWillShow(panelHeight: viewModel.panelHeight)
4242
setFindPanelConstraintShow()
4343
} onComplete: { }
4444

@@ -59,7 +59,7 @@ extension FindViewController {
5959
findPanel.removeEventMonitor()
6060

6161
conditionalAnimated(animated) {
62-
viewModel.target?.findPanelWillHide(panelHeight: panelHeight)
62+
viewModel.target?.findPanelWillHide(panelHeight: viewModel.panelHeight)
6363
setFindPanelConstraintHide()
6464
} onComplete: { [weak self] in
6565
self?.findPanel.isHidden = true
@@ -119,7 +119,7 @@ extension FindViewController {
119119
// SwiftUI hates us. It refuses to move views outside of the safe are if they don't have the `.ignoresSafeArea`
120120
// modifier, but with that modifier on it refuses to allow it to be animated outside the safe area.
121121
// The only way I found to fix it was to multiply the height by 3 here.
122-
findPanelVerticalConstraint.constant = resolvedTopPadding - (panelHeight * 3)
122+
findPanelVerticalConstraint.constant = resolvedTopPadding - (viewModel.panelHeight * 3)
123123
findPanelVerticalConstraint.isActive = true
124124
}
125125
}

Sources/CodeEditSourceEditor/Find/FindViewController.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ final class FindViewController: NSViewController {
2323
}
2424

2525
var childView: NSView
26-
var findPanel: FindPanel
26+
var findPanel: FindPanelHostingView
2727
var findPanelVerticalConstraint: NSLayoutConstraint!
2828

2929
/// The 'real' top padding amount.
@@ -32,16 +32,10 @@ final class FindViewController: NSViewController {
3232
(topPadding ?? view.safeAreaInsets.top)
3333
}
3434

35-
/// The height of the find panel.
36-
var panelHeight: CGFloat {
37-
print(findPanel.intrinsicContentSize.height)
38-
return viewModel.mode == .replace ? 56 : 28
39-
}
40-
4135
init(target: FindPanelTarget, childView: NSView) {
4236
viewModel = FindPanelViewModel(target: target)
4337
self.childView = childView
44-
findPanel = FindPanel(viewModel: viewModel)
38+
findPanel = FindPanelHostingView(viewModel: viewModel)
4539
super.init(nibName: nil, bundle: nil)
4640
viewModel.dismiss = { [weak self] in
4741
self?.hideFindPanel()

Sources/CodeEditSourceEditor/Find/PanelView/FindBarView.swift

Lines changed: 0 additions & 106 deletions
This file was deleted.

Sources/CodeEditSourceEditor/Find/PanelView/FindPanel.swift renamed to Sources/CodeEditSourceEditor/Find/PanelView/FindPanelHostingView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// FindPanel.swift
2+
// FindPanelHostingView.swift
33
// CodeEditSourceEditor
44
//
55
// Created by Khan Winter on 3/10/25.
@@ -10,7 +10,7 @@ import AppKit
1010
import Combine
1111

1212
// NSView wrapper for using SwiftUI view in AppKit
13-
final class FindPanel: NSHostingView<FindPanelView> {
13+
final class FindPanelHostingView: NSHostingView<FindPanelView> {
1414
private weak var viewModel: FindPanelViewModel?
1515

1616
private var eventMonitor: Any?

Sources/CodeEditSourceEditor/Find/PanelView/FindPanelView.swift

Lines changed: 92 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,23 @@ struct FindPanelView: View {
2222
@FocusState private var focus: FindPanelFocus?
2323

2424
var body: some View {
25-
VStack(alignment: .leading, spacing: 5) {
26-
FindBarView(viewModel: viewModel, focus: $focus, findModePickerWidth: $findModePickerWidth)
27-
if viewModel.mode == .replace {
28-
ReplaceBarView(viewModel: viewModel, focus: $focus, findModePickerWidth: $findModePickerWidth)
25+
HStack(spacing: 5) {
26+
VStack(alignment: .leading, spacing: 4) {
27+
FindSearchField(viewModel: viewModel, focus: $focus, findModePickerWidth: $findModePickerWidth)
28+
if viewModel.mode == .replace {
29+
ReplaceSearchField(viewModel: viewModel, focus: $focus, findModePickerWidth: $findModePickerWidth)
30+
}
31+
}
32+
VStack(alignment: .leading, spacing: 4) {
33+
doneNextControls
34+
if viewModel.mode == .replace {
35+
Spacer(minLength: 0)
36+
replaceControls
37+
}
2938
}
39+
.fixedSize()
3040
}
41+
.padding(.horizontal, 5)
3142
.frame(height: viewModel.panelHeight)
3243
.background(.bar)
3344
.onChange(of: focus) { newValue in
@@ -36,15 +47,12 @@ struct FindPanelView: View {
3647
.onChange(of: viewModel.findText) { _ in
3748
viewModel.findTextDidChange()
3849
}
39-
// .onChange(of: viewModel.mode) { newMode in
40-
//
41-
// }
42-
// .onChange(of: viewModel.wrapAround) { newValue in
43-
// viewModel.onWrapAroundChange(newValue)
44-
// }
45-
// .onChange(of: viewModel.matchCase) { newValue in
46-
// viewModel.onMatchCaseChange(newValue)
47-
// }
50+
.onChange(of: viewModel.wrapAround) { _ in
51+
viewModel.find()
52+
}
53+
.onChange(of: viewModel.matchCase) { _ in
54+
viewModel.find()
55+
}
4856
.onChange(of: viewModel.isFocused) { newValue in
4957
if newValue {
5058
if focus == nil {
@@ -59,6 +67,77 @@ struct FindPanelView: View {
5967
}
6068
}
6169
}
70+
71+
@ViewBuilder private var doneNextControls: some View {
72+
HStack(spacing: 4) {
73+
ControlGroup {
74+
Button {
75+
viewModel.moveToPreviousMatch()
76+
} label: {
77+
Image(systemName: "chevron.left")
78+
.opacity(viewModel.matchCount == 0 ? 0.33 : 1)
79+
.padding(.horizontal, 5)
80+
}
81+
.disabled(viewModel.matchCount == 0)
82+
Divider()
83+
.overlay(Color(nsColor: .tertiaryLabelColor))
84+
Button {
85+
viewModel.moveToNextMatch()
86+
} label: {
87+
Image(systemName: "chevron.right")
88+
.opacity(viewModel.matchCount == 0 ? 0.33 : 1)
89+
.padding(.horizontal, 5)
90+
}
91+
.disabled(viewModel.matchCount == 0)
92+
}
93+
.controlGroupStyle(PanelControlGroupStyle())
94+
.fixedSize()
95+
Button {
96+
viewModel.dismiss?()
97+
} label: {
98+
Text("Done")
99+
.padding(.horizontal, 5)
100+
}
101+
.buttonStyle(PanelButtonStyle())
102+
}
103+
}
104+
105+
@ViewBuilder private var replaceControls: some View {
106+
HStack(spacing: 4) {
107+
ControlGroup {
108+
Button {
109+
viewModel.replace(all: false)
110+
} label: {
111+
Text("Replace")
112+
.opacity(
113+
!viewModel.isFocused
114+
|| viewModel.findText.isEmpty
115+
|| viewModel.matchCount == 0 ? 0.33 : 1
116+
)
117+
}
118+
// TODO: disable if there is not an active match
119+
.disabled(
120+
!viewModel.isFocused
121+
|| viewModel.findText.isEmpty
122+
|| viewModel.matchCount == 0
123+
)
124+
.frame(maxWidth: .infinity)
125+
126+
Divider().overlay(Color(nsColor: .tertiaryLabelColor))
127+
128+
Button {
129+
viewModel.replace(all: true)
130+
} label: {
131+
Text("All")
132+
.opacity(viewModel.findText.isEmpty || viewModel.matchCount == 0 ? 0.33 : 1)
133+
}
134+
.disabled(viewModel.findText.isEmpty || viewModel.matchCount == 0)
135+
.frame(maxWidth: .infinity)
136+
}
137+
.controlGroupStyle(PanelControlGroupStyle())
138+
}
139+
.fixedSize(horizontal: false, vertical: true)
140+
}
62141
}
63142

64143
private struct FindModePickerWidthPreferenceKey: PreferenceKey {

0 commit comments

Comments
 (0)