PresentationTheme.swift 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*****************************************************************************
  2. * PresentationTheme.swift
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2018 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Carola Nitz <caro # videolan.org>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. import Foundation
  13. extension Notification.Name {
  14. static let VLCThemeDidChangeNotification = Notification.Name("themeDidChangeNotfication")
  15. }
  16. @objcMembers class ColorPalette: NSObject {
  17. let isDark: Bool
  18. let name: String
  19. let statusBarStyle: UIStatusBarStyle
  20. let navigationbarColor: UIColor
  21. let navigationbarTextColor: UIColor
  22. let background: UIColor
  23. let cellBackgroundA: UIColor
  24. let cellBackgroundB: UIColor
  25. let cellDetailTextColor: UIColor
  26. let cellTextColor: UIColor
  27. let lightTextColor: UIColor
  28. let sectionHeaderTextColor: UIColor
  29. let separatorColor: UIColor
  30. let mediaCategorySeparatorColor: UIColor
  31. let tabBarColor: UIColor
  32. let orangeUI: UIColor
  33. let toolBarStyle: UIBarStyle
  34. init(isDark: Bool,
  35. name: String,
  36. statusBarStyle: UIStatusBarStyle,
  37. navigationbarColor: UIColor,
  38. navigationbarTextColor: UIColor,
  39. background: UIColor,
  40. cellBackgroundA: UIColor,
  41. cellBackgroundB: UIColor,
  42. cellDetailTextColor: UIColor,
  43. cellTextColor: UIColor,
  44. lightTextColor: UIColor,
  45. sectionHeaderTextColor: UIColor,
  46. separatorColor: UIColor,
  47. mediaCategorySeparatorColor: UIColor,
  48. tabBarColor: UIColor,
  49. orangeUI: UIColor,
  50. toolBarStyle: UIBarStyle) {
  51. self.isDark = isDark
  52. self.name = name
  53. self.statusBarStyle = statusBarStyle
  54. self.navigationbarColor = navigationbarColor
  55. self.navigationbarTextColor = navigationbarTextColor
  56. self.background = background
  57. self.cellBackgroundA = cellBackgroundA
  58. self.cellBackgroundB = cellBackgroundB
  59. self.cellDetailTextColor = cellDetailTextColor
  60. self.cellTextColor = cellTextColor
  61. self.lightTextColor = lightTextColor
  62. self.sectionHeaderTextColor = sectionHeaderTextColor
  63. self.separatorColor = separatorColor
  64. self.mediaCategorySeparatorColor = mediaCategorySeparatorColor
  65. self.tabBarColor = tabBarColor
  66. self.orangeUI = orangeUI
  67. self.toolBarStyle = toolBarStyle
  68. }
  69. }
  70. @objcMembers class Typography: NSObject {
  71. let tableHeaderFont: UIFont
  72. init(tableHeaderFont: UIFont) {
  73. self.tableHeaderFont = tableHeaderFont
  74. }
  75. }
  76. // MARK: - PresentationThemeType
  77. enum PresentationThemeType: Int {
  78. case bright = 0
  79. case dark
  80. case auto
  81. }
  82. @objcMembers class PresentationTheme: NSObject {
  83. static let brightTheme = PresentationTheme(colors: brightPalette)
  84. static let darkTheme = PresentationTheme(colors: darkPalette)
  85. static var current: PresentationTheme = {
  86. let themeSettings = UserDefaults.standard.integer(forKey: kVLCSettingAppTheme)
  87. return PresentationTheme.respectiveTheme(for: PresentationThemeType(rawValue: themeSettings))
  88. }() {
  89. didSet {
  90. AppearanceManager.setupAppearance(theme: self.current)
  91. NotificationCenter.default.post(name: .VLCThemeDidChangeNotification, object: self)
  92. }
  93. }
  94. init(colors: ColorPalette) {
  95. self.colors = colors
  96. super.init()
  97. }
  98. static func themeDidUpdate() {
  99. let themeSettings = UserDefaults.standard.integer(forKey: kVLCSettingAppTheme)
  100. PresentationTheme.current = PresentationTheme.respectiveTheme(for:
  101. PresentationThemeType(rawValue: themeSettings))
  102. }
  103. static func respectiveTheme(for theme: PresentationThemeType?) -> PresentationTheme {
  104. guard let theme = theme else {
  105. return PresentationTheme.brightTheme
  106. }
  107. var presentationTheme = PresentationTheme.brightTheme
  108. if theme == .dark {
  109. presentationTheme = PresentationTheme.darkTheme
  110. } else if theme == .auto {
  111. if #available(iOS 13.0, *) {
  112. let isSystemDarkTheme = UIScreen.main.traitCollection.userInterfaceStyle == .dark
  113. presentationTheme = isSystemDarkTheme ? PresentationTheme.darkTheme : PresentationTheme.brightTheme
  114. }
  115. }
  116. return presentationTheme
  117. }
  118. let colors: ColorPalette
  119. let font = defaultFont
  120. }
  121. @objc extension UIColor {
  122. convenience init(_ rgbValue: UInt32, _ alpha: CGFloat = 1.0) {
  123. let r = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0
  124. let g = CGFloat((rgbValue & 0xFF00) >> 8) / 255.0
  125. let b = CGFloat(rgbValue & 0xFF) / 255.0
  126. self.init(red: r, green: g, blue: b, alpha: 1.0)
  127. }
  128. private func toHex(alpha: Bool = false) -> String? {
  129. guard let components = cgColor.components, components.count >= 3 else {
  130. assertionFailure()
  131. return nil
  132. }
  133. let r = Float(components[0])
  134. let g = Float(components[1])
  135. let b = Float(components[2])
  136. var a = Float(1.0)
  137. if components.count == 4 {
  138. a = Float(components[3])
  139. }
  140. if alpha {
  141. return String(format: "#%02lX%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255), lroundf(a * 255))
  142. } else {
  143. return String(format: "#%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255))
  144. }
  145. }
  146. var toHex: String? {
  147. return toHex()
  148. }
  149. }
  150. let brightPalette = ColorPalette(isDark: false,
  151. name: "Default",
  152. statusBarStyle: .autoDarkContent,
  153. navigationbarColor: UIColor(0xFFFFFF),
  154. navigationbarTextColor: UIColor(0x000000),
  155. background: UIColor(0xFFFFFF),
  156. cellBackgroundA: UIColor(0xFFFFFF),
  157. cellBackgroundB: UIColor(0xE5E5E3),
  158. cellDetailTextColor: UIColor(0x84929C),
  159. cellTextColor: UIColor(0x000000),
  160. lightTextColor: UIColor(0x888888),
  161. sectionHeaderTextColor: UIColor(0x25292C),
  162. separatorColor: UIColor(0xF0F2F7),
  163. mediaCategorySeparatorColor: UIColor(0xECF2F6),
  164. tabBarColor: UIColor(0xFFFFFF),
  165. orangeUI: UIColor(0xFF8800),
  166. toolBarStyle: UIBarStyle.default)
  167. let darkPalette = ColorPalette(isDark: true,
  168. name: "Dark",
  169. statusBarStyle: .lightContent,
  170. navigationbarColor: UIColor(0x1B1E21),
  171. navigationbarTextColor: UIColor(0xFFFFFF),
  172. background: UIColor(0x1B1E21),
  173. cellBackgroundA: UIColor(0x1B1E21),
  174. cellBackgroundB: UIColor(0x494B4D),
  175. cellDetailTextColor: UIColor(0x84929C),
  176. cellTextColor: UIColor(0xFFFFFF),
  177. lightTextColor: UIColor(0xB8B8B8),
  178. sectionHeaderTextColor: UIColor(0x828282),
  179. separatorColor: UIColor(0x25292C),
  180. mediaCategorySeparatorColor: UIColor(0x25292C),
  181. tabBarColor: UIColor(0x25292C),
  182. orangeUI: UIColor(0xFF8800),
  183. toolBarStyle: UIBarStyle.black)
  184. let defaultFont = Typography(tableHeaderFont: UIFont.systemFont(ofSize: 24, weight: .semibold))
  185. // MARK: - UIStatusBarStyle - autoDarkContent
  186. extension UIStatusBarStyle {
  187. static var autoDarkContent: UIStatusBarStyle {
  188. if #available(iOS 13.0, *) {
  189. return .darkContent
  190. } else {
  191. return .default
  192. }
  193. }
  194. }