Skip to content

Commit 4499fdd

Browse files
committed
Added Resizing
1 parent 14d0b7f commit 4499fdd

File tree

1 file changed

+89
-54
lines changed

1 file changed

+89
-54
lines changed

CodeEdit/Features/Editor/Views/EditorAreaFileView.swift

Lines changed: 89 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct HTMLRenderer {
5353
}
5454
}
5555

56-
// MARK: - WebKit Crash-Aware Delegate
56+
// MARK: - WebKit Crash Delegate
5757
final class PreviewNavDelegate: NSObject, WKNavigationDelegate {
5858
var onCrash: (() -> Void)?
5959

@@ -73,7 +73,7 @@ final class PreviewNavDelegate: NSObject, WKNavigationDelegate {
7373
}
7474
}
7575

76-
// MARK: - WebView (Coordinator reuse, safe refresh)
76+
// MARK: - WebView
7777
struct WebView: NSViewRepresentable {
7878
let html: String
7979
let baseURL: URL?
@@ -347,9 +347,13 @@ struct EditorAreaFileView: View {
347347
@State private var watcher = DirectoryWatcher()
348348
@State private var lastKnownFileMTime: Date?
349349

350-
// Fixed size constants
351-
private let FIXED_PREVIEW_HEIGHT: CGFloat = 320
352-
private let FIXED_PREVIEW_WIDTH: CGFloat = 420
350+
// Width-resize state
351+
@State private var previewWidth: CGFloat = 420 // default width for split mode
352+
@State private var dragStartPreviewWidth: CGFloat?
353+
354+
// Min/max constraints for width-only resizing
355+
private let MIN_PREVIEW_WIDTH: CGFloat = 200
356+
private let MAX_PREVIEW_WIDTH: CGFloat = 1400
353357

354358
private func bindContent() {
355359
NotificationCenter.default.publisher(
@@ -501,6 +505,26 @@ struct EditorAreaFileView: View {
501505

502506
Divider()
503507

508+
// thin draggable vertical divider between code and preview (width-resize)
509+
let verticalDivider: some View = Rectangle()
510+
.fill(Color(NSColor.separatorColor))
511+
.frame(width: 2)
512+
// give a larger transparent hit area so it is easy to grab
513+
.padding(.horizontal, 6)
514+
.contentShape(Rectangle())
515+
.gesture(DragGesture(minimumDistance: 1).onChanged { value in
516+
if dragStartPreviewWidth == nil { dragStartPreviewWidth = previewWidth }
517+
let start = dragStartPreviewWidth ?? previewWidth
518+
let delta = value.location.x - value.startLocation.x
519+
let newW = start - delta
520+
previewWidth = max(MIN_PREVIEW_WIDTH, min(MAX_PREVIEW_WIDTH, newW))
521+
}.onEnded { _ in
522+
dragStartPreviewWidth = nil
523+
})
524+
.onHover { hovering in
525+
if hovering { NSCursor.resizeLeftRight.push() } else { NSCursor.pop() }
526+
}
527+
504528
if isHTML {
505529
switch displayMode {
506530
case .code:
@@ -519,7 +543,9 @@ struct EditorAreaFileView: View {
519543
allowJavaScript: webViewAllowJS
520544
)
521545
.id(webViewRefreshToken)
522-
.frame(maxWidth: .infinity, minHeight: FIXED_PREVIEW_HEIGHT, maxHeight: FIXED_PREVIEW_HEIGHT)
546+
.frame(maxWidth: .infinity, minHeight: 320, maxHeight: .infinity)
547+
// ensure top safe area isn't covered — add top padding to push web content down
548+
.padding(.top, edgeInsets.top)
523549
.background(Color.white)
524550

525551
VStack(spacing: 0) {
@@ -579,7 +605,7 @@ struct EditorAreaFileView: View {
579605

580606
case .split:
581607
HStack(spacing: 0) {
582-
// Wrap code view so we can show the "show preview" button when preview is hidden
608+
// Code area
583609
ZStack {
584610
CodeFileView(editorInstance: editorInstance, codeFile: codeFile)
585611

@@ -606,53 +632,57 @@ struct EditorAreaFileView: View {
606632
.frame(minWidth: 200)
607633

608634
if showPreviewPane {
609-
VStack(spacing: 0) {
610-
ZStack {
611-
WebView(
612-
html: renderedHTMLState.isEmpty
613-
? "<!doctype html><html><body style='background:#fff'><h1>Preview Ready</h1></body></html>"
614-
: renderedHTMLState,
615-
baseURL: codeFile.fileURL?.deletingLastPathComponent(),
616-
onCrash: { /* WebKit always on */ },
617-
allowJavaScript: webViewAllowJS
618-
)
619-
.id(webViewRefreshToken)
620-
.frame(maxWidth: .infinity, minHeight: FIXED_PREVIEW_HEIGHT, maxHeight: FIXED_PREVIEW_HEIGHT)
621-
.background(Color.white)
635+
// divider placed between code and preview (gesture here)
636+
verticalDivider
637+
.zIndex(5)
622638

623-
VStack(spacing: 0) {
624-
Spacer()
625-
PreviewBottomBar(
626-
refresh: { refreshPreview() },
627-
reloadIgnoreCache: { webViewRefreshToken = UUID() },
628-
enableJS: $webViewAllowJS,
629-
previewSource: $previewSource,
630-
serverErrorMessage: serverErrorMessage
631-
)
632-
}
639+
// Preview container constrained to adjustable width
640+
ZStack {
641+
WebView(
642+
html: renderedHTMLState.isEmpty
643+
? "<!doctype html><html><body style='background:#fff'><h1>Preview Ready</h1></body></html>"
644+
: renderedHTMLState,
645+
baseURL: codeFile.fileURL?.deletingLastPathComponent(),
646+
onCrash: { /* WebKit always on */ },
647+
allowJavaScript: webViewAllowJS
648+
)
649+
.id(webViewRefreshToken)
650+
.frame(maxWidth: .infinity, minHeight: 320, maxHeight: .infinity)
651+
// push content below top chrome so h1 isn't cut off
652+
.padding(.top, edgeInsets.top)
653+
.background(Color.white)
633654

634-
// drag / divider area (kept minimal here, you can replace with more advanced drag logic)
655+
VStack(spacing: 0) {
656+
Spacer()
657+
PreviewBottomBar(
658+
refresh: { refreshPreview() },
659+
reloadIgnoreCache: { webViewRefreshToken = UUID() },
660+
enableJS: $webViewAllowJS,
661+
previewSource: $previewSource,
662+
serverErrorMessage: serverErrorMessage
663+
)
635664
}
636-
.overlay(alignment: .topTrailing) {
637-
Button {
638-
withAnimation(.easeInOut(duration: 0.18)) {
639-
showPreviewPane = false
640-
}
641-
} label: {
642-
Image(systemName: "eye.slash")
643-
.font(.system(size: 14, weight: .medium))
644-
.padding(6)
645-
.background(Color.black.opacity(0.12))
646-
.clipShape(Circle())
665+
}
666+
.overlay(alignment: .topTrailing) {
667+
Button {
668+
withAnimation(.easeInOut(duration: 0.18)) {
669+
showPreviewPane = false
647670
}
648-
.buttonStyle(.plain)
649-
.help("Hide Preview")
650-
.padding(.top, edgeInsets.top + 8)
651-
.padding(.trailing, 8)
652-
.zIndex(10)
671+
} label: {
672+
Image(systemName: "eye.slash")
673+
.font(.system(size: 14, weight: .medium))
674+
.padding(6)
675+
.background(Color.black.opacity(0.12))
676+
.clipShape(Circle())
653677
}
678+
.buttonStyle(.plain)
679+
.help("Hide Preview")
680+
.padding(.top, edgeInsets.top + 8)
681+
.padding(.trailing, 8)
682+
.zIndex(10)
654683
}
655-
.frame(width: FIXED_PREVIEW_WIDTH)
684+
// Constrain preview to the adjustable width
685+
.frame(width: previewWidth)
656686
.frame(maxHeight: .infinity)
657687
.background(Color.white)
658688
}
@@ -668,7 +698,8 @@ struct EditorAreaFileView: View {
668698
VStack(spacing: 0) {
669699
ZStack {
670700
MarkdownView(source: contentString)
671-
.frame(maxWidth: .infinity, minHeight: FIXED_PREVIEW_HEIGHT, maxHeight: FIXED_PREVIEW_HEIGHT)
701+
.frame(maxWidth: .infinity, minHeight: 320, maxHeight: .infinity)
702+
.padding(.top, edgeInsets.top)
672703
.background(Color.white)
673704

674705
VStack(spacing: 0) {
@@ -727,7 +758,7 @@ struct EditorAreaFileView: View {
727758

728759
case .split:
729760
HStack(spacing: 0) {
730-
// Wrap code view so we can show the "show preview" button when preview is hidden
761+
// Code area
731762
ZStack {
732763
CodeFileView(editorInstance: editorInstance, codeFile: codeFile)
733764

@@ -753,10 +784,14 @@ struct EditorAreaFileView: View {
753784
.frame(minWidth: 200)
754785

755786
if showPreviewPane {
787+
verticalDivider
788+
.zIndex(5)
789+
756790
VStack(spacing: 0) {
757791
ZStack {
758792
MarkdownView(source: contentString)
759-
.frame(maxWidth: .infinity, minHeight: FIXED_PREVIEW_HEIGHT, maxHeight: FIXED_PREVIEW_HEIGHT)
793+
.frame(maxWidth: .infinity, minHeight: 320, maxHeight: .infinity)
794+
.padding(.top, edgeInsets.top)
760795
.background(Color.white)
761796

762797
VStack(spacing: 0) {
@@ -789,9 +824,9 @@ struct EditorAreaFileView: View {
789824
.zIndex(10)
790825
}
791826
}
792-
.frame(minWidth: FIXED_PREVIEW_WIDTH,
793-
idealWidth: FIXED_PREVIEW_WIDTH,
794-
maxWidth: FIXED_PREVIEW_WIDTH,
827+
.frame(minWidth: previewWidth,
828+
idealWidth: previewWidth,
829+
maxWidth: previewWidth,
795830
maxHeight: .infinity, alignment: .center)
796831
.background(Color.white)
797832
}

0 commit comments

Comments
 (0)