Skip to content

Commit

Permalink
Adds backgroundColor parameter to override theme’s default.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kinark committed Jul 2, 2024
1 parent f5c076b commit 0666597
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 161 deletions.
220 changes: 114 additions & 106 deletions Sources/CodeEditor/CodeEditor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -205,128 +205,136 @@ public struct CodeEditor: View {
* Configures a CodeEditor View with the given parameters.
*
* - Parameters:
* - source: A binding to a String that holds the source code to be
* edited (or displayed).
* - selection: A binding to the selected range of the `source`.
* - language: Optionally set a language (e.g. `.swift`), otherwise
* Highlight.js will attempt to detect the language.
* - theme: The name of the theme to use, defaults to "pojoaque".
* - fontSize: On macOS this Binding can be used to persist the size of
* the font in use. At runtime this is combined with the
* theme to produce the full font information. (optional)
* - flags: Configure whether the text is editable and/or selectable
* (defaults to both).
* - indentStyle: Optionally insert a configurable amount of spaces if the
* user hits "tab".
* - autoPairs: A mapping of open/close characters, where the close
* characters are automatically injected when the user enters
* the opening character. For example: `[ "{": "}" ]` would
* automatically insert the closing "}" if the user enters
* "{". If no value is given, the default mapping for the
* language is used.
* - inset: The editor can be inset in the scroll view. Defaults to
* 8/8.
* - autoscroll: If enabled, the editor automatically scrolls to the respective
* region when the `selection` is changed programatically.
* - source: A binding to a String that holds the source code to be
* edited (or displayed).
* - selection: A binding to the selected range of the `source`.
* - language: Optionally set a language (e.g. `.swift`), otherwise
* Highlight.js will attempt to detect the language.
* - theme: The name of the theme to use, defaults to "pojoaque".
* - fontSize: On macOS this Binding can be used to persist the size of
* the font in use. At runtime this is combined with the
* theme to produce the full font information. (optional)
* - flags: Configure whether the text is editable and/or selectable
* (defaults to both).
* - indentStyle: Optionally insert a configurable amount of spaces if the
* user hits "tab".
* - autoPairs: A mapping of open/close characters, where the close
* characters are automatically injected when the user enters
* the opening character. For example: `[ "{": "}" ]` would
* automatically insert the closing "}" if the user enters
* "{". If no value is given, the default mapping for the
* language is used.
* - inset: The editor can be inset in the scroll view. Defaults to
* 8/8.
* - autoscroll: If enabled, the editor automatically scrolls to the respective
* region when the `selection` is changed programatically.
* - backgroundColor: Overrides theme's background color.
*/
public init(source : Binding<String>,
selection : Binding<Range<String.Index>>? = nil,
language : Language? = nil,
theme : ThemeName = .default,
fontSize : Binding<CGFloat>? = nil,
flags : Flags = .defaultEditorFlags,
indentStyle : IndentStyle = .system,
autoPairs : [ String : String ]? = nil,
inset : CGSize? = nil,
allowsUndo : Bool = true,
autoscroll : Bool = true)
public init(source : Binding<String>,
selection : Binding<Range<String.Index>>? = nil,
language : Language? = nil,
theme : ThemeName = .default,
fontSize : Binding<CGFloat>? = nil,
flags : Flags = .defaultEditorFlags,
indentStyle : IndentStyle = .system,
autoPairs : [ String : String ]? = nil,
inset : CGSize? = nil,
allowsUndo : Bool = true,
autoscroll : Bool = true,
backgroundColor: NSColor? = nil)
{
self.source = source
self.selection = selection
self.fontSize = fontSize
self.language = language
self.themeName = theme
self.flags = flags
self.indentStyle = indentStyle
self.inset = inset ?? CGSize(width: 8, height: 8)
self.autoPairs = autoPairs
?? language.flatMap({ CodeEditor.defaultAutoPairs[$0] })
?? [:]
self.allowsUndo = allowsUndo
self.autoscroll = autoscroll
self.source = source
self.selection = selection
self.fontSize = fontSize
self.language = language
self.themeName = theme
self.flags = flags
self.indentStyle = indentStyle
self.inset = inset ?? CGSize(width: 8, height: 8)
self.autoPairs = autoPairs
?? language.flatMap({ CodeEditor.defaultAutoPairs[$0] })
?? [:]
self.allowsUndo = allowsUndo
self.autoscroll = autoscroll
self.backgroundColor = backgroundColor
}

/**
* Configures a read-only CodeEditor View with the given parameters.
*
* - Parameters:
* - source: A String that holds the source code to be displayed.
* - language: Optionally set a language (e.g. `.swift`), otherwise
* Highlight.js will attempt to detect the language.
* - theme: The name of the theme to use, defaults to "pojoaque".
* - fontSize: On macOS this Binding can be used to persist the size of
* the font in use. At runtime this is combined with the
* theme to produce the full font information. (optional)
* - flags: Configure whether the text is selectable
* (defaults to both).
* - indentStyle: Optionally insert a configurable amount of spaces if the
* user hits "tab".
* - autoPairs: A mapping of open/close characters, where the close
* characters are automatically injected when the user enters
* the opening character. For example: `[ "{": "}" ]` would
* automatically insert the closing "}" if the user enters
* "{". If no value is given, the default mapping for the
* language is used.
* - inset: The editor can be inset in the scroll view. Defaults to
* 8/8.
* - source: A String that holds the source code to be displayed.
* - language: Optionally set a language (e.g. `.swift`), otherwise
* Highlight.js will attempt to detect the language.
* - theme: The name of the theme to use, defaults to "pojoaque".
* - fontSize: On macOS this Binding can be used to persist the size of
* the font in use. At runtime this is combined with the
* theme to produce the full font information. (optional)
* - flags: Configure whether the text is selectable
* (defaults to both).
* - indentStyle: Optionally insert a configurable amount of spaces if the
* user hits "tab".
* - autoPairs: A mapping of open/close characters, where the close
* characters are automatically injected when the user enters
* the opening character. For example: `[ "{": "}" ]` would
* automatically insert the closing "}" if the user enters
* "{". If no value is given, the default mapping for the
* language is used.
* - inset: The editor can be inset in the scroll view. Defaults to
* 8/8.
* - backgroundColor: Overrides theme's background color.
*/
@inlinable
public init(source : String,
language : Language? = nil,
theme : ThemeName = .default,
fontSize : Binding<CGFloat>? = nil,
flags : Flags = .defaultViewerFlags,
indentStyle : IndentStyle = .system,
autoPairs : [ String : String ]? = nil,
inset : CGSize? = nil,
allowsUndo : Bool = true)
public init(source : String,
language : Language? = nil,
theme : ThemeName = .default,
fontSize : Binding<CGFloat>? = nil,
flags : Flags = .defaultViewerFlags,
indentStyle : IndentStyle = .system,
autoPairs : [ String : String ]? = nil,
inset : CGSize? = nil,
allowsUndo : Bool = true,
backgroundColor: NSColor? = nil)
{
assert(!flags.contains(.editable), "Editing requires a Binding")
self.init(source : .constant(source),
language : language,
theme : theme,
fontSize : fontSize,
flags : flags.subtracting(.editable),
indentStyle : indentStyle,
autoPairs : autoPairs,
inset : inset,
allowsUndo : allowsUndo)
self.init(source : .constant(source),
language : language,
theme : theme,
fontSize : fontSize,
flags : flags.subtracting(.editable),
indentStyle : indentStyle,
autoPairs : autoPairs,
inset : inset,
allowsUndo : allowsUndo,
backgroundColor: backgroundColor)
}

private var source : Binding<String>
private var selection : Binding<Range<String.Index>>?
private var fontSize : Binding<CGFloat>?
private let language : Language?
private let themeName : ThemeName
private let flags : Flags
private let indentStyle : IndentStyle
private let autoPairs : [ String : String ]
private let inset : CGSize
private let allowsUndo : Bool
private let autoscroll : Bool
private var source : Binding<String>
private var selection : Binding<Range<String.Index>>?
private var fontSize : Binding<CGFloat>?
private let language : Language?
private let themeName : ThemeName
private let flags : Flags
private let indentStyle : IndentStyle
private let autoPairs : [ String : String ]
private let inset : CGSize
private let allowsUndo : Bool
private let autoscroll : Bool
private let backgroundColor : NSColor?

public var body: some View {
UXCodeTextViewRepresentable(source : source,
selection : selection,
language : language,
theme : themeName,
fontSize : fontSize,
flags : flags,
indentStyle : indentStyle,
autoPairs : autoPairs,
inset : inset,
allowsUndo : allowsUndo,
autoscroll : autoscroll)
UXCodeTextViewRepresentable(source : source,
selection : selection,
language : language,
theme : themeName,
fontSize : fontSize,
flags : flags,
indentStyle : indentStyle,
autoPairs : autoPairs,
inset : inset,
allowsUndo : allowsUndo,
autoscroll : autoscroll,
backgroundColor: backgroundColor)
}
}

Expand Down
6 changes: 4 additions & 2 deletions Sources/CodeEditor/UXCodeTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import Highlightr
final class UXCodeTextView: UXTextView {

fileprivate let highlightr = Highlightr()

var customBackgroundColor: NSColor? = nil

private var hlTextStorage : CodeAttributedString? {
return textStorage as? CodeAttributedString
Expand Down Expand Up @@ -245,7 +247,7 @@ final class UXCodeTextView: UXTextView {
guard let highlightr = highlightr,
highlightr.setTheme(to: newTheme.rawValue),
let theme = highlightr.theme else { return false }
self.backgroundColor = theme.themeBackgroundColor
self.backgroundColor = customBackgroundColor ?? theme.themeBackgroundColor
if let font = theme.codeFont, font !== self.font { self.font = font }
return true
}
Expand All @@ -264,7 +266,7 @@ final class UXCodeTextView: UXTextView {
theme.codeFont = theme.codeFont? .withSize(newSize)
theme.boldCodeFont = theme.boldCodeFont? .withSize(newSize)
theme.italicCodeFont = theme.italicCodeFont?.withSize(newSize)
self.backgroundColor = theme.themeBackgroundColor
self.backgroundColor = customBackgroundColor ?? theme.themeBackgroundColor
if let font = theme.codeFont, font !== self.font { self.font = font }
return true
}
Expand Down
Loading

0 comments on commit 0666597

Please sign in to comment.