| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- //
- // AppLayoutDirection.swift
- // App for Indeed
- //
- import Cocoa
- /// Layout direction for the in-app language (Arabic and Hebrew are RTL).
- enum AppLayoutDirection {
- static var isRightToLeft: Bool {
- currentAppLanguage().isRightToLeft
- }
- static var interface: NSUserInterfaceLayoutDirection {
- isRightToLeft ? .rightToLeft : .leftToRight
- }
- static var naturalTextAlignment: NSTextAlignment {
- isRightToLeft ? .right : .natural
- }
- static var naturalWritingDirection: NSWritingDirection {
- isRightToLeft ? .rightToLeft : .natural
- }
- static func naturalParagraphStyle(
- alignment: NSTextAlignment? = nil,
- lineBreakMode: NSLineBreakMode = .byWordWrapping
- ) -> NSParagraphStyle {
- let paragraph = NSMutableParagraphStyle()
- paragraph.alignment = alignment ?? naturalTextAlignment
- paragraph.baseWritingDirection = naturalWritingDirection
- paragraph.lineBreakMode = lineBreakMode
- return paragraph
- }
- static func apply(to view: NSView) {
- view.userInterfaceLayoutDirection = interface
- }
- static func applyRecursively(to root: NSView) {
- var stack: [NSView] = [root]
- while let view = stack.popLast() {
- view.userInterfaceLayoutDirection = interface
- stack.append(contentsOf: view.subviews)
- }
- }
- static func configureTextField(_ field: NSTextField) {
- field.alignment = naturalTextAlignment
- field.baseWritingDirection = naturalWritingDirection
- if let cell = field.cell as? NSTextFieldCell {
- cell.alignment = naturalTextAlignment
- cell.baseWritingDirection = naturalWritingDirection
- }
- }
- static func placeholderAttributes(
- font: NSFont,
- color: NSColor,
- lineBreakMode: NSLineBreakMode = .byTruncatingTail
- ) -> [NSAttributedString.Key: Any] {
- [
- .foregroundColor: color,
- .font: font,
- .paragraphStyle: naturalParagraphStyle(alignment: naturalTextAlignment, lineBreakMode: lineBreakMode)
- ]
- }
- static func attributedString(
- _ text: String,
- font: NSFont,
- color: NSColor,
- lineBreakMode: NSLineBreakMode = .byWordWrapping
- ) -> NSAttributedString {
- NSAttributedString(string: text, attributes: [
- .font: font,
- .foregroundColor: color,
- .paragraphStyle: naturalParagraphStyle(lineBreakMode: lineBreakMode)
- ])
- }
- static func refreshTextFields(in root: NSView) {
- var stack: [NSView] = [root]
- while let view = stack.popLast() {
- if let field = view as? NSTextField {
- configureTextField(field)
- }
- stack.append(contentsOf: view.subviews)
- }
- }
- @MainActor
- static func applyToAllWindows() {
- for window in NSApp.windows {
- guard let content = window.contentView else { continue }
- applyRecursively(to: content)
- refreshTextFields(in: content)
- }
- }
- }
- extension AppLanguage {
- var isRightToLeft: Bool {
- switch self {
- case .arabic, .hebrew:
- return true
- default:
- return false
- }
- }
- }
|