Skip to content

Commit

Permalink
Support font family (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-divyesh-v authored Nov 25, 2024
1 parent 55892a4 commit 9e4cbdf
Show file tree
Hide file tree
Showing 28 changed files with 896 additions and 117 deletions.
4 changes: 2 additions & 2 deletions RichEditorDemo/RichEditorDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 14.0;
Expand Down Expand Up @@ -344,7 +344,7 @@
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 14.0;
Expand Down
48 changes: 34 additions & 14 deletions RichEditorDemo/RichEditorDemo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@
// Created by Divyesh Vekariya on 11/10/23.
//

import SwiftUI
import RichEditorSwiftUI
import SwiftUI

struct ContentView: View {
@Environment(\.colorScheme) var colorScheme

@ObservedObject var state: RichEditorState
@State private var isInspectorPresented = false

init(state: RichEditorState? = nil) {
if let state {
self.state = state
} else {
if let richText = readJSONFromFile(fileName: "Sample_json",
type: RichText.self) {
if let richText = readJSONFromFile(
fileName: "Sample_json",
type: RichText.self)
{
self.state = .init(richText: richText)
} else {
self.state = .init(input: "Hello World!")
Expand All @@ -29,9 +32,9 @@ struct ContentView: View {
var body: some View {
NavigationStack {
VStack {
#if os(iOS) || os(macOS) || os(visionOS)
EditorToolBarView(state: state)
#endif
#if os(macOS)
RichTextFormat.Toolbar(context: state)
#endif

RichTextEditor(
context: _state,
Expand All @@ -40,22 +43,39 @@ struct ContentView: View {
}
)
.cornerRadius(10)

#if os(iOS)
RichTextKeyboardToolbar(
context: state,
leadingButtons: { $0 },
trailingButtons: { $0 },
formatSheet: { $0 }
)
#endif
}
.inspector(isPresented: $isInspectorPresented) {
RichTextFormat.Sidebar(context: state)
#if os(macOS)
.inspectorColumnWidth(min: 200, ideal: 200, max: 315)
#endif
}
.padding(10)
.toolbar {
ToolbarItem() {
Button(action: {
print("Exported JSON == \(state.output())")
}, label: {
Image(systemName: "printer.inverse")
.padding()
})
ToolbarItem(placement: .automatic) {
Button(
action: {
print("Exported JSON == \(state.output())")
},
label: {
Image(systemName: "printer.inverse")
.padding()
})
}
}
.background(colorScheme == .dark ? .black : .gray.opacity(0.07))
.navigationTitle("Rich Editor")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
.navigationBarTitleDisplayMode(.inline)
#endif
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/RichEditorSwiftUI/Actions/RichTextAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public enum RichTextAction: Identifiable, Equatable {
case undoLatestChange

/// Set HeaderStyle.
case setHeaderStyle(_ style: RichTextStyle)
case setHeaderStyle(_ style: RichTextSpanStyle)
}

public extension RichTextAction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ public extension RichTextAttributeReader {
public extension RichTextAttributeReader {

/// Get the text styles at a certain range.
func richTextStyles(at range: NSRange) -> [RichTextStyle] {
func richTextStyles(at range: NSRange) -> [RichTextSpanStyle] {
let attributes = richTextAttributes(at: range)
let traits = richTextFont(at: range)?.fontDescriptor.symbolicTraits
var styles = traits?.enabledRichTextStyles ?? []
if attributes.isStrikethrough { styles.append(.strikethrough) }
if attributes.isUnderlined { styles.append(.underline) }
return styles
return styles.map({ $0.richTextSpanStyle })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public extension NSMutableAttributedString {
- range: The range to affect, by default the entire text.
*/
func setRichTextStyle(
_ style: RichTextStyle,
_ style: RichTextSpanStyle,
to newValue: Bool,
at range: NSRange? = nil
) {
Expand All @@ -43,8 +43,8 @@ public extension NSMutableAttributedString {
let shouldRemove = !newValue && styles.hasStyle(style)
guard shouldAdd || shouldRemove || style.isHeaderStyle else { return }
var descriptor = font.fontDescriptor
if !style.isDefault && !style.isHeaderStyle {
descriptor = descriptor.byTogglingStyle(style)
if let richTextStyle = style.richTextStyle, !style.isDefault && !style.isHeaderStyle {
descriptor = descriptor.byTogglingStyle(richTextStyle)
}
let newFont: FontRepresentable? = FontRepresentable(
descriptor: descriptor,
Expand All @@ -56,7 +56,7 @@ public extension NSMutableAttributedString {
/**
This will reset font size before multiplying new size
*/
private func byTogglingFontSizeFor(style: TextSpanStyle, font: FontRepresentable, shouldAdd: Bool) -> CGFloat {
private func byTogglingFontSizeFor(style: RichTextSpanStyle, font: FontRepresentable, shouldAdd: Bool) -> CGFloat {
guard style.isHeaderStyle || style.isDefault else { return font.pointSize }

let cleanFont = style.getFontAfterRemovingStyle(font: font)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ extension RichTextCoordinator {

func setStyle(_ style: RichTextStyle, to newValue: Bool) {
let hasStyle = textView.richTextStyles.hasStyle(style)
if newValue == hasStyle { return }
guard newValue != hasStyle else { return }
textView.setRichTextStyle(style, to: newValue)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ public extension RichTextViewComponent {
setRichTextAttribute(.underlineStyle, to: value)
case .strikethrough:
setRichTextAttribute(.strikethroughStyle, to: value)
default:
return
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public enum HeaderType: Int, CaseIterable, Codable {
}
}

func getTextSpanStyle() -> TextSpanStyle {
func getTextSpanStyle() -> RichTextSpanStyle {
switch self {
case .default: return .default
case .h1: return .h1
Expand Down
18 changes: 9 additions & 9 deletions Sources/RichEditorSwiftUI/Data/Models/RichAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ extension RichAttributes {
)
}

public func copy(with style: TextSpanStyle, byAdding: Bool = true) -> RichAttributes {
public func copy(with style: RichTextSpanStyle, byAdding: Bool = true) -> RichAttributes {
return copy(with: [style], byAdding: byAdding)
}

public func copy(with styles: [TextSpanStyle], byAdding: Bool = true) -> RichAttributes {
public func copy(with styles: [RichTextSpanStyle], byAdding: Bool = true) -> RichAttributes {
let att = getRichAttributesFor(styles: styles)
return RichAttributes(
bold: (att.bold != nil ? (byAdding ? att.bold! : nil) : self.bold),
Expand All @@ -169,8 +169,8 @@ extension RichAttributes {
}

extension RichAttributes {
public func styles() -> [TextSpanStyle] {
var styles: [TextSpanStyle] = []
public func styles() -> [RichTextSpanStyle] {
var styles: [RichTextSpanStyle] = []
if let bold = bold, bold {
styles.append(.bold)
}
Expand Down Expand Up @@ -204,8 +204,8 @@ extension RichAttributes {
return styles
}

public func stylesSet() -> Set<TextSpanStyle> {
var styles: Set<TextSpanStyle> = []
public func stylesSet() -> Set<RichTextSpanStyle> {
var styles: Set<RichTextSpanStyle> = []
if let bold = bold, bold {
styles.insert(.bold)
}
Expand Down Expand Up @@ -241,7 +241,7 @@ extension RichAttributes {
}

extension RichAttributes {
public func hasStyle(style: RichTextStyle) -> Bool {
public func hasStyle(style: RichTextSpanStyle) -> Bool {
switch style {
case .default:
return true
Expand Down Expand Up @@ -279,11 +279,11 @@ extension RichAttributes {
}
}

internal func getRichAttributesFor(style: RichTextStyle) -> RichAttributes {
internal func getRichAttributesFor(style: RichTextSpanStyle) -> RichAttributes {
return getRichAttributesFor(styles: [style])
}

internal func getRichAttributesFor(styles: [RichTextStyle]) -> RichAttributes {
internal func getRichAttributesFor(styles: [RichTextSpanStyle]) -> RichAttributes {
guard !styles.isEmpty else { return RichAttributes() }
var bold: Bool? = nil
var italic: Bool? = nil
Expand Down
8 changes: 4 additions & 4 deletions Sources/RichEditorSwiftUI/Format/RichTextFormat+Sheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ public extension RichTextFormat {
public var body: some View {
NavigationView {
VStack(spacing: 0) {
// RichTextFont.ListPicker(
// selection: $context.fontName
// )
// Divider()
RichTextFont.ListPicker(
selection: $context.fontName
)
Divider()
RichTextFormat.Toolbar(
context: context
)
Expand Down
7 changes: 5 additions & 2 deletions Sources/RichEditorSwiftUI/Format/RichTextFormat+Sidebar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ public extension RichTextFormat {
VStack(alignment: .leading, spacing: style.spacing) {
SidebarSection {
fontPicker(value: $context.fontName)
.onChangeBackPort(of: context.fontName) { newValue in
context.updateStyle(style: .font(newValue))
}
HStack {
// styleToggleGroup(for: context)
// Spacer()
styleToggleGroup(for: context)
Spacer()
fontSizePicker(for: context)
}
}
Expand Down
9 changes: 6 additions & 3 deletions Sources/RichEditorSwiftUI/Format/RichTextFormat+Toolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ public extension RichTextFormat {

public var body: some View {
VStack(spacing: style.spacing) {
// controls
controls
if hasColorPickers {
// Divider()
Divider()
colorPickers(for: context)
}
}
Expand Down Expand Up @@ -115,8 +115,11 @@ private extension RichTextFormat.Toolbar {
HStack {
#if macOS
fontPicker(value: $context.fontName)
.onChangeBackPort(of: context.fontName) { newValue in
context.updateStyle(style: .font(newValue))
}
#endif
// styleToggleGroup(for: context)
styleToggleGroup(for: context)
if !useSingleLine {
Spacer()
}
Expand Down
23 changes: 12 additions & 11 deletions Sources/RichEditorSwiftUI/Format/RichTextFormatToolbarBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ extension RichTextFormatToolbarBase {
.labelStyle(.iconOnly)
.frame(minWidth: 30)
}
.padding(.horizontal)
}
}

Expand Down Expand Up @@ -148,17 +149,17 @@ extension RichTextFormatToolbarBase {
// }
// }

// @ViewBuilder
// func styleToggleGroup(
// for context: RichEditorState
// ) -> some View {
// if !config.styles.isEmpty {
// RichTextStyle.ToggleGroup(
// context: context,
// styles: config.styles
// )
// }
// }
@ViewBuilder
func styleToggleGroup(
for context: RichEditorState
) -> some View {
if !config.styles.isEmpty {
RichTextStyle.ToggleGroup(
context: context,
styles: config.styles
)
}
}

// @ViewBuilder
// func superscriptButtons(
Expand Down
Loading

0 comments on commit 9e4cbdf

Please sign in to comment.