Skip to content

Commit

Permalink
Added a wrapper for a SwiftUI View.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Eades committed Aug 14, 2020
1 parent 9cdd591 commit 1802336
Showing 1 changed file with 117 additions and 0 deletions.
117 changes: 117 additions & 0 deletions Sources/Sourceful/SwiftUI/SourceCodeTextEditor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//
// SourceCodeTextEditor.swift
//
// Created by Andrew Eades on 14/08/2020.
//

import Foundation
import Sourceful
import SwiftUI

#if os(macOS)
public typealias _ViewRepresentable = NSViewRepresentable
#endif

#if os(iOS)
public typealias _ViewRepresentable = UIViewRepresentable
#endif


public struct SourceCodeTextEditor: _ViewRepresentable {

public struct Customization {
var didChangeText: (SourceCodeTextEditor) -> Void
var insertionPointColor: () -> Sourceful.Color
var lexerForSource: (String) -> Lexer
var textViewDidBeginEditing: (SourceCodeTextEditor) -> Void
var theme: () -> SourceCodeTheme

/// Creates a **Customization** to pass into the *init()* of a **SourceCodeTextEditor**.
///
/// - Parameters:
/// - didChangeText: A SyntaxTextView delegate action.
/// - lexerForSource: The lexer to use (default: SwiftLexer()).
/// - insertionPointColor: To customize color of insertion point caret (default: .white).
/// - textViewDidBeginEditing: A SyntaxTextView delegate action.
/// - theme: Custom theme (default: DefaultSourceCodeTheme()).
public init(
didChangeText: @escaping (SourceCodeTextEditor) -> Void,
insertionPointColor: @escaping () -> Sourceful.Color,
lexerForSource: @escaping (String) -> Lexer,
textViewDidBeginEditing: @escaping (SourceCodeTextEditor) -> Void,
theme: @escaping () -> SourceCodeTheme
) {
self.didChangeText = didChangeText
self.insertionPointColor = insertionPointColor
self.lexerForSource = lexerForSource
self.textViewDidBeginEditing = textViewDidBeginEditing
self.theme = theme
}
}

@Binding private var text: String

private var custom: Customization

public init(
text: Binding<String>,
cusotmization: Customization = Customization(
didChangeText: {_ in },
insertionPointColor: { Sourceful.Color.white },
lexerForSource: { _ in SwiftLexer() },
textViewDidBeginEditing: { _ in },
theme: { DefaultSourceCodeTheme() }
)
) {
self._text = text
self.custom = cusotmization
}

public func makeCoordinator() -> Coordinator {
Coordinator(self)
}

public func makeNSView(context: Context) -> SyntaxTextView {
let wrappedView = SyntaxTextView()
wrappedView.delegate = context.coordinator
wrappedView.theme = custom.theme()
wrappedView.contentTextView.insertionPointColor = custom.insertionPointColor()

context.coordinator.wrappedView = wrappedView
context.coordinator.wrappedView.text = text

return wrappedView
}

public func updateNSView(_ view: SyntaxTextView, context: Context) {
}
}

extension SourceCodeTextEditor {

public class Coordinator: SyntaxTextViewDelegate {
let parent: SourceCodeTextEditor
var wrappedView: SyntaxTextView!

init(_ parent: SourceCodeTextEditor) {
self.parent = parent
}

public func lexerForSource(_ source: String) -> Lexer {
parent.custom.lexerForSource(source)
}

public func didChangeText(_ syntaxTextView: SyntaxTextView) {
DispatchQueue.main.async {
self.parent.text = syntaxTextView.text
}

// allow the client to decide on thread
parent.custom.didChangeText(parent)
}

public func textViewDidBeginEditing(_ syntaxTextView: SyntaxTextView) {
parent.custom.textViewDidBeginEditing(parent)
}
}
}

0 comments on commit 1802336

Please sign in to comment.