Skip to content

Commit

Permalink
Merge pull request #129 from danielsaidi/improvement/richtextaction
Browse files Browse the repository at this point in the history
RichTextAction subscription
  • Loading branch information
danielsaidi authored Feb 3, 2024
2 parents b410667 + d3789d8 commit 697e073
Show file tree
Hide file tree
Showing 25 changed files with 596 additions and 328 deletions.
30 changes: 30 additions & 0 deletions Sources/RichTextKit/Actions/Insertion.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Insertion.swift
//
//
// Created by Dominik Bucher on 17.01.2024.
//

import Foundation

extension String: Insertable {}
extension ImageRepresentable: Insertable {}
extension [ImageRepresentable]: Insertable {}
extension NSAttributedString: Insertable {}

public protocol Insertable: Hashable {}

public struct Insertion<T: Insertable>: Hashable {
typealias Index = Int
let content: T
let at: Index
let moveCursor: Bool
}

extension Insertion: Equatable {
public static func == (lhs: Insertion<T>, rhs: Insertion<T>) -> Bool {
return true
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public extension View {
case .stepSuperscript: self
case .toggleStyle(let style): keyboardShortcut(for: style)
case .undoLatestChange: keyboardShortcut("z", modifiers: .command)
default: self // TODO: Probably not defined, object to discuss.
}
#else
self
Expand Down
60 changes: 59 additions & 1 deletion Sources/RichTextKit/Actions/RichTextAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public enum RichTextAction: Identifiable, Equatable, RichTextLabelValue {

/// Copy the currently selected text, if any.
case copy

/// Dismiss any presented software keyboard.
case dismissKeyboard

Expand All @@ -46,6 +45,28 @@ public enum RichTextAction: Identifiable, Equatable, RichTextLabelValue {

/// Undo the latest change.
case undoLatestChange

// Change background color
case setColor(ColorRepresentable, RichTextColor)

// Highlighted renge
case setHighlightedRange(NSRange?)

// Change highlighting style
case setHighlightingStyle(RichTextHighlightingStyle)

case pasteImage(Insertion<ImageRepresentable>)

case pasteImages(Insertion<[ImageRepresentable]>)

case pasteText(Insertion<String>)

case selectRange(NSRange)

case setAttributedString(NSAttributedString)

// Change style of text (bold, italic, underline, strikethrough
case setStyle(RichTextStyle, Bool)
}

public extension RichTextAction {
Expand All @@ -66,6 +87,16 @@ public extension RichTextAction {
case .stepSuperscript(let val): .richTextStepSuperscript(val)
case .toggleStyle(let val): val.icon
case .undoLatestChange: .richTextActionUndo
case .setColor(_, let richTextColor): richTextColor.icon ?? .richTextColorBackground
case .setHighlightedRange: .richTextAlignmentCenter
case .setHighlightingStyle: .richTextAlignmentCenter
case .pasteImage: .richTextDocuments
case .pasteImages: .richTextDocuments
case .pasteText: .richTextStepIndent(1)
case .selectRange: .richTextAlignmentCenter
case .setAttributedString: .richTextAlignmentCenter
case .setStyle:
Image.richTextStyleBold
}
}

Expand Down Expand Up @@ -100,6 +131,33 @@ public extension RichTextAction {
case .stepSuperscript(let steps): .actionStepSuperscript(steps)
case .toggleStyle(let style): style.titleKey
case .undoLatestChange: .actionUndoLatestChange
case .setColor(_, let richTextColor):
switch richTextColor {
case .foreground: .foregroundColor
case .background: .backgroundColor
case .strikethrough: .strikethroughColor
case .stroke: .strokeColor
case .underline: .underlineColor
case .undefined: .strokeColor
}
case .setHighlightedRange: .highlightedRange
case .setHighlightingStyle: .highlightingStyle
case .pasteImage: .pasteImage
case .pasteImages: .pasteImages
case .pasteText: .pasteText
case .selectRange: .selectRange
case .setAttributedString: .setAttributedString
case .setStyle(let style, _):
switch style {
case .bold:
.styleBold
case .italic:
.styleItalic
case .underlined:
.styleUnderlined
case .strikethrough:
.styleStrikethrough
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/RichTextKit/Component/RichTextViewComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public extension RichTextViewComponent {
}
}

internal extension RichTextViewComponent {
extension RichTextViewComponent {

/// This can be called to setup the initial font size.
func setupInitialFontSize() {
Expand Down
32 changes: 21 additions & 11 deletions Sources/RichTextKit/Context/RichTextContext+Actions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,33 @@ public extension RichTextContext {
case .setAlignment(let align): textAlignment = align
case .stepFontSize(let points): fontSize += CGFloat(points)
case .toggleStyle(let style): toggle(style)
default: triggerAction = action
default: break
}
}

/// Check if the context can handle a certain action.
func canHandle(_ action: RichTextAction) -> Bool {
switch action {
case .copy: canCopy
case .dismissKeyboard: true
case .print: false
case .redoLatestChange: canRedoLatestChange
case .setAlignment: true
case .stepFontSize: true
case .stepIndent(let points): points < 0 ? canDecreaseIndent : canIncreaseIndent
case .stepSuperscript: false
case .toggleStyle: true
case .undoLatestChange: canUndoLatestChange
case .copy: return canCopy
case .dismissKeyboard: return true
case .print: return false
case .redoLatestChange: return canRedoLatestChange
case .setAlignment: return true
case .stepFontSize: return true
case .stepIndent(let points):
return points < 0 ? canDecreaseIndent : canIncreaseIndent
case .stepSuperscript: return false
case .toggleStyle: return true
case .undoLatestChange: return canUndoLatestChange
case .setColor: return true
case .setHighlightedRange: return true
case .setHighlightingStyle: return true
case .pasteImage: return true
case .pasteImages: return true
case .pasteText: return true
case .selectRange: return true
case .setAttributedString: return true
case .setStyle: return true
}
}
}
4 changes: 3 additions & 1 deletion Sources/RichTextKit/Context/RichTextContext+Colors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ public extension RichTextContext {
_ color: ColorRepresentable,
for val: RichTextColor
) {
if self.color(for: val) == color { return }
guard self.color(for: val) != color else { return }
userActionPublisher.send(.setColor(color, val))

switch val {
case .foreground: foregroundColor = color
case .background: backgroundColor = color
Expand Down
8 changes: 4 additions & 4 deletions Sources/RichTextKit/Context/RichTextContext+Styles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ public extension RichTextContext {
to val: Bool
) {
switch style {
case .bold: isBold = val
case .italic: isItalic = val
case .underlined: isUnderlined = val
case .strikethrough: isStrikethrough = val
case .bold: userActionPublisher.send(.setStyle(.bold, val)); isBold = val
case .italic: userActionPublisher.send(.setStyle(.italic, val)); isItalic = val
case .underlined: userActionPublisher.send(.setStyle(.underlined, val)); isUnderlined = val
case .strikethrough: userActionPublisher.send(.setStyle(.strikethrough, val)); isStrikethrough = val
}
}

Expand Down
Loading

0 comments on commit 697e073

Please sign in to comment.