Last active
June 6, 2016 08:13
-
-
Save leonbreedt/b669c00cc17e70e89a232559dfca7d6f to your computer and use it in GitHub Desktop.
Simple attributed string styles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
/// Enumerates the types of fonts supported for attributed strings. | |
enum TextFontType { | |
case System | |
case Named(String) | |
} | |
/// Describes font attributes that can be applied to attributed strings. | |
struct TextFont { | |
let type: TextFontType | |
let size: Float | |
let bold: Bool | |
let italic: Bool | |
} | |
/// Describes colors that can be applied to text in attributed strings. | |
struct TextColor { | |
let foreground: NSColor? | |
let background: NSColor? | |
} | |
/// Aggregates all style attributes that can be applied to text in attributed strings. | |
struct TextStyle { | |
let font: TextFont | |
let color: TextColor | |
let underline: Bool | |
let strikethrough: Bool | |
} | |
/// Protocol for composing text styles in a fluent manner. | |
protocol TextStyleConfigurable { | |
func font(type: TextFontType, size: Float, bold: Bool, italic: Bool) -> Self | |
func font(font: NSFont) -> Self | |
func underline() -> Self | |
func strikethrough() -> Self | |
func foreground(color: NSColor) -> Self | |
func background(color: NSColor) -> Self | |
} | |
final class AttributedTextStyle: TextStyleConfigurable { | |
private var attributes: [String: NSObject] = [:] | |
func font(type: TextFontType = .System, | |
size: Float = Float(NSFont.systemFontSize()), | |
bold: Bool = false, | |
italic: Bool = false) -> Self { | |
let pointSize = CGFloat(size) | |
let systemFont = NSFont.systemFontOfSize(pointSize) | |
var font: NSFont | |
switch type { | |
case .System: | |
font = systemFont | |
case let .Named(name): | |
font = NSFont(name: name, size: pointSize) ?? systemFont | |
} | |
let fontManager = NSFontManager.sharedFontManager() | |
if bold { | |
font = fontManager.convertFont(font, toHaveTrait: .BoldFontMask) | |
} | |
if italic { | |
font = fontManager.convertFont(font, toHaveTrait: .ItalicFontMask) | |
} | |
self.font(font) | |
return self | |
} | |
func font(font: NSFont) -> Self { | |
attributes[NSFontAttributeName] = font | |
return self | |
} | |
func underline() -> Self { | |
attributes[NSUnderlineStyleAttributeName] = 1 | |
return self | |
} | |
func strikethrough() -> Self { | |
attributes[NSStrikethroughStyleAttributeName] = 1 | |
return self | |
} | |
func foreground(color: NSColor) -> Self { | |
attributes[NSForegroundColorAttributeName] = color | |
return self | |
} | |
func background(color: NSColor) -> Self { | |
attributes[NSBackgroundColorAttributeName] = color | |
return self | |
} | |
} | |
typealias AttributedTextStyleBlock = AttributedTextStyle -> Void | |
extension NSMutableAttributedString { | |
/// Appends a string to this attributed string, after applying the styles provided by the | |
/// configuration block, if any. | |
func append(string: String, _ styleConfigurationBlock: AttributedTextStyleBlock? = nil) { | |
let style = AttributedTextStyle() | |
styleConfigurationBlock?(style) | |
appendAttributedString(NSMutableAttributedString(string: string, attributes: style.attributes)) | |
} | |
} | |
let boldWhiteAvenirOnRed: AttributedTextStyleBlock = { style in | |
style | |
.font(.Named("Avenir"), size: 18, bold: true) | |
.background(NSColor.redColor()) | |
.foreground(NSColor.whiteColor()) | |
} | |
// Let's try! | |
let string = NSMutableAttributedString() | |
string.append("CocoaPods", boldWhiteAvenirOnRed) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment